aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-12-18 20:11:37 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-12-18 20:11:37 +0000
commit461a67fa15370a9ec88f8f8a240bf7c123bb2029 (patch)
tree6942083d7d56bba40ec790a453ca58ad3baf6832 /test
parent75c3240472ba6ac2669ee72ca67eb72d4e2851fc (diff)
downloadsrc-461a67fa15370a9ec88f8f8a240bf7c123bb2029.tar.gz
src-461a67fa15370a9ec88f8f8a240bf7c123bb2029.zip
Vendor import of clang trunk r321017:vendor/clang/clang-trunk-r321017
Notes
Notes: svn path=/vendor/clang/dist/; revision=326941 svn path=/vendor/clang/clang-trunk-r321017/; revision=326942; tag=vendor/clang/clang-trunk-r321017
Diffstat (limited to 'test')
-rw-r--r--test/ASTMerge/namespace/Inputs/namespace1.cpp10
-rw-r--r--test/ASTMerge/namespace/Inputs/namespace2.cpp43
-rw-r--r--test/ASTMerge/namespace/test.cpp17
-rw-r--r--test/Analysis/DeleteWithNonVirtualDtor.cpp187
-rw-r--r--test/Analysis/MisusedMovedObject.cpp78
-rw-r--r--test/Analysis/analyzer-config.c4
-rw-r--r--test/Analysis/analyzer-config.cpp4
-rw-r--r--test/Analysis/bitwise-ops.c27
-rw-r--r--test/Analysis/block-in-critical-section.cpp42
-rw-r--r--test/Analysis/block-in-critical-section.m10
-rw-r--r--test/Analysis/bstring.cpp41
-rw-r--r--test/Analysis/bug_hash_test.cpp1423
-rw-r--r--test/Analysis/bug_hash_test.m1182
-rw-r--r--test/Analysis/call_once.cpp361
-rw-r--r--test/Analysis/casts.c26
-rw-r--r--test/Analysis/cfg-indirect-goto-determinism.cpp96
-rw-r--r--test/Analysis/compound-literals.c9
-rw-r--r--test/Analysis/constant-folding.c39
-rw-r--r--test/Analysis/conversion.c2
-rw-r--r--test/Analysis/copypaste/asm.cpp2
-rw-r--r--test/Analysis/copypaste/attributes.cpp2
-rw-r--r--test/Analysis/copypaste/autogenerated_automoc.cpp2
-rw-r--r--test/Analysis/copypaste/blocks.cpp2
-rw-r--r--test/Analysis/copypaste/call.cpp2
-rw-r--r--test/Analysis/copypaste/catch.cpp2
-rw-r--r--test/Analysis/copypaste/delete.cpp2
-rw-r--r--test/Analysis/copypaste/dependent-exist.cpp2
-rw-r--r--test/Analysis/copypaste/expr-types.cpp2
-rw-r--r--test/Analysis/copypaste/fold.cpp2
-rw-r--r--test/Analysis/copypaste/function-try-block.cpp2
-rw-r--r--test/Analysis/copypaste/functions.cpp2
-rw-r--r--test/Analysis/copypaste/generic.c2
-rw-r--r--test/Analysis/copypaste/labels.cpp2
-rw-r--r--test/Analysis/copypaste/lambda.cpp2
-rw-r--r--test/Analysis/copypaste/macros.cpp2
-rw-r--r--test/Analysis/copypaste/not-autogenerated.cpp2
-rw-r--r--test/Analysis/copypaste/objc-methods.m2
-rw-r--r--test/Analysis/copypaste/plist-diagnostics-notes-as-events.cpp2
-rw-r--r--test/Analysis/copypaste/plist-diagnostics.cpp2
-rw-r--r--test/Analysis/copypaste/sub-sequences.cpp2
-rw-r--r--test/Analysis/copypaste/suspicious-clones.cpp2
-rw-r--r--test/Analysis/copypaste/text-diagnostics.cpp2
-rw-r--r--test/Analysis/ctor.mm11
-rw-r--r--test/Analysis/diagnostics/diag-cross-file-boundaries.c12
-rw-r--r--test/Analysis/edges-new.mm2
-rw-r--r--test/Analysis/exercise-ps.c8
-rw-r--r--test/Analysis/expr-inspection.c1
-rw-r--r--test/Analysis/func-mapping-test.cpp7
-rw-r--r--test/Analysis/generics.m1161
-rw-r--r--test/Analysis/gtest.cpp14
-rw-r--r--test/Analysis/html-diag-singlefile.c14
-rw-r--r--test/Analysis/html-diag-singlefile.h (renamed from test/Analysis/diagnostics/diag-cross-file-boundaries.h)0
-rw-r--r--test/Analysis/html-diags-analyze-headers.c10
-rw-r--r--test/Analysis/html-diags-analyze-headers.h5
-rw-r--r--test/Analysis/html-diags-multifile.c5
-rw-r--r--test/Analysis/html-diags.c18
-rw-r--r--test/Analysis/initializer.cpp22
-rw-r--r--test/Analysis/inlining/inline-defensive-checks.c12
-rw-r--r--test/Analysis/lambdas.cpp10
-rw-r--r--test/Analysis/loop-unrolling.cpp381
-rw-r--r--test/Analysis/loop-widening-notes.cpp72
-rw-r--r--test/Analysis/loopexit-cfg-output.cpp476
-rw-r--r--test/Analysis/malloc-plist.c1074
-rw-r--r--test/Analysis/malloc.mm2
-rw-r--r--test/Analysis/max-nodes-suppress-on-sink.c52
-rw-r--r--test/Analysis/max-nodes-suppress-on-sink.cpp34
-rw-r--r--test/Analysis/nonnull-global-constants.mm103
-rw-r--r--test/Analysis/null-deref-path-notes.c9
-rw-r--r--test/Analysis/null-deref-path-notes.cpp25
-rw-r--r--test/Analysis/null-deref-path-notes.m240
-rw-r--r--test/Analysis/null-deref-ps.c4
-rw-r--r--test/Analysis/nullptr.cpp65
-rw-r--r--test/Analysis/objc-boxing.m35
-rw-r--r--test/Analysis/objc-encode.m9
-rw-r--r--test/Analysis/objc-for.m25
-rw-r--r--test/Analysis/pointer-arithmetic.c30
-rw-r--r--test/Analysis/pointer-to-member.cpp39
-rw-r--r--test/Analysis/ptr-arith.c5
-rw-r--r--test/Analysis/ptr-arith.cpp19
-rw-r--r--test/Analysis/reference.cpp11
-rw-r--r--test/Analysis/retain-release-inline.m44
-rw-r--r--test/Analysis/retain-release-safe.c72
-rw-r--r--test/Analysis/retain-release.m62
-rw-r--r--test/Analysis/retain-release.mm9
-rw-r--r--test/Analysis/stack-capture-leak-arc.mm189
-rw-r--r--test/Analysis/stack-capture-leak-no-arc.mm37
-rw-r--r--test/Analysis/string-with-signedness.c10
-rw-r--r--test/Analysis/taint-tester.c7
-rw-r--r--test/Analysis/temp-obj-dtors-cfg-output.cpp81
-rw-r--r--test/Analysis/uninit-const.c30
-rw-r--r--test/Analysis/unix-fns.c994
-rw-r--r--test/Analysis/unreachable-code-path.c10
-rw-r--r--test/Analysis/vector.m61
-rw-r--r--test/Analysis/virtualcall.cpp281
-rw-r--r--test/Analysis/virtualcall.h32
-rw-r--r--test/CMakeLists.txt24
-rw-r--r--test/CXX/basic/basic.link/p8.cpp78
-rw-r--r--test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp1
-rw-r--r--test/CXX/basic/basic.scope/basic.scope.declarative/p4.cpp19
-rw-r--r--test/CXX/class/class.static/class.static.data/p3.cpp2
-rw-r--r--test/CXX/concepts-ts/dcl.dcl/lit.cfg.py26
-rw-r--r--test/CXX/conv/conv.prom/p2.cpp2
-rw-r--r--test/CXX/dcl.dcl/dcl.attr/dcl.attr.depend/p1.cpp6
-rw-r--r--test/CXX/dcl.dcl/dcl.attr/dcl.attr.fallthrough/p1.cpp2
-rw-r--r--test/CXX/dcl.dcl/dcl.attr/dcl.attr.nodiscard/p1.cpp2
-rw-r--r--test/CXX/dcl.dcl/dcl.attr/dcl.attr.nodiscard/p2.cpp12
-rw-r--r--test/CXX/dcl.dcl/dcl.spec/dcl.stc/p2.cpp1
-rw-r--r--test/CXX/drs/dr11xx.cpp30
-rw-r--r--test/CXX/drs/dr4xx.cpp11
-rw-r--r--test/CXX/except/except.spec/p1.cpp9
-rw-r--r--test/CXX/expr/expr.const/p2-0x.cpp14
-rw-r--r--test/CXX/expr/expr.prim/expr.prim.lambda/p8.cpp4
-rw-r--r--test/CXX/expr/expr.unary/expr.new/p2-cxx0x.cpp6
-rw-r--r--test/CXX/expr/expr.unary/expr.new/p2-cxx14.cpp10
-rw-r--r--test/CXX/expr/expr.unary/expr.new/p2-cxx1z.cpp11
-rw-r--r--test/CXX/modules-ts/basic/basic.def.odr/p4/module.cpp23
-rw-r--r--test/CXX/modules-ts/basic/basic.def.odr/p4/module.cppm43
-rw-r--r--test/CXX/modules-ts/basic/basic.def.odr/p4/user.cpp6
-rw-r--r--test/CXX/modules-ts/basic/basic.def.odr/p6/global-vs-module.cpp55
-rw-r--r--test/CXX/modules-ts/basic/basic.def.odr/p6/module-vs-global.cpp19
-rw-r--r--test/CXX/modules-ts/basic/basic.def.odr/p6/module-vs-module.cpp44
-rw-r--r--test/CXX/modules-ts/basic/basic.link/module-declaration.cpp13
-rw-r--r--test/CXX/modules-ts/basic/basic.link/p3.cppm11
-rw-r--r--test/CXX/modules-ts/basic/basic.search/module-import.cpp39
-rw-r--r--test/CXX/modules-ts/codegen-basics.cppm16
-rw-r--r--test/CXX/modules-ts/dcl.dcl/dcl.module/dcl.module.export/p1.cpp40
-rw-r--r--test/CXX/modules-ts/dcl.dcl/dcl.module/dcl.module.import/p1.cpp14
-rw-r--r--test/CXX/modules-ts/dcl.dcl/dcl.module/dcl.module.interface/p1.cpp13
-rw-r--r--test/CXX/modules-ts/dcl.dcl/dcl.module/p1.cpp14
-rw-r--r--test/CXX/modules-ts/dcl.dcl/dcl.module/p2.cpp6
-rw-r--r--test/CXX/over/over.match/over.match.best/p1.cpp6
-rw-r--r--test/CXX/over/over.match/over.match.funcs/over.match.class.deduct/p2.cpp68
-rw-r--r--test/CXX/special/class.dtor/p5-implicit.cpp21
-rw-r--r--test/CXX/temp/temp.decls/temp.variadic/p4.cpp98
-rw-r--r--test/CodeCompletion/call.cpp4
-rw-r--r--test/CodeCompletion/crash-func-init.cpp4
-rw-r--r--test/CodeCompletion/ignore-ns-level-decls.cpp21
-rw-r--r--test/CodeCompletion/qualifiers-as-written.cpp31
-rw-r--r--test/CodeCompletion/uninstantiated_params.cpp2
-rw-r--r--test/CodeGen/2004-02-20-Builtins.c5
-rw-r--r--test/CodeGen/2005-07-20-SqrtNoErrno.c10
-rw-r--r--test/CodeGen/2009-10-20-GlobalDebug.c4
-rw-r--r--test/CodeGen/2010-08-10-DbgConstant.c3
-rw-r--r--test/CodeGen/Inputs/sanitizer-special-case-list.sanitized.txt4
-rw-r--r--test/CodeGen/Inputs/sanitizer-special-case-list.unsanitized1.txt2
-rw-r--r--test/CodeGen/Inputs/sanitizer-special-case-list.unsanitized2.txt4
-rw-r--r--test/CodeGen/Inputs/sanitizer-special-case-list.unsanitized3.txt4
-rw-r--r--test/CodeGen/Inputs/sanitizer-special-case-list.unsanitized4.txt4
-rw-r--r--test/CodeGen/adc-builtins.c4
-rw-r--r--test/CodeGen/address-safety-attr-kasan-hwasan.cpp53
-rw-r--r--test/CodeGen/arm-metadata.c2
-rw-r--r--test/CodeGen/arm64-microsoft-intrinsics.c26
-rw-r--r--test/CodeGen/attr-availability.c6
-rw-r--r--test/CodeGen/attr-mprefer-vector-width.c14
-rw-r--r--test/CodeGen/attr-target-x86.c25
-rw-r--r--test/CodeGen/avx-builtins.c6
-rw-r--r--test/CodeGen/avx2-builtins.c32
-rw-r--r--test/CodeGen/avx512-reduceMinMaxIntrin.c2852
-rw-r--r--test/CodeGen/avx512bw-builtins.c330
-rw-r--r--test/CodeGen/avx512cdintrin.c38
-rw-r--r--test/CodeGen/avx512dq-builtins.c16
-rw-r--r--test/CodeGen/avx512f-builtins.c437
-rw-r--r--test/CodeGen/avx512ifmavl-builtins.c4
-rw-r--r--test/CodeGen/avx512vl-builtins.c205
-rw-r--r--test/CodeGen/avx512vlbw-builtins.c347
-rw-r--r--test/CodeGen/avx512vlcd-builtins.c56
-rw-r--r--test/CodeGen/avx512vldq-builtins.c24
-rw-r--r--test/CodeGen/avx512vpopcntdqvlintrin.c73
-rw-r--r--test/CodeGen/blocks-opencl.cl17
-rw-r--r--test/CodeGen/bounds-checking.c4
-rw-r--r--test/CodeGen/builtin-clflushopt.c6
-rw-r--r--test/CodeGen/builtin-clwb.c9
-rw-r--r--test/CodeGen/builtin-clzero.c4
-rw-r--r--test/CodeGen/builtin-cpu-is.c53
-rw-r--r--test/CodeGen/builtin-cpu-supports.c4
-rw-r--r--test/CodeGen/builtin-sqrt.c15
-rw-r--r--test/CodeGen/builtins-hexagon.c4158
-rw-r--r--test/CodeGen/builtins-nvptx-ptx50.cu23
-rw-r--r--test/CodeGen/builtins-nvptx-ptx60.cu97
-rw-r--r--test/CodeGen/builtins-nvptx-sm_70.cu166
-rw-r--r--test/CodeGen/builtins-nvptx.c33
-rw-r--r--test/CodeGen/builtins-overflow.c119
-rw-r--r--test/CodeGen/builtins-x86.c21
-rw-r--r--test/CodeGen/builtins.c536
-rw-r--r--test/CodeGen/catch-undef-behavior.c3
-rw-r--r--test/CodeGen/cetintrin.c84
-rw-r--r--test/CodeGen/cfi-icall-cross-dso.c10
-rw-r--r--test/CodeGen/cfi-icall-generalize.c19
-rw-r--r--test/CodeGen/cfi-icall.c10
-rw-r--r--test/CodeGen/cfi-unrelated-cast.cpp37
-rw-r--r--test/CodeGen/complex-builtins.c206
-rw-r--r--test/CodeGen/complex-libcalls.c208
-rw-r--r--test/CodeGen/darwin-ppc-varargs.c28
-rw-r--r--test/CodeGen/debug-info-attributed-stmt.c12
-rw-r--r--test/CodeGen/debug-info-block-vars.c20
-rw-r--r--test/CodeGen/debug-info-global-constant.c3
-rw-r--r--test/CodeGen/debug-info-lto.c4
-rw-r--r--test/CodeGen/debug-info-preprocessed-file.i11
-rw-r--r--test/CodeGen/debug-info-static-const-fp.c11
-rw-r--r--test/CodeGen/debug-info-static.c2
-rw-r--r--test/CodeGen/debug-info-vla.c3
-rw-r--r--test/CodeGen/finite-math.c2
-rw-r--r--test/CodeGen/fma-builtins.c104
-rw-r--r--test/CodeGen/fma4-builtins.c76
-rw-r--r--test/CodeGen/fp16-ops.c55
-rw-r--r--test/CodeGen/fp16vec-ops.c163
-rw-r--r--test/CodeGen/function-attributes.c1
-rw-r--r--test/CodeGen/hexagon-inline-asm.c8
-rw-r--r--test/CodeGen/instrument-functions.c30
-rw-r--r--test/CodeGen/libcall-declarations.c600
-rw-r--r--test/CodeGen/libcalls.c51
-rw-r--r--test/CodeGen/linux-arm-atomic.c1
-rw-r--r--test/CodeGen/long-call-attr.c21
-rw-r--r--test/CodeGen/mangle-blocks.c6
-rw-r--r--test/CodeGen/math-builtins.c578
-rw-r--r--test/CodeGen/math-libcalls.c547
-rw-r--r--test/CodeGen/mcount.c8
-rw-r--r--test/CodeGen/mozilla-ms-inline-asm.c2
-rw-r--r--test/CodeGen/ms-annotation.c26
-rw-r--r--test/CodeGen/ms-inline-asm-64.c8
-rw-r--r--test/CodeGen/ms-inline-asm-enums.cpp55
-rw-r--r--test/CodeGen/ms-inline-asm-variables.c35
-rw-r--r--test/CodeGen/ms-inline-asm.c183
-rw-r--r--test/CodeGen/ms-inline-asm.cpp22
-rw-r--r--test/CodeGen/ms-intrinsics.c23
-rw-r--r--test/CodeGen/nobuiltin.c4
-rw-r--r--test/CodeGen/noplt.c9
-rw-r--r--test/CodeGen/nullptr-arithmetic.c47
-rw-r--r--test/CodeGen/pascal-wchar-string.c2
-rw-r--r--test/CodeGen/ppc-vector-compare.cc34
-rw-r--r--test/CodeGen/pr34021.c25
-rw-r--r--test/CodeGen/pragma-comment.c1
-rw-r--r--test/CodeGen/preserve-call-conv.c3
-rw-r--r--test/CodeGen/profile-sample-accurate.c7
-rw-r--r--test/CodeGen/push-hidden-visibility-subclass.cpp20
-rw-r--r--test/CodeGen/sanitizer-special-case-list.c26
-rw-r--r--test/CodeGen/sse2-builtins.c16
-rw-r--r--test/CodeGen/ssse3-builtins.c12
-rw-r--r--test/CodeGen/string-literal-short-wstring.c4
-rw-r--r--test/CodeGen/string-literal-unicode-conversion.c2
-rw-r--r--test/CodeGen/target-builtin-noerror.c38
-rw-r--r--test/CodeGen/target-data.c4
-rw-r--r--test/CodeGen/tbaa-array.cpp18
-rw-r--r--test/CodeGen/tbaa-cast.cpp23
-rw-r--r--test/CodeGen/tbaa-for-vptr.cpp6
-rw-r--r--test/CodeGen/tbaa-reference.cpp37
-rw-r--r--test/CodeGen/tbm-builtins.c96
-rw-r--r--test/CodeGen/thinlto-debug-pm.c10
-rw-r--r--test/CodeGen/thinlto-emit-llvm.c2
-rw-r--r--test/CodeGen/ubsan-builtin-checks.c44
-rw-r--r--test/CodeGen/ubsan-pass-object-size.c68
-rw-r--r--test/CodeGen/unsigned-overflow-minimal.c21
-rw-r--r--test/CodeGen/verify-debuginfo.ll17
-rw-r--r--test/CodeGen/wchar-size.c2
-rw-r--r--test/CodeGen/x86-GCC-inline-asm-Y-constraints.c68
-rw-r--r--test/CodeGen/x86_32-xsave.c60
-rw-r--r--test/CodeGen/x86_64-instrument-functions.c38
-rw-r--r--test/CodeGen/x86_64-xsave.c120
-rw-r--r--test/CodeGen/xray-always-emit-customevent.cpp10
-rw-r--r--test/CodeGenCXX/anonymous-namespaces.cpp9
-rw-r--r--test/CodeGenCXX/anonymous-union-member-initializer.cpp32
-rw-r--r--test/CodeGenCXX/arm64-constructor-return.cpp2
-rw-r--r--test/CodeGenCXX/atomic-align.cpp30
-rw-r--r--test/CodeGenCXX/atomic-inline.cpp69
-rw-r--r--test/CodeGenCXX/blocks.cpp1
-rw-r--r--test/CodeGenCXX/catch-undef-behavior.cpp91
-rw-r--r--test/CodeGenCXX/cfi-blacklist.cpp16
-rw-r--r--test/CodeGenCXX/cfi-icall.cpp19
-rw-r--r--test/CodeGenCXX/cfi-ms-vbase-derived-cast.cpp29
-rw-r--r--test/CodeGenCXX/cfi-ms-vbase-nvcall.cpp27
-rw-r--r--test/CodeGenCXX/cfi-vcall-no-trap.cpp15
-rw-r--r--test/CodeGenCXX/cxx11-extern-constexpr.cpp68
-rw-r--r--test/CodeGenCXX/cxx11-special-members.cpp4
-rw-r--r--test/CodeGenCXX/cxx1y-variable-template.cpp6
-rw-r--r--test/CodeGenCXX/cxx1z-aligned-allocation.cpp16
-rw-r--r--test/CodeGenCXX/cxx1z-copy-omission.cpp26
-rw-r--r--test/CodeGenCXX/cxx1z-inline-variables.cpp30
-rw-r--r--test/CodeGenCXX/cxx2a-destroying-delete.cpp161
-rw-r--r--test/CodeGenCXX/cxx2a-three-way-comparison.cpp29
-rw-r--r--test/CodeGenCXX/debug-info-anon-namespace.cpp18
-rw-r--r--test/CodeGenCXX/debug-info-codeview-display-name.cpp7
-rw-r--r--test/CodeGenCXX/debug-info-codeview-nested-types.cpp25
-rw-r--r--test/CodeGenCXX/debug-info-fwd-template-param.cpp20
-rw-r--r--test/CodeGenCXX/debug-info-inheriting-constructor.cpp2
-rw-r--r--test/CodeGenCXX/debug-info-inlined.cpp50
-rw-r--r--test/CodeGenCXX/debug-info-method.cpp3
-rw-r--r--test/CodeGenCXX/debug-info-ms-abi.cpp9
-rw-r--r--test/CodeGenCXX/debug-info-nested-exprs.cpp202
-rw-r--r--test/CodeGenCXX/debug-info-static-member.cpp6
-rw-r--r--test/CodeGenCXX/debug-info-template-member.cpp2
-rw-r--r--test/CodeGenCXX/debug-info-template.cpp6
-rw-r--r--test/CodeGenCXX/debug-info.cpp5
-rw-r--r--test/CodeGenCXX/default_calling_conv.cpp18
-rw-r--r--test/CodeGenCXX/dllexport-vtable-thunks.cpp23
-rw-r--r--test/CodeGenCXX/dllexport.cpp25
-rw-r--r--test/CodeGenCXX/dllimport-dtor-thunks.cpp49
-rw-r--r--test/CodeGenCXX/dllimport-members.cpp4
-rw-r--r--test/CodeGenCXX/dllimport.cpp11
-rw-r--r--test/CodeGenCXX/eh.cpp4
-rw-r--r--test/CodeGenCXX/exceptions-seh.cpp21
-rw-r--r--test/CodeGenCXX/explicit-instantiation.cpp19
-rw-r--r--test/CodeGenCXX/extern-section-attribute.cpp11
-rw-r--r--test/CodeGenCXX/finegrain-bitfield-access.cpp162
-rw-r--r--test/CodeGenCXX/float16-declarations.cpp149
-rw-r--r--test/CodeGenCXX/fp16-mangle.cpp4
-rw-r--r--test/CodeGenCXX/inline-dllexport-member.cpp2
-rw-r--r--test/CodeGenCXX/instrument-functions.cpp18
-rw-r--r--test/CodeGenCXX/invariant.group-for-vptrs.cpp2
-rw-r--r--test/CodeGenCXX/mangle-exprs.cpp32
-rw-r--r--test/CodeGenCXX/mangle-fail.cpp6
-rw-r--r--test/CodeGenCXX/mangle-lambdas.cpp28
-rw-r--r--test/CodeGenCXX/mangle-ms-cxx11.cpp7
-rw-r--r--test/CodeGenCXX/mangle.cpp3
-rw-r--r--test/CodeGenCXX/member-expr-references-variable.cpp104
-rw-r--r--test/CodeGenCXX/microsoft-abi-dynamic-cast.cpp4
-rw-r--r--test/CodeGenCXX/microsoft-abi-multiple-nonvirtual-inheritance.cpp43
-rw-r--r--test/CodeGenCXX/microsoft-abi-static-initializers.cpp2
-rw-r--r--test/CodeGenCXX/microsoft-abi-thread-safe-statics.cpp9
-rw-r--r--test/CodeGenCXX/microsoft-abi-virtual-inheritance-vtordisps.cpp1
-rw-r--r--test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp53
-rw-r--r--test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-this-adjustment.cpp10
-rw-r--r--test/CodeGenCXX/microsoft-abi-vtables-return-thunks.cpp15
-rw-r--r--test/CodeGenCXX/microsoft-inaccessible-base.cpp20
-rw-r--r--test/CodeGenCXX/mingw-w64-exceptions.c22
-rw-r--r--test/CodeGenCXX/mingw-w64-seh-exceptions.cpp3
-rw-r--r--test/CodeGenCXX/ms-eh-personality.cpp20
-rw-r--r--test/CodeGenCXX/ms-inline-asm-return.cpp4
-rw-r--r--test/CodeGenCXX/new-overflow.cpp16
-rw-r--r--test/CodeGenCXX/new.cpp2
-rw-r--r--test/CodeGenCXX/noescape.cpp67
-rw-r--r--test/CodeGenCXX/pr29160.cpp41
-rw-r--r--test/CodeGenCXX/regcall.cpp12
-rw-r--r--test/CodeGenCXX/rtti-mingw64.cpp5
-rw-r--r--test/CodeGenCXX/runtime-dllstorage.cpp2
-rw-r--r--test/CodeGenCXX/sanitize-dtor-callback.cpp3
-rw-r--r--test/CodeGenCXX/static-init-wasm.cpp12
-rw-r--r--test/CodeGenCXX/static-initializer-branch-weights.cpp126
-rw-r--r--test/CodeGenCXX/stmtexpr.cpp2
-rw-r--r--test/CodeGenCXX/strict-vtable-pointers.cpp58
-rw-r--r--test/CodeGenCXX/tmp-md-nodes1.cpp18
-rw-r--r--test/CodeGenCXX/tmp-md-nodes2.cpp33
-rw-r--r--test/CodeGenCXX/ubsan-devirtualized-calls.cpp9
-rw-r--r--test/CodeGenCXX/ubsan-suppress-checks.cpp12
-rw-r--r--test/CodeGenCXX/ubsan-type-checks.cpp51
-rw-r--r--test/CodeGenCXX/ubsan-vtable-checks.cpp4
-rw-r--r--test/CodeGenCXX/virt-dtor-key.cpp4
-rw-r--r--test/CodeGenCXX/visibility-inlines-hidden.cpp13
-rw-r--r--test/CodeGenCXX/vla.cpp31
-rw-r--r--test/CodeGenCXX/vtable-available-externally.cpp4
-rw-r--r--test/CodeGenCXX/warn-padded-packed.cpp93
-rw-r--r--test/CodeGenCoroutines/coro-await.cpp18
-rw-r--r--test/CodeGenCoroutines/coro-dest-slot.cpp26
-rw-r--r--test/CodeGenCoroutines/coro-ret-void.cpp14
-rw-r--r--test/CodeGenObjC/NSFastEnumeration.m16
-rw-r--r--test/CodeGenObjC/arc-arm.m2
-rw-r--r--test/CodeGenObjC/arc-bridged-cast.m8
-rw-r--r--test/CodeGenObjC/attr-exception.m8
-rw-r--r--test/CodeGenObjC/debug-info-block-captured-self.m72
-rw-r--r--test/CodeGenObjC/debug-info-blocks.m21
-rw-r--r--test/CodeGenObjC/dllstorage.m10
-rw-r--r--test/CodeGenObjC/ivar-layout-flexible-array.m28
-rw-r--r--test/CodeGenObjC/local-static-block.m11
-rw-r--r--test/CodeGenObjC/mangle-blocks.m6
-rw-r--r--test/CodeGenObjC/no-sanitize.m3
-rw-r--r--test/CodeGenObjC/noescape.m71
-rw-r--r--test/CodeGenObjC/objc-asm-attribute-neg-test.m6
-rw-r--r--test/CodeGenObjC/os_log.m78
-rw-r--r--test/CodeGenObjCXX/arc-forwarded-lambda-call.mm23
-rw-r--r--test/CodeGenObjCXX/mangle-blocks.mm10
-rw-r--r--test/CodeGenObjCXX/microsoft-abi-arc-param-order.mm2
-rw-r--r--test/CodeGenObjCXX/msabi-objc-types.mm122
-rw-r--r--test/CodeGenOpenCL/addr-space-struct-arg.cl88
-rw-r--r--test/CodeGenOpenCL/address-spaces-mangling.cl22
-rw-r--r--test/CodeGenOpenCL/address-spaces.cl68
-rw-r--r--test/CodeGenOpenCL/amdgcn-automatic-variable.cl8
-rw-r--r--test/CodeGenOpenCL/amdgpu-abi-struct-coerce.cl506
-rw-r--r--test/CodeGenOpenCL/amdgpu-attrs.cl50
-rw-r--r--test/CodeGenOpenCL/amdgpu-debug-info-variable-expression.cl79
-rw-r--r--test/CodeGenOpenCL/amdgpu-enqueue-kernel.cl45
-rw-r--r--test/CodeGenOpenCL/amdgpu-nullptr.cl4
-rw-r--r--test/CodeGenOpenCL/atomic-ops-libcall.cl82
-rw-r--r--test/CodeGenOpenCL/atomic-ops.cl291
-rw-r--r--test/CodeGenOpenCL/blocks.cl49
-rw-r--r--test/CodeGenOpenCL/builtins-amdgcn.cl21
-rw-r--r--test/CodeGenOpenCL/cl20-device-side-enqueue.cl258
-rw-r--r--test/CodeGenOpenCL/convergent.cl79
-rw-r--r--test/CodeGenOpenCL/func-call-dbg-loc.cl18
-rw-r--r--test/CodeGenOpenCL/kernel-arg-info.cl22
-rw-r--r--test/CodeGenOpenCL/no-half.cl39
-rw-r--r--test/CodeGenOpenCL/opencl_types.cl29
-rw-r--r--test/CodeGenOpenCL/pipe_builtin.cl4
-rw-r--r--test/CodeGenOpenCL/sampler.cl18
-rw-r--r--test/CodeGenOpenCL/vectorLoadStore.cl17
-rw-r--r--test/Coverage/html-diagnostics.c7
-rw-r--r--test/Coverage/html-multifile-diagnostics.c21
-rw-r--r--test/Coverage/html-multifile-diagnostics.h3
-rw-r--r--test/CoverageMapping/Inputs/deferred-region-helper.h5
-rw-r--r--test/CoverageMapping/abspath.cpp2
-rw-r--r--test/CoverageMapping/break.c14
-rw-r--r--test/CoverageMapping/casts.c2
-rw-r--r--test/CoverageMapping/continue.c8
-rw-r--r--test/CoverageMapping/deferred-region.cpp204
-rw-r--r--test/CoverageMapping/header.cpp5
-rw-r--r--test/CoverageMapping/if.cpp37
-rw-r--r--test/CoverageMapping/includehell.cpp64
-rw-r--r--test/CoverageMapping/label.cpp39
-rw-r--r--test/CoverageMapping/logical.cpp15
-rw-r--r--test/CoverageMapping/loops.cpp19
-rw-r--r--test/CoverageMapping/macro-expansion.c14
-rw-r--r--test/CoverageMapping/macro-expressions.cpp12
-rw-r--r--test/CoverageMapping/macros.c2
-rw-r--r--test/CoverageMapping/macroscopes.cpp8
-rw-r--r--test/CoverageMapping/md.cpp11
-rw-r--r--test/CoverageMapping/moremacros.c10
-rw-r--r--test/CoverageMapping/objc.m8
-rw-r--r--test/CoverageMapping/preprocessor.c55
-rw-r--r--test/CoverageMapping/return.c14
-rw-r--r--test/CoverageMapping/switch.cpp43
-rw-r--r--test/CoverageMapping/switchmacro.c5
-rw-r--r--test/CoverageMapping/test.c4
-rw-r--r--test/CoverageMapping/trycatch.cpp8
-rw-r--r--test/CoverageMapping/while.c8
-rw-r--r--test/Driver/Inputs/CUDA-nolibdevice/usr/local/cuda/bin/.keep0
-rw-r--r--test/Driver/Inputs/CUDA-nolibdevice/usr/local/cuda/include/.keep0
-rw-r--r--test/Driver/Inputs/CUDA-nolibdevice/usr/local/cuda/lib/.keep0
-rw-r--r--test/Driver/Inputs/CUDA-nolibdevice/usr/local/cuda/lib64/.keep0
-rw-r--r--test/Driver/Inputs/CUDA_90/usr/local/cuda/bin/.keep0
-rw-r--r--test/Driver/Inputs/CUDA_90/usr/local/cuda/include/.keep0
-rw-r--r--test/Driver/Inputs/CUDA_90/usr/local/cuda/lib/.keep0
-rw-r--r--test/Driver/Inputs/CUDA_90/usr/local/cuda/lib64/.keep0
-rw-r--r--test/Driver/Inputs/CUDA_90/usr/local/cuda/nvvm/libdevice/libdevice.10.bc0
-rw-r--r--test/Driver/Inputs/CUDA_90/usr/local/cuda/version.txt1
-rwxr-xr-xtest/Driver/Inputs/Windows/usr/bin/ld.bfd0
-rw-r--r--test/Driver/Inputs/basic_linux_tree/usr/i686-unknown-linux/lib/.keep0
-rw-r--r--test/Driver/Inputs/basic_linux_tree/usr/lib/gcc/i686-unknown-linux/4.6.0/crtbegin.o0
-rw-r--r--test/Driver/Inputs/resource_dir/hwasan_blacklist.txt0
-rw-r--r--test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.hwasan-aarch64.a.syms0
-rw-r--r--test/Driver/Inputs/resource_dir/ubsan_blacklist.txt0
-rw-r--r--test/Driver/XRay/lit.local.cfg22
-rw-r--r--test/Driver/XRay/xray-shared-noxray.cpp16
-rw-r--r--test/Driver/aarch64-cpus.c255
-rw-r--r--test/Driver/aarch64-dotprod.c11
-rw-r--r--test/Driver/aarch64-ras.c2
-rw-r--r--test/Driver/aarch64-rcpc.s14
-rw-r--r--test/Driver/aarch64-rdm.c9
-rw-r--r--test/Driver/amdgpu-features.c6
-rw-r--r--test/Driver/amdgpu-mcpu.cl (renamed from test/Driver/r600-mcpu.cl)72
-rw-r--r--test/Driver/amdgpu-toolchain-opencl.cl19
-rw-r--r--test/Driver/android-pie.c66
-rw-r--r--test/Driver/arm-cortex-cpus.c33
-rw-r--r--test/Driver/arm-dotprod.c11
-rw-r--r--test/Driver/arm-ras.c2
-rw-r--r--test/Driver/arm-target-as-mthumb.s17
-rw-r--r--test/Driver/arm-thumb-only-cores.c12
-rw-r--r--test/Driver/arm-wchar_t-defaults.c53
-rw-r--r--test/Driver/as-mcpu.c11
-rw-r--r--test/Driver/asan.c5
-rw-r--r--test/Driver/autocomplete.c21
-rw-r--r--test/Driver/baremetal.cpp10
-rw-r--r--test/Driver/bitrig.c29
-rw-r--r--test/Driver/cl-cc-flags.c3
-rw-r--r--test/Driver/cl-options.c16
-rw-r--r--test/Driver/clang-translation.c28
-rw-r--r--test/Driver/clang_f_opts.c23
-rw-r--r--test/Driver/compilation_database.c2
-rw-r--r--test/Driver/constructors.c6
-rw-r--r--test/Driver/coverage.c8
-rw-r--r--test/Driver/cpath.c8
-rw-r--r--test/Driver/cuda-arch-translation.cu36
-rw-r--r--test/Driver/cuda-bad-arch.cu6
-rw-r--r--test/Driver/cuda-bail-out.cu54
-rw-r--r--test/Driver/cuda-detect.cu16
-rw-r--r--test/Driver/cuda-external-tools.cu6
-rw-r--r--test/Driver/cxa-atexit.cpp27
-rw-r--r--test/Driver/darwin-ld-lto.c8
-rw-r--r--test/Driver/darwin-ld.c24
-rw-r--r--test/Driver/darwin-sdkroot.c2
-rw-r--r--test/Driver/darwin-simulator-macro.c7
-rw-r--r--test/Driver/darwin-version.c21
-rw-r--r--test/Driver/debug-options.c4
-rw-r--r--test/Driver/fast-math.c65
-rw-r--r--test/Driver/freebsd.c2
-rw-r--r--test/Driver/fsanitize-blacklist.c13
-rw-r--r--test/Driver/fsanitize-coverage.c30
-rw-r--r--test/Driver/fsanitize.c158
-rw-r--r--test/Driver/fuchsia.c43
-rw-r--r--test/Driver/fuchsia.cpp9
-rw-r--r--test/Driver/fuse-ld.c26
-rw-r--r--test/Driver/fuzzer.c12
-rw-r--r--test/Driver/gold-lto-new-pass-man.c7
-rw-r--r--test/Driver/gold-lto.c8
-rw-r--r--test/Driver/hexagon-hvx.c103
-rw-r--r--test/Driver/hexagon-toolchain-elf.c18
-rw-r--r--test/Driver/linker-opts.c6
-rw-r--r--test/Driver/linux-as.c15
-rw-r--r--test/Driver/linux-ld.c47
-rw-r--r--test/Driver/lto-plugin-darwin.c6
-rw-r--r--test/Driver/lto-plugin-linux.c6
-rw-r--r--test/Driver/lto-plugin-windows.c6
-rw-r--r--test/Driver/lto.c6
-rw-r--r--test/Driver/mingw-msvcrt.c5
-rw-r--r--test/Driver/mingw-useld.c19
-rw-r--r--test/Driver/mips-abi.c2
-rw-r--r--test/Driver/mips-abicalls-warning.c9
-rw-r--r--test/Driver/mips-features.c136
-rw-r--r--test/Driver/mips-gpopt-warning.c6
-rw-r--r--test/Driver/mips-mabs-warning.c6
-rw-r--r--test/Driver/mprefer-vector-width.c24
-rw-r--r--test/Driver/nostdlib.c2
-rw-r--r--test/Driver/nostdlibxx.cpp8
-rw-r--r--test/Driver/openmp-offload-gpu.c144
-rw-r--r--test/Driver/openmp-offload.c56
-rw-r--r--test/Driver/opt-record.c4
-rw-r--r--test/Driver/output-file-cleanup.c39
-rw-r--r--test/Driver/parse-progname.c80
-rw-r--r--test/Driver/pic.c59
-rw-r--r--test/Driver/ppc-features.cpp2
-rw-r--r--test/Driver/print-libgcc-file-name-clangrt.c30
-rw-r--r--test/Driver/ps4-linker-non-win.c18
-rw-r--r--test/Driver/ps4-linker-win.c15
-rw-r--r--test/Driver/rewrite-legacy-objc.m6
-rw-r--r--test/Driver/rewrite-objc.m2
-rw-r--r--test/Driver/sanitize_unwind_tables.c2
-rw-r--r--test/Driver/sanitizer-ld.c257
-rw-r--r--test/Driver/stack-protector.c17
-rw-r--r--test/Driver/target-override.c16
-rw-r--r--test/Driver/thinlto.c6
-rw-r--r--test/Driver/unix-conformance.c24
-rw-r--r--test/Driver/unknown-std.c2
-rw-r--r--test/Driver/unknown-std.cpp2
-rw-r--r--test/Driver/warning-options.cpp2
-rw-r--r--test/Driver/wasm-toolchain.c14
-rw-r--r--test/Driver/whole-program-vtables.c9
-rw-r--r--test/Driver/windows-cross.c12
-rw-r--r--test/Driver/x86-march.c8
-rw-r--r--test/Driver/x86-target-features.c10
-rw-r--r--test/FixIt/Inputs/nullability-objc.h48
-rw-r--r--test/FixIt/fixit-availability.c8
-rw-r--r--test/FixIt/fixit-availability.mm39
-rw-r--r--test/FixIt/fixit-cxx0x.cpp1
-rw-r--r--test/FixIt/fixit-format-ios.m26
-rw-r--r--test/FixIt/fixit-include.c11
-rw-r--r--test/FixIt/fixit-pragma-pack.c5
-rw-r--r--test/FixIt/fixit-vexing-parse.cpp21
-rw-r--r--test/FixIt/format.m31
-rw-r--r--test/FixIt/nullability.mm2
-rw-r--r--test/Format/style-on-command-line.cpp19
-rw-r--r--test/Format/verbose.cpp16
-rw-r--r--test/Frontend/Inputs/optimization-remark-with-hotness-sample.proftext10
-rw-r--r--test/Frontend/Inputs/optimization-remark-with-hotness.proftext4
-rw-r--r--test/Frontend/diagnostics-order.c12
-rw-r--r--test/Frontend/float16.cpp326
-rw-r--r--test/Frontend/gnu-mcount.c72
-rw-r--r--test/Frontend/optimization-remark-extra-analysis.c11
-rw-r--r--test/Frontend/optimization-remark-options.c2
-rw-r--r--test/Frontend/optimization-remark-with-hotness.c19
-rw-r--r--test/Frontend/optimization-remark.c3
-rw-r--r--test/Frontend/remove-file-on-signal.c7
-rw-r--r--test/Frontend/system-header-line-directive-ms-lineendings.c21
-rw-r--r--test/Frontend/verify-prefixes.c118
-rw-r--r--test/Frontend/x86-target-cpu.c2
-rw-r--r--test/Headers/float16.c65
-rw-r--r--test/Headers/mm3dnow.c16
-rw-r--r--test/Headers/ms-intrin.cpp4
-rw-r--r--test/Headers/stdarg.cpp36
-rw-r--r--test/Headers/stdbool.cpp16
-rw-r--r--test/Headers/wchar_limits.cpp2
-rw-r--r--test/Import/extern-c-function/Inputs/F.cpp3
-rw-r--r--test/Import/extern-c-function/test.cpp4
-rw-r--r--test/Import/forward-declared-objc-class/Inputs/S1.m1
-rw-r--r--test/Import/forward-declared-objc-class/Inputs/S2.m6
-rw-r--r--test/Import/forward-declared-objc-class/Inputs/S3.m1
-rw-r--r--test/Import/forward-declared-objc-class/test.m6
-rw-r--r--test/Import/forward-declared-struct/Inputs/S3.c1
-rw-r--r--test/Import/forward-declared-struct/test.c2
-rw-r--r--test/Import/local-struct-use-origins/Inputs/Callee.cpp12
-rw-r--r--test/Import/local-struct-use-origins/test.cpp7
-rw-r--r--test/Import/local-struct/Inputs/Callee.cpp12
-rw-r--r--test/Import/local-struct/test.cpp7
-rw-r--r--test/Import/objc-definitions-in-expression/Inputs/S.m4
-rw-r--r--test/Import/objc-definitions-in-expression/test.m21
-rw-r--r--test/Import/objc-method/Inputs/S.m4
-rw-r--r--test/Import/objc-method/test.m5
-rw-r--r--test/Import/struct-and-var/Inputs/S1.cpp1
-rw-r--r--test/Import/struct-and-var/Inputs/S2.cpp3
-rw-r--r--test/Import/struct-and-var/test.cpp5
-rw-r--r--test/Import/struct-layout/Inputs/Callee.cpp9
-rw-r--r--test/Import/struct-layout/test.cpp6
-rw-r--r--test/Import/template/Inputs/T.cpp5
-rw-r--r--test/Import/template/test.cpp4
-rw-r--r--test/Index/Core/index-dependent-source.cpp66
-rw-r--r--test/Index/Core/index-source.cpp52
-rw-r--r--test/Index/Core/index-source.m13
-rw-r--r--test/Index/Inputs/record-parsing-invocation-remap.c2
-rw-r--r--test/Index/USR/array-type.cpp11
-rw-r--r--test/Index/USR/func-type.cpp18
-rw-r--r--test/Index/annotate-attribute.cpp12
-rw-r--r--test/Index/code-completion.cpp12
-rw-r--r--test/Index/comment-cplus-decls.cpp2
-rw-r--r--test/Index/comment-to-html-xml-conversion-with-original-literals.cpp26
-rw-r--r--test/Index/complete-access-checks.cpp24
-rw-r--r--test/Index/complete-call.cpp61
-rw-r--r--test/Index/complete-constructor-params.cpp17
-rw-r--r--test/Index/complete-cxx-inline-methods.cpp4
-rw-r--r--test/Index/complete-interfaces.m16
-rw-r--r--test/Index/complete-method-decls.m22
-rw-r--r--test/Index/complete-qualified.cpp2
-rw-r--r--test/Index/complete-super.cpp5
-rw-r--r--test/Index/complete-with-annotations.cpp4
-rw-r--r--test/Index/get-cursor.cpp8
-rw-r--r--test/Index/index-pch.cpp2
-rw-r--r--test/Index/index-template-template-param.cpp7
-rw-r--r--test/Index/index-templates.cpp2
-rw-r--r--test/Index/load-classes.cpp2
-rw-r--r--test/Index/preamble-conditionals-inverted-with-error.cpp8
-rw-r--r--test/Index/preamble-conditionals-inverted.cpp10
-rw-r--r--test/Index/preamble-conditionals-skipping.cpp16
-rw-r--r--test/Index/print-objc-manglings.m18
-rw-r--r--test/Index/record-completion-invocation.c11
-rw-r--r--test/Index/record-parsing-invocation.c28
-rw-r--r--test/Index/recover-bad-code-rdar_7487294.c2
-rw-r--r--test/Index/skipped-function-bodies.cpp9
-rw-r--r--test/Index/skipped-ranges.c6
-rw-r--r--test/Integration/thinlto_profile_sample_accurate.c9
-rw-r--r--test/Lexer/case-insensitive-include-ms.c10
-rwxr-xr-xtest/Lexer/case-insensitive-include-pr31836.sh6
-rw-r--r--test/Lexer/case-insensitive-include.c14
-rw-r--r--test/Lexer/case-insensitive-system-include.c10
-rw-r--r--test/Lexer/cxx-features.cpp4
-rw-r--r--test/Lexer/cxx2a-spaceship.cpp73
-rw-r--r--test/Lexer/cxx2a_keyword_as_cxx17.cpp9
-rw-r--r--test/Lexer/half-literal.cpp5
-rw-r--r--test/Lexer/has_feature_address_sanitizer.cpp13
-rw-r--r--test/Lexer/keywords_test.cpp3
-rw-r--r--test/Lexer/unicode.c5
-rw-r--r--test/Lexer/wchar.c2
-rw-r--r--test/Misc/ast-dump-attr.cpp8
-rw-r--r--test/Misc/ast-dump-c-attr.c46
-rw-r--r--test/Misc/ast-dump-decl.cpp54
-rw-r--r--test/Misc/ast-dump-invalid.cpp2
-rw-r--r--test/Misc/find-diagnostic-id.c4
-rw-r--r--test/Misc/pragma-attribute-cxx-subject-match-rules.cpp10
-rw-r--r--test/Misc/pragma-attribute-cxx.cpp4
-rw-r--r--test/Misc/pragma-attribute-supported-attributes-list.test10
-rw-r--r--test/Misc/warning-flags-tree.c11
-rw-r--r--test/Misc/warning-flags.c3
-rw-r--r--test/Modules/ExtDebugInfo.cpp9
-rw-r--r--test/Modules/Inputs/DebugCXX.h6
-rw-r--r--test/Modules/Inputs/codegen/foo.h3
-rw-r--r--test/Modules/Inputs/codegen/use.cpp3
-rw-r--r--test/Modules/Inputs/export_as_test.modulemap9
-rw-r--r--test/Modules/ModuleDebugInfo.cpp11
-rw-r--r--test/Modules/adl.cpp40
-rw-r--r--test/Modules/anon-linkage.cpp12
-rw-r--r--test/Modules/builtin-import.mm4
-rw-r--r--test/Modules/codegen-opt.test12
-rw-r--r--test/Modules/codegen.test4
-rw-r--r--test/Modules/crash-typo-correction-visibility.cpp5
-rw-r--r--test/Modules/crash-vfs-ivfsoverlay.m1
-rw-r--r--test/Modules/cxx-templates.cpp14
-rw-r--r--test/Modules/cxx17-inline-variables.cpp30
-rw-r--r--test/Modules/export_as_test.c9
-rw-r--r--test/Modules/merge-anon-in-extern_c.cpp19
-rw-r--r--test/Modules/module-imported-by-pch-path.m17
-rw-r--r--test/Modules/modules-cache-path-canonicalization.m4
-rw-r--r--test/Modules/odr_hash.cpp1030
-rw-r--r--test/Modules/path-resolution.modulemap70
-rw-r--r--test/Modules/umbrella-header-include-builtin.mm4
-rw-r--r--test/Modules/using-decl-inheritance.cpp34
-rw-r--r--test/Modules/using-directive-redecl.cpp37
-rw-r--r--test/Modules/using-directive.cpp62
-rw-r--r--test/Modules/var-templates.cpp24
-rw-r--r--test/Modules/visibility-in-instantiation.cpp51
-rw-r--r--test/OpenMP/atomic_capture_codegen.cpp50
-rw-r--r--test/OpenMP/atomic_read_codegen.c6
-rw-r--r--test/OpenMP/atomic_update_codegen.cpp48
-rw-r--r--test/OpenMP/atomic_write_codegen.c6
-rw-r--r--test/OpenMP/capturing_in_templates.cpp2
-rw-r--r--test/OpenMP/declare_reduction_messages.cpp18
-rw-r--r--test/OpenMP/declare_simd_codegen.cpp29
-rw-r--r--test/OpenMP/declare_simd_messages.cpp2
-rw-r--r--test/OpenMP/declare_target_ast_print.cpp32
-rw-r--r--test/OpenMP/declare_target_messages.cpp20
-rw-r--r--test/OpenMP/distribute_codegen.cpp15
-rw-r--r--test/OpenMP/distribute_firstprivate_codegen.cpp94
-rw-r--r--test/OpenMP/distribute_firstprivate_messages.cpp8
-rw-r--r--test/OpenMP/distribute_lastprivate_codegen.cpp3
-rw-r--r--test/OpenMP/distribute_parallel_for_ast_print.cpp6
-rw-r--r--test/OpenMP/distribute_parallel_for_codegen.cpp1
-rw-r--r--test/OpenMP/distribute_parallel_for_firstprivate_codegen.cpp66
-rw-r--r--test/OpenMP/distribute_parallel_for_firstprivate_messages.cpp13
-rw-r--r--test/OpenMP/distribute_parallel_for_lastprivate_codegen.cpp8
-rw-r--r--test/OpenMP/distribute_parallel_for_lastprivate_messages.cpp14
-rw-r--r--test/OpenMP/distribute_parallel_for_messages.cpp13
-rw-r--r--test/OpenMP/distribute_parallel_for_reduction_messages.cpp4
-rw-r--r--test/OpenMP/distribute_parallel_for_simd_ast_print.cpp22
-rw-r--r--test/OpenMP/distribute_parallel_for_simd_codegen.cpp2262
-rw-r--r--test/OpenMP/distribute_parallel_for_simd_firstprivate_codegen.cpp611
-rw-r--r--test/OpenMP/distribute_parallel_for_simd_firstprivate_messages.cpp13
-rw-r--r--test/OpenMP/distribute_parallel_for_simd_if_codegen.cpp192
-rw-r--r--test/OpenMP/distribute_parallel_for_simd_lastprivate_codegen.cpp671
-rw-r--r--test/OpenMP/distribute_parallel_for_simd_lastprivate_messages.cpp14
-rw-r--r--test/OpenMP/distribute_parallel_for_simd_linear_messages.cpp52
-rw-r--r--test/OpenMP/distribute_parallel_for_simd_loop_messages.cpp5
-rw-r--r--test/OpenMP/distribute_parallel_for_simd_misc_messages.c88
-rw-r--r--test/OpenMP/distribute_parallel_for_simd_num_threads_codegen.cpp121
-rw-r--r--test/OpenMP/distribute_parallel_for_simd_private_codegen.cpp297
-rw-r--r--test/OpenMP/distribute_parallel_for_simd_proc_bind_codegen.cpp93
-rw-r--r--test/OpenMP/distribute_parallel_for_simd_reduction_messages.cpp4
-rw-r--r--test/OpenMP/distribute_private_messages.cpp2
-rw-r--r--test/OpenMP/distribute_simd_ast_print.cpp13
-rw-r--r--test/OpenMP/distribute_simd_codegen.cpp269
-rw-r--r--test/OpenMP/distribute_simd_firstprivate_codegen.cpp380
-rw-r--r--test/OpenMP/distribute_simd_firstprivate_messages.cpp13
-rw-r--r--test/OpenMP/distribute_simd_lastprivate_codegen.cpp393
-rw-r--r--test/OpenMP/distribute_simd_lastprivate_messages.cpp14
-rw-r--r--test/OpenMP/distribute_simd_linear_messages.cpp63
-rw-r--r--test/OpenMP/distribute_simd_misc_messages.c105
-rw-r--r--test/OpenMP/distribute_simd_private_codegen.cpp208
-rw-r--r--test/OpenMP/distribute_simd_reduction_codegen.cpp204
-rw-r--r--test/OpenMP/distribute_simd_reduction_messages.cpp4
-rw-r--r--test/OpenMP/dump.cpp8
-rw-r--r--test/OpenMP/for_codegen.cpp27
-rw-r--r--test/OpenMP/for_firstprivate_codegen.cpp51
-rw-r--r--test/OpenMP/for_lastprivate_codegen.cpp18
-rw-r--r--test/OpenMP/for_lastprivate_messages.cpp4
-rw-r--r--test/OpenMP/for_linear_codegen.cpp9
-rw-r--r--test/OpenMP/for_private_codegen.cpp18
-rw-r--r--test/OpenMP/for_reduction_codegen.cpp336
-rw-r--r--test/OpenMP/for_reduction_codegen_UDR.cpp141
-rw-r--r--test/OpenMP/for_reduction_messages.cpp4
-rw-r--r--test/OpenMP/for_simd_lastprivate_messages.cpp4
-rw-r--r--test/OpenMP/for_simd_reduction_messages.cpp4
-rw-r--r--test/OpenMP/is_initial_device.c36
-rw-r--r--test/OpenMP/nvptx_data_sharing.cpp57
-rw-r--r--test/OpenMP/nvptx_parallel_codegen.cpp26
-rw-r--r--test/OpenMP/nvptx_param_translate.c19
-rw-r--r--test/OpenMP/nvptx_target_codegen.cpp12
-rw-r--r--test/OpenMP/nvptx_target_firstprivate_codegen.cpp70
-rw-r--r--test/OpenMP/nvptx_target_teams_codegen.cpp16
-rw-r--r--test/OpenMP/nvptx_teams_reduction_codegen.cpp6
-rw-r--r--test/OpenMP/openmp_offload_codegen.cpp36
-rw-r--r--test/OpenMP/openmp_win_codegen.cpp61
-rw-r--r--test/OpenMP/ordered_codegen.cpp4
-rw-r--r--test/OpenMP/parallel_ast_print.cpp11
-rw-r--r--test/OpenMP/parallel_codegen.cpp12
-rw-r--r--test/OpenMP/parallel_firstprivate_messages.cpp4
-rw-r--r--test/OpenMP/parallel_for_codegen.cpp41
-rw-r--r--test/OpenMP/parallel_for_lastprivate_messages.cpp4
-rw-r--r--test/OpenMP/parallel_for_linear_codegen.cpp6
-rw-r--r--test/OpenMP/parallel_for_reduction_messages.cpp10
-rw-r--r--test/OpenMP/parallel_for_simd_codegen.cpp1
-rw-r--r--test/OpenMP/parallel_for_simd_lastprivate_messages.cpp4
-rw-r--r--test/OpenMP/parallel_for_simd_reduction_messages.cpp4
-rw-r--r--test/OpenMP/parallel_reduction_messages.cpp4
-rw-r--r--test/OpenMP/parallel_sections_codegen.cpp4
-rw-r--r--test/OpenMP/parallel_sections_lastprivate_messages.cpp4
-rw-r--r--test/OpenMP/parallel_sections_reduction_messages.cpp4
-rw-r--r--test/OpenMP/sections_codegen.cpp7
-rw-r--r--test/OpenMP/sections_firstprivate_codegen.cpp9
-rw-r--r--test/OpenMP/sections_lastprivate_messages.cpp4
-rw-r--r--test/OpenMP/sections_reduction_messages.cpp4
-rw-r--r--test/OpenMP/simd_lastprivate_messages.cpp4
-rw-r--r--test/OpenMP/simd_reduction_messages.cpp4
-rw-r--r--test/OpenMP/single_firstprivate_codegen.cpp12
-rw-r--r--test/OpenMP/target_codegen.cpp171
-rw-r--r--test/OpenMP/target_codegen_registration.cpp24
-rw-r--r--test/OpenMP/target_data_codegen.cpp42
-rw-r--r--test/OpenMP/target_data_use_device_ptr_codegen.cpp32
-rw-r--r--test/OpenMP/target_depend_messages.cpp10
-rw-r--r--test/OpenMP/target_enter_data_codegen.cpp28
-rw-r--r--test/OpenMP/target_enter_data_depend_messages.cpp20
-rw-r--r--test/OpenMP/target_exit_data_codegen.cpp28
-rw-r--r--test/OpenMP/target_exit_data_depend_messages.cpp20
-rw-r--r--test/OpenMP/target_firstprivate_codegen.cpp27
-rw-r--r--test/OpenMP/target_is_device_ptr_codegen.cpp40
-rw-r--r--test/OpenMP/target_map_codegen.cpp976
-rw-r--r--test/OpenMP/target_map_messages.cpp100
-rw-r--r--test/OpenMP/target_messages.cpp2
-rw-r--r--test/OpenMP/target_parallel_codegen.cpp103
-rw-r--r--test/OpenMP/target_parallel_codegen_registration.cpp24
-rw-r--r--test/OpenMP/target_parallel_debug_codegen.cpp123
-rw-r--r--test/OpenMP/target_parallel_depend_messages.cpp10
-rw-r--r--test/OpenMP/target_parallel_for_codegen.cpp812
-rw-r--r--test/OpenMP/target_parallel_for_codegen_registration.cpp451
-rw-r--r--test/OpenMP/target_parallel_for_codegen_registration_naming.cpp68
-rw-r--r--test/OpenMP/target_parallel_for_debug_codegen.cpp113
-rw-r--r--test/OpenMP/target_parallel_for_depend_messages.cpp10
-rw-r--r--test/OpenMP/target_parallel_for_lastprivate_messages.cpp4
-rw-r--r--test/OpenMP/target_parallel_for_map_messages.cpp12
-rw-r--r--test/OpenMP/target_parallel_for_reduction_messages.cpp4
-rw-r--r--test/OpenMP/target_parallel_for_simd_ast_print.cpp4
-rw-r--r--test/OpenMP/target_parallel_for_simd_codegen.cpp812
-rw-r--r--test/OpenMP/target_parallel_for_simd_codegen_registration.cpp451
-rw-r--r--test/OpenMP/target_parallel_for_simd_codegen_registration_naming.cpp68
-rw-r--r--test/OpenMP/target_parallel_for_simd_depend_messages.cpp10
-rw-r--r--test/OpenMP/target_parallel_for_simd_firstprivate_messages.cpp10
-rw-r--r--test/OpenMP/target_parallel_for_simd_lastprivate_messages.cpp6
-rw-r--r--test/OpenMP/target_parallel_for_simd_loop_messages.cpp20
-rw-r--r--test/OpenMP/target_parallel_for_simd_map_messages.cpp12
-rw-r--r--test/OpenMP/target_parallel_for_simd_misc_messages.c2
-rw-r--r--test/OpenMP/target_parallel_for_simd_ordered_messages.cpp54
-rw-r--r--test/OpenMP/target_parallel_for_simd_reduction_messages.cpp4
-rw-r--r--test/OpenMP/target_parallel_if_codegen.cpp94
-rw-r--r--test/OpenMP/target_parallel_map_messages.cpp12
-rw-r--r--test/OpenMP/target_parallel_no_exceptions.cpp18
-rw-r--r--test/OpenMP/target_parallel_num_threads_codegen.cpp36
-rw-r--r--test/OpenMP/target_parallel_reduction_messages.cpp4
-rw-r--r--test/OpenMP/target_reduction_codegen.cpp215
-rw-r--r--test/OpenMP/target_reduction_messages.cpp262
-rw-r--r--test/OpenMP/target_simd_codegen.cpp675
-rw-r--r--test/OpenMP/target_simd_codegen_registration.cpp451
-rw-r--r--test/OpenMP/target_simd_codegen_registration_naming.cpp68
-rw-r--r--test/OpenMP/target_simd_depend_messages.cpp10
-rw-r--r--test/OpenMP/target_simd_lastprivate_messages.cpp4
-rw-r--r--test/OpenMP/target_simd_map_messages.cpp12
-rw-r--r--test/OpenMP/target_simd_reduction_messages.cpp4
-rw-r--r--test/OpenMP/target_teams_codegen.cpp135
-rw-r--r--test/OpenMP/target_teams_codegen_registration.cpp24
-rw-r--r--test/OpenMP/target_teams_depend_messages.cpp10
-rw-r--r--test/OpenMP/target_teams_distribute_codegen.cpp820
-rw-r--r--test/OpenMP/target_teams_distribute_codegen_registration.cpp451
-rw-r--r--test/OpenMP/target_teams_distribute_codegen_registration_naming.cpp68
-rw-r--r--test/OpenMP/target_teams_distribute_collapse_codegen.cpp125
-rw-r--r--test/OpenMP/target_teams_distribute_depend_messages.cpp10
-rw-r--r--test/OpenMP/target_teams_distribute_dist_schedule_codegen.cpp197
-rw-r--r--test/OpenMP/target_teams_distribute_firstprivate_codegen.cpp342
-rw-r--r--test/OpenMP/target_teams_distribute_firstprivate_messages.cpp3
-rw-r--r--test/OpenMP/target_teams_distribute_lastprivate_codegen.cpp384
-rw-r--r--test/OpenMP/target_teams_distribute_lastprivate_messages.cpp14
-rw-r--r--test/OpenMP/target_teams_distribute_loop_messages.cpp5
-rw-r--r--test/OpenMP/target_teams_distribute_map_messages.cpp12
-rw-r--r--test/OpenMP/target_teams_distribute_misc_messages.c3
-rw-r--r--test/OpenMP/target_teams_distribute_parallel_for_ast_print.cpp13
-rw-r--r--test/OpenMP/target_teams_distribute_parallel_for_depend_messages.cpp10
-rw-r--r--test/OpenMP/target_teams_distribute_parallel_for_firstprivate_messages.cpp3
-rw-r--r--test/OpenMP/target_teams_distribute_parallel_for_lastprivate_messages.cpp14
-rw-r--r--test/OpenMP/target_teams_distribute_parallel_for_linear_messages.cpp248
-rw-r--r--test/OpenMP/target_teams_distribute_parallel_for_loop_messages.cpp5
-rw-r--r--test/OpenMP/target_teams_distribute_parallel_for_map_messages.cpp12
-rw-r--r--test/OpenMP/target_teams_distribute_parallel_for_messages.cpp2
-rw-r--r--test/OpenMP/target_teams_distribute_parallel_for_misc_messages.c3
-rw-r--r--test/OpenMP/target_teams_distribute_parallel_for_reduction_messages.cpp4
-rw-r--r--test/OpenMP/target_teams_distribute_parallel_for_simd_ast_print.cpp15
-rw-r--r--test/OpenMP/target_teams_distribute_parallel_for_simd_depend_messages.cpp10
-rw-r--r--test/OpenMP/target_teams_distribute_parallel_for_simd_firstprivate_messages.cpp3
-rw-r--r--test/OpenMP/target_teams_distribute_parallel_for_simd_lastprivate_messages.cpp14
-rw-r--r--test/OpenMP/target_teams_distribute_parallel_for_simd_linear_messages.cpp52
-rw-r--r--test/OpenMP/target_teams_distribute_parallel_for_simd_loop_messages.cpp5
-rw-r--r--test/OpenMP/target_teams_distribute_parallel_for_simd_map_messages.cpp12
-rw-r--r--test/OpenMP/target_teams_distribute_parallel_for_simd_misc_messages.c7
-rw-r--r--test/OpenMP/target_teams_distribute_parallel_for_simd_reduction_messages.cpp4
-rw-r--r--test/OpenMP/target_teams_distribute_private_codegen.cpp233
-rw-r--r--test/OpenMP/target_teams_distribute_reduction_codegen.cpp211
-rw-r--r--test/OpenMP/target_teams_distribute_reduction_messages.cpp4
-rw-r--r--test/OpenMP/target_teams_distribute_simd_ast_print.cpp15
-rw-r--r--test/OpenMP/target_teams_distribute_simd_codegen.cpp824
-rw-r--r--test/OpenMP/target_teams_distribute_simd_codegen_registration.cpp454
-rw-r--r--test/OpenMP/target_teams_distribute_simd_codegen_registration_naming.cpp71
-rw-r--r--test/OpenMP/target_teams_distribute_simd_collapse_codegen.cpp125
-rw-r--r--test/OpenMP/target_teams_distribute_simd_depend_messages.cpp10
-rw-r--r--test/OpenMP/target_teams_distribute_simd_dist_schedule_codegen.cpp197
-rw-r--r--test/OpenMP/target_teams_distribute_simd_firstprivate_codegen.cpp342
-rw-r--r--test/OpenMP/target_teams_distribute_simd_firstprivate_messages.cpp3
-rw-r--r--test/OpenMP/target_teams_distribute_simd_lastprivate_codegen.cpp385
-rw-r--r--test/OpenMP/target_teams_distribute_simd_lastprivate_messages.cpp14
-rw-r--r--test/OpenMP/target_teams_distribute_simd_linear_messages.cpp52
-rw-r--r--test/OpenMP/target_teams_distribute_simd_loop_messages.cpp5
-rw-r--r--test/OpenMP/target_teams_distribute_simd_map_messages.cpp12
-rw-r--r--test/OpenMP/target_teams_distribute_simd_misc_messages.c7
-rw-r--r--test/OpenMP/target_teams_distribute_simd_private_codegen.cpp233
-rw-r--r--test/OpenMP/target_teams_distribute_simd_reduction_codegen.cpp211
-rw-r--r--test/OpenMP/target_teams_distribute_simd_reduction_messages.cpp4
-rw-r--r--test/OpenMP/target_teams_map_messages.cpp18
-rw-r--r--test/OpenMP/target_teams_num_teams_codegen.cpp36
-rw-r--r--test/OpenMP/target_teams_reduction_messages.cpp4
-rw-r--r--test/OpenMP/target_teams_thread_limit_codegen.cpp36
-rw-r--r--test/OpenMP/target_update_codegen.cpp28
-rw-r--r--test/OpenMP/target_update_depend_messages.cpp20
-rw-r--r--test/OpenMP/target_update_from_messages.cpp12
-rw-r--r--test/OpenMP/target_update_to_messages.cpp12
-rw-r--r--test/OpenMP/target_vla_messages.cpp201
-rw-r--r--test/OpenMP/task_ast_print.cpp37
-rw-r--r--test/OpenMP/task_depend_messages.cpp10
-rw-r--r--test/OpenMP/task_in_reduction_codegen.cpp81
-rw-r--r--test/OpenMP/task_in_reduction_message.cpp308
-rw-r--r--test/OpenMP/taskgroup_task_reduction_codegen.cpp212
-rw-r--r--test/OpenMP/taskgroup_task_reduction_messages.cpp4
-rw-r--r--test/OpenMP/taskloop_ast_print.cpp12
-rw-r--r--test/OpenMP/taskloop_firstprivate_messages.cpp4
-rw-r--r--test/OpenMP/taskloop_in_reduction_codegen.cpp82
-rw-r--r--test/OpenMP/taskloop_in_reduction_messages.cpp376
-rw-r--r--test/OpenMP/taskloop_lastprivate_messages.cpp4
-rw-r--r--test/OpenMP/taskloop_reduction_codegen.cpp6
-rw-r--r--test/OpenMP/taskloop_reduction_messages.cpp4
-rw-r--r--test/OpenMP/taskloop_simd_ast_print.cpp12
-rw-r--r--test/OpenMP/taskloop_simd_codegen.cpp4
-rw-r--r--test/OpenMP/taskloop_simd_firstprivate_messages.cpp4
-rw-r--r--test/OpenMP/taskloop_simd_in_reduction_codegen.cpp82
-rw-r--r--test/OpenMP/taskloop_simd_in_reduction_messages.cpp376
-rw-r--r--test/OpenMP/taskloop_simd_lastprivate_messages.cpp4
-rw-r--r--test/OpenMP/taskloop_simd_misc_messages.c4
-rw-r--r--test/OpenMP/taskloop_simd_reduction_codegen.cpp3
-rw-r--r--test/OpenMP/taskloop_simd_reduction_messages.cpp4
-rw-r--r--test/OpenMP/teams_codegen.cpp20
-rw-r--r--test/OpenMP/teams_distribute_codegen.cpp241
-rw-r--r--test/OpenMP/teams_distribute_collapse_codegen.cpp128
-rw-r--r--test/OpenMP/teams_distribute_dist_schedule_codegen.cpp206
-rw-r--r--test/OpenMP/teams_distribute_firstprivate_codegen.cpp336
-rw-r--r--test/OpenMP/teams_distribute_firstprivate_messages.cpp3
-rw-r--r--test/OpenMP/teams_distribute_lastprivate_codegen.cpp369
-rw-r--r--test/OpenMP/teams_distribute_lastprivate_messages.cpp14
-rw-r--r--test/OpenMP/teams_distribute_loop_messages.cpp8
-rw-r--r--test/OpenMP/teams_distribute_parallel_for_ast_print.cpp27
-rw-r--r--test/OpenMP/teams_distribute_parallel_for_codegen.cpp247
-rw-r--r--test/OpenMP/teams_distribute_parallel_for_collapse_codegen.cpp144
-rw-r--r--test/OpenMP/teams_distribute_parallel_for_copyin_codegen.cpp199
-rw-r--r--test/OpenMP/teams_distribute_parallel_for_copyin_messages.cpp113
-rw-r--r--test/OpenMP/teams_distribute_parallel_for_dist_schedule_codegen.cpp263
-rw-r--r--test/OpenMP/teams_distribute_parallel_for_firstprivate_codegen.cpp496
-rw-r--r--test/OpenMP/teams_distribute_parallel_for_firstprivate_messages.cpp3
-rw-r--r--test/OpenMP/teams_distribute_parallel_for_if_codegen.cpp184
-rw-r--r--test/OpenMP/teams_distribute_parallel_for_lastprivate_codegen.cpp584
-rw-r--r--test/OpenMP/teams_distribute_parallel_for_lastprivate_messages.cpp14
-rw-r--r--test/OpenMP/teams_distribute_parallel_for_linear_messages.cpp293
-rw-r--r--test/OpenMP/teams_distribute_parallel_for_loop_messages.cpp5
-rw-r--r--test/OpenMP/teams_distribute_parallel_for_messages.cpp16
-rw-r--r--test/OpenMP/teams_distribute_parallel_for_num_threads_codegen.cpp120
-rw-r--r--test/OpenMP/teams_distribute_parallel_for_private_codegen.cpp332
-rw-r--r--test/OpenMP/teams_distribute_parallel_for_proc_bind_codegen.cpp90
-rw-r--r--test/OpenMP/teams_distribute_parallel_for_reduction_codegen.cpp345
-rw-r--r--test/OpenMP/teams_distribute_parallel_for_reduction_messages.cpp4
-rw-r--r--test/OpenMP/teams_distribute_parallel_for_schedule_codegen.cpp398
-rw-r--r--test/OpenMP/teams_distribute_parallel_for_shared_messages.cpp2
-rw-r--r--test/OpenMP/teams_distribute_parallel_for_simd_ast_print.cpp15
-rw-r--r--test/OpenMP/teams_distribute_parallel_for_simd_codegen.cpp263
-rw-r--r--test/OpenMP/teams_distribute_parallel_for_simd_collapse_codegen.cpp149
-rw-r--r--test/OpenMP/teams_distribute_parallel_for_simd_dist_schedule_codegen.cpp268
-rw-r--r--test/OpenMP/teams_distribute_parallel_for_simd_firstprivate_codegen.cpp501
-rw-r--r--test/OpenMP/teams_distribute_parallel_for_simd_firstprivate_messages.cpp3
-rw-r--r--test/OpenMP/teams_distribute_parallel_for_simd_if_codegen.cpp187
-rw-r--r--test/OpenMP/teams_distribute_parallel_for_simd_lastprivate_codegen.cpp599
-rw-r--r--test/OpenMP/teams_distribute_parallel_for_simd_lastprivate_messages.cpp14
-rw-r--r--test/OpenMP/teams_distribute_parallel_for_simd_linear_messages.cpp60
-rw-r--r--test/OpenMP/teams_distribute_parallel_for_simd_loop_messages.cpp5
-rw-r--r--test/OpenMP/teams_distribute_parallel_for_simd_messages.cpp3
-rw-r--r--test/OpenMP/teams_distribute_parallel_for_simd_num_threads_codegen.cpp123
-rw-r--r--test/OpenMP/teams_distribute_parallel_for_simd_private_codegen.cpp336
-rw-r--r--test/OpenMP/teams_distribute_parallel_for_simd_proc_bind_codegen.cpp93
-rw-r--r--test/OpenMP/teams_distribute_parallel_for_simd_reduction_codegen.cpp351
-rw-r--r--test/OpenMP/teams_distribute_parallel_for_simd_reduction_messages.cpp4
-rw-r--r--test/OpenMP/teams_distribute_parallel_for_simd_schedule_codegen.cpp402
-rw-r--r--test/OpenMP/teams_distribute_parallel_for_simd_shared_messages.cpp2
-rw-r--r--test/OpenMP/teams_distribute_private_codegen.cpp236
-rw-r--r--test/OpenMP/teams_distribute_reduction_codegen.cpp217
-rw-r--r--test/OpenMP/teams_distribute_reduction_messages.cpp4
-rw-r--r--test/OpenMP/teams_distribute_shared_messages.cpp2
-rw-r--r--test/OpenMP/teams_distribute_simd_ast_print.cpp15
-rw-r--r--test/OpenMP/teams_distribute_simd_codegen.cpp251
-rw-r--r--test/OpenMP/teams_distribute_simd_collapse_codegen.cpp131
-rw-r--r--test/OpenMP/teams_distribute_simd_dist_schedule_codegen.cpp208
-rw-r--r--test/OpenMP/teams_distribute_simd_firstprivate_codegen.cpp337
-rw-r--r--test/OpenMP/teams_distribute_simd_firstprivate_messages.cpp1
-rw-r--r--test/OpenMP/teams_distribute_simd_lastprivate_codegen.cpp371
-rw-r--r--test/OpenMP/teams_distribute_simd_lastprivate_messages.cpp14
-rw-r--r--test/OpenMP/teams_distribute_simd_linear_messages.cpp60
-rw-r--r--test/OpenMP/teams_distribute_simd_loop_messages.cpp5
-rw-r--r--test/OpenMP/teams_distribute_simd_messages.cpp3
-rw-r--r--test/OpenMP/teams_distribute_simd_private_codegen.cpp238
-rw-r--r--test/OpenMP/teams_distribute_simd_reduction_codegen.cpp218
-rw-r--r--test/OpenMP/teams_distribute_simd_reduction_messages.cpp4
-rw-r--r--test/OpenMP/teams_distribute_simd_shared_messages.cpp2
-rw-r--r--test/OpenMP/teams_messages.cpp3
-rw-r--r--test/OpenMP/teams_private_codegen.cpp9
-rw-r--r--test/OpenMP/teams_reduction_messages.cpp4
-rw-r--r--test/OpenMP/teams_shared_messages.cpp2
-rw-r--r--test/OpenMP/vla_crash.c22
-rw-r--r--test/PCH/case-insensitive-include.c15
-rw-r--r--test/PCH/cxx11-lambdas.mm2
-rw-r--r--test/PCH/cxx2a-bitfield-init.cpp25
-rw-r--r--test/PCH/include-timestamp.cpp20
-rw-r--r--test/PCH/line-directive-nofilename.c9
-rw-r--r--test/PCH/line-directive-nofilename.h5
-rw-r--r--test/PCH/pragma-pack.c30
-rw-r--r--test/PCH/suspicious-pragma-pack.c10
-rw-r--r--test/Parser/MicrosoftExtensions.cpp4
-rw-r--r--test/Parser/arm-windows-calling-convention-handling.c1
-rw-r--r--test/Parser/builtin_types_compatible.c17
-rw-r--r--test/Parser/c2x-attributes.c122
-rw-r--r--test/Parser/c2x-attributes.m21
-rw-r--r--test/Parser/cxx-bool.cpp9
-rw-r--r--test/Parser/cxx-concept-declaration.cpp29
-rw-r--r--test/Parser/cxx0x-attributes.cpp6
-rw-r--r--test/Parser/cxx0x-condition.cpp4
-rw-r--r--test/Parser/cxx1z-class-template-argument-deduction.cpp1
-rw-r--r--test/Parser/cxx1z-decomposition.cpp15
-rw-r--r--test/Parser/cxx1z-fold-expressions.cpp17
-rw-r--r--test/Parser/cxx1z-nested-namespace-definition.cpp2
-rw-r--r--test/Parser/cxx2a-bitfield-init.cpp22
-rw-r--r--test/Parser/cxx2a-spaceship.cpp18
-rw-r--r--test/Parser/decomposed-condition.cpp61
-rw-r--r--test/Parser/editor-placeholder-recovery.cpp4
-rw-r--r--test/Parser/ms-square-bracket-attributes.mm2
-rw-r--r--test/Parser/objcxx11-invalid-lambda.cpp10
-rw-r--r--test/Parser/pragma-options.c2
-rw-r--r--test/Parser/pragma-options.cpp2
-rw-r--r--test/Parser/pragma-pack.c2
-rw-r--r--test/Preprocessor/arm-target-features.c2
-rw-r--r--test/Preprocessor/c17.c4
-rw-r--r--test/Preprocessor/cuda-types.cu32
-rw-r--r--test/Preprocessor/has_c_attribute.c12
-rw-r--r--test/Preprocessor/hexagon-predefines.c59
-rw-r--r--test/Preprocessor/init.c362
-rw-r--r--test/Preprocessor/is_target.c67
-rw-r--r--test/Preprocessor/is_target_arm.c51
-rw-r--r--test/Preprocessor/is_target_arm64.c10
-rw-r--r--test/Preprocessor/is_target_environment_version.c6
-rw-r--r--test/Preprocessor/is_target_os_darwin.c26
-rw-r--r--test/Preprocessor/is_target_unknown.c22
-rw-r--r--test/Preprocessor/macro_raw_string.cpp11
-rw-r--r--test/Preprocessor/macro_vaopt_check.cpp64
-rw-r--r--test/Preprocessor/macro_vaopt_expand.cpp148
-rw-r--r--test/Preprocessor/pr19649-unsigned-wchar_t.c2
-rw-r--r--test/Preprocessor/pragma_assume_nonnull.c16
-rw-r--r--test/Preprocessor/predefined-arch-macros.c266
-rw-r--r--test/Preprocessor/predefined-macros.c82
-rw-r--r--test/Preprocessor/print-assembler.s16
-rw-r--r--test/Preprocessor/stdint.c10
-rw-r--r--test/Preprocessor/wchar_t.c113
-rw-r--r--test/Preprocessor/woa-defaults.c5
-rw-r--r--test/Preprocessor/x86_target_features.c4
-rw-r--r--test/Profile/Inputs/c-captured.proftext8
-rw-r--r--test/Profile/Inputs/c-counter-overflows.proftext2
-rw-r--r--test/Profile/Inputs/c-general.proftext24
-rw-r--r--test/Profile/Inputs/c-unprofiled-blocks.proftext6
-rw-r--r--test/Profile/Inputs/cxx-class.proftext18
-rw-r--r--test/Profile/Inputs/cxx-hash-v2.profdata.v5bin0 -> 3280 bytes
-rw-r--r--test/Profile/Inputs/cxx-hash-v2.proftext239
-rw-r--r--test/Profile/Inputs/cxx-lambda.proftext6
-rw-r--r--test/Profile/Inputs/cxx-rangefor.proftext4
-rw-r--r--test/Profile/Inputs/cxx-templates.proftext6
-rw-r--r--test/Profile/Inputs/cxx-throws.proftext6
-rw-r--r--test/Profile/Inputs/func-entry.proftext4
-rw-r--r--test/Profile/Inputs/gcc-flag-compatibility.proftext2
-rw-r--r--test/Profile/Inputs/objc-general.proftext19
-rw-r--r--test/Profile/c-outdated-data.c4
-rw-r--r--test/Profile/cxx-hash-v2.cpp177
-rw-r--r--test/Profile/objc-general.m18
-rw-r--r--test/Refactor/Extract/ExtractExprIntoFunction.cpp70
-rw-r--r--test/Refactor/Extract/ExtractionSemicolonPolicy.cpp192
-rw-r--r--test/Refactor/Extract/ExtractionSemicolonPolicy.m56
-rw-r--r--test/Refactor/Extract/FromMethodToFunction.cpp42
-rw-r--r--test/Refactor/Extract/ObjCProperty.m41
-rw-r--r--test/Refactor/LocalRename/BuiltinOffsetof.cpp32
-rw-r--r--test/Refactor/LocalRename/Field.cpp11
-rw-r--r--test/Refactor/LocalRename/NoSymbolSelectedError.cpp8
-rw-r--r--test/Refactor/LocalRename/QualifiedRename.cpp24
-rw-r--r--test/Refactor/tool-apply-replacements.cpp9
-rw-r--r--test/Refactor/tool-common-options.c3
-rw-r--r--test/Refactor/tool-selection-option.c15
-rw-r--r--test/Refactor/tool-test-support.c46
-rw-r--r--test/Rewriter/objc-modern-metadata-visibility2.mm45
-rw-r--r--test/Sema/Inputs/pragma-pack1.h27
-rw-r--r--test/Sema/Inputs/pragma-pack2.h8
-rw-r--r--test/Sema/_Float128.c22
-rw-r--r--test/Sema/assign.c43
-rw-r--r--test/Sema/attr-alias.c5
-rw-r--r--test/Sema/attr-availability-app-extensions.c11
-rw-r--r--test/Sema/attr-availability-ios.c4
-rw-r--r--test/Sema/attr-availability-macosx.c4
-rw-r--r--test/Sema/attr-availability-tvos.c4
-rw-r--r--test/Sema/attr-availability-watchos.c4
-rw-r--r--test/Sema/attr-capabilities.c7
-rw-r--r--test/Sema/attr-capabilities.cpp17
-rw-r--r--test/Sema/attr-cleanup.c10
-rw-r--r--test/Sema/attr-deprecated-c2x.c54
-rw-r--r--test/Sema/attr-disable-tail-calls.c2
-rw-r--r--test/Sema/attr-long-call.c26
-rw-r--r--test/Sema/attr-minsize.c2
-rw-r--r--test/Sema/attr-mode.c4
-rw-r--r--test/Sema/attr-nodebug.c2
-rw-r--r--test/Sema/attr-section.c17
-rw-r--r--test/Sema/attr-target.c10
-rw-r--r--test/Sema/attr-weak.c4
-rw-r--r--test/Sema/builtin-assume-aligned.c2
-rw-r--r--test/Sema/builtin-cpu-supports.c6
-rw-r--r--test/Sema/builtins-arm.c184
-rw-r--r--test/Sema/c2x-fallthrough.c75
-rw-r--r--test/Sema/c2x-maybe_unused-errors.c12
-rw-r--r--test/Sema/c2x-maybe_unused.c35
-rw-r--r--test/Sema/c2x-nodiscard.c49
-rw-r--r--test/Sema/compare.c59
-rw-r--r--test/Sema/const-eval.c8
-rw-r--r--test/Sema/dllexport.c12
-rw-r--r--test/Sema/dllimport.c20
-rw-r--r--test/Sema/enum-sign-conversion.c13
-rw-r--r--test/Sema/enum.c12
-rw-r--r--test/Sema/error-type-safety.cpp23
-rw-r--r--test/Sema/format-strings-fixit-ssize_t.c10
-rw-r--r--test/Sema/format-strings-scanf.c64
-rw-r--r--test/Sema/fp16vec-sema.c51
-rw-r--r--test/Sema/implicit-decl-c90.c50
-rw-r--r--test/Sema/implicit-decl.c5
-rw-r--r--test/Sema/inline-asm-validate-amdgpu.cl66
-rw-r--r--test/Sema/internal_linkage.c2
-rw-r--r--test/Sema/ms-annotation.c13
-rw-r--r--test/Sema/ms-inline-asm.c11
-rw-r--r--test/Sema/noescape.c25
-rw-r--r--test/Sema/nonnull.c2
-rw-r--r--test/Sema/outof-range-constant-compare.c36
-rw-r--r--test/Sema/outof-range-enum-constant-compare.c379
-rw-r--r--test/Sema/pointer-addition.c11
-rw-r--r--test/Sema/pragma-ms_struct.c4
-rw-r--r--test/Sema/pragma-pack.c5
-rw-r--r--test/Sema/preserve-call-conv.c3
-rw-r--r--test/Sema/sign-compare-enum.c24
-rw-r--r--test/Sema/struct-packed-align.c14
-rw-r--r--test/Sema/suspicious-pragma-pack.c50
-rw-r--r--test/Sema/switch.c1
-rw-r--r--test/Sema/tautological-constant-compare.c585
-rw-r--r--test/Sema/tautological-constant-enum-compare.c406
-rw-r--r--test/Sema/tautological-unsigned-enum-zero-compare.c126
-rw-r--r--test/Sema/tautological-unsigned-enum-zero-compare.cpp147
-rw-r--r--test/Sema/tautological-unsigned-zero-compare.c257
-rw-r--r--test/Sema/tls.c4
-rw-r--r--test/Sema/transparent-union.c2
-rw-r--r--test/Sema/types.c2
-rw-r--r--test/Sema/unused-expr.c2
-rw-r--r--test/Sema/vector_swizzle_length.c10
-rw-r--r--test/Sema/warn-documentation.cpp22
-rw-r--r--test/Sema/warn-documentation.m11
-rw-r--r--test/Sema/warn-thread-safety-analysis.c2
-rw-r--r--test/Sema/warn-unreachable-ms.c55
-rw-r--r--test/Sema/wchar.c2
-rw-r--r--test/Sema/xray-always-instrument-attr.c2
-rw-r--r--test/Sema/xray-always-instrument-attr.cpp2
-rw-r--r--test/Sema/xray-log-args-oob.c2
-rw-r--r--test/Sema/xray-log-args-oob.cpp2
-rw-r--r--test/Sema/zero-initializer.c41
-rw-r--r--test/SemaCUDA/call-stack-for-deferred-err.cu2
-rw-r--r--test/SemaCUDA/error-includes-mode.cu7
-rw-r--r--test/SemaCUDA/launch_bounds.cu2
-rw-r--r--test/SemaCUDA/no-call-stack-for-immediate-errs.cu2
-rw-r--r--test/SemaCUDA/vla.cu4
-rw-r--r--test/SemaCXX/Inputs/warn-zero-nullptr.h3
-rw-r--r--test/SemaCXX/MicrosoftExtensions.cpp14
-rw-r--r--test/SemaCXX/accessible-base.cpp32
-rw-r--r--test/SemaCXX/address-packed.cpp9
-rw-r--r--test/SemaCXX/aggregate-initialization.cpp32
-rw-r--r--test/SemaCXX/attr-cxx-disabled.cpp12
-rw-r--r--test/SemaCXX/attr-lto-visibility-public.cpp10
-rw-r--r--test/SemaCXX/attr-mode-tmpl.cpp2
-rw-r--r--test/SemaCXX/attr-no-sanitize.cpp11
-rw-r--r--test/SemaCXX/attr-require-constant-initialization.cpp8
-rw-r--r--test/SemaCXX/attr-weak.cpp2
-rw-r--r--test/SemaCXX/builtin-assume-aligned-tmpl.cpp2
-rw-r--r--test/SemaCXX/compare-cxx2a.cpp166
-rw-r--r--test/SemaCXX/compare.cpp26
-rw-r--r--test/SemaCXX/complex-conversion.cpp18
-rw-r--r--test/SemaCXX/complex-overload.cpp7
-rw-r--r--test/SemaCXX/constant-expression-cxx11.cpp49
-rw-r--r--test/SemaCXX/constant-expression-cxx1y.cpp33
-rw-r--r--test/SemaCXX/constant-expression-cxx2a.cpp27
-rw-r--r--test/SemaCXX/constexpr-array-unknown-bound.cpp26
-rw-r--r--test/SemaCXX/coroutines.cpp10
-rw-r--r--test/SemaCXX/cxx0x-compat.cpp7
-rw-r--r--test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp10
-rw-r--r--test/SemaCXX/cxx11-ast-print.cpp4
-rw-r--r--test/SemaCXX/cxx17-compat.cpp29
-rw-r--r--test/SemaCXX/cxx1y-generic-lambdas-capturing.cpp142
-rw-r--r--test/SemaCXX/cxx1y-generic-lambdas-variadics.cpp24
-rw-r--r--test/SemaCXX/cxx1y-init-captures.cpp8
-rw-r--r--test/SemaCXX/cxx1z-class-template-argument-deduction.cpp4
-rw-r--r--test/SemaCXX/cxx1z-copy-omission.cpp41
-rw-r--r--test/SemaCXX/cxx1z-init-statement-template.cpp32
-rw-r--r--test/SemaCXX/cxx1z-noexcept-function-type.cpp2
-rw-r--r--test/SemaCXX/cxx2a-destroying-delete.cpp122
-rw-r--r--test/SemaCXX/cxx2a-lambda-equals-this.cpp15
-rw-r--r--test/SemaCXX/cxx2a-pointer-to-const-ref-member.cpp14
-rw-r--r--test/SemaCXX/cxx2a-three-way-comparison.cpp24
-rw-r--r--test/SemaCXX/cxx98-compat-flags.cpp6
-rw-r--r--test/SemaCXX/decl-expr-ambiguity.cpp24
-rw-r--r--test/SemaCXX/decomposed-condition.cpp99
-rw-r--r--test/SemaCXX/deleted-operator.cpp4
-rw-r--r--test/SemaCXX/deprecated.cpp10
-rw-r--r--test/SemaCXX/destructor.cpp67
-rw-r--r--test/SemaCXX/dllexport.cpp16
-rw-r--r--test/SemaCXX/dllimport.cpp16
-rw-r--r--test/SemaCXX/enum-scoped.cpp5
-rw-r--r--test/SemaCXX/enum.cpp10
-rw-r--r--test/SemaCXX/flexible-array-test.cpp5
-rw-r--r--test/SemaCXX/has_unique_object_reps_member_ptr.cpp32
-rw-r--r--test/SemaCXX/imaginary-constants.cpp44
-rw-r--r--test/SemaCXX/implicit-exception-spec.cpp2
-rw-r--r--test/SemaCXX/init-expr-crash.cpp31
-rw-r--r--test/SemaCXX/integer-overflow.cpp2
-rw-r--r--test/SemaCXX/internal_linkage.cpp8
-rw-r--r--test/SemaCXX/linkage2.cpp36
-rw-r--r--test/SemaCXX/member-init.cpp2
-rw-r--r--test/SemaCXX/microsoft-varargs.cpp5
-rw-r--r--test/SemaCXX/microsoft-vs-float128.cpp34
-rw-r--r--test/SemaCXX/missing-members.cpp14
-rw-r--r--test/SemaCXX/modules-ts.cppm18
-rw-r--r--test/SemaCXX/ms-interface.cpp29
-rw-r--r--test/SemaCXX/ms-iunknown-inline-def.cpp8
-rw-r--r--test/SemaCXX/ms-iunknown-outofline-def.cpp10
-rw-r--r--test/SemaCXX/ms-iunknown-template-function.cpp39
-rw-r--r--test/SemaCXX/ms-iunknown.cpp50
-rw-r--r--test/SemaCXX/new-array-size-conv.cpp2
-rw-r--r--test/SemaCXX/new-delete.cpp26
-rw-r--r--test/SemaCXX/no-warn-user-defined-literals-in-system-headers.cpp5
-rw-r--r--test/SemaCXX/no-warn-user-defined-literals-in-system-headers.h2
-rw-r--r--test/SemaCXX/nothrow-as-noexcept-ctor.cpp26
-rw-r--r--test/SemaCXX/nullptr-arithmetic.cpp30
-rw-r--r--test/SemaCXX/overload-call.cpp8
-rw-r--r--test/SemaCXX/overloaded-operator.cpp54
-rw-r--r--test/SemaCXX/short-wchar-sign.cpp2
-rw-r--r--test/SemaCXX/static-assert.cpp17
-rw-r--r--test/SemaCXX/template-default-param-through-using.cpp33
-rw-r--r--test/SemaCXX/type-traits.cpp317
-rw-r--r--test/SemaCXX/typo-correction-crash.cpp4
-rw-r--r--test/SemaCXX/unavailable_aligned_allocation.cpp58
-rw-r--r--test/SemaCXX/undefined-internal.cpp8
-rw-r--r--test/SemaCXX/underlying_type.cpp14
-rw-r--r--test/SemaCXX/unknown-type-name.cpp11
-rw-r--r--test/SemaCXX/unused.cpp2
-rw-r--r--test/SemaCXX/varargs.cpp2
-rw-r--r--test/SemaCXX/vartemplate-lambda.cpp2
-rw-r--r--test/SemaCXX/warn-absolute-value.cpp155
-rw-r--r--test/SemaCXX/warn-consumed-parsing.cpp12
-rw-r--r--test/SemaCXX/warn-enum-compare.cpp74
-rw-r--r--test/SemaCXX/warn-global-constructors.cpp19
-rw-r--r--test/SemaCXX/warn-sign-conversion-cpp11.cpp21
-rw-r--r--test/SemaCXX/warn-thread-safety-analysis.cpp64
-rw-r--r--test/SemaCXX/warn-thread-safety-parsing.cpp75
-rw-r--r--test/SemaCXX/warn-throw-out-noexcept-func.cpp32
-rw-r--r--test/SemaCXX/warn-unreachable.cpp16
-rw-r--r--test/SemaCXX/warn-unused-attribute.cpp2
-rw-r--r--test/SemaCXX/warn-unused-lambda-capture.cpp9
-rw-r--r--test/SemaCXX/warn-unused-private-field.cpp17
-rw-r--r--test/SemaCXX/warn-unused-variables.cpp43
-rw-r--r--test/SemaCXX/warn-zero-nullptr.cpp71
-rw-r--r--test/SemaObjC/Inputs/empty.h1
-rw-r--r--test/SemaObjC/arc-nsconsumed-errors.m13
-rw-r--r--test/SemaObjC/arc-property-lifetime.m2
-rw-r--r--test/SemaObjC/attr-availability.m4
-rw-r--r--test/SemaObjC/block-literal-with-attribute.m14
-rw-r--r--test/SemaObjC/default-synthesize-1.m16
-rw-r--r--test/SemaObjC/dllexport.m12
-rw-r--r--test/SemaObjC/dllimport.m12
-rw-r--r--test/SemaObjC/flexible-array-arc.m36
-rw-r--r--test/SemaObjC/flexible-array.m288
-rw-r--r--test/SemaObjC/format-arg-attribute.m6
-rw-r--r--test/SemaObjC/ivar-sem-check-1.m5
-rw-r--r--test/SemaObjC/objc-asm-attribute-neg-test.m6
-rw-r--r--test/SemaObjC/objcbridge-attribute-arc.m2
-rw-r--r--test/SemaObjC/objcbridge-attribute.m2
-rw-r--r--test/SemaObjC/property-implement-readonly-with-custom-setter.m21
-rw-r--r--test/SemaObjC/suspicious-pragma-pack.m6
-rw-r--r--test/SemaObjC/transfer-boxed-string-nullability.m28
-rw-r--r--test/SemaObjC/typo-correction.m20
-rw-r--r--test/SemaObjC/unguarded-availability-new.m8
-rw-r--r--test/SemaObjC/unguarded-availability.m42
-rw-r--r--test/SemaObjC/warn-messaging-id.mm21
-rw-r--r--test/SemaObjC/warn-retain-cycle.m12
-rw-r--r--test/SemaObjCXX/Inputs/nullability-completeness-cferror.h13
-rw-r--r--test/SemaObjCXX/Inputs/nullability-consistency-2.h2
-rw-r--r--test/SemaObjCXX/block-variable-move.mm43
-rw-r--r--test/SemaObjCXX/flexible-array.mm37
-rw-r--r--test/SemaObjCXX/noescape.mm90
-rw-r--r--test/SemaObjCXX/nullability-completeness-cferror.mm5
-rw-r--r--test/SemaObjCXX/typo-correction.mm53
-rw-r--r--test/SemaOpenCL/address-spaces.cl23
-rw-r--r--test/SemaOpenCL/atomic-ops.cl195
-rw-r--r--test/SemaOpenCL/cl20-device-side-enqueue.cl32
-rw-r--r--test/SemaOpenCL/clang-builtin-version.cl2
-rw-r--r--test/SemaOpenCL/extension-version.cl18
-rw-r--r--test/SemaOpenCL/extern.cl9
-rw-r--r--test/SemaOpenCL/func.cl5
-rw-r--r--test/SemaOpenCL/invalid-block.cl11
-rw-r--r--test/SemaOpenCL/invalid-pipe-builtin-cl2.0.cl4
-rw-r--r--test/SemaOpenCL/invalid-pipes-cl2.0.cl2
-rw-r--r--test/SemaOpenCL/sampler_t.cl27
-rw-r--r--test/SemaOpenCL/storageclass-cl20.cl34
-rw-r--r--test/SemaOpenCL/storageclass.cl31
-rw-r--r--test/SemaOpenCL/to_addr_builtin.cl2
-rw-r--r--test/SemaOpenCL/vector_conv_invalid.cl10
-rw-r--r--test/SemaOpenCL/vector_swizzle_length.cl2
-rw-r--r--test/SemaTemplate/address_space-dependent.cpp119
-rw-r--r--test/SemaTemplate/class-template-decl.cpp3
-rw-r--r--test/SemaTemplate/crash-unparsed-exception.cpp5
-rw-r--r--test/SemaTemplate/cxx17-inline-variables.cpp18
-rw-r--r--test/SemaTemplate/cxx1z-fold-expressions.cpp16
-rw-r--r--test/SemaTemplate/deduction-crash.cpp17
-rw-r--r--test/SemaTemplate/default-arguments-cxx0x.cpp27
-rw-r--r--test/SemaTemplate/default-expr-arguments-3.cpp2
-rw-r--r--test/SemaTemplate/explicit-instantiation.cpp12
-rw-r--r--test/SemaTemplate/explicit-specialization-member.cpp12
-rw-r--r--test/SemaTemplate/extern-templates.cpp7
-rw-r--r--test/SemaTemplate/instantiate-friend-function.cpp49
-rw-r--r--test/SemaTemplate/temp_arg_nontype_cxx1z.cpp7
-rw-r--r--test/SemaTemplate/temp_arg_template.cpp7
-rw-r--r--test/Tooling/Inputs/clang-diff-basic-src.cpp33
-rw-r--r--test/Tooling/Inputs/fixed-header.h1
-rw-r--r--test/Tooling/clang-diff-args.test12
-rw-r--r--test/Tooling/clang-diff-ast.cpp92
-rw-r--r--test/Tooling/clang-diff-basic.cpp57
-rw-r--r--test/Tooling/clang-diff-bottomup.cpp39
-rw-r--r--test/Tooling/clang-diff-html.test36
-rw-r--r--test/Tooling/clang-diff-json.cpp27
-rw-r--r--test/Tooling/clang-diff-opt.cpp45
-rw-r--r--test/Tooling/clang-diff-topdown.cpp83
-rw-r--r--test/Tooling/fixed-database.cpp19
-rw-r--r--test/Unit/lit.cfg110
-rw-r--r--test/Unit/lit.cfg.py57
-rw-r--r--test/Unit/lit.site.cfg.py.in (renamed from test/Unit/lit.site.cfg.in)2
-rw-r--r--test/clang-rename/Field.cpp15
-rw-r--r--test/clang-rename/ForceMulti.cpp8
-rw-r--r--test/clang-rename/TemplatedClassFunction.cpp17
-rw-r--r--test/lit.cfg534
-rw-r--r--test/lit.cfg.py182
-rw-r--r--test/lit.site.cfg.py.in (renamed from test/lit.site.cfg.in)7
1322 files changed, 68157 insertions, 13710 deletions
diff --git a/test/ASTMerge/namespace/Inputs/namespace1.cpp b/test/ASTMerge/namespace/Inputs/namespace1.cpp
index 1ff84f3111c9..4a539523aaec 100644
--- a/test/ASTMerge/namespace/Inputs/namespace1.cpp
+++ b/test/ASTMerge/namespace/Inputs/namespace1.cpp
@@ -15,3 +15,13 @@ namespace N2 {
namespace N3 {
extern float z;
}
+
+namespace AliasWithSameName = N3;
+
+namespace TestUnresolvedTypenameAndValueDecls {
+template <class T> class Base {
+public:
+ typedef T foo;
+ void bar();
+};
+}
diff --git a/test/ASTMerge/namespace/Inputs/namespace2.cpp b/test/ASTMerge/namespace/Inputs/namespace2.cpp
index 80429f700b13..f65057d1ca66 100644
--- a/test/ASTMerge/namespace/Inputs/namespace2.cpp
+++ b/test/ASTMerge/namespace/Inputs/namespace2.cpp
@@ -15,3 +15,46 @@ namespace N2 {
namespace N3 {
extern double z;
}
+
+namespace Enclosing {
+namespace Nested {
+ const int z = 4;
+}
+}
+
+namespace ContainsInline {
+ inline namespace Inline {
+ const int z = 10;
+ }
+}
+
+namespace TestAliasName = Enclosing::Nested;
+// NOTE: There is no warning on this alias.
+namespace AliasWithSameName = Enclosing::Nested;
+
+namespace TestUsingDecls {
+
+namespace A {
+void foo();
+}
+namespace B {
+using A::foo; // <- a UsingDecl creating a UsingShadow
+}
+
+}// end namespace TestUsingDecls
+
+namespace TestUnresolvedTypenameAndValueDecls {
+
+template <class T> class Base;
+template <class T> class Derived : public Base<T> {
+public:
+ using typename Base<T>::foo;
+ using Base<T>::bar;
+ typedef typename Derived::foo NewUnresolvedUsingType;
+};
+
+} // end namespace TestUnresolvedTypenameAndValueDecls
+
+namespace TestUsingNamespace {
+ using namespace Enclosing;
+}
diff --git a/test/ASTMerge/namespace/test.cpp b/test/ASTMerge/namespace/test.cpp
index 8cc0fa2a6d97..f1796c03b07e 100644
--- a/test/ASTMerge/namespace/test.cpp
+++ b/test/ASTMerge/namespace/test.cpp
@@ -1,6 +1,17 @@
-// RUN: %clang_cc1 -emit-pch -o %t.1.ast %S/Inputs/namespace1.cpp
-// RUN: %clang_cc1 -emit-pch -o %t.2.ast %S/Inputs/namespace2.cpp
-// RUN: not %clang_cc1 -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only %s 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -emit-pch -std=c++1z -o %t.1.ast %S/Inputs/namespace1.cpp
+// RUN: %clang_cc1 -emit-pch -std=c++1z -o %t.2.ast %S/Inputs/namespace2.cpp
+// RUN: not %clang_cc1 -std=c++1z -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only %s 2>&1 | FileCheck %s
+
+static_assert(TestAliasName::z == 4);
+static_assert(ContainsInline::z == 10);
+
+void testImport() {
+ typedef TestUnresolvedTypenameAndValueDecls::Derived<int> Imported;
+ Imported a; // Successfull instantiation
+ static_assert(sizeof(Imported::foo) == sizeof(int));
+ static_assert(sizeof(TestUnresolvedTypenameAndValueDecls::Derived<double>::NewUnresolvedUsingType) == sizeof(double));
+}
+
// CHECK: namespace2.cpp:16:17: error: external variable 'z' declared with incompatible types in different translation units ('double' vs. 'float')
// CHECK: namespace1.cpp:16:16: note: declared here with type 'float'
diff --git a/test/Analysis/DeleteWithNonVirtualDtor.cpp b/test/Analysis/DeleteWithNonVirtualDtor.cpp
new file mode 100644
index 000000000000..a9b8a11f3482
--- /dev/null
+++ b/test/Analysis/DeleteWithNonVirtualDtor.cpp
@@ -0,0 +1,187 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=alpha.cplusplus.DeleteWithNonVirtualDtor -std=c++11 -verify -analyzer-output=text %s
+
+struct Virtual {
+ virtual ~Virtual() {}
+};
+
+struct VDerived : public Virtual {};
+
+struct NonVirtual {
+ ~NonVirtual() {}
+};
+
+struct NVDerived : public NonVirtual {};
+struct NVDoubleDerived : public NVDerived {};
+
+struct Base {
+ virtual void destroy() = 0;
+};
+
+class PrivateDtor final : public Base {
+public:
+ void destroy() { delete this; }
+private:
+ ~PrivateDtor() {}
+};
+
+struct ImplicitNV {
+ virtual void f();
+};
+
+struct ImplicitNVDerived : public ImplicitNV {};
+
+NVDerived *get();
+
+NonVirtual *create() {
+ NonVirtual *x = new NVDerived(); // expected-note{{Conversion from derived to base happened here}}
+ return x;
+}
+
+void sink(NonVirtual *x) {
+ delete x; // expected-warning{{Destruction of a polymorphic object with no virtual destructor}}
+ // expected-note@-1{{Destruction of a polymorphic object with no virtual destructor}}
+}
+
+void sinkCast(NonVirtual *y) {
+ delete reinterpret_cast<NVDerived*>(y);
+}
+
+void sinkParamCast(NVDerived *z) {
+ delete z;
+}
+
+void singleDerived() {
+ NonVirtual *sd;
+ sd = new NVDerived(); // expected-note{{Conversion from derived to base happened here}}
+ delete sd; // expected-warning{{Destruction of a polymorphic object with no virtual destructor}}
+ // expected-note@-1{{Destruction of a polymorphic object with no virtual destructor}}
+}
+
+void singleDerivedArr() {
+ NonVirtual *sda = new NVDerived[5]; // expected-note{{Conversion from derived to base happened here}}
+ delete[] sda; // expected-warning{{Destruction of a polymorphic object with no virtual destructor}}
+ // expected-note@-1{{Destruction of a polymorphic object with no virtual destructor}}
+}
+
+void doubleDerived() {
+ NonVirtual *dd = new NVDoubleDerived(); // expected-note{{Conversion from derived to base happened here}}
+ delete (dd); // expected-warning{{Destruction of a polymorphic object with no virtual destructor}}
+ // expected-note@-1{{Destruction of a polymorphic object with no virtual destructor}}
+}
+
+void assignThroughFunction() {
+ NonVirtual *atf = get(); // expected-note{{Conversion from derived to base happened here}}
+ delete atf; // expected-warning{{Destruction of a polymorphic object with no virtual destructor}}
+ // expected-note@-1{{Destruction of a polymorphic object with no virtual destructor}}
+}
+
+void assignThroughFunction2() {
+ NonVirtual *atf2;
+ atf2 = get(); // expected-note{{Conversion from derived to base happened here}}
+ delete atf2; // expected-warning{{Destruction of a polymorphic object with no virtual destructor}}
+ // expected-note@-1{{Destruction of a polymorphic object with no virtual destructor}}
+}
+
+void createThroughFunction() {
+ NonVirtual *ctf = create(); // expected-note{{Calling 'create'}}
+ // expected-note@-1{{Returning from 'create'}}
+ delete ctf; // expected-warning {{Destruction of a polymorphic object with no virtual destructor}}
+ // expected-note@-1{{Destruction of a polymorphic object with no virtual destructor}}
+}
+
+void deleteThroughFunction() {
+ NonVirtual *dtf = new NVDerived(); // expected-note{{Conversion from derived to base happened here}}
+ sink(dtf); // expected-note{{Calling 'sink'}}
+}
+
+void singleCastCStyle() {
+ NVDerived *sccs = new NVDerived();
+ NonVirtual *sccs2 = (NonVirtual*)sccs; // expected-note{{Conversion from derived to base happened here}}
+ delete sccs2; // expected-warning{{Destruction of a polymorphic object with no virtual destructor}}
+ // expected-note@-1{{Destruction of a polymorphic object with no virtual destructor}}
+}
+
+void doubleCastCStyle() {
+ NonVirtual *dccs = new NVDerived();
+ NVDerived *dccs2 = (NVDerived*)dccs;
+ dccs = (NonVirtual*)dccs2; // expected-note{{Conversion from derived to base happened here}}
+ delete dccs; // expected-warning{{Destruction of a polymorphic object with no virtual destructor}}
+ // expected-note@-1{{Destruction of a polymorphic object with no virtual destructor}}
+}
+
+void singleCast() {
+ NVDerived *sc = new NVDerived();
+ NonVirtual *sc2 = reinterpret_cast<NonVirtual*>(sc); // expected-note{{Conversion from derived to base happened here}}
+ delete sc2; // expected-warning{{Destruction of a polymorphic object with no virtual destructor}}
+ // expected-note@-1{{Destruction of a polymorphic object with no virtual destructor}}
+}
+
+void doubleCast() {
+ NonVirtual *dd = new NVDerived();
+ NVDerived *dd2 = reinterpret_cast<NVDerived*>(dd);
+ dd = reinterpret_cast<NonVirtual*>(dd2); // expected-note {{Conversion from derived to base happened here}}
+ delete dd; // expected-warning {{Destruction of a polymorphic object with no virtual destructor}}
+ // expected-note@-1{{Destruction of a polymorphic object with no virtual destructor}}
+}
+
+void implicitNV() {
+ ImplicitNV *invd = new ImplicitNVDerived(); // expected-note{{Conversion from derived to base happened here}}
+ delete invd; // expected-warning{{Destruction of a polymorphic object with no virtual destructor}}
+ // expected-note@-1{{Destruction of a polymorphic object with no virtual destructor}}
+}
+
+void doubleDecl() {
+ ImplicitNV *dd1, *dd2;
+ dd1 = new ImplicitNVDerived(); // expected-note{{Conversion from derived to base happened here}}
+ delete dd1; // expected-warning{{Destruction of a polymorphic object with no virtual destructor}}
+ // expected-note@-1{{Destruction of a polymorphic object with no virtual destructor}}
+}
+
+void virtualBase() {
+ Virtual *vb = new VDerived();
+ delete vb; // no-warning
+}
+
+void notDerived() {
+ NonVirtual *nd = new NonVirtual();
+ delete nd; // no-warning
+}
+
+void notDerivedArr() {
+ NonVirtual *nda = new NonVirtual[3];
+ delete[] nda; // no-warning
+}
+
+void cast() {
+ NonVirtual *c = new NVDerived();
+ delete reinterpret_cast<NVDerived*>(c); // no-warning
+}
+
+void deleteThroughFunction2() {
+ NonVirtual *dtf2 = new NVDerived();
+ sinkCast(dtf2); // no-warning
+}
+
+void deleteThroughFunction3() {
+ NVDerived *dtf3;
+ dtf3 = new NVDerived();
+ sinkParamCast(dtf3); // no-warning
+}
+
+void stackVar() {
+ NonVirtual sv2;
+ delete &sv2; // no-warning
+}
+
+// Deleting a polymorphic object with a non-virtual dtor
+// is not a problem if it is referenced by its precise type.
+
+void preciseType() {
+ NVDerived *pt = new NVDerived();
+ delete pt; // no-warning
+}
+
+void privateDtor() {
+ Base *pd = new PrivateDtor();
+ pd->destroy(); // no-warning
+}
diff --git a/test/Analysis/MisusedMovedObject.cpp b/test/Analysis/MisusedMovedObject.cpp
index 44e055fd407b..132a65de104e 100644
--- a/test/Analysis/MisusedMovedObject.cpp
+++ b/test/Analysis/MisusedMovedObject.cpp
@@ -38,6 +38,7 @@ public:
B() = default;
B(const B &) = default;
B(B &&) = default;
+ B& operator=(const B &q) = default;
void operator=(B &&b) {
return;
}
@@ -70,6 +71,12 @@ public:
A(A &&other, char *k) {
moveconstruct(std::move(other));
}
+ void operator=(const A &other) {
+ i = other.i;
+ d = other.d;
+ b = other.b;
+ return;
+ }
void operator=(A &&other) {
moveconstruct(std::move(other));
return;
@@ -105,17 +112,42 @@ void copyOrMoveCall(A a) {
}
void simpleMoveCtorTest() {
- A a;
- A b;
- b = std::move(a); // expected-note {{'a' became 'moved-from' here}}
- a.foo(); // expected-warning {{Method call on a 'moved-from' object 'a'}} expected-note {{Method call on a 'moved-from' object 'a'}}
+ {
+ A a;
+ A b = std::move(a); // expected-note {{'a' became 'moved-from' here}}
+ a.foo(); // expected-warning {{Method call on a 'moved-from' object 'a'}} expected-note {{Method call on a 'moved-from' object 'a'}}
+ }
+ {
+ A a;
+ A b = std::move(a); // expected-note {{'a' became 'moved-from' here}}
+ b = a; // expected-warning {{Copying a 'moved-from' object 'a'}} expected-note {{Copying a 'moved-from' object 'a'}}
+ }
+ {
+ A a;
+ A b = std::move(a); // expected-note {{'a' became 'moved-from' here}}
+ b = std::move(a); // expected-warning {{Moving a 'moved-from' object 'a'}} expected-note {{Moving a 'moved-from' object 'a'}}
+ }
}
void simpleMoveAssignementTest() {
- A a;
- A b;
- b = std::move(a); // expected-note {{'a' became 'moved-from' here}}
- a.foo(); // expected-warning {{Method call on a 'moved-from' object 'a'}} expected-note {{Method call on a 'moved-from' object 'a'}}
+ {
+ A a;
+ A b;
+ b = std::move(a); // expected-note {{'a' became 'moved-from' here}}
+ a.foo(); // expected-warning {{Method call on a 'moved-from' object 'a'}} expected-note {{Method call on a 'moved-from' object 'a'}}
+ }
+ {
+ A a;
+ A b;
+ b = std::move(a); // expected-note {{'a' became 'moved-from' here}}
+ A c(a); // expected-warning {{Copying a 'moved-from' object 'a'}} expected-note {{Copying a 'moved-from' object 'a'}}
+ }
+ {
+ A a;
+ A b;
+ b = std::move(a); // expected-note {{'a' became 'moved-from' here}}
+ A c(std::move(a)); // expected-warning {{Moving a 'moved-from' object 'a'}} expected-note {{Moving a 'moved-from' object 'a'}}
+ }
}
void moveInInitListTest() {
@@ -270,7 +302,7 @@ void loopTest() {
{
A a;
for (int i = 0; i < bignum(); i++) { // expected-note {{Loop condition is true. Entering loop body}} expected-note {{Loop condition is true. Entering loop body}}
- constCopyOrMoveCall(std::move(a)); // expected-warning {{Copying a 'moved-from' object 'a'}} expected-note {{Copying a 'moved-from' object 'a'}}
+ constCopyOrMoveCall(std::move(a)); // expected-warning {{Moving a 'moved-from' object 'a'}} expected-note {{Moving a 'moved-from' object 'a'}}
// expected-note@-1 {{'a' became 'moved-from' here}}
}
}
@@ -332,6 +364,8 @@ void moveStateResetFunctionsTest() {
A b = std::move(a);
a.reset(); // no-warning
a.foo(); // no-warning
+ // Test if resets the state of subregions as well.
+ a.b.foo(); // no-warning
}
{
A a;
@@ -344,6 +378,7 @@ void moveStateResetFunctionsTest() {
A b = std::move(a);
a.clear(); // no-warning
a.foo(); // no-warning
+ a.b.foo(); // no-warning
}
}
@@ -444,7 +479,7 @@ void differentBranchesTest(int i) {
// Same thing, but with a switch statement.
{
A a, b;
- switch (i) { // expected-note {{Control jumps to 'case 1:' at line 448}}
+ switch (i) { // expected-note {{Control jumps to 'case 1:' at line 483}}
case 1:
b = std::move(a); // no-warning
break; // expected-note {{Execution jumps to the end of the function}}
@@ -456,7 +491,7 @@ void differentBranchesTest(int i) {
// However, if there's a fallthrough, we do warn.
{
A a, b;
- switch (i) { // expected-note {{Control jumps to 'case 1:' at line 460}}
+ switch (i) { // expected-note {{Control jumps to 'case 1:' at line 495}}
case 1:
b = std::move(a); // expected-note {{'a' became 'moved-from' here}}
case 2:
@@ -598,6 +633,7 @@ void ifStmtSequencesDeclAndConditionTest() {
}
}
+class C : public A {};
void subRegionMoveTest() {
{
A a;
@@ -616,4 +652,24 @@ void subRegionMoveTest() {
a.foo(); // expected-warning {{Method call on a 'moved-from' object 'a'}} expected-note {{Method call on a 'moved-from' object 'a'}}
a.b.foo(); // no-warning
}
+ {
+ C c;
+ C c1 = std::move(c); // expected-note {{'c' became 'moved-from' here}}
+ c.foo(); // expected-warning {{Method call on a 'moved-from' object 'c'}} expected-note {{Method call on a 'moved-from' object 'c'}}
+ c.b.foo(); // no-warning
+ }
+}
+
+void resetSuperClass() {
+ C c;
+ C c1 = std::move(c);
+ c.clear();
+ C c2 = c; // no-warning
+}
+
+void reportSuperClass() {
+ C c;
+ C c1 = std::move(c); // expected-note {{'c' became 'moved-from' here}}
+ c.foo(); // expected-warning {{Method call on a 'moved-from' object 'c'}} expected-note {{Method call on a 'moved-from' object 'c'}}
+ C c2 = c; // no-warning
}
diff --git a/test/Analysis/analyzer-config.c b/test/Analysis/analyzer-config.c
index 0d8d34fbf6b0..4daea898ecd0 100644
--- a/test/Analysis/analyzer-config.c
+++ b/test/Analysis/analyzer-config.c
@@ -14,6 +14,7 @@ void foo() {
// CHECK-NEXT: cfg-conditional-static-initializers = true
// CHECK-NEXT: cfg-implicit-dtors = true
// CHECK-NEXT: cfg-lifetime = false
+// CHECK-NEXT: cfg-loopexit = false
// CHECK-NEXT: cfg-temporary-dtors = false
// CHECK-NEXT: faux-bodies = true
// CHECK-NEXT: graph-trim-interval = 1000
@@ -27,6 +28,7 @@ void foo() {
// CHECK-NEXT: min-cfg-size-treat-functions-as-large = 14
// CHECK-NEXT: mode = deep
// CHECK-NEXT: region-store-small-struct-limit = 2
+// CHECK-NEXT: unroll-loops = false
// CHECK-NEXT: widen-loops = false
// CHECK-NEXT: [stats]
-// CHECK-NEXT: num-entries = 17
+// CHECK-NEXT: num-entries = 19
diff --git a/test/Analysis/analyzer-config.cpp b/test/Analysis/analyzer-config.cpp
index 4166a730cf53..a08e85e53e48 100644
--- a/test/Analysis/analyzer-config.cpp
+++ b/test/Analysis/analyzer-config.cpp
@@ -25,6 +25,7 @@ public:
// CHECK-NEXT: cfg-conditional-static-initializers = true
// CHECK-NEXT: cfg-implicit-dtors = true
// CHECK-NEXT: cfg-lifetime = false
+// CHECK-NEXT: cfg-loopexit = false
// CHECK-NEXT: cfg-temporary-dtors = false
// CHECK-NEXT: faux-bodies = true
// CHECK-NEXT: graph-trim-interval = 1000
@@ -38,6 +39,7 @@ public:
// CHECK-NEXT: min-cfg-size-treat-functions-as-large = 14
// CHECK-NEXT: mode = deep
// CHECK-NEXT: region-store-small-struct-limit = 2
+// CHECK-NEXT: unroll-loops = false
// CHECK-NEXT: widen-loops = false
// CHECK-NEXT: [stats]
-// CHECK-NEXT: num-entries = 22
+// CHECK-NEXT: num-entries = 24
diff --git a/test/Analysis/bitwise-ops.c b/test/Analysis/bitwise-ops.c
index 407aa19289c5..fe546580be3d 100644
--- a/test/Analysis/bitwise-ops.c
+++ b/test/Analysis/bitwise-ops.c
@@ -22,11 +22,32 @@ int testConstantShifts_PR18073(int which) {
case 1:
return 0ULL << 63; // no-warning
case 2:
- return 0ULL << 64; // expected-warning{{The result of the '<<' expression is undefined}}
+ return 0ULL << 64; // expected-warning{{The result of the left shift is undefined due to shifting by '64', which is greater or equal to the width of type 'unsigned long long'}}
case 3:
- return 0ULL << 65; // expected-warning{{The result of the '<<' expression is undefined}}
+ return 0ULL << 65; // expected-warning{{The result of the left shift is undefined due to shifting by '65', which is greater or equal to the width of type 'unsigned long long'}}
default:
return 0;
}
-} \ No newline at end of file
+}
+
+int testOverflowShift(int a) {
+ if (a == 323) {
+ return 1 << a; // expected-warning{{The result of the left shift is undefined due to shifting by '323', which is greater or equal to the width of type 'int'}}
+ }
+ return 0;
+}
+
+int testNegativeShift(int a) {
+ if (a == -5) {
+ return 1 << a; // expected-warning{{The result of the left shift is undefined because the right operand is negative}}
+ }
+ return 0;
+}
+
+int testNegativeLeftShift(int a) {
+ if (a == -3) {
+ return a << 1; // expected-warning{{The result of the left shift is undefined because the left operand is negative}}
+ }
+ return 0;
+}
diff --git a/test/Analysis/block-in-critical-section.cpp b/test/Analysis/block-in-critical-section.cpp
index c65cc612cf73..fcf6188fc033 100644
--- a/test/Analysis/block-in-critical-section.cpp
+++ b/test/Analysis/block-in-critical-section.cpp
@@ -7,6 +7,20 @@ struct mutex {
void lock() {}
void unlock() {}
};
+template<typename T>
+struct lock_guard {
+ lock_guard<T>(std::mutex) {}
+ ~lock_guard<T>() {}
+};
+template<typename T>
+struct unique_lock {
+ unique_lock<T>(std::mutex) {}
+ ~unique_lock<T>() {}
+};
+template<typename T>
+struct not_real_lock {
+ not_real_lock<T>(std::mutex) {}
+};
}
void getc() {}
@@ -110,3 +124,31 @@ void testBlockInCriticalSectionUnexpectedUnlock() {
m.lock();
sleep(1); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}
}
+
+void testBlockInCriticalSectionLockGuard() {
+ std::mutex g_mutex;
+ std::not_real_lock<std::mutex> not_real_lock(g_mutex);
+ sleep(1); // no-warning
+
+ std::lock_guard<std::mutex> lock(g_mutex);
+ sleep(1); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}
+}
+
+void testBlockInCriticalSectionLockGuardNested() {
+ testBlockInCriticalSectionLockGuard();
+ sleep(1); // no-warning
+}
+
+void testBlockInCriticalSectionUniqueLock() {
+ std::mutex g_mutex;
+ std::not_real_lock<std::mutex> not_real_lock(g_mutex);
+ sleep(1); // no-warning
+
+ std::unique_lock<std::mutex> lock(g_mutex);
+ sleep(1); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}
+}
+
+void testBlockInCriticalSectionUniqueLockNested() {
+ testBlockInCriticalSectionUniqueLock();
+ sleep(1); // no-warning
+}
diff --git a/test/Analysis/block-in-critical-section.m b/test/Analysis/block-in-critical-section.m
new file mode 100644
index 000000000000..73d58479f4bf
--- /dev/null
+++ b/test/Analysis/block-in-critical-section.m
@@ -0,0 +1,10 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.unix.BlockInCriticalSection -verify -Wno-objc-root-class %s
+// expected-no-diagnostics
+
+@interface SomeClass
+-(void)someMethod;
+@end
+
+void shouldNotCrash(SomeClass *o) {
+ [o someMethod];
+}
diff --git a/test/Analysis/bstring.cpp b/test/Analysis/bstring.cpp
index a6d7b4016277..fea76cc082fa 100644
--- a/test/Analysis/bstring.cpp
+++ b/test/Analysis/bstring.cpp
@@ -1,8 +1,35 @@
// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -DUSE_BUILTINS -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -DVARIANT -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -DUSE_BUILTINS -DVARIANT -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s
#include "Inputs/system-header-simulator-cxx.h"
#include "Inputs/system-header-simulator-for-malloc.h"
+// This provides us with four possible mempcpy() definitions.
+// See also comments in bstring.c.
+
+#ifdef USE_BUILTINS
+#define BUILTIN(f) __builtin_##f
+#else /* USE_BUILTINS */
+#define BUILTIN(f) f
+#endif /* USE_BUILTINS */
+
+#ifdef VARIANT
+
+#define __mempcpy_chk BUILTIN(__mempcpy_chk)
+void *__mempcpy_chk(void *__restrict__ s1, const void *__restrict__ s2,
+ size_t n, size_t destlen);
+
+#define mempcpy(a,b,c) __mempcpy_chk(a,b,c,(size_t)-1)
+
+#else /* VARIANT */
+
+#define mempcpy BUILTIN(mempcpy)
+void *mempcpy(void *__restrict__ s1, const void *__restrict__ s2, size_t n);
+
+#endif /* VARIANT */
+
void clang_analyzer_eval(int);
int *testStdCopyInvalidatesBuffer(std::vector<int> v) {
@@ -36,3 +63,17 @@ int *testStdCopyBackwardInvalidatesBuffer(std::vector<int> v) {
return buf;
}
+
+namespace pr34460 {
+short a;
+class b {
+ int c;
+ long g;
+ void d() {
+ int e = c;
+ f += e;
+ mempcpy(f, &a, g);
+ }
+ unsigned *f;
+};
+}
diff --git a/test/Analysis/bug_hash_test.cpp b/test/Analysis/bug_hash_test.cpp
index 0efcb5f7cdcd..f397d181e665 100644
--- a/test/Analysis/bug_hash_test.cpp
+++ b/test/Analysis/bug_hash_test.cpp
@@ -1,1345 +1,122 @@
-// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,debug.DumpBugHash -analyzer-output=plist %s -o %t.plist
-// RUN: FileCheck --input-file=%t.plist %s
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,debug.ExprInspection %s -verify
-int function(int p) {
- return 5;
+constexpr int clang_analyzer_hashDump(int) { return 5; }
+
+void function(int) {
+ clang_analyzer_hashDump(5); // expected-warning {{debug.ExprInspection$void function(int)$27$clang_analyzer_hashDump(5);$Category}}
}
namespace {
-int variadicParam(int p, ...) {
- return 5;
-}
+void variadicParam(int, ...) {
+ clang_analyzer_hashDump(5); // expected-warning {{debug.ExprInspection$void (anonymous namespace)::variadicParam(int, ...)$27$clang_analyzer_hashDump(5);$Category}}
}
+} // namespace
-constexpr int f() { return 5; }
+constexpr int f() {
+ return clang_analyzer_hashDump(5); // expected-warning {{debug.ExprInspection$int f()$34$returnclang_analyzer_hashDump(5);$Category}}
+}
namespace AA {
- class X {
- int priv;
- X() : priv(5) { priv = 0; }
+class X {
+ X() {
+ clang_analyzer_hashDump(5); // expected-warning {{debug.ExprInspection$AA::X::X()$29$clang_analyzer_hashDump(5);$Category}}
+ }
- static int static_method() {
- return 5;
- }
+ static void static_method() {
+ clang_analyzer_hashDump(5); // expected-warning {{debug.ExprInspection$void AA::X::static_method()$29$clang_analyzer_hashDump(5);$Category}}
+ variadicParam(5);
+ }
- int method() && {
- class Y {
- inline int method() const & {
- return 5;
- }
- };
+ void method() && {
+ struct Y {
+ inline void method() const & {
+ clang_analyzer_hashDump(5); // expected-warning {{debug.ExprInspection$void AA::X::method()::Y::method() const &$33$clang_analyzer_hashDump(5);$Category}}
+ }
+ };
- return 5;
- }
+ Y y;
+ y.method();
- int OutOfLine();
+ clang_analyzer_hashDump(5); // expected-warning {{debug.ExprInspection$void AA::X::method() &&$29$clang_analyzer_hashDump(5);$Category}}
+ }
- X& operator=(int a) {
- return *this;
- }
+ void OutOfLine();
- operator int() {
- return 0;
- }
+ X &operator=(int) {
+ clang_analyzer_hashDump(5); // expected-warning {{debug.ExprInspection$class AA::X & AA::X::operator=(int)$29$clang_analyzer_hashDump(5);$Category}}
+ return *this;
+ }
- explicit operator float() {
- return 0;
- }
- };
-}
+ operator int() {
+ clang_analyzer_hashDump(5); // expected-warning {{debug.ExprInspection$AA::X::operator int()$29$clang_analyzer_hashDump(5);$Category}}
+ return 0;
+ }
-int AA::X::OutOfLine() {
- return 5;
+ explicit operator float() {
+ clang_analyzer_hashDump(5); // expected-warning {{debug.ExprInspection$AA::X::operator float()$29$clang_analyzer_hashDump(5);$Category}}
+ return 0;
+ }
+};
+} // namespace AA
+
+void AA::X::OutOfLine() {
+ clang_analyzer_hashDump(5); // expected-warning {{debug.ExprInspection$void AA::X::OutOfLine()$27$clang_analyzer_hashDump(5);$Category}}
}
void testLambda() {
- [] () {
- return;
+ []() {
+ clang_analyzer_hashDump(5); // expected-warning {{debug.ExprInspection$void testLambda()::(anonymous class)::operator()() const$29$clang_analyzer_hashDump(5);$Category}}
}();
}
-// CHECK: <key>diagnostics</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>path</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>control</string>
-// CHECK-NEXT: <key>edges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>start</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>5</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>5</integer>
-// CHECK-NEXT: <key>col</key><integer>8</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>end</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>5</integer>
-// CHECK-NEXT: <key>col</key><integer>10</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>5</integer>
-// CHECK-NEXT: <key>col</key><integer>10</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>event</string>
-// CHECK-NEXT: <key>location</key>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>5</integer>
-// CHECK-NEXT: <key>col</key><integer>10</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <key>ranges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>5</integer>
-// CHECK-NEXT: <key>col</key><integer>10</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>5</integer>
-// CHECK-NEXT: <key>col</key><integer>10</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>depth</key><integer>0</integer>
-// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>debug.DumpBugHash$int function(int)$10$return5;$debug</string>
-// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>debug.DumpBugHash$int function(int)$10$return5;$debug</string>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>description</key><string>debug.DumpBugHash$int function(int)$10$return5;$debug</string>
-// CHECK-NEXT: <key>category</key><string>debug</string>
-// CHECK-NEXT: <key>type</key><string>Dump hash components</string>
-// CHECK-NEXT: <key>check_name</key><string>debug.DumpBugHash</string>
-// CHECK-NEXT: <!-- This hash is experimental and going to change! -->
-// CHECK-NEXT: <key>issue_hash_content_of_line_in_context</key><string>e7be204e83f8e5ad3c870ec011d5131d</string>
-// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
-// CHECK-NEXT: <key>issue_context</key><string>function</string>
-// CHECK-NEXT: <key>issue_hash_function_offset</key><string>1</string>
-// CHECK-NEXT: <key>location</key>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>5</integer>
-// CHECK-NEXT: <key>col</key><integer>10</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>path</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>control</string>
-// CHECK-NEXT: <key>edges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>start</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>10</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>10</integer>
-// CHECK-NEXT: <key>col</key><integer>8</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>end</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>10</integer>
-// CHECK-NEXT: <key>col</key><integer>10</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>10</integer>
-// CHECK-NEXT: <key>col</key><integer>10</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>event</string>
-// CHECK-NEXT: <key>location</key>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>10</integer>
-// CHECK-NEXT: <key>col</key><integer>10</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <key>ranges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>10</integer>
-// CHECK-NEXT: <key>col</key><integer>10</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>10</integer>
-// CHECK-NEXT: <key>col</key><integer>10</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>depth</key><integer>0</integer>
-// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>debug.DumpBugHash$int (anonymous namespace)::variadicParam(int, ...)$10$return5;$debug</string>
-// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>debug.DumpBugHash$int (anonymous namespace)::variadicParam(int, ...)$10$return5;$debug</string>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>description</key><string>debug.DumpBugHash$int (anonymous namespace)::variadicParam(int, ...)$10$return5;$debug</string>
-// CHECK-NEXT: <key>category</key><string>debug</string>
-// CHECK-NEXT: <key>type</key><string>Dump hash components</string>
-// CHECK-NEXT: <key>check_name</key><string>debug.DumpBugHash</string>
-// CHECK-NEXT: <!-- This hash is experimental and going to change! -->
-// CHECK-NEXT: <key>issue_hash_content_of_line_in_context</key><string>bc5dc0507ee90f1d14259057d25fb2b9</string>
-// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
-// CHECK-NEXT: <key>issue_context</key><string>variadicParam</string>
-// CHECK-NEXT: <key>issue_hash_function_offset</key><string>1</string>
-// CHECK-NEXT: <key>location</key>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>10</integer>
-// CHECK-NEXT: <key>col</key><integer>10</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>path</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>control</string>
-// CHECK-NEXT: <key>edges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>start</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>14</integer>
-// CHECK-NEXT: <key>col</key><integer>21</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>14</integer>
-// CHECK-NEXT: <key>col</key><integer>26</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>end</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>14</integer>
-// CHECK-NEXT: <key>col</key><integer>28</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>14</integer>
-// CHECK-NEXT: <key>col</key><integer>28</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>event</string>
-// CHECK-NEXT: <key>location</key>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>14</integer>
-// CHECK-NEXT: <key>col</key><integer>28</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <key>ranges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>14</integer>
-// CHECK-NEXT: <key>col</key><integer>28</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>14</integer>
-// CHECK-NEXT: <key>col</key><integer>28</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>depth</key><integer>0</integer>
-// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>debug.DumpBugHash$int f()$28$constexprintf(){return5;}$debug</string>
-// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>debug.DumpBugHash$int f()$28$constexprintf(){return5;}$debug</string>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>description</key><string>debug.DumpBugHash$int f()$28$constexprintf(){return5;}$debug</string>
-// CHECK-NEXT: <key>category</key><string>debug</string>
-// CHECK-NEXT: <key>type</key><string>Dump hash components</string>
-// CHECK-NEXT: <key>check_name</key><string>debug.DumpBugHash</string>
-// CHECK-NEXT: <!-- This hash is experimental and going to change! -->
-// CHECK-NEXT: <key>issue_hash_content_of_line_in_context</key><string>f5471f52854dc14167fe96db50c4ba5f</string>
-// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
-// CHECK-NEXT: <key>issue_context</key><string>f</string>
-// CHECK-NEXT: <key>issue_hash_function_offset</key><string>0</string>
-// CHECK-NEXT: <key>location</key>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>14</integer>
-// CHECK-NEXT: <key>col</key><integer>28</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>path</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>event</string>
-// CHECK-NEXT: <key>location</key>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>19</integer>
-// CHECK-NEXT: <key>col</key><integer>16</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <key>ranges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>19</integer>
-// CHECK-NEXT: <key>col</key><integer>16</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>19</integer>
-// CHECK-NEXT: <key>col</key><integer>16</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>depth</key><integer>0</integer>
-// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>debug.DumpBugHash$AA::X::X()$16$X():priv(5){priv=0;}$debug</string>
-// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>debug.DumpBugHash$AA::X::X()$16$X():priv(5){priv=0;}$debug</string>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>description</key><string>debug.DumpBugHash$AA::X::X()$16$X():priv(5){priv=0;}$debug</string>
-// CHECK-NEXT: <key>category</key><string>debug</string>
-// CHECK-NEXT: <key>type</key><string>Dump hash components</string>
-// CHECK-NEXT: <key>check_name</key><string>debug.DumpBugHash</string>
-// CHECK-NEXT: <!-- This hash is experimental and going to change! -->
-// CHECK-NEXT: <key>issue_hash_content_of_line_in_context</key><string>d23266517ac17d5ec5e2fbbdb1922af1</string>
-// CHECK-NEXT: <key>issue_hash_function_offset</key><string>0</string>
-// CHECK-NEXT: <key>location</key>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>19</integer>
-// CHECK-NEXT: <key>col</key><integer>16</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>path</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>control</string>
-// CHECK-NEXT: <key>edges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>start</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>19</integer>
-// CHECK-NEXT: <key>col</key><integer>16</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>19</integer>
-// CHECK-NEXT: <key>col</key><integer>16</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>end</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>19</integer>
-// CHECK-NEXT: <key>col</key><integer>21</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>19</integer>
-// CHECK-NEXT: <key>col</key><integer>24</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>event</string>
-// CHECK-NEXT: <key>location</key>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>19</integer>
-// CHECK-NEXT: <key>col</key><integer>21</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <key>ranges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>19</integer>
-// CHECK-NEXT: <key>col</key><integer>21</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>19</integer>
-// CHECK-NEXT: <key>col</key><integer>24</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>depth</key><integer>0</integer>
-// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>debug.DumpBugHash$AA::X::X()$21$X():priv(5){priv=0;}$debug</string>
-// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>debug.DumpBugHash$AA::X::X()$21$X():priv(5){priv=0;}$debug</string>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>description</key><string>debug.DumpBugHash$AA::X::X()$21$X():priv(5){priv=0;}$debug</string>
-// CHECK-NEXT: <key>category</key><string>debug</string>
-// CHECK-NEXT: <key>type</key><string>Dump hash components</string>
-// CHECK-NEXT: <key>check_name</key><string>debug.DumpBugHash</string>
-// CHECK-NEXT: <!-- This hash is experimental and going to change! -->
-// CHECK-NEXT: <key>issue_hash_content_of_line_in_context</key><string>7bfcc45512a6a3f61dda6e3ecebc7384</string>
-// CHECK-NEXT: <key>issue_hash_function_offset</key><string>0</string>
-// CHECK-NEXT: <key>location</key>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>19</integer>
-// CHECK-NEXT: <key>col</key><integer>21</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>path</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>control</string>
-// CHECK-NEXT: <key>edges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>start</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>19</integer>
-// CHECK-NEXT: <key>col</key><integer>16</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>19</integer>
-// CHECK-NEXT: <key>col</key><integer>16</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>end</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>19</integer>
-// CHECK-NEXT: <key>col</key><integer>21</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>19</integer>
-// CHECK-NEXT: <key>col</key><integer>24</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>control</string>
-// CHECK-NEXT: <key>edges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>start</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>19</integer>
-// CHECK-NEXT: <key>col</key><integer>21</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>19</integer>
-// CHECK-NEXT: <key>col</key><integer>24</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>end</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>19</integer>
-// CHECK-NEXT: <key>col</key><integer>26</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>19</integer>
-// CHECK-NEXT: <key>col</key><integer>26</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>event</string>
-// CHECK-NEXT: <key>location</key>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>19</integer>
-// CHECK-NEXT: <key>col</key><integer>26</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <key>ranges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>19</integer>
-// CHECK-NEXT: <key>col</key><integer>21</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>19</integer>
-// CHECK-NEXT: <key>col</key><integer>28</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>depth</key><integer>0</integer>
-// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>debug.DumpBugHash$AA::X::X()$21$X():priv(5){priv=0;}$debug</string>
-// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>debug.DumpBugHash$AA::X::X()$21$X():priv(5){priv=0;}$debug</string>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>description</key><string>debug.DumpBugHash$AA::X::X()$21$X():priv(5){priv=0;}$debug</string>
-// CHECK-NEXT: <key>category</key><string>debug</string>
-// CHECK-NEXT: <key>type</key><string>Dump hash components</string>
-// CHECK-NEXT: <key>check_name</key><string>debug.DumpBugHash</string>
-// CHECK-NEXT: <!-- This hash is experimental and going to change! -->
-// CHECK-NEXT: <key>issue_hash_content_of_line_in_context</key><string>95dbfbcdd1dd6401d262994c45d088be</string>
-// CHECK-NEXT: <key>issue_hash_function_offset</key><string>0</string>
-// CHECK-NEXT: <key>location</key>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>19</integer>
-// CHECK-NEXT: <key>col</key><integer>26</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>path</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>control</string>
-// CHECK-NEXT: <key>edges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>start</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>19</integer>
-// CHECK-NEXT: <key>col</key><integer>16</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>19</integer>
-// CHECK-NEXT: <key>col</key><integer>16</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>end</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>19</integer>
-// CHECK-NEXT: <key>col</key><integer>21</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>19</integer>
-// CHECK-NEXT: <key>col</key><integer>24</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>control</string>
-// CHECK-NEXT: <key>edges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>start</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>19</integer>
-// CHECK-NEXT: <key>col</key><integer>21</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>19</integer>
-// CHECK-NEXT: <key>col</key><integer>24</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>end</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>19</integer>
-// CHECK-NEXT: <key>col</key><integer>28</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>19</integer>
-// CHECK-NEXT: <key>col</key><integer>28</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>event</string>
-// CHECK-NEXT: <key>location</key>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>19</integer>
-// CHECK-NEXT: <key>col</key><integer>28</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <key>ranges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>19</integer>
-// CHECK-NEXT: <key>col</key><integer>28</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>19</integer>
-// CHECK-NEXT: <key>col</key><integer>28</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>depth</key><integer>0</integer>
-// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>debug.DumpBugHash$AA::X::X()$28$X():priv(5){priv=0;}$debug</string>
-// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>debug.DumpBugHash$AA::X::X()$28$X():priv(5){priv=0;}$debug</string>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>description</key><string>debug.DumpBugHash$AA::X::X()$28$X():priv(5){priv=0;}$debug</string>
-// CHECK-NEXT: <key>category</key><string>debug</string>
-// CHECK-NEXT: <key>type</key><string>Dump hash components</string>
-// CHECK-NEXT: <key>check_name</key><string>debug.DumpBugHash</string>
-// CHECK-NEXT: <!-- This hash is experimental and going to change! -->
-// CHECK-NEXT: <key>issue_hash_content_of_line_in_context</key><string>064a01551caa8eca3202f1fd55b9c692</string>
-// CHECK-NEXT: <key>issue_hash_function_offset</key><string>0</string>
-// CHECK-NEXT: <key>location</key>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>19</integer>
-// CHECK-NEXT: <key>col</key><integer>28</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>path</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>control</string>
-// CHECK-NEXT: <key>edges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>start</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>22</integer>
-// CHECK-NEXT: <key>col</key><integer>7</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>22</integer>
-// CHECK-NEXT: <key>col</key><integer>12</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>end</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>22</integer>
-// CHECK-NEXT: <key>col</key><integer>14</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>22</integer>
-// CHECK-NEXT: <key>col</key><integer>14</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>event</string>
-// CHECK-NEXT: <key>location</key>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>22</integer>
-// CHECK-NEXT: <key>col</key><integer>14</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <key>ranges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>22</integer>
-// CHECK-NEXT: <key>col</key><integer>14</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>22</integer>
-// CHECK-NEXT: <key>col</key><integer>14</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>depth</key><integer>0</integer>
-// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>debug.DumpBugHash$int AA::X::static_method()$14$return5;$debug</string>
-// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>debug.DumpBugHash$int AA::X::static_method()$14$return5;$debug</string>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>description</key><string>debug.DumpBugHash$int AA::X::static_method()$14$return5;$debug</string>
-// CHECK-NEXT: <key>category</key><string>debug</string>
-// CHECK-NEXT: <key>type</key><string>Dump hash components</string>
-// CHECK-NEXT: <key>check_name</key><string>debug.DumpBugHash</string>
-// CHECK-NEXT: <!-- This hash is experimental and going to change! -->
-// CHECK-NEXT: <key>issue_hash_content_of_line_in_context</key><string>651fcca72f8ad65771702903ecd5f68a</string>
-// CHECK-NEXT: <key>issue_context_kind</key><string>C++ method</string>
-// CHECK-NEXT: <key>issue_context</key><string>static_method</string>
-// CHECK-NEXT: <key>issue_hash_function_offset</key><string>1</string>
-// CHECK-NEXT: <key>location</key>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>22</integer>
-// CHECK-NEXT: <key>col</key><integer>14</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>path</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>control</string>
-// CHECK-NEXT: <key>edges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>start</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>32</integer>
-// CHECK-NEXT: <key>col</key><integer>7</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>32</integer>
-// CHECK-NEXT: <key>col</key><integer>12</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>end</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>32</integer>
-// CHECK-NEXT: <key>col</key><integer>14</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>32</integer>
-// CHECK-NEXT: <key>col</key><integer>14</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>event</string>
-// CHECK-NEXT: <key>location</key>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>32</integer>
-// CHECK-NEXT: <key>col</key><integer>14</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <key>ranges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>32</integer>
-// CHECK-NEXT: <key>col</key><integer>14</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>32</integer>
-// CHECK-NEXT: <key>col</key><integer>14</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>depth</key><integer>0</integer>
-// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>debug.DumpBugHash$int AA::X::method() &amp;&amp;$14$return5;$debug</string>
-// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>debug.DumpBugHash$int AA::X::method() &amp;&amp;$14$return5;$debug</string>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>description</key><string>debug.DumpBugHash$int AA::X::method() &amp;&amp;$14$return5;$debug</string>
-// CHECK-NEXT: <key>category</key><string>debug</string>
-// CHECK-NEXT: <key>type</key><string>Dump hash components</string>
-// CHECK-NEXT: <key>check_name</key><string>debug.DumpBugHash</string>
-// CHECK-NEXT: <!-- This hash is experimental and going to change! -->
-// CHECK-NEXT: <key>issue_hash_content_of_line_in_context</key><string>c8ac8f24467234bea1f34adf5ad5007b</string>
-// CHECK-NEXT: <key>issue_context_kind</key><string>C++ method</string>
-// CHECK-NEXT: <key>issue_context</key><string>method</string>
-// CHECK-NEXT: <key>issue_hash_function_offset</key><string>7</string>
-// CHECK-NEXT: <key>location</key>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>32</integer>
-// CHECK-NEXT: <key>col</key><integer>14</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>path</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>control</string>
-// CHECK-NEXT: <key>edges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>start</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>38</integer>
-// CHECK-NEXT: <key>col</key><integer>7</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>38</integer>
-// CHECK-NEXT: <key>col</key><integer>12</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>end</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>38</integer>
-// CHECK-NEXT: <key>col</key><integer>14</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>38</integer>
-// CHECK-NEXT: <key>col</key><integer>14</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>event</string>
-// CHECK-NEXT: <key>location</key>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>38</integer>
-// CHECK-NEXT: <key>col</key><integer>14</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <key>ranges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>38</integer>
-// CHECK-NEXT: <key>col</key><integer>14</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>38</integer>
-// CHECK-NEXT: <key>col</key><integer>18</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>depth</key><integer>0</integer>
-// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>debug.DumpBugHash$class AA::X &amp; AA::X::operator=(int)$14$return*this;$debug</string>
-// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>debug.DumpBugHash$class AA::X &amp; AA::X::operator=(int)$14$return*this;$debug</string>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>description</key><string>debug.DumpBugHash$class AA::X &amp; AA::X::operator=(int)$14$return*this;$debug</string>
-// CHECK-NEXT: <key>category</key><string>debug</string>
-// CHECK-NEXT: <key>type</key><string>Dump hash components</string>
-// CHECK-NEXT: <key>check_name</key><string>debug.DumpBugHash</string>
-// CHECK-NEXT: <!-- This hash is experimental and going to change! -->
-// CHECK-NEXT: <key>issue_hash_content_of_line_in_context</key><string>b47cf7973c9b459d9c99c483e722db8e</string>
-// CHECK-NEXT: <key>issue_context_kind</key><string>C++ method</string>
-// CHECK-NEXT: <key>issue_context</key><string>operator=</string>
-// CHECK-NEXT: <key>issue_hash_function_offset</key><string>1</string>
-// CHECK-NEXT: <key>location</key>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>38</integer>
-// CHECK-NEXT: <key>col</key><integer>14</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>path</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>control</string>
-// CHECK-NEXT: <key>edges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>start</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>42</integer>
-// CHECK-NEXT: <key>col</key><integer>7</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>42</integer>
-// CHECK-NEXT: <key>col</key><integer>12</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>end</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>42</integer>
-// CHECK-NEXT: <key>col</key><integer>14</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>42</integer>
-// CHECK-NEXT: <key>col</key><integer>14</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>event</string>
-// CHECK-NEXT: <key>location</key>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>42</integer>
-// CHECK-NEXT: <key>col</key><integer>14</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <key>ranges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>42</integer>
-// CHECK-NEXT: <key>col</key><integer>14</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>42</integer>
-// CHECK-NEXT: <key>col</key><integer>14</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>depth</key><integer>0</integer>
-// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>debug.DumpBugHash$AA::X::operator int()$14$return0;$debug</string>
-// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>debug.DumpBugHash$AA::X::operator int()$14$return0;$debug</string>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>description</key><string>debug.DumpBugHash$AA::X::operator int()$14$return0;$debug</string>
-// CHECK-NEXT: <key>category</key><string>debug</string>
-// CHECK-NEXT: <key>type</key><string>Dump hash components</string>
-// CHECK-NEXT: <key>check_name</key><string>debug.DumpBugHash</string>
-// CHECK-NEXT: <!-- This hash is experimental and going to change! -->
-// CHECK-NEXT: <key>issue_hash_content_of_line_in_context</key><string>0cbb0e1e5b03ba5b4f7f8f17504de671</string>
-// CHECK-NEXT: <key>issue_hash_function_offset</key><string>1</string>
-// CHECK-NEXT: <key>location</key>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>42</integer>
-// CHECK-NEXT: <key>col</key><integer>14</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>path</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>control</string>
-// CHECK-NEXT: <key>edges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>start</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>46</integer>
-// CHECK-NEXT: <key>col</key><integer>7</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>46</integer>
-// CHECK-NEXT: <key>col</key><integer>12</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>end</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>46</integer>
-// CHECK-NEXT: <key>col</key><integer>14</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>46</integer>
-// CHECK-NEXT: <key>col</key><integer>14</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>event</string>
-// CHECK-NEXT: <key>location</key>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>46</integer>
-// CHECK-NEXT: <key>col</key><integer>14</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <key>ranges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>46</integer>
-// CHECK-NEXT: <key>col</key><integer>14</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>46</integer>
-// CHECK-NEXT: <key>col</key><integer>14</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>depth</key><integer>0</integer>
-// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>debug.DumpBugHash$AA::X::operator float()$14$return0;$debug</string>
-// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>debug.DumpBugHash$AA::X::operator float()$14$return0;$debug</string>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>description</key><string>debug.DumpBugHash$AA::X::operator float()$14$return0;$debug</string>
-// CHECK-NEXT: <key>category</key><string>debug</string>
-// CHECK-NEXT: <key>type</key><string>Dump hash components</string>
-// CHECK-NEXT: <key>check_name</key><string>debug.DumpBugHash</string>
-// CHECK-NEXT: <!-- This hash is experimental and going to change! -->
-// CHECK-NEXT: <key>issue_hash_content_of_line_in_context</key><string>df306826bf89e50c1b55e1d379a761b3</string>
-// CHECK-NEXT: <key>issue_hash_function_offset</key><string>1</string>
-// CHECK-NEXT: <key>location</key>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>46</integer>
-// CHECK-NEXT: <key>col</key><integer>14</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>path</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>control</string>
-// CHECK-NEXT: <key>edges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>start</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>52</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>52</integer>
-// CHECK-NEXT: <key>col</key><integer>8</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>end</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>52</integer>
-// CHECK-NEXT: <key>col</key><integer>10</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>52</integer>
-// CHECK-NEXT: <key>col</key><integer>10</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>event</string>
-// CHECK-NEXT: <key>location</key>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>52</integer>
-// CHECK-NEXT: <key>col</key><integer>10</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <key>ranges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>52</integer>
-// CHECK-NEXT: <key>col</key><integer>10</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>52</integer>
-// CHECK-NEXT: <key>col</key><integer>10</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>depth</key><integer>0</integer>
-// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>debug.DumpBugHash$int AA::X::OutOfLine()$10$return5;$debug</string>
-// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>debug.DumpBugHash$int AA::X::OutOfLine()$10$return5;$debug</string>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>description</key><string>debug.DumpBugHash$int AA::X::OutOfLine()$10$return5;$debug</string>
-// CHECK-NEXT: <key>category</key><string>debug</string>
-// CHECK-NEXT: <key>type</key><string>Dump hash components</string>
-// CHECK-NEXT: <key>check_name</key><string>debug.DumpBugHash</string>
-// CHECK-NEXT: <!-- This hash is experimental and going to change! -->
-// CHECK-NEXT: <key>issue_hash_content_of_line_in_context</key><string>9dd7b17a6f62ed8c95b37a38cf71f3a9</string>
-// CHECK-NEXT: <key>issue_context_kind</key><string>C++ method</string>
-// CHECK-NEXT: <key>issue_context</key><string>OutOfLine</string>
-// CHECK-NEXT: <key>issue_hash_function_offset</key><string>1</string>
-// CHECK-NEXT: <key>location</key>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>52</integer>
-// CHECK-NEXT: <key>col</key><integer>10</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>path</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>event</string>
-// CHECK-NEXT: <key>location</key>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>56</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <key>ranges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>56</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>58</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>depth</key><integer>0</integer>
-// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>debug.DumpBugHash$void testLambda()$3$[](){$debug</string>
-// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>debug.DumpBugHash$void testLambda()$3$[](){$debug</string>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>description</key><string>debug.DumpBugHash$void testLambda()$3$[](){$debug</string>
-// CHECK-NEXT: <key>category</key><string>debug</string>
-// CHECK-NEXT: <key>type</key><string>Dump hash components</string>
-// CHECK-NEXT: <key>check_name</key><string>debug.DumpBugHash</string>
-// CHECK-NEXT: <!-- This hash is experimental and going to change! -->
-// CHECK-NEXT: <key>issue_hash_content_of_line_in_context</key><string>6ad4400e40885a78a0f57f585421a515</string>
-// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
-// CHECK-NEXT: <key>issue_context</key><string>testLambda</string>
-// CHECK-NEXT: <key>issue_hash_function_offset</key><string>1</string>
-// CHECK-NEXT: <key>location</key>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>56</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>path</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>event</string>
-// CHECK-NEXT: <key>location</key>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>56</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <key>ranges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>56</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>58</integer>
-// CHECK-NEXT: <key>col</key><integer>5</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>depth</key><integer>0</integer>
-// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>debug.DumpBugHash$void testLambda()$3$[](){$debug</string>
-// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>debug.DumpBugHash$void testLambda()$3$[](){$debug</string>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>description</key><string>debug.DumpBugHash$void testLambda()$3$[](){$debug</string>
-// CHECK-NEXT: <key>category</key><string>debug</string>
-// CHECK-NEXT: <key>type</key><string>Dump hash components</string>
-// CHECK-NEXT: <key>check_name</key><string>debug.DumpBugHash</string>
-// CHECK-NEXT: <!-- This hash is experimental and going to change! -->
-// CHECK-NEXT: <key>issue_hash_content_of_line_in_context</key><string>6ad4400e40885a78a0f57f585421a515</string>
-// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
-// CHECK-NEXT: <key>issue_context</key><string>testLambda</string>
-// CHECK-NEXT: <key>issue_hash_function_offset</key><string>1</string>
-// CHECK-NEXT: <key>location</key>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>56</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>path</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>control</string>
-// CHECK-NEXT: <key>edges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>start</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>56</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>56</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>end</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>58</integer>
-// CHECK-NEXT: <key>col</key><integer>4</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>58</integer>
-// CHECK-NEXT: <key>col</key><integer>4</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>event</string>
-// CHECK-NEXT: <key>location</key>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>58</integer>
-// CHECK-NEXT: <key>col</key><integer>4</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <key>ranges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>58</integer>
-// CHECK-NEXT: <key>col</key><integer>4</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>58</integer>
-// CHECK-NEXT: <key>col</key><integer>5</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>depth</key><integer>0</integer>
-// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>debug.DumpBugHash$void testLambda()$4$}();$debug</string>
-// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>debug.DumpBugHash$void testLambda()$4$}();$debug</string>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>description</key><string>debug.DumpBugHash$void testLambda()$4$}();$debug</string>
-// CHECK-NEXT: <key>category</key><string>debug</string>
-// CHECK-NEXT: <key>type</key><string>Dump hash components</string>
-// CHECK-NEXT: <key>check_name</key><string>debug.DumpBugHash</string>
-// CHECK-NEXT: <!-- This hash is experimental and going to change! -->
-// CHECK-NEXT: <key>issue_hash_content_of_line_in_context</key><string>378e6de75fb41b05bcef3950ad5ffa5e</string>
-// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
-// CHECK-NEXT: <key>issue_context</key><string>testLambda</string>
-// CHECK-NEXT: <key>issue_hash_function_offset</key><string>3</string>
-// CHECK-NEXT: <key>location</key>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>58</integer>
-// CHECK-NEXT: <key>col</key><integer>4</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
+template <typename T>
+void f(T) {
+ clang_analyzer_hashDump(5); // expected-warning {{debug.ExprInspection$void f(T)$27$clang_analyzer_hashDump(5);$Category}}
+}
+
+template <typename T>
+struct TX {
+ void f(T) {
+ clang_analyzer_hashDump(5); // expected-warning {{debug.ExprInspection$void TX::f(T)$29$clang_analyzer_hashDump(5);$Category}}
+ }
+};
+
+template <>
+void f<long>(long) {
+ clang_analyzer_hashDump(5); // expected-warning {{debug.ExprInspection$void f(long)$27$clang_analyzer_hashDump(5);$Category}}
+}
+
+template <>
+struct TX<long> {
+ void f(long) {
+ clang_analyzer_hashDump(5); // expected-warning {{debug.ExprInspection$void TX<long>::f(long)$29$clang_analyzer_hashDump(5);$Category}}
+ }
+};
+
+template <typename T>
+struct TTX {
+ template<typename S>
+ void f(T, S) {
+ clang_analyzer_hashDump(5); // expected-warning {{debug.ExprInspection$void TTX::f(T, S)$29$clang_analyzer_hashDump(5);$Category}}
+ }
+};
+
+void g() {
+ // TX<int> and TX<double> is instantiated from the same code with the same
+ // source locations. The same error happining in both of the instantiations
+ // should share the common hash. This means we should not include the
+ // template argument for these types in the function signature.
+ // Note that, we still want the hash to be different for explicit
+ // specializations.
+ TX<int> x;
+ TX<double> y;
+ TX<long> xl;
+ x.f(1);
+ xl.f(1);
+ f(5);
+ f(3.0);
+ y.f(2);
+ TTX<int> z;
+ z.f<int>(5, 5);
+ f(5l);
+}
diff --git a/test/Analysis/bug_hash_test.m b/test/Analysis/bug_hash_test.m
index 1e99d3c0b9ac..fbb70e5d626a 100644
--- a/test/Analysis/bug_hash_test.m
+++ b/test/Analysis/bug_hash_test.m
@@ -1,5 +1,6 @@
-// RUN: %clang_analyze_cc1 -fblocks -analyzer-checker=core,debug.DumpBugHash -analyzer-output=plist %s -o %t.plist
-// RUN: FileCheck --input-file=%t.plist %s
+// RUN: %clang_analyze_cc1 -fblocks -analyzer-checker=core,debug.ExprInspection %s -verify
+
+void clang_analyzer_hashDump(int);
@protocol NSObject
+ (id)alloc;
@@ -15,1178 +16,21 @@ __attribute__((objc_root_class))
@end
@implementation NSObject
++ (id)alloc {
+ return 0;
+}
+- (id)init {
+ return self;
+}
- (void)method:(int)arg param:(int)arg2 {
- arg = 5;
- return;
+ clang_analyzer_hashDump(5); // expected-warning {{debug.ExprInspection$NSObject::method:param:$27$clang_analyzer_hashDump(5);$Category}}
}
@end
void testBlocks() {
int x = 5;
- ^{ int y = 1 + x; }();
+ ^{
+ clang_analyzer_hashDump(x); // expected-warning {{debug.ExprInspection$$29$clang_analyzer_hashDump(x);$Category}}
+ }();
}
-
-// CHECK: <key>diagnostics</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>path</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>control</string>
-// CHECK-NEXT: <key>edges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>start</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>19</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>19</integer>
-// CHECK-NEXT: <key>col</key><integer>5</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>end</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>19</integer>
-// CHECK-NEXT: <key>col</key><integer>7</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>19</integer>
-// CHECK-NEXT: <key>col</key><integer>7</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>event</string>
-// CHECK-NEXT: <key>location</key>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>19</integer>
-// CHECK-NEXT: <key>col</key><integer>7</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <key>ranges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>19</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>19</integer>
-// CHECK-NEXT: <key>col</key><integer>9</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>depth</key><integer>0</integer>
-// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>debug.DumpBugHash$NSObject::method:param:$3$arg=5;$debug</string>
-// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>debug.DumpBugHash$NSObject::method:param:$3$arg=5;$debug</string>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>description</key><string>debug.DumpBugHash$NSObject::method:param:$3$arg=5;$debug</string>
-// CHECK-NEXT: <key>category</key><string>debug</string>
-// CHECK-NEXT: <key>type</key><string>Dump hash components</string>
-// CHECK-NEXT: <key>check_name</key><string>debug.DumpBugHash</string>
-// CHECK-NEXT: <!-- This hash is experimental and going to change! -->
-// CHECK-NEXT: <key>issue_hash_content_of_line_in_context</key><string>f9f569e94382c1f969aabd304581b294</string>
-// CHECK-NEXT: <key>issue_context_kind</key><string>Objective-C method</string>
-// CHECK-NEXT: <key>issue_context</key><string>method:param:</string>
-// CHECK-NEXT: <key>issue_hash_function_offset</key><string>1</string>
-// CHECK-NEXT: <key>location</key>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>19</integer>
-// CHECK-NEXT: <key>col</key><integer>7</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>path</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>control</string>
-// CHECK-NEXT: <key>edges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>start</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>19</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>19</integer>
-// CHECK-NEXT: <key>col</key><integer>5</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>end</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>19</integer>
-// CHECK-NEXT: <key>col</key><integer>9</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>19</integer>
-// CHECK-NEXT: <key>col</key><integer>9</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>event</string>
-// CHECK-NEXT: <key>location</key>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>19</integer>
-// CHECK-NEXT: <key>col</key><integer>9</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <key>ranges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>19</integer>
-// CHECK-NEXT: <key>col</key><integer>9</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>19</integer>
-// CHECK-NEXT: <key>col</key><integer>9</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>depth</key><integer>0</integer>
-// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>debug.DumpBugHash$NSObject::method:param:$9$arg=5;$debug</string>
-// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>debug.DumpBugHash$NSObject::method:param:$9$arg=5;$debug</string>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>description</key><string>debug.DumpBugHash$NSObject::method:param:$9$arg=5;$debug</string>
-// CHECK-NEXT: <key>category</key><string>debug</string>
-// CHECK-NEXT: <key>type</key><string>Dump hash components</string>
-// CHECK-NEXT: <key>check_name</key><string>debug.DumpBugHash</string>
-// CHECK-NEXT: <!-- This hash is experimental and going to change! -->
-// CHECK-NEXT: <key>issue_hash_content_of_line_in_context</key><string>ca44d6aa882ee55f76e11a80d5a66372</string>
-// CHECK-NEXT: <key>issue_context_kind</key><string>Objective-C method</string>
-// CHECK-NEXT: <key>issue_context</key><string>method:param:</string>
-// CHECK-NEXT: <key>issue_hash_function_offset</key><string>1</string>
-// CHECK-NEXT: <key>location</key>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>19</integer>
-// CHECK-NEXT: <key>col</key><integer>9</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>path</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>event</string>
-// CHECK-NEXT: <key>location</key>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>26</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <key>ranges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>26</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>26</integer>
-// CHECK-NEXT: <key>col</key><integer>7</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>depth</key><integer>0</integer>
-// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>debug.DumpBugHash$void testBlocks()$3$intx=5;$debug</string>
-// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>debug.DumpBugHash$void testBlocks()$3$intx=5;$debug</string>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>description</key><string>debug.DumpBugHash$void testBlocks()$3$intx=5;$debug</string>
-// CHECK-NEXT: <key>category</key><string>debug</string>
-// CHECK-NEXT: <key>type</key><string>Dump hash components</string>
-// CHECK-NEXT: <key>check_name</key><string>debug.DumpBugHash</string>
-// CHECK-NEXT: <!-- This hash is experimental and going to change! -->
-// CHECK-NEXT: <key>issue_hash_content_of_line_in_context</key><string>84ec7c854c1c7849abfa03f7f20b4f06</string>
-// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
-// CHECK-NEXT: <key>issue_context</key><string>testBlocks</string>
-// CHECK-NEXT: <key>issue_hash_function_offset</key><string>1</string>
-// CHECK-NEXT: <key>location</key>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>26</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>path</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>control</string>
-// CHECK-NEXT: <key>edges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>start</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>26</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>26</integer>
-// CHECK-NEXT: <key>col</key><integer>5</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>end</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>26</integer>
-// CHECK-NEXT: <key>col</key><integer>11</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>26</integer>
-// CHECK-NEXT: <key>col</key><integer>11</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>event</string>
-// CHECK-NEXT: <key>location</key>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>26</integer>
-// CHECK-NEXT: <key>col</key><integer>11</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <key>ranges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>26</integer>
-// CHECK-NEXT: <key>col</key><integer>11</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>26</integer>
-// CHECK-NEXT: <key>col</key><integer>11</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>depth</key><integer>0</integer>
-// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>debug.DumpBugHash$void testBlocks()$11$intx=5;$debug</string>
-// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>debug.DumpBugHash$void testBlocks()$11$intx=5;$debug</string>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>description</key><string>debug.DumpBugHash$void testBlocks()$11$intx=5;$debug</string>
-// CHECK-NEXT: <key>category</key><string>debug</string>
-// CHECK-NEXT: <key>type</key><string>Dump hash components</string>
-// CHECK-NEXT: <key>check_name</key><string>debug.DumpBugHash</string>
-// CHECK-NEXT: <!-- This hash is experimental and going to change! -->
-// CHECK-NEXT: <key>issue_hash_content_of_line_in_context</key><string>f91db2d7b129ed60e7c9caf6f8a84d5c</string>
-// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
-// CHECK-NEXT: <key>issue_context</key><string>testBlocks</string>
-// CHECK-NEXT: <key>issue_hash_function_offset</key><string>1</string>
-// CHECK-NEXT: <key>location</key>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>26</integer>
-// CHECK-NEXT: <key>col</key><integer>11</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>path</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>control</string>
-// CHECK-NEXT: <key>edges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>start</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>26</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>26</integer>
-// CHECK-NEXT: <key>col</key><integer>5</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>end</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>event</string>
-// CHECK-NEXT: <key>location</key>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <key>ranges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>21</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>depth</key><integer>0</integer>
-// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>debug.DumpBugHash$void testBlocks()$3$^{inty=1+x;}();$debug</string>
-// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>debug.DumpBugHash$void testBlocks()$3$^{inty=1+x;}();$debug</string>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>description</key><string>debug.DumpBugHash$void testBlocks()$3$^{inty=1+x;}();$debug</string>
-// CHECK-NEXT: <key>category</key><string>debug</string>
-// CHECK-NEXT: <key>type</key><string>Dump hash components</string>
-// CHECK-NEXT: <key>check_name</key><string>debug.DumpBugHash</string>
-// CHECK-NEXT: <!-- This hash is experimental and going to change! -->
-// CHECK-NEXT: <key>issue_hash_content_of_line_in_context</key><string>0f1e9483a8ff59e787eaac18b68068ad</string>
-// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
-// CHECK-NEXT: <key>issue_context</key><string>testBlocks</string>
-// CHECK-NEXT: <key>issue_hash_function_offset</key><string>2</string>
-// CHECK-NEXT: <key>location</key>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>path</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>control</string>
-// CHECK-NEXT: <key>edges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>start</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>26</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>26</integer>
-// CHECK-NEXT: <key>col</key><integer>5</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>end</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>event</string>
-// CHECK-NEXT: <key>location</key>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <key>ranges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>23</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>depth</key><integer>0</integer>
-// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>debug.DumpBugHash$void testBlocks()$3$^{inty=1+x;}();$debug</string>
-// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>debug.DumpBugHash$void testBlocks()$3$^{inty=1+x;}();$debug</string>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>description</key><string>debug.DumpBugHash$void testBlocks()$3$^{inty=1+x;}();$debug</string>
-// CHECK-NEXT: <key>category</key><string>debug</string>
-// CHECK-NEXT: <key>type</key><string>Dump hash components</string>
-// CHECK-NEXT: <key>check_name</key><string>debug.DumpBugHash</string>
-// CHECK-NEXT: <!-- This hash is experimental and going to change! -->
-// CHECK-NEXT: <key>issue_hash_content_of_line_in_context</key><string>0f1e9483a8ff59e787eaac18b68068ad</string>
-// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
-// CHECK-NEXT: <key>issue_context</key><string>testBlocks</string>
-// CHECK-NEXT: <key>issue_hash_function_offset</key><string>2</string>
-// CHECK-NEXT: <key>location</key>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>path</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>control</string>
-// CHECK-NEXT: <key>edges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>start</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>26</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>26</integer>
-// CHECK-NEXT: <key>col</key><integer>5</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>end</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>event</string>
-// CHECK-NEXT: <key>location</key>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <key>ranges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>23</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>depth</key><integer>0</integer>
-// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>Calling anonymous block</string>
-// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>Calling anonymous block</string>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>event</string>
-// CHECK-NEXT: <key>location</key>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <key>depth</key><integer>1</integer>
-// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>Entered call from &apos;testBlocks&apos;</string>
-// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>Entered call from &apos;testBlocks&apos;</string>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>control</string>
-// CHECK-NEXT: <key>edges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>start</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>end</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>6</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>8</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>event</string>
-// CHECK-NEXT: <key>location</key>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>6</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <key>ranges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>6</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>10</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>depth</key><integer>1</integer>
-// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>debug.DumpBugHash$$6$^{inty=1+x;}();$debug</string>
-// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>debug.DumpBugHash$$6$^{inty=1+x;}();$debug</string>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>description</key><string>debug.DumpBugHash$$6$^{inty=1+x;}();$debug</string>
-// CHECK-NEXT: <key>category</key><string>debug</string>
-// CHECK-NEXT: <key>type</key><string>Dump hash components</string>
-// CHECK-NEXT: <key>check_name</key><string>debug.DumpBugHash</string>
-// CHECK-NEXT: <!-- This hash is experimental and going to change! -->
-// CHECK-NEXT: <key>issue_hash_content_of_line_in_context</key><string>8a8e42efc427e1334b77d510d3fb6361</string>
-// CHECK-NEXT: <key>location</key>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>6</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>path</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>control</string>
-// CHECK-NEXT: <key>edges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>start</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>26</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>26</integer>
-// CHECK-NEXT: <key>col</key><integer>5</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>end</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>event</string>
-// CHECK-NEXT: <key>location</key>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <key>ranges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>23</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>depth</key><integer>0</integer>
-// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>Calling anonymous block</string>
-// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>Calling anonymous block</string>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>event</string>
-// CHECK-NEXT: <key>location</key>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <key>depth</key><integer>1</integer>
-// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>Entered call from &apos;testBlocks&apos;</string>
-// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>Entered call from &apos;testBlocks&apos;</string>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>control</string>
-// CHECK-NEXT: <key>edges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>start</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>end</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>6</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>8</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>control</string>
-// CHECK-NEXT: <key>edges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>start</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>6</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>8</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>end</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>14</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>14</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>event</string>
-// CHECK-NEXT: <key>location</key>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>14</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <key>ranges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>14</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>14</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>depth</key><integer>1</integer>
-// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>debug.DumpBugHash$$14$^{inty=1+x;}();$debug</string>
-// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>debug.DumpBugHash$$14$^{inty=1+x;}();$debug</string>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>description</key><string>debug.DumpBugHash$$14$^{inty=1+x;}();$debug</string>
-// CHECK-NEXT: <key>category</key><string>debug</string>
-// CHECK-NEXT: <key>type</key><string>Dump hash components</string>
-// CHECK-NEXT: <key>check_name</key><string>debug.DumpBugHash</string>
-// CHECK-NEXT: <!-- This hash is experimental and going to change! -->
-// CHECK-NEXT: <key>issue_hash_content_of_line_in_context</key><string>6d6028808f1d47ec5b74a417e96c2a02</string>
-// CHECK-NEXT: <key>location</key>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>14</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>path</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>control</string>
-// CHECK-NEXT: <key>edges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>start</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>26</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>26</integer>
-// CHECK-NEXT: <key>col</key><integer>5</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>end</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>event</string>
-// CHECK-NEXT: <key>location</key>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <key>ranges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>23</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>depth</key><integer>0</integer>
-// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>Calling anonymous block</string>
-// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>Calling anonymous block</string>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>event</string>
-// CHECK-NEXT: <key>location</key>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <key>depth</key><integer>1</integer>
-// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>Entered call from &apos;testBlocks&apos;</string>
-// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>Entered call from &apos;testBlocks&apos;</string>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>control</string>
-// CHECK-NEXT: <key>edges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>start</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>end</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>16</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>16</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>event</string>
-// CHECK-NEXT: <key>location</key>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>16</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <key>ranges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>14</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>18</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>depth</key><integer>1</integer>
-// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>debug.DumpBugHash$$14$^{inty=1+x;}();$debug</string>
-// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>debug.DumpBugHash$$14$^{inty=1+x;}();$debug</string>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>description</key><string>debug.DumpBugHash$$14$^{inty=1+x;}();$debug</string>
-// CHECK-NEXT: <key>category</key><string>debug</string>
-// CHECK-NEXT: <key>type</key><string>Dump hash components</string>
-// CHECK-NEXT: <key>check_name</key><string>debug.DumpBugHash</string>
-// CHECK-NEXT: <!-- This hash is experimental and going to change! -->
-// CHECK-NEXT: <key>issue_hash_content_of_line_in_context</key><string>162138b23629276baad7dd3e8051fd6f</string>
-// CHECK-NEXT: <key>location</key>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>16</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>path</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>control</string>
-// CHECK-NEXT: <key>edges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>start</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>26</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>26</integer>
-// CHECK-NEXT: <key>col</key><integer>5</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>end</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>event</string>
-// CHECK-NEXT: <key>location</key>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <key>ranges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>23</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>depth</key><integer>0</integer>
-// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>Calling anonymous block</string>
-// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>Calling anonymous block</string>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>event</string>
-// CHECK-NEXT: <key>location</key>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <key>depth</key><integer>1</integer>
-// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>Entered call from &apos;testBlocks&apos;</string>
-// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>Entered call from &apos;testBlocks&apos;</string>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>control</string>
-// CHECK-NEXT: <key>edges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>start</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>end</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>6</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>8</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>control</string>
-// CHECK-NEXT: <key>edges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>start</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>6</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>8</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>end</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>18</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>18</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>event</string>
-// CHECK-NEXT: <key>location</key>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>18</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <key>ranges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>18</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>18</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>depth</key><integer>1</integer>
-// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>debug.DumpBugHash$$18$^{inty=1+x;}();$debug</string>
-// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>debug.DumpBugHash$$18$^{inty=1+x;}();$debug</string>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>description</key><string>debug.DumpBugHash$$18$^{inty=1+x;}();$debug</string>
-// CHECK-NEXT: <key>category</key><string>debug</string>
-// CHECK-NEXT: <key>type</key><string>Dump hash components</string>
-// CHECK-NEXT: <key>check_name</key><string>debug.DumpBugHash</string>
-// CHECK-NEXT: <!-- This hash is experimental and going to change! -->
-// CHECK-NEXT: <key>issue_hash_content_of_line_in_context</key><string>b3add78bcab0ebc3da3b640081057525</string>
-// CHECK-NEXT: <key>location</key>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
-// CHECK-NEXT: <key>col</key><integer>18</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
diff --git a/test/Analysis/call_once.cpp b/test/Analysis/call_once.cpp
new file mode 100644
index 000000000000..db9e5cc7ca16
--- /dev/null
+++ b/test/Analysis/call_once.cpp
@@ -0,0 +1,361 @@
+// RUN: %clang_analyze_cc1 -std=c++11 -fblocks -analyzer-checker=core,debug.ExprInspection -verify %s
+// RUN: %clang_analyze_cc1 -std=c++11 -fblocks -analyzer-checker=core,debug.ExprInspection -DEMULATE_LIBSTDCPP -verify %s
+
+// We do NOT model libcxx03 implementation, but the analyzer should still
+// not crash.
+// RUN: %clang_analyze_cc1 -std=c++11 -fblocks -analyzer-checker=core,debug.ExprInspection -DEMULATE_LIBCXX03 -verify %s
+// RUN: %clang_analyze_cc1 -std=c++11 -fblocks -analyzer-checker=core,debug.ExprInspection -DEMULATE_LIBCXX03 -DEMULATE_LIBSTDCPP -verify %s
+
+void clang_analyzer_eval(bool);
+
+// Faking std::std::call_once implementation.
+namespace std {
+
+#ifndef EMULATE_LIBSTDCPP
+typedef struct once_flag_s {
+ unsigned long __state_ = 0;
+} once_flag;
+#else
+typedef struct once_flag_s {
+ int _M_once = 0;
+} once_flag;
+#endif
+
+#ifndef EMULATE_LIBCXX03
+template <class Callable, class... Args>
+void call_once(once_flag &o, Callable&& func, Args&&... args) {};
+#else
+template <class Callable, class... Args> // libcxx03 call_once
+void call_once(once_flag &o, Callable func, Args&&... args) {};
+#endif
+
+} // namespace std
+
+// Check with Lambdas.
+void test_called_warning() {
+ std::once_flag g_initialize;
+ int z;
+
+ std::call_once(g_initialize, [&] {
+ int *x = nullptr;
+#ifndef EMULATE_LIBCXX03
+ int y = *x; // expected-warning{{Dereference of null pointer (loaded from variable 'x')}}
+#endif
+ z = 200;
+ });
+}
+
+void test_called_on_path_inside_no_warning() {
+ std::once_flag g_initialize;
+
+ int *x = nullptr;
+ int y = 100;
+ int z;
+
+ std::call_once(g_initialize, [&] {
+ z = 200;
+ x = &z;
+ });
+
+#ifndef EMULATE_LIBCXX03
+ *x = 100; // no-warning
+ clang_analyzer_eval(z == 100); // expected-warning{{TRUE}}
+#endif
+}
+
+void test_called_on_path_no_warning() {
+ std::once_flag g_initialize;
+
+ int *x = nullptr;
+ int y = 100;
+
+ std::call_once(g_initialize, [&] {
+ x = &y;
+ });
+
+#ifndef EMULATE_LIBCXX03
+ *x = 100; // no-warning
+#else
+ *x = 100; // expected-warning{{Dereference of null pointer (loaded from variable 'x')}}
+#endif
+}
+
+void test_called_on_path_warning() {
+ std::once_flag g_initialize;
+
+ int y = 100;
+ int *x = &y;
+
+ std::call_once(g_initialize, [&] {
+ x = nullptr;
+ });
+
+#ifndef EMULATE_LIBCXX03
+ *x = 100; // expected-warning{{Dereference of null pointer (loaded from variable 'x')}}
+#endif
+}
+
+void test_called_once_warning() {
+ std::once_flag g_initialize;
+
+ int *x = nullptr;
+ int y = 100;
+
+ std::call_once(g_initialize, [&] {
+ x = nullptr;
+ });
+
+ std::call_once(g_initialize, [&] {
+ x = &y;
+ });
+
+#ifndef EMULATE_LIBCXX03
+ *x = 100; // expected-warning{{Dereference of null pointer (loaded from variable 'x')}}
+#endif
+}
+
+void test_called_once_no_warning() {
+ std::once_flag g_initialize;
+
+ int *x = nullptr;
+ int y = 100;
+
+ std::call_once(g_initialize, [&] {
+ x = &y;
+ });
+
+ std::call_once(g_initialize, [&] {
+ x = nullptr;
+ });
+
+#ifndef EMULATE_LIBCXX03
+ *x = 100; // no-warning
+#endif
+}
+
+static int global = 0;
+void funcPointer() {
+ global = 1;
+}
+
+void test_func_pointers() {
+ static std::once_flag flag;
+ std::call_once(flag, &funcPointer);
+#ifndef EMULATE_LIBCXX03
+ clang_analyzer_eval(global == 1); // expected-warning{{TRUE}}
+#endif
+}
+
+template <class _Fp>
+class function; // undefined
+template <class _Rp, class... _ArgTypes>
+struct function<_Rp(_ArgTypes...)> {
+ _Rp operator()(_ArgTypes...) const {};
+ template <class _Fp>
+ function(_Fp) {};
+};
+
+// Note: currently we do not support calls to std::function,
+// but the analyzer should not crash either.
+void test_function_objects_warning() {
+ int x = 0;
+ int *y = &x;
+
+ std::once_flag flag;
+
+ function<void()> func = [&]() {
+ y = nullptr;
+ };
+
+ std::call_once(flag, func);
+
+ func();
+ int z = *y;
+}
+
+void test_param_passing_lambda() {
+ std::once_flag flag;
+ int x = 120;
+ int y = 0;
+
+ std::call_once(flag, [&](int p) {
+ y = p;
+ },
+ x);
+
+#ifndef EMULATE_LIBCXX03
+ clang_analyzer_eval(y == 120); // expected-warning{{TRUE}}
+#endif
+}
+
+void test_param_passing_lambda_false() {
+ std::once_flag flag;
+ int x = 120;
+
+ std::call_once(flag, [&](int p) {
+ x = 0;
+ },
+ x);
+
+#ifndef EMULATE_LIBCXX03
+ clang_analyzer_eval(x == 120); // expected-warning{{FALSE}}
+#endif
+}
+
+void test_param_passing_stored_lambda() {
+ std::once_flag flag;
+ int x = 120;
+ int y = 0;
+
+ auto lambda = [&](int p) {
+ y = p;
+ };
+
+ std::call_once(flag, lambda, x);
+#ifndef EMULATE_LIBCXX03
+ clang_analyzer_eval(y == 120); // expected-warning{{TRUE}}
+#endif
+}
+
+void test_multiparam_passing_lambda() {
+ std::once_flag flag;
+ int x = 120;
+
+ std::call_once(flag, [&](int a, int b, int c) {
+ x = a + b + c;
+ },
+ 1, 2, 3);
+
+#ifndef EMULATE_LIBCXX03
+ clang_analyzer_eval(x == 120); // expected-warning{{FALSE}}
+ clang_analyzer_eval(x == 6); // expected-warning{{TRUE}}
+#endif
+}
+
+static int global2 = 0;
+void test_param_passing_lambda_global() {
+ std::once_flag flag;
+ global2 = 0;
+ std::call_once(flag, [&](int a, int b, int c) {
+ global2 = a + b + c;
+ },
+ 1, 2, 3);
+#ifndef EMULATE_LIBCXX03
+ clang_analyzer_eval(global2 == 6); // expected-warning{{TRUE}}
+#endif
+}
+
+static int global3 = 0;
+void funcptr(int a, int b, int c) {
+ global3 = a + b + c;
+}
+
+void test_param_passing_funcptr() {
+ std::once_flag flag;
+ global3 = 0;
+
+ std::call_once(flag, &funcptr, 1, 2, 3);
+
+#ifndef EMULATE_LIBCXX03
+ clang_analyzer_eval(global3 == 6); // expected-warning{{TRUE}}
+#endif
+}
+
+void test_blocks() {
+ global3 = 0;
+ std::once_flag flag;
+ std::call_once(flag, ^{
+ global3 = 120;
+ });
+#ifndef EMULATE_LIBCXX03
+ clang_analyzer_eval(global3 == 120); // expected-warning{{TRUE}}
+#endif
+}
+
+int call_once() {
+ return 5;
+}
+
+void test_non_std_call_once() {
+ int x = call_once();
+#ifndef EMULATE_LIBCXX03
+ clang_analyzer_eval(x == 5); // expected-warning{{TRUE}}
+#endif
+}
+
+namespace std {
+template <typename d, typename e>
+void call_once(d, e);
+}
+void g();
+void test_no_segfault_on_different_impl() {
+#ifndef EMULATE_LIBCXX03
+ std::call_once(g, false); // no-warning
+#endif
+}
+
+void test_lambda_refcapture() {
+ static std::once_flag flag;
+ int a = 6;
+ std::call_once(flag, [&](int &a) { a = 42; }, a);
+#ifndef EMULATE_LIBCXX03
+ clang_analyzer_eval(a == 42); // expected-warning{{TRUE}}
+#endif
+}
+
+void test_lambda_refcapture2() {
+ static std::once_flag flag;
+ int a = 6;
+ std::call_once(flag, [=](int &a) { a = 42; }, a);
+#ifndef EMULATE_LIBCXX03
+ clang_analyzer_eval(a == 42); // expected-warning{{TRUE}}
+#endif
+}
+
+void test_lambda_fail_refcapture() {
+ static std::once_flag flag;
+ int a = 6;
+ std::call_once(flag, [=](int a) { a = 42; }, a);
+#ifndef EMULATE_LIBCXX03
+ clang_analyzer_eval(a == 42); // expected-warning{{FALSE}}
+#endif
+}
+
+void mutator(int &param) {
+ param = 42;
+}
+void test_reftypes_funcptr() {
+ static std::once_flag flag;
+ int a = 6;
+ std::call_once(flag, &mutator, a);
+#ifndef EMULATE_LIBCXX03
+ clang_analyzer_eval(a == 42); // expected-warning{{TRUE}}
+#endif
+}
+
+void fail_mutator(int param) {
+ param = 42;
+}
+void test_mutator_noref() {
+ static std::once_flag flag;
+ int a = 6;
+ std::call_once(flag, &fail_mutator, a);
+#ifndef EMULATE_LIBCXX03
+ clang_analyzer_eval(a == 42); // expected-warning{{FALSE}}
+#endif
+}
+
+// Function is implicitly treated as a function pointer
+// even when an ampersand is not explicitly set.
+void callbackn(int &param) {
+ param = 42;
+}
+void test_implicit_funcptr() {
+ int x = 0;
+ static std::once_flag flagn;
+
+ std::call_once(flagn, callbackn, x);
+#ifndef EMULATE_LIBCXX03
+ clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}
+#endif
+}
diff --git a/test/Analysis/casts.c b/test/Analysis/casts.c
index 3ba12e4318de..24bba8a30a00 100644
--- a/test/Analysis/casts.c
+++ b/test/Analysis/casts.c
@@ -123,3 +123,29 @@ void locAsIntegerCasts(void *p) {
int x = (int) p;
clang_analyzer_eval(++x < 10); // no-crash // expected-warning{{UNKNOWN}}
}
+
+void multiDimensionalArrayPointerCasts() {
+ static int x[10][10];
+ int *y1 = &(x[3][5]);
+ char *z = ((char *) y1) + 2;
+ int *y2 = (int *)(z - 2);
+ int *y3 = ((int *)x) + 35; // This is offset for [3][5].
+
+ clang_analyzer_eval(y1 == y2); // expected-warning{{TRUE}}
+
+ // FIXME: should be FALSE (i.e. equal pointers).
+ clang_analyzer_eval(y1 - y2); // expected-warning{{UNKNOWN}}
+ // FIXME: should be TRUE (i.e. same symbol).
+ clang_analyzer_eval(*y1 == *y2); // expected-warning{{UNKNOWN}}
+
+ clang_analyzer_eval(*((char *)y1) == *((char *) y2)); // expected-warning{{TRUE}}
+
+ clang_analyzer_eval(y1 == y3); // expected-warning{{TRUE}}
+
+ // FIXME: should be FALSE (i.e. equal pointers).
+ clang_analyzer_eval(y1 - y3); // expected-warning{{UNKNOWN}}
+ // FIXME: should be TRUE (i.e. same symbol).
+ clang_analyzer_eval(*y1 == *y3); // expected-warning{{UNKNOWN}}
+
+ clang_analyzer_eval(*((char *)y1) == *((char *) y3)); // expected-warning{{TRUE}}
+}
diff --git a/test/Analysis/cfg-indirect-goto-determinism.cpp b/test/Analysis/cfg-indirect-goto-determinism.cpp
new file mode 100644
index 000000000000..895535e0c712
--- /dev/null
+++ b/test/Analysis/cfg-indirect-goto-determinism.cpp
@@ -0,0 +1,96 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=debug.DumpCFG %s 2>&1 | FileCheck %s
+
+void *target;
+int indirectBlockSuccessorDeterminism() {
+ (void)&&L1;
+ (void)&&L2;
+ (void)&&L3;
+ (void)&&L4;
+ (void)&&L5;
+ (void)&&L6;
+ (void)&&L7;
+ (void)&&L8;
+ (void)&&L9;
+ (void)&&L10;
+ (void)&&L11;
+ (void)&&L12;
+ (void)&&L13;
+ (void)&&L14;
+ (void)&&L15;
+ (void)&&L16;
+ (void)&&L17;
+ (void)&&L18;
+ (void)&&L19;
+ (void)&&L20;
+ (void)&&L21;
+ (void)&&L22;
+ (void)&&L23;
+ (void)&&L24;
+ (void)&&L25;
+ (void)&&L26;
+ (void)&&L27;
+ (void)&&L28;
+ (void)&&L29;
+ (void)&&L30;
+ (void)&&L31;
+ (void)&&L32;
+ (void)&&L33;
+ (void)&&L34;
+ (void)&&L35;
+ (void)&&L36;
+ (void)&&L37;
+ (void)&&L38;
+ (void)&&L39;
+ (void)&&L40;
+
+ goto *target;
+ L1:
+ L2:
+ L3:
+ L4:
+ L5:
+ L6:
+ L7:
+ L8:
+ L9:
+ L10:
+ L11:
+ L12:
+ L13:
+ L14:
+ L15:
+ L16:
+ L17:
+ L18:
+ L19:
+ L20:
+ L21:
+ L22:
+ L23:
+ L24:
+ L25:
+ L26:
+ L27:
+ L28:
+ L29:
+ L30:
+ L31:
+ L32:
+ L33:
+ L34:
+ L35:
+ L36:
+ L37:
+ L38:
+ L39:
+ L40:
+ return 0;
+}
+
+// CHECK-LABEL: [B41 (INDIRECT GOTO DISPATCH)]
+// CHECK-NEXT: Preds (1): B42
+// CHECK-NEXT: Succs (40): B1 B2 B3 B4 B5 B6 B7 B8
+// CHECK-NEXT: B9 B10 B11 B12 B13 B14 B15 B16 B17 B18
+// CHECK-NEXT: B19 B20 B21 B22 B23 B24 B25 B26 B27 B28
+// CHECK-NEXT: B29 B30 B31 B32 B33 B34 B35 B36 B37 B38
+// CHECK-NEXT: B39 B40
diff --git a/test/Analysis/compound-literals.c b/test/Analysis/compound-literals.c
new file mode 100644
index 000000000000..a2556d2a7950
--- /dev/null
+++ b/test/Analysis/compound-literals.c
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -triple=i386-apple-darwin10 -analyze -analyzer-checker=debug.ExprInspection -verify %s
+void clang_analyzer_eval(int);
+
+// pr28449: Used to crash.
+void foo(void) {
+ static const unsigned short array[] = (const unsigned short[]){0x0F00};
+ // FIXME: Should be true.
+ clang_analyzer_eval(array[0] == 0x0F00); // expected-warning{{UNKNOWN}}
+}
diff --git a/test/Analysis/constant-folding.c b/test/Analysis/constant-folding.c
index a6d2b749427c..8189868be2ec 100644
--- a/test/Analysis/constant-folding.c
+++ b/test/Analysis/constant-folding.c
@@ -76,3 +76,42 @@ void testMixedTypeComparisons (char a, unsigned long b) {
clang_analyzer_eval(b >= a); // expected-warning{{TRUE}}
clang_analyzer_eval(a != b); // expected-warning{{TRUE}}
}
+
+void testBitwiseRules(unsigned int a, int b) {
+ clang_analyzer_eval((a | 1) >= 1); // expected-warning{{TRUE}}
+ clang_analyzer_eval((a | -1) >= -1); // expected-warning{{TRUE}}
+ clang_analyzer_eval((a | 2) >= 2); // expected-warning{{TRUE}}
+ clang_analyzer_eval((a | 5) >= 5); // expected-warning{{TRUE}}
+ clang_analyzer_eval((a | 10) >= 10); // expected-warning{{TRUE}}
+
+ // Argument order should not influence this
+ clang_analyzer_eval((1 | a) >= 1); // expected-warning{{TRUE}}
+
+ clang_analyzer_eval((a & 1) <= 1); // expected-warning{{TRUE}}
+ clang_analyzer_eval((a & 2) <= 2); // expected-warning{{TRUE}}
+ clang_analyzer_eval((a & 5) <= 5); // expected-warning{{TRUE}}
+ clang_analyzer_eval((a & 10) <= 10); // expected-warning{{TRUE}}
+ clang_analyzer_eval((a & -10) <= 10); // expected-warning{{UNKNOWN}}
+
+ // Again, check for different argument order.
+ clang_analyzer_eval((1 & a) <= 1); // expected-warning{{TRUE}}
+
+ unsigned int c = a;
+ c |= 1;
+ clang_analyzer_eval((c | 0) == 0); // expected-warning{{FALSE}}
+
+ // Rules don't apply to signed typed, as the values might be negative.
+ clang_analyzer_eval((b | 1) > 0); // expected-warning{{UNKNOWN}}
+
+ // Even for signed values, bitwise OR with a non-zero is always non-zero.
+ clang_analyzer_eval((b | 1) == 0); // expected-warning{{FALSE}}
+ clang_analyzer_eval((b | -2) == 0); // expected-warning{{FALSE}}
+ clang_analyzer_eval((b | 10) == 0); // expected-warning{{FALSE}}
+ clang_analyzer_eval((b | 0) == 0); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval((b | -2) >= 0); // expected-warning{{UNKNOWN}}
+
+ // Check that dynamically computed constants also work.
+ int constant = 1 << 3;
+ unsigned int d = a | constant;
+ clang_analyzer_eval(constant > 0); // expected-warning{{TRUE}}
+}
diff --git a/test/Analysis/conversion.c b/test/Analysis/conversion.c
index a22a56765407..7adb336eb249 100644
--- a/test/Analysis/conversion.c
+++ b/test/Analysis/conversion.c
@@ -1,4 +1,4 @@
-// RUN: %clang_analyze_cc1 -Wno-conversion -analyzer-checker=core,alpha.core.Conversion -verify %s
+// RUN: %clang_analyze_cc1 -Wno-conversion -Wno-tautological-constant-compare -analyzer-checker=core,alpha.core.Conversion -verify %s
unsigned char U8;
signed char S8;
diff --git a/test/Analysis/copypaste/asm.cpp b/test/Analysis/copypaste/asm.cpp
index 2e3613dfca4b..1d93469aa3c2 100644
--- a/test/Analysis/copypaste/asm.cpp
+++ b/test/Analysis/copypaste/asm.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_analyze_cc1 -triple x86_64-unknown-linux -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -triple x86_64-unknown-linux -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:MinimumCloneComplexity=10 -verify %s
// expected-no-diagnostics
diff --git a/test/Analysis/copypaste/attributes.cpp b/test/Analysis/copypaste/attributes.cpp
index 083be74436df..f71545130cbb 100644
--- a/test/Analysis/copypaste/attributes.cpp
+++ b/test/Analysis/copypaste/attributes.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_analyze_cc1 -std=c++1z -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -std=c++1z -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:MinimumCloneComplexity=10 -verify %s
// expected-no-diagnostics
diff --git a/test/Analysis/copypaste/autogenerated_automoc.cpp b/test/Analysis/copypaste/autogenerated_automoc.cpp
index 55963c4545c9..0f7f9c9e4565 100644
--- a/test/Analysis/copypaste/autogenerated_automoc.cpp
+++ b/test/Analysis/copypaste/autogenerated_automoc.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:IgnoredFilesPattern="moc_|.*_automoc.cpp" -verify %s
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:MinimumCloneComplexity=10 -analyzer-config alpha.clone.CloneChecker:IgnoredFilesPattern="moc_|.*_automoc.cpp" -verify %s
// Because files that have `_automoc.' in their names are most likely autogenerated,
// we suppress copy-paste warnings here.
diff --git a/test/Analysis/copypaste/blocks.cpp b/test/Analysis/copypaste/blocks.cpp
index 10467b7248c1..23821560ea37 100644
--- a/test/Analysis/copypaste/blocks.cpp
+++ b/test/Analysis/copypaste/blocks.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_analyze_cc1 -fblocks -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -fblocks -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:MinimumCloneComplexity=10 -verify %s
// This tests if we search for clones in blocks.
diff --git a/test/Analysis/copypaste/call.cpp b/test/Analysis/copypaste/call.cpp
index 046229a30a4a..c5ddae5a65f3 100644
--- a/test/Analysis/copypaste/call.cpp
+++ b/test/Analysis/copypaste/call.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_analyze_cc1 -std=c++1z -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -std=c++1z -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:MinimumCloneComplexity=10 -verify %s
// expected-no-diagnostics
diff --git a/test/Analysis/copypaste/catch.cpp b/test/Analysis/copypaste/catch.cpp
index cf3e8076bd54..edcf44ae6fc0 100644
--- a/test/Analysis/copypaste/catch.cpp
+++ b/test/Analysis/copypaste/catch.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_analyze_cc1 -fcxx-exceptions -std=c++1z -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -fcxx-exceptions -std=c++1z -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:MinimumCloneComplexity=10 -verify %s
// expected-no-diagnostics
diff --git a/test/Analysis/copypaste/delete.cpp b/test/Analysis/copypaste/delete.cpp
index 394226bedf1b..4edb46035a39 100644
--- a/test/Analysis/copypaste/delete.cpp
+++ b/test/Analysis/copypaste/delete.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_analyze_cc1 -std=c++1z -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -std=c++1z -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:MinimumCloneComplexity=10 -verify %s
// expected-no-diagnostics
diff --git a/test/Analysis/copypaste/dependent-exist.cpp b/test/Analysis/copypaste/dependent-exist.cpp
index 9046353d0f07..28f2ceb21ada 100644
--- a/test/Analysis/copypaste/dependent-exist.cpp
+++ b/test/Analysis/copypaste/dependent-exist.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_analyze_cc1 -fms-extensions -std=c++1z -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -fms-extensions -std=c++1z -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:MinimumCloneComplexity=10 -verify %s
// expected-no-diagnostics
diff --git a/test/Analysis/copypaste/expr-types.cpp b/test/Analysis/copypaste/expr-types.cpp
index 601f0b192ac5..6062be306e2d 100644
--- a/test/Analysis/copypaste/expr-types.cpp
+++ b/test/Analysis/copypaste/expr-types.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:MinimumCloneComplexity=10 -verify %s
// expected-no-diagnostics
diff --git a/test/Analysis/copypaste/fold.cpp b/test/Analysis/copypaste/fold.cpp
index 0aed11bcf070..fadcb49fa0b3 100644
--- a/test/Analysis/copypaste/fold.cpp
+++ b/test/Analysis/copypaste/fold.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_analyze_cc1 -std=c++1z -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -std=c++1z -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:MinimumCloneComplexity=10 -verify %s
// expected-no-diagnostics
diff --git a/test/Analysis/copypaste/function-try-block.cpp b/test/Analysis/copypaste/function-try-block.cpp
index d77714591b91..d0fbc50f67ef 100644
--- a/test/Analysis/copypaste/function-try-block.cpp
+++ b/test/Analysis/copypaste/function-try-block.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_analyze_cc1 -fcxx-exceptions -std=c++1z -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -fcxx-exceptions -std=c++1z -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:MinimumCloneComplexity=10 -verify %s
// Tests if function try blocks are correctly handled.
diff --git a/test/Analysis/copypaste/functions.cpp b/test/Analysis/copypaste/functions.cpp
index d2c607b2171e..2bfe591a50bc 100644
--- a/test/Analysis/copypaste/functions.cpp
+++ b/test/Analysis/copypaste/functions.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:MinimumCloneComplexity=10 -verify %s
// This tests if we search for clones in functions.
diff --git a/test/Analysis/copypaste/generic.c b/test/Analysis/copypaste/generic.c
index d4d456473621..2fa6c302da17 100644
--- a/test/Analysis/copypaste/generic.c
+++ b/test/Analysis/copypaste/generic.c
@@ -1,4 +1,4 @@
-// RUN: %clang_analyze_cc1 -std=c11 -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -std=c11 -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:MinimumCloneComplexity=10 -verify %s
// expected-no-diagnostics
diff --git a/test/Analysis/copypaste/labels.cpp b/test/Analysis/copypaste/labels.cpp
index eff3330a0f39..18c5b22d3b1c 100644
--- a/test/Analysis/copypaste/labels.cpp
+++ b/test/Analysis/copypaste/labels.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_analyze_cc1 -std=gnu++11 -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -std=gnu++11 -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:MinimumCloneComplexity=10 -verify %s
// expected-no-diagnostics
diff --git a/test/Analysis/copypaste/lambda.cpp b/test/Analysis/copypaste/lambda.cpp
index 17c874894319..456d83a995b1 100644
--- a/test/Analysis/copypaste/lambda.cpp
+++ b/test/Analysis/copypaste/lambda.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:MinimumCloneComplexity=10 -verify %s
// expected-no-diagnostics
diff --git a/test/Analysis/copypaste/macros.cpp b/test/Analysis/copypaste/macros.cpp
index bdacd4839a67..ea05bbd4281b 100644
--- a/test/Analysis/copypaste/macros.cpp
+++ b/test/Analysis/copypaste/macros.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:MinimumCloneComplexity=10 -verify %s
// Tests that macros and non-macro clones aren't mixed into the same hash
// group. This is currently necessary as all clones in a hash group need
diff --git a/test/Analysis/copypaste/not-autogenerated.cpp b/test/Analysis/copypaste/not-autogenerated.cpp
index 765e7aaf2aab..d54ee176fa88 100644
--- a/test/Analysis/copypaste/not-autogenerated.cpp
+++ b/test/Analysis/copypaste/not-autogenerated.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:IgnoredFilesPattern="moc_|ui_|dbus_|.*_automoc" -verify %s
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:MinimumCloneComplexity=10 -analyzer-config alpha.clone.CloneChecker:IgnoredFilesPattern="moc_|ui_|dbus_|.*_automoc" -verify %s
void f1() {
int *p1 = new int[1];
diff --git a/test/Analysis/copypaste/objc-methods.m b/test/Analysis/copypaste/objc-methods.m
index e63c7f6288bc..0a843707937a 100644
--- a/test/Analysis/copypaste/objc-methods.m
+++ b/test/Analysis/copypaste/objc-methods.m
@@ -1,4 +1,4 @@
-// RUN: %clang_analyze_cc1 -Wno-objc-root-class -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -Wno-objc-root-class -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:MinimumCloneComplexity=10 -verify %s
// This tests if we search for clones in Objective-C methods.
diff --git a/test/Analysis/copypaste/plist-diagnostics-notes-as-events.cpp b/test/Analysis/copypaste/plist-diagnostics-notes-as-events.cpp
index 7c4f35525fea..d4402a9dd58c 100644
--- a/test/Analysis/copypaste/plist-diagnostics-notes-as-events.cpp
+++ b/test/Analysis/copypaste/plist-diagnostics-notes-as-events.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_analyze_cc1 -analyzer-output=plist -analyzer-config notes-as-events=true -o %t.plist -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-output=plist -analyzer-config notes-as-events=true -o %t.plist -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:MinimumCloneComplexity=10 -verify %s
// RUN: FileCheck --input-file=%t.plist %s
void log();
diff --git a/test/Analysis/copypaste/plist-diagnostics.cpp b/test/Analysis/copypaste/plist-diagnostics.cpp
index e2fa7597caf6..c138c6f1f92a 100644
--- a/test/Analysis/copypaste/plist-diagnostics.cpp
+++ b/test/Analysis/copypaste/plist-diagnostics.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_analyze_cc1 -analyzer-output=plist -o %t.plist -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-output=plist -o %t.plist -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:MinimumCloneComplexity=10 -verify %s
// RUN: FileCheck --input-file=%t.plist %s
void log();
diff --git a/test/Analysis/copypaste/sub-sequences.cpp b/test/Analysis/copypaste/sub-sequences.cpp
index 798662d25663..d2c08350ab4c 100644
--- a/test/Analysis/copypaste/sub-sequences.cpp
+++ b/test/Analysis/copypaste/sub-sequences.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:MinimumCloneComplexity=10 -verify %s
// This tests if sub-sequences can match with normal sequences.
diff --git a/test/Analysis/copypaste/suspicious-clones.cpp b/test/Analysis/copypaste/suspicious-clones.cpp
index 3a760e256279..ae29b0e16d19 100644
--- a/test/Analysis/copypaste/suspicious-clones.cpp
+++ b/test/Analysis/copypaste/suspicious-clones.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:ReportSuspiciousClones=true -analyzer-config alpha.clone.CloneChecker:ReportNormalClones=false -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:ReportSuspiciousClones=true -analyzer-config alpha.clone.CloneChecker:ReportNormalClones=false -analyzer-config alpha.clone.CloneChecker:MinimumCloneComplexity=10 -verify %s
// Tests finding a suspicious clone that references local variables.
diff --git a/test/Analysis/copypaste/text-diagnostics.cpp b/test/Analysis/copypaste/text-diagnostics.cpp
index a6e358cc8535..a3132e9534c5 100644
--- a/test/Analysis/copypaste/text-diagnostics.cpp
+++ b/test/Analysis/copypaste/text-diagnostics.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_analyze_cc1 -analyzer-output=text -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-output=text -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:MinimumCloneComplexity=10 -verify %s
void log();
diff --git a/test/Analysis/ctor.mm b/test/Analysis/ctor.mm
index 619e2cb0f044..e903263431fc 100644
--- a/test/Analysis/ctor.mm
+++ b/test/Analysis/ctor.mm
@@ -199,7 +199,7 @@ namespace PODUninitialized {
Inner p;
};
- void testPOD() {
+ void testPOD(const POD &pp) {
POD p;
p.x = 1;
POD p2 = p; // no-warning
@@ -210,6 +210,15 @@ namespace PODUninitialized {
// Use rvalues as well.
clang_analyzer_eval(POD(p3).x == 1); // expected-warning{{TRUE}}
+ // Copy from symbolic references correctly.
+ POD p4 = pp;
+ // Make sure that p4.x contains a symbol after copy.
+ if (p4.x > 0)
+ clang_analyzer_eval(p4.x > 0); // expected-warning{{TRUE}}
+ // FIXME: Element region gets in the way, so these aren't the same symbols
+ // as they should be.
+ clang_analyzer_eval(pp.x == p4.x); // expected-warning{{UNKNOWN}}
+
PODWrapper w;
w.p.y = 1;
PODWrapper w2 = w; // no-warning
diff --git a/test/Analysis/diagnostics/diag-cross-file-boundaries.c b/test/Analysis/diagnostics/diag-cross-file-boundaries.c
deleted file mode 100644
index b975af3fb29f..000000000000
--- a/test/Analysis/diagnostics/diag-cross-file-boundaries.c
+++ /dev/null
@@ -1,12 +0,0 @@
-// RUN: %clang_analyze_cc1 -analyzer-checker=core -verify %s
-// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=html -o PR12421.html %s 2>&1 | FileCheck %s
-
-// Test for PR12421
-#include "diag-cross-file-boundaries.h"
-
-int main(){
- f();
- return 0;
-}
-
-// CHECK: warning: Path diagnostic report is not generated.
diff --git a/test/Analysis/edges-new.mm b/test/Analysis/edges-new.mm
index 47a125ab0901..f310f1bfa12e 100644
--- a/test/Analysis/edges-new.mm
+++ b/test/Analysis/edges-new.mm
@@ -20288,7 +20288,7 @@ namespace rdar14960554 {
// CHECK-NEXT: <key>type</key><string>Bad deallocator</string>
// CHECK-NEXT: <key>check_name</key><string>unix.MismatchedDeallocator</string>
// CHECK-NEXT: <!-- This hash is experimental and going to change! -->
-// CHECK-NEXT: <key>issue_hash_content_of_line_in_context</key><string>d9dbbf68db41ab74e2158f4b131abe34</string>
+// CHECK-NEXT: <key>issue_hash_content_of_line_in_context</key><string>046c88d1c91ff46d6506dff5ff880756</string>
// CHECK-NEXT: <key>issue_hash_function_offset</key><string>0</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
diff --git a/test/Analysis/exercise-ps.c b/test/Analysis/exercise-ps.c
index 577b88bf837f..c459260c2a1d 100644
--- a/test/Analysis/exercise-ps.c
+++ b/test/Analysis/exercise-ps.c
@@ -21,3 +21,11 @@ static void f2(void *buf) {
memcpy((&x[1]), (buf), 1); // expected-warning{{implicitly declaring library function 'memcpy' with type 'void *(void *, const void *}} \
// expected-note{{include the header <string.h> or explicitly provide a declaration for 'memcpy'}}
}
+
+// AllocaRegion is untyped. Void pointer isn't of much help either. Before
+// realizing that the value is undefined, we need to somehow figure out
+// what type of value do we expect.
+void f3(void *dest) {
+ void *src = __builtin_alloca(5);
+ memcpy(dest, src, 1); // expected-warning{{2nd function call argument is a pointer to uninitialized value}}
+}
diff --git a/test/Analysis/expr-inspection.c b/test/Analysis/expr-inspection.c
index 59406cd420ad..ec0e682b6536 100644
--- a/test/Analysis/expr-inspection.c
+++ b/test/Analysis/expr-inspection.c
@@ -8,6 +8,7 @@ void clang_analyzer_numTimesReached();
void foo(int x) {
clang_analyzer_dump(x); // expected-warning{{reg_$0<int x>}}
+ clang_analyzer_dump(x + (-1)); // expected-warning{{(reg_$0<int x>) + -1}}
int y = 1;
clang_analyzer_printState();
for (; y < 3; ++y)
diff --git a/test/Analysis/func-mapping-test.cpp b/test/Analysis/func-mapping-test.cpp
new file mode 100644
index 000000000000..37e653882b7b
--- /dev/null
+++ b/test/Analysis/func-mapping-test.cpp
@@ -0,0 +1,7 @@
+// RUN: %clang_func_map %s -- | FileCheck %s
+
+int f(int) {
+ return 0;
+}
+
+// CHECK: c:@F@f#I#
diff --git a/test/Analysis/generics.m b/test/Analysis/generics.m
index dac148d42e8e..e506e89bdf51 100644
--- a/test/Analysis/generics.m
+++ b/test/Analysis/generics.m
@@ -159,10 +159,26 @@ void verifyAPIusage(id a, MutableArray<NSString *> *b) {
doStuff(a); // expected-warning {{Conversion}}
}
-void trustExplicitCasts(MutableArray *a,
+void dontInferFromExplicitCastsOnUnspecialized(MutableArray *a,
MutableArray<NSMutableString *> *b) {
b = (MutableArray<NSMutableString *> *)a;
- [a addObject: [[NSString alloc] init]]; // expected-warning {{Conversion}}
+ [a addObject: [[NSString alloc] init]]; // no-warning
+}
+
+void dontWarnOnExplicitCastsAfterInference(MutableArray *a) {
+ withMutArrString(a);
+ withMutArrMutableString((MutableArray<NSMutableString *> *)a); // no-warning
+}
+
+void dontDiagnoseOnExplicitCrossCasts(MutableArray<NSSet *> *a,
+ MutableArray<NSMutableString *> *b) {
+ // Treat an explicit cast to a specialized type as an indication that
+ // Objective-C's type system is not expressive enough to represent a
+ // the invariant the programmer wanted. After an explicit cast, do not
+ // warn about potential generics shenanigans.
+ b = (MutableArray<NSMutableString *> *)a; // no-warning
+ [a addObject: [[NSSet alloc] init]]; // no-warning
+ [b addObject: [[NSMutableString alloc] init]]; //no-warning
}
void subtypeOfGeneric(id d, MyMutableStringArray *a,
@@ -2361,118 +2377,6 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>path</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>event</string>
-// CHECK-NEXT: <key>location</key>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>164</integer>
-// CHECK-NEXT: <key>col</key><integer>7</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <key>ranges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>164</integer>
-// CHECK-NEXT: <key>col</key><integer>7</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>164</integer>
-// CHECK-NEXT: <key>col</key><integer>42</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>depth</key><integer>0</integer>
-// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>Type &apos;MutableArray&lt;NSMutableString *&gt; *&apos; is inferred from explicit cast (from &apos;MutableArray *&apos; to &apos;MutableArray&lt;NSMutableString *&gt; *&apos;)</string>
-// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>Type &apos;MutableArray&lt;NSMutableString *&gt; *&apos; is inferred from explicit cast (from &apos;MutableArray *&apos; to &apos;MutableArray&lt;NSMutableString *&gt; *&apos;)</string>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>control</string>
-// CHECK-NEXT: <key>edges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>start</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>164</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>164</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>end</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>165</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>165</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>kind</key><string>event</string>
-// CHECK-NEXT: <key>location</key>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>165</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <key>ranges</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>165</integer>
-// CHECK-NEXT: <key>col</key><integer>17</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>165</integer>
-// CHECK-NEXT: <key>col</key><integer>39</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>depth</key><integer>0</integer>
-// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>Conversion from value of type &apos;NSString *&apos; to incompatible type &apos;NSMutableString *&apos;</string>
-// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>Conversion from value of type &apos;NSString *&apos; to incompatible type &apos;NSMutableString *&apos;</string>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>description</key><string>Conversion from value of type &apos;NSString *&apos; to incompatible type &apos;NSMutableString *&apos;</string>
-// CHECK-NEXT: <key>category</key><string>Core Foundation/Objective-C</string>
-// CHECK-NEXT: <key>type</key><string>Generics</string>
-// CHECK-NEXT: <key>check_name</key><string>core.DynamicTypePropagation</string>
-// CHECK-NEXT: <!-- This hash is experimental and going to change! -->
-// CHECK-NEXT: <key>issue_hash_content_of_line_in_context</key><string>0549631e5a7fa668375061b6c898e438</string>
-// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
-// CHECK-NEXT: <key>issue_context</key><string>trustExplicitCasts</string>
-// CHECK-NEXT: <key>issue_hash_function_offset</key><string>2</string>
-// CHECK-NEXT: <key>location</key>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>165</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
-// CHECK-NEXT: <key>file</key><integer>0</integer>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: </dict>
-// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>path</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>kind</key><string>control</string>
// CHECK-NEXT: <key>edges</key>
// CHECK-NEXT: <array>
@@ -2480,12 +2384,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>171</integer>
+// CHECK-NEXT: <key>line</key><integer>187</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>171</integer>
+// CHECK-NEXT: <key>line</key><integer>187</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2493,12 +2397,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>172</integer>
+// CHECK-NEXT: <key>line</key><integer>188</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>172</integer>
+// CHECK-NEXT: <key>line</key><integer>188</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2510,7 +2414,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>172</integer>
+// CHECK-NEXT: <key>line</key><integer>188</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2518,12 +2422,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>172</integer>
+// CHECK-NEXT: <key>line</key><integer>188</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>172</integer>
+// CHECK-NEXT: <key>line</key><integer>188</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2543,12 +2447,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>172</integer>
+// CHECK-NEXT: <key>line</key><integer>188</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>172</integer>
+// CHECK-NEXT: <key>line</key><integer>188</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2556,12 +2460,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>173</integer>
+// CHECK-NEXT: <key>line</key><integer>189</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>173</integer>
+// CHECK-NEXT: <key>line</key><integer>189</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2577,12 +2481,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>173</integer>
+// CHECK-NEXT: <key>line</key><integer>189</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>173</integer>
+// CHECK-NEXT: <key>line</key><integer>189</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2590,12 +2494,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>173</integer>
+// CHECK-NEXT: <key>line</key><integer>189</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>173</integer>
+// CHECK-NEXT: <key>line</key><integer>189</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2607,7 +2511,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>173</integer>
+// CHECK-NEXT: <key>line</key><integer>189</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2615,12 +2519,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>173</integer>
+// CHECK-NEXT: <key>line</key><integer>189</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>173</integer>
+// CHECK-NEXT: <key>line</key><integer>189</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2644,7 +2548,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>issue_hash_function_offset</key><string>3</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>173</integer>
+// CHECK-NEXT: <key>line</key><integer>189</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2656,7 +2560,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>179</integer>
+// CHECK-NEXT: <key>line</key><integer>195</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2664,12 +2568,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>179</integer>
+// CHECK-NEXT: <key>line</key><integer>195</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>179</integer>
+// CHECK-NEXT: <key>line</key><integer>195</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2689,12 +2593,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>179</integer>
+// CHECK-NEXT: <key>line</key><integer>195</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>179</integer>
+// CHECK-NEXT: <key>line</key><integer>195</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2702,12 +2606,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>183</integer>
+// CHECK-NEXT: <key>line</key><integer>199</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>183</integer>
+// CHECK-NEXT: <key>line</key><integer>199</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2723,12 +2627,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>183</integer>
+// CHECK-NEXT: <key>line</key><integer>199</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>183</integer>
+// CHECK-NEXT: <key>line</key><integer>199</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2736,12 +2640,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>183</integer>
+// CHECK-NEXT: <key>line</key><integer>199</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>183</integer>
+// CHECK-NEXT: <key>line</key><integer>199</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2753,7 +2657,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>183</integer>
+// CHECK-NEXT: <key>line</key><integer>199</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2761,12 +2665,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>183</integer>
+// CHECK-NEXT: <key>line</key><integer>199</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>183</integer>
+// CHECK-NEXT: <key>line</key><integer>199</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2790,7 +2694,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>issue_hash_function_offset</key><string>5</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>183</integer>
+// CHECK-NEXT: <key>line</key><integer>199</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2802,7 +2706,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>179</integer>
+// CHECK-NEXT: <key>line</key><integer>195</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2810,12 +2714,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>179</integer>
+// CHECK-NEXT: <key>line</key><integer>195</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>179</integer>
+// CHECK-NEXT: <key>line</key><integer>195</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2835,12 +2739,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>179</integer>
+// CHECK-NEXT: <key>line</key><integer>195</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>179</integer>
+// CHECK-NEXT: <key>line</key><integer>195</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2848,12 +2752,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>185</integer>
+// CHECK-NEXT: <key>line</key><integer>201</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>185</integer>
+// CHECK-NEXT: <key>line</key><integer>201</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2865,7 +2769,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>185</integer>
+// CHECK-NEXT: <key>line</key><integer>201</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2873,12 +2777,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>185</integer>
+// CHECK-NEXT: <key>line</key><integer>201</integer>
// CHECK-NEXT: <key>col</key><integer>17</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>185</integer>
+// CHECK-NEXT: <key>line</key><integer>201</integer>
// CHECK-NEXT: <key>col</key><integer>39</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2902,7 +2806,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>issue_hash_function_offset</key><string>7</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>185</integer>
+// CHECK-NEXT: <key>line</key><integer>201</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2914,7 +2818,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>191</integer>
+// CHECK-NEXT: <key>line</key><integer>207</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2922,12 +2826,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>191</integer>
+// CHECK-NEXT: <key>line</key><integer>207</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>191</integer>
+// CHECK-NEXT: <key>line</key><integer>207</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2947,12 +2851,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>191</integer>
+// CHECK-NEXT: <key>line</key><integer>207</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>191</integer>
+// CHECK-NEXT: <key>line</key><integer>207</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2960,12 +2864,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>195</integer>
+// CHECK-NEXT: <key>line</key><integer>211</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>195</integer>
+// CHECK-NEXT: <key>line</key><integer>211</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2981,12 +2885,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>195</integer>
+// CHECK-NEXT: <key>line</key><integer>211</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>195</integer>
+// CHECK-NEXT: <key>line</key><integer>211</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2994,12 +2898,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>195</integer>
+// CHECK-NEXT: <key>line</key><integer>211</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>195</integer>
+// CHECK-NEXT: <key>line</key><integer>211</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3011,7 +2915,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>195</integer>
+// CHECK-NEXT: <key>line</key><integer>211</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3019,12 +2923,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>195</integer>
+// CHECK-NEXT: <key>line</key><integer>211</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>195</integer>
+// CHECK-NEXT: <key>line</key><integer>211</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3048,7 +2952,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>issue_hash_function_offset</key><string>5</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>195</integer>
+// CHECK-NEXT: <key>line</key><integer>211</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3060,7 +2964,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>191</integer>
+// CHECK-NEXT: <key>line</key><integer>207</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3068,12 +2972,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>191</integer>
+// CHECK-NEXT: <key>line</key><integer>207</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>191</integer>
+// CHECK-NEXT: <key>line</key><integer>207</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3093,12 +2997,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>191</integer>
+// CHECK-NEXT: <key>line</key><integer>207</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>191</integer>
+// CHECK-NEXT: <key>line</key><integer>207</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3106,12 +3010,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>197</integer>
+// CHECK-NEXT: <key>line</key><integer>213</integer>
// CHECK-NEXT: <key>col</key><integer>2</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>197</integer>
+// CHECK-NEXT: <key>line</key><integer>213</integer>
// CHECK-NEXT: <key>col</key><integer>2</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3123,7 +3027,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>197</integer>
+// CHECK-NEXT: <key>line</key><integer>213</integer>
// CHECK-NEXT: <key>col</key><integer>2</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3131,12 +3035,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>197</integer>
+// CHECK-NEXT: <key>line</key><integer>213</integer>
// CHECK-NEXT: <key>col</key><integer>16</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>197</integer>
+// CHECK-NEXT: <key>line</key><integer>213</integer>
// CHECK-NEXT: <key>col</key><integer>38</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3160,7 +3064,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>issue_hash_function_offset</key><string>7</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>197</integer>
+// CHECK-NEXT: <key>line</key><integer>213</integer>
// CHECK-NEXT: <key>col</key><integer>2</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3172,7 +3076,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>203</integer>
+// CHECK-NEXT: <key>line</key><integer>219</integer>
// CHECK-NEXT: <key>col</key><integer>20</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3180,12 +3084,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>203</integer>
+// CHECK-NEXT: <key>line</key><integer>219</integer>
// CHECK-NEXT: <key>col</key><integer>20</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>203</integer>
+// CHECK-NEXT: <key>line</key><integer>219</integer>
// CHECK-NEXT: <key>col</key><integer>20</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3205,12 +3109,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>203</integer>
+// CHECK-NEXT: <key>line</key><integer>219</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>203</integer>
+// CHECK-NEXT: <key>line</key><integer>219</integer>
// CHECK-NEXT: <key>col</key><integer>18</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3218,12 +3122,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>204</integer>
+// CHECK-NEXT: <key>line</key><integer>220</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>204</integer>
+// CHECK-NEXT: <key>line</key><integer>220</integer>
// CHECK-NEXT: <key>col</key><integer>25</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3239,12 +3143,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>204</integer>
+// CHECK-NEXT: <key>line</key><integer>220</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>204</integer>
+// CHECK-NEXT: <key>line</key><integer>220</integer>
// CHECK-NEXT: <key>col</key><integer>25</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3252,12 +3156,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>204</integer>
+// CHECK-NEXT: <key>line</key><integer>220</integer>
// CHECK-NEXT: <key>col</key><integer>27</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>204</integer>
+// CHECK-NEXT: <key>line</key><integer>220</integer>
// CHECK-NEXT: <key>col</key><integer>27</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3269,7 +3173,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>204</integer>
+// CHECK-NEXT: <key>line</key><integer>220</integer>
// CHECK-NEXT: <key>col</key><integer>27</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3277,12 +3181,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>204</integer>
+// CHECK-NEXT: <key>line</key><integer>220</integer>
// CHECK-NEXT: <key>col</key><integer>27</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>204</integer>
+// CHECK-NEXT: <key>line</key><integer>220</integer>
// CHECK-NEXT: <key>col</key><integer>27</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3306,7 +3210,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>issue_hash_function_offset</key><string>4</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>204</integer>
+// CHECK-NEXT: <key>line</key><integer>220</integer>
// CHECK-NEXT: <key>col</key><integer>27</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3318,7 +3222,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>208</integer>
+// CHECK-NEXT: <key>line</key><integer>224</integer>
// CHECK-NEXT: <key>col</key><integer>27</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3326,12 +3230,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>208</integer>
+// CHECK-NEXT: <key>line</key><integer>224</integer>
// CHECK-NEXT: <key>col</key><integer>27</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>208</integer>
+// CHECK-NEXT: <key>line</key><integer>224</integer>
// CHECK-NEXT: <key>col</key><integer>27</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3351,12 +3255,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>208</integer>
+// CHECK-NEXT: <key>line</key><integer>224</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>208</integer>
+// CHECK-NEXT: <key>line</key><integer>224</integer>
// CHECK-NEXT: <key>col</key><integer>25</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3364,12 +3268,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>209</integer>
+// CHECK-NEXT: <key>line</key><integer>225</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>209</integer>
+// CHECK-NEXT: <key>line</key><integer>225</integer>
// CHECK-NEXT: <key>col</key><integer>18</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3385,12 +3289,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>209</integer>
+// CHECK-NEXT: <key>line</key><integer>225</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>209</integer>
+// CHECK-NEXT: <key>line</key><integer>225</integer>
// CHECK-NEXT: <key>col</key><integer>18</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3398,12 +3302,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>209</integer>
+// CHECK-NEXT: <key>line</key><integer>225</integer>
// CHECK-NEXT: <key>col</key><integer>20</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>209</integer>
+// CHECK-NEXT: <key>line</key><integer>225</integer>
// CHECK-NEXT: <key>col</key><integer>20</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3415,7 +3319,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>209</integer>
+// CHECK-NEXT: <key>line</key><integer>225</integer>
// CHECK-NEXT: <key>col</key><integer>20</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3423,12 +3327,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>209</integer>
+// CHECK-NEXT: <key>line</key><integer>225</integer>
// CHECK-NEXT: <key>col</key><integer>20</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>209</integer>
+// CHECK-NEXT: <key>line</key><integer>225</integer>
// CHECK-NEXT: <key>col</key><integer>20</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3452,7 +3356,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>issue_hash_function_offset</key><string>2</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>209</integer>
+// CHECK-NEXT: <key>line</key><integer>225</integer>
// CHECK-NEXT: <key>col</key><integer>20</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3464,7 +3368,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>213</integer>
+// CHECK-NEXT: <key>line</key><integer>229</integer>
// CHECK-NEXT: <key>col</key><integer>27</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3472,12 +3376,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>213</integer>
+// CHECK-NEXT: <key>line</key><integer>229</integer>
// CHECK-NEXT: <key>col</key><integer>27</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>213</integer>
+// CHECK-NEXT: <key>line</key><integer>229</integer>
// CHECK-NEXT: <key>col</key><integer>27</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3497,12 +3401,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>213</integer>
+// CHECK-NEXT: <key>line</key><integer>229</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>213</integer>
+// CHECK-NEXT: <key>line</key><integer>229</integer>
// CHECK-NEXT: <key>col</key><integer>25</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3510,12 +3414,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>214</integer>
+// CHECK-NEXT: <key>line</key><integer>230</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>214</integer>
+// CHECK-NEXT: <key>line</key><integer>230</integer>
// CHECK-NEXT: <key>col</key><integer>18</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3531,12 +3435,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>214</integer>
+// CHECK-NEXT: <key>line</key><integer>230</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>214</integer>
+// CHECK-NEXT: <key>line</key><integer>230</integer>
// CHECK-NEXT: <key>col</key><integer>18</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3544,12 +3448,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>214</integer>
+// CHECK-NEXT: <key>line</key><integer>230</integer>
// CHECK-NEXT: <key>col</key><integer>20</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>214</integer>
+// CHECK-NEXT: <key>line</key><integer>230</integer>
// CHECK-NEXT: <key>col</key><integer>20</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3561,7 +3465,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>214</integer>
+// CHECK-NEXT: <key>line</key><integer>230</integer>
// CHECK-NEXT: <key>col</key><integer>20</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3569,12 +3473,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>214</integer>
+// CHECK-NEXT: <key>line</key><integer>230</integer>
// CHECK-NEXT: <key>col</key><integer>20</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>214</integer>
+// CHECK-NEXT: <key>line</key><integer>230</integer>
// CHECK-NEXT: <key>col</key><integer>20</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3598,7 +3502,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>issue_hash_function_offset</key><string>2</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>214</integer>
+// CHECK-NEXT: <key>line</key><integer>230</integer>
// CHECK-NEXT: <key>col</key><integer>20</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3610,7 +3514,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>218</integer>
+// CHECK-NEXT: <key>line</key><integer>234</integer>
// CHECK-NEXT: <key>col</key><integer>20</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3618,12 +3522,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>218</integer>
+// CHECK-NEXT: <key>line</key><integer>234</integer>
// CHECK-NEXT: <key>col</key><integer>20</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>218</integer>
+// CHECK-NEXT: <key>line</key><integer>234</integer>
// CHECK-NEXT: <key>col</key><integer>20</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3643,12 +3547,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>218</integer>
+// CHECK-NEXT: <key>line</key><integer>234</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>218</integer>
+// CHECK-NEXT: <key>line</key><integer>234</integer>
// CHECK-NEXT: <key>col</key><integer>18</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3656,12 +3560,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>219</integer>
+// CHECK-NEXT: <key>line</key><integer>235</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>219</integer>
+// CHECK-NEXT: <key>line</key><integer>235</integer>
// CHECK-NEXT: <key>col</key><integer>25</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3677,12 +3581,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>219</integer>
+// CHECK-NEXT: <key>line</key><integer>235</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>219</integer>
+// CHECK-NEXT: <key>line</key><integer>235</integer>
// CHECK-NEXT: <key>col</key><integer>25</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3690,12 +3594,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>219</integer>
+// CHECK-NEXT: <key>line</key><integer>235</integer>
// CHECK-NEXT: <key>col</key><integer>27</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>219</integer>
+// CHECK-NEXT: <key>line</key><integer>235</integer>
// CHECK-NEXT: <key>col</key><integer>27</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3707,7 +3611,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>219</integer>
+// CHECK-NEXT: <key>line</key><integer>235</integer>
// CHECK-NEXT: <key>col</key><integer>27</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3715,12 +3619,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>219</integer>
+// CHECK-NEXT: <key>line</key><integer>235</integer>
// CHECK-NEXT: <key>col</key><integer>27</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>219</integer>
+// CHECK-NEXT: <key>line</key><integer>235</integer>
// CHECK-NEXT: <key>col</key><integer>27</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3744,7 +3648,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>issue_hash_function_offset</key><string>2</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>219</integer>
+// CHECK-NEXT: <key>line</key><integer>235</integer>
// CHECK-NEXT: <key>col</key><integer>27</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3756,7 +3660,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>223</integer>
+// CHECK-NEXT: <key>line</key><integer>239</integer>
// CHECK-NEXT: <key>col</key><integer>27</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3764,12 +3668,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>223</integer>
+// CHECK-NEXT: <key>line</key><integer>239</integer>
// CHECK-NEXT: <key>col</key><integer>27</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>223</integer>
+// CHECK-NEXT: <key>line</key><integer>239</integer>
// CHECK-NEXT: <key>col</key><integer>27</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3789,12 +3693,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>223</integer>
+// CHECK-NEXT: <key>line</key><integer>239</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>223</integer>
+// CHECK-NEXT: <key>line</key><integer>239</integer>
// CHECK-NEXT: <key>col</key><integer>20</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3802,12 +3706,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>224</integer>
+// CHECK-NEXT: <key>line</key><integer>240</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>224</integer>
+// CHECK-NEXT: <key>line</key><integer>240</integer>
// CHECK-NEXT: <key>col</key><integer>18</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3819,7 +3723,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>224</integer>
+// CHECK-NEXT: <key>line</key><integer>240</integer>
// CHECK-NEXT: <key>col</key><integer>20</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3827,12 +3731,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>224</integer>
+// CHECK-NEXT: <key>line</key><integer>240</integer>
// CHECK-NEXT: <key>col</key><integer>20</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>224</integer>
+// CHECK-NEXT: <key>line</key><integer>240</integer>
// CHECK-NEXT: <key>col</key><integer>20</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3852,12 +3756,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>224</integer>
+// CHECK-NEXT: <key>line</key><integer>240</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>224</integer>
+// CHECK-NEXT: <key>line</key><integer>240</integer>
// CHECK-NEXT: <key>col</key><integer>18</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3865,12 +3769,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>225</integer>
+// CHECK-NEXT: <key>line</key><integer>241</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>225</integer>
+// CHECK-NEXT: <key>line</key><integer>241</integer>
// CHECK-NEXT: <key>col</key><integer>25</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3886,12 +3790,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>225</integer>
+// CHECK-NEXT: <key>line</key><integer>241</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>225</integer>
+// CHECK-NEXT: <key>line</key><integer>241</integer>
// CHECK-NEXT: <key>col</key><integer>25</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3899,12 +3803,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>225</integer>
+// CHECK-NEXT: <key>line</key><integer>241</integer>
// CHECK-NEXT: <key>col</key><integer>27</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>225</integer>
+// CHECK-NEXT: <key>line</key><integer>241</integer>
// CHECK-NEXT: <key>col</key><integer>27</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3916,7 +3820,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>225</integer>
+// CHECK-NEXT: <key>line</key><integer>241</integer>
// CHECK-NEXT: <key>col</key><integer>27</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3924,12 +3828,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>225</integer>
+// CHECK-NEXT: <key>line</key><integer>241</integer>
// CHECK-NEXT: <key>col</key><integer>27</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>225</integer>
+// CHECK-NEXT: <key>line</key><integer>241</integer>
// CHECK-NEXT: <key>col</key><integer>27</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3953,7 +3857,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>issue_hash_function_offset</key><string>3</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>225</integer>
+// CHECK-NEXT: <key>line</key><integer>241</integer>
// CHECK-NEXT: <key>col</key><integer>27</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3965,7 +3869,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>229</integer>
+// CHECK-NEXT: <key>line</key><integer>245</integer>
// CHECK-NEXT: <key>col</key><integer>20</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3973,12 +3877,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>229</integer>
+// CHECK-NEXT: <key>line</key><integer>245</integer>
// CHECK-NEXT: <key>col</key><integer>20</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>229</integer>
+// CHECK-NEXT: <key>line</key><integer>245</integer>
// CHECK-NEXT: <key>col</key><integer>20</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3998,12 +3902,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>229</integer>
+// CHECK-NEXT: <key>line</key><integer>245</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>229</integer>
+// CHECK-NEXT: <key>line</key><integer>245</integer>
// CHECK-NEXT: <key>col</key><integer>18</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4011,12 +3915,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>230</integer>
+// CHECK-NEXT: <key>line</key><integer>246</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>230</integer>
+// CHECK-NEXT: <key>line</key><integer>246</integer>
// CHECK-NEXT: <key>col</key><integer>25</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4032,12 +3936,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>230</integer>
+// CHECK-NEXT: <key>line</key><integer>246</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>230</integer>
+// CHECK-NEXT: <key>line</key><integer>246</integer>
// CHECK-NEXT: <key>col</key><integer>25</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4045,12 +3949,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>230</integer>
+// CHECK-NEXT: <key>line</key><integer>246</integer>
// CHECK-NEXT: <key>col</key><integer>27</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>230</integer>
+// CHECK-NEXT: <key>line</key><integer>246</integer>
// CHECK-NEXT: <key>col</key><integer>27</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4062,7 +3966,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>230</integer>
+// CHECK-NEXT: <key>line</key><integer>246</integer>
// CHECK-NEXT: <key>col</key><integer>27</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4070,12 +3974,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>230</integer>
+// CHECK-NEXT: <key>line</key><integer>246</integer>
// CHECK-NEXT: <key>col</key><integer>27</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>230</integer>
+// CHECK-NEXT: <key>line</key><integer>246</integer>
// CHECK-NEXT: <key>col</key><integer>27</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4099,7 +4003,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>issue_hash_function_offset</key><string>2</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>230</integer>
+// CHECK-NEXT: <key>line</key><integer>246</integer>
// CHECK-NEXT: <key>col</key><integer>27</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4111,7 +4015,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>234</integer>
+// CHECK-NEXT: <key>line</key><integer>250</integer>
// CHECK-NEXT: <key>col</key><integer>27</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4119,12 +4023,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>234</integer>
+// CHECK-NEXT: <key>line</key><integer>250</integer>
// CHECK-NEXT: <key>col</key><integer>27</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>234</integer>
+// CHECK-NEXT: <key>line</key><integer>250</integer>
// CHECK-NEXT: <key>col</key><integer>27</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4144,12 +4048,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>234</integer>
+// CHECK-NEXT: <key>line</key><integer>250</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>234</integer>
+// CHECK-NEXT: <key>line</key><integer>250</integer>
// CHECK-NEXT: <key>col</key><integer>25</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4157,12 +4061,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>235</integer>
+// CHECK-NEXT: <key>line</key><integer>251</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>235</integer>
+// CHECK-NEXT: <key>line</key><integer>251</integer>
// CHECK-NEXT: <key>col</key><integer>18</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4178,12 +4082,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>235</integer>
+// CHECK-NEXT: <key>line</key><integer>251</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>235</integer>
+// CHECK-NEXT: <key>line</key><integer>251</integer>
// CHECK-NEXT: <key>col</key><integer>18</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4191,12 +4095,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>235</integer>
+// CHECK-NEXT: <key>line</key><integer>251</integer>
// CHECK-NEXT: <key>col</key><integer>20</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>235</integer>
+// CHECK-NEXT: <key>line</key><integer>251</integer>
// CHECK-NEXT: <key>col</key><integer>20</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4208,7 +4112,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>235</integer>
+// CHECK-NEXT: <key>line</key><integer>251</integer>
// CHECK-NEXT: <key>col</key><integer>20</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4216,12 +4120,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>235</integer>
+// CHECK-NEXT: <key>line</key><integer>251</integer>
// CHECK-NEXT: <key>col</key><integer>20</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>235</integer>
+// CHECK-NEXT: <key>line</key><integer>251</integer>
// CHECK-NEXT: <key>col</key><integer>20</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4245,7 +4149,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>issue_hash_function_offset</key><string>2</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>235</integer>
+// CHECK-NEXT: <key>line</key><integer>251</integer>
// CHECK-NEXT: <key>col</key><integer>20</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4257,7 +4161,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>239</integer>
+// CHECK-NEXT: <key>line</key><integer>255</integer>
// CHECK-NEXT: <key>col</key><integer>10</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4265,12 +4169,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>239</integer>
+// CHECK-NEXT: <key>line</key><integer>255</integer>
// CHECK-NEXT: <key>col</key><integer>10</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>239</integer>
+// CHECK-NEXT: <key>line</key><integer>255</integer>
// CHECK-NEXT: <key>col</key><integer>10</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4290,12 +4194,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>239</integer>
+// CHECK-NEXT: <key>line</key><integer>255</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>239</integer>
+// CHECK-NEXT: <key>line</key><integer>255</integer>
// CHECK-NEXT: <key>col</key><integer>4</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4303,12 +4207,75 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>241</integer>
+// CHECK-NEXT: <key>line</key><integer>256</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>241</integer>
+// CHECK-NEXT: <key>line</key><integer>256</integer>
+// CHECK-NEXT: <key>col</key><integer>25</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>256</integer>
+// CHECK-NEXT: <key>col</key><integer>27</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>256</integer>
+// CHECK-NEXT: <key>col</key><integer>27</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>256</integer>
+// CHECK-NEXT: <key>col</key><integer>67</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Type &apos;MutableArray&lt;NSMutableString *&gt; *&apos; is inferred from implicit cast (from &apos;BuggyMutableArray&lt;NSMutableString *&gt; *&apos; to &apos;MutableArray&lt;NSMutableString *&gt; *&apos;)</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Type &apos;MutableArray&lt;NSMutableString *&gt; *&apos; is inferred from implicit cast (from &apos;BuggyMutableArray&lt;NSMutableString *&gt; *&apos; to &apos;MutableArray&lt;NSMutableString *&gt; *&apos;)</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>256</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>256</integer>
+// CHECK-NEXT: <key>col</key><integer>25</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>257</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>257</integer>
// CHECK-NEXT: <key>col</key><integer>18</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4324,12 +4291,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>241</integer>
+// CHECK-NEXT: <key>line</key><integer>257</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>241</integer>
+// CHECK-NEXT: <key>line</key><integer>257</integer>
// CHECK-NEXT: <key>col</key><integer>18</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4337,12 +4304,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>241</integer>
+// CHECK-NEXT: <key>line</key><integer>257</integer>
// CHECK-NEXT: <key>col</key><integer>20</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>241</integer>
+// CHECK-NEXT: <key>line</key><integer>257</integer>
// CHECK-NEXT: <key>col</key><integer>20</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4354,7 +4321,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>241</integer>
+// CHECK-NEXT: <key>line</key><integer>257</integer>
// CHECK-NEXT: <key>col</key><integer>20</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4362,12 +4329,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>241</integer>
+// CHECK-NEXT: <key>line</key><integer>257</integer>
// CHECK-NEXT: <key>col</key><integer>20</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>241</integer>
+// CHECK-NEXT: <key>line</key><integer>257</integer>
// CHECK-NEXT: <key>col</key><integer>20</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4391,7 +4358,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>issue_hash_function_offset</key><string>3</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>241</integer>
+// CHECK-NEXT: <key>line</key><integer>257</integer>
// CHECK-NEXT: <key>col</key><integer>20</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4403,7 +4370,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>245</integer>
+// CHECK-NEXT: <key>line</key><integer>261</integer>
// CHECK-NEXT: <key>col</key><integer>45</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4411,12 +4378,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>245</integer>
+// CHECK-NEXT: <key>line</key><integer>261</integer>
// CHECK-NEXT: <key>col</key><integer>45</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>245</integer>
+// CHECK-NEXT: <key>line</key><integer>261</integer>
// CHECK-NEXT: <key>col</key><integer>45</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4436,12 +4403,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>245</integer>
+// CHECK-NEXT: <key>line</key><integer>261</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>245</integer>
+// CHECK-NEXT: <key>line</key><integer>261</integer>
// CHECK-NEXT: <key>col</key><integer>19</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4449,12 +4416,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>246</integer>
+// CHECK-NEXT: <key>line</key><integer>262</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>246</integer>
+// CHECK-NEXT: <key>line</key><integer>262</integer>
// CHECK-NEXT: <key>col</key><integer>18</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4466,7 +4433,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>246</integer>
+// CHECK-NEXT: <key>line</key><integer>262</integer>
// CHECK-NEXT: <key>col</key><integer>20</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4474,12 +4441,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>246</integer>
+// CHECK-NEXT: <key>line</key><integer>262</integer>
// CHECK-NEXT: <key>col</key><integer>20</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>246</integer>
+// CHECK-NEXT: <key>line</key><integer>262</integer>
// CHECK-NEXT: <key>col</key><integer>20</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4499,12 +4466,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>246</integer>
+// CHECK-NEXT: <key>line</key><integer>262</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>246</integer>
+// CHECK-NEXT: <key>line</key><integer>262</integer>
// CHECK-NEXT: <key>col</key><integer>18</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4512,12 +4479,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>247</integer>
+// CHECK-NEXT: <key>line</key><integer>263</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>247</integer>
+// CHECK-NEXT: <key>line</key><integer>263</integer>
// CHECK-NEXT: <key>col</key><integer>25</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4533,12 +4500,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>247</integer>
+// CHECK-NEXT: <key>line</key><integer>263</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>247</integer>
+// CHECK-NEXT: <key>line</key><integer>263</integer>
// CHECK-NEXT: <key>col</key><integer>25</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4546,12 +4513,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>247</integer>
+// CHECK-NEXT: <key>line</key><integer>263</integer>
// CHECK-NEXT: <key>col</key><integer>27</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>247</integer>
+// CHECK-NEXT: <key>line</key><integer>263</integer>
// CHECK-NEXT: <key>col</key><integer>27</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4563,7 +4530,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>247</integer>
+// CHECK-NEXT: <key>line</key><integer>263</integer>
// CHECK-NEXT: <key>col</key><integer>27</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4571,12 +4538,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>247</integer>
+// CHECK-NEXT: <key>line</key><integer>263</integer>
// CHECK-NEXT: <key>col</key><integer>27</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>247</integer>
+// CHECK-NEXT: <key>line</key><integer>263</integer>
// CHECK-NEXT: <key>col</key><integer>27</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4600,7 +4567,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>issue_hash_function_offset</key><string>3</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>247</integer>
+// CHECK-NEXT: <key>line</key><integer>263</integer>
// CHECK-NEXT: <key>col</key><integer>27</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4616,12 +4583,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>259</integer>
+// CHECK-NEXT: <key>line</key><integer>275</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>259</integer>
+// CHECK-NEXT: <key>line</key><integer>275</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4629,12 +4596,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>260</integer>
+// CHECK-NEXT: <key>line</key><integer>276</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>260</integer>
+// CHECK-NEXT: <key>line</key><integer>276</integer>
// CHECK-NEXT: <key>col</key><integer>10</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4650,12 +4617,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>260</integer>
+// CHECK-NEXT: <key>line</key><integer>276</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>260</integer>
+// CHECK-NEXT: <key>line</key><integer>276</integer>
// CHECK-NEXT: <key>col</key><integer>10</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4663,12 +4630,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>260</integer>
+// CHECK-NEXT: <key>line</key><integer>276</integer>
// CHECK-NEXT: <key>col</key><integer>19</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>260</integer>
+// CHECK-NEXT: <key>line</key><integer>276</integer>
// CHECK-NEXT: <key>col</key><integer>19</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4680,7 +4647,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>260</integer>
+// CHECK-NEXT: <key>line</key><integer>276</integer>
// CHECK-NEXT: <key>col</key><integer>19</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4688,12 +4655,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>260</integer>
+// CHECK-NEXT: <key>line</key><integer>276</integer>
// CHECK-NEXT: <key>col</key><integer>19</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>260</integer>
+// CHECK-NEXT: <key>line</key><integer>276</integer>
// CHECK-NEXT: <key>col</key><integer>38</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4709,7 +4676,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>260</integer>
+// CHECK-NEXT: <key>line</key><integer>276</integer>
// CHECK-NEXT: <key>col</key><integer>19</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4717,12 +4684,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>260</integer>
+// CHECK-NEXT: <key>line</key><integer>276</integer>
// CHECK-NEXT: <key>col</key><integer>19</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>260</integer>
+// CHECK-NEXT: <key>line</key><integer>276</integer>
// CHECK-NEXT: <key>col</key><integer>38</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4746,7 +4713,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>issue_hash_function_offset</key><string>2</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>260</integer>
+// CHECK-NEXT: <key>line</key><integer>276</integer>
// CHECK-NEXT: <key>col</key><integer>19</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4762,12 +4729,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>259</integer>
+// CHECK-NEXT: <key>line</key><integer>275</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>259</integer>
+// CHECK-NEXT: <key>line</key><integer>275</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4775,12 +4742,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>262</integer>
+// CHECK-NEXT: <key>line</key><integer>278</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>262</integer>
+// CHECK-NEXT: <key>line</key><integer>278</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4796,12 +4763,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>262</integer>
+// CHECK-NEXT: <key>line</key><integer>278</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>262</integer>
+// CHECK-NEXT: <key>line</key><integer>278</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4809,12 +4776,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>262</integer>
+// CHECK-NEXT: <key>line</key><integer>278</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>262</integer>
+// CHECK-NEXT: <key>line</key><integer>278</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4826,7 +4793,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>262</integer>
+// CHECK-NEXT: <key>line</key><integer>278</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4834,12 +4801,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>262</integer>
+// CHECK-NEXT: <key>line</key><integer>278</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>262</integer>
+// CHECK-NEXT: <key>line</key><integer>278</integer>
// CHECK-NEXT: <key>col</key><integer>23</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4855,7 +4822,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>262</integer>
+// CHECK-NEXT: <key>line</key><integer>278</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4863,12 +4830,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>262</integer>
+// CHECK-NEXT: <key>line</key><integer>278</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>262</integer>
+// CHECK-NEXT: <key>line</key><integer>278</integer>
// CHECK-NEXT: <key>col</key><integer>23</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4892,7 +4859,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>issue_hash_function_offset</key><string>4</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>262</integer>
+// CHECK-NEXT: <key>line</key><integer>278</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4908,12 +4875,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>259</integer>
+// CHECK-NEXT: <key>line</key><integer>275</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>259</integer>
+// CHECK-NEXT: <key>line</key><integer>275</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4921,12 +4888,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>264</integer>
+// CHECK-NEXT: <key>line</key><integer>280</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>264</integer>
+// CHECK-NEXT: <key>line</key><integer>280</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4942,12 +4909,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>264</integer>
+// CHECK-NEXT: <key>line</key><integer>280</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>264</integer>
+// CHECK-NEXT: <key>line</key><integer>280</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4955,12 +4922,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>264</integer>
+// CHECK-NEXT: <key>line</key><integer>280</integer>
// CHECK-NEXT: <key>col</key><integer>11</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>264</integer>
+// CHECK-NEXT: <key>line</key><integer>280</integer>
// CHECK-NEXT: <key>col</key><integer>21</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4972,7 +4939,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>264</integer>
+// CHECK-NEXT: <key>line</key><integer>280</integer>
// CHECK-NEXT: <key>col</key><integer>11</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4980,12 +4947,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>264</integer>
+// CHECK-NEXT: <key>line</key><integer>280</integer>
// CHECK-NEXT: <key>col</key><integer>11</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>264</integer>
+// CHECK-NEXT: <key>line</key><integer>280</integer>
// CHECK-NEXT: <key>col</key><integer>21</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5001,7 +4968,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>264</integer>
+// CHECK-NEXT: <key>line</key><integer>280</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5009,12 +4976,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>264</integer>
+// CHECK-NEXT: <key>line</key><integer>280</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>264</integer>
+// CHECK-NEXT: <key>line</key><integer>280</integer>
// CHECK-NEXT: <key>col</key><integer>21</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5038,7 +5005,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>issue_hash_function_offset</key><string>6</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>264</integer>
+// CHECK-NEXT: <key>line</key><integer>280</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5054,12 +5021,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>259</integer>
+// CHECK-NEXT: <key>line</key><integer>275</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>259</integer>
+// CHECK-NEXT: <key>line</key><integer>275</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5067,12 +5034,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>266</integer>
+// CHECK-NEXT: <key>line</key><integer>282</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>266</integer>
+// CHECK-NEXT: <key>line</key><integer>282</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5088,12 +5055,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>266</integer>
+// CHECK-NEXT: <key>line</key><integer>282</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>266</integer>
+// CHECK-NEXT: <key>line</key><integer>282</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5101,12 +5068,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>266</integer>
+// CHECK-NEXT: <key>line</key><integer>282</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>266</integer>
+// CHECK-NEXT: <key>line</key><integer>282</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5118,7 +5085,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>266</integer>
+// CHECK-NEXT: <key>line</key><integer>282</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5126,12 +5093,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>266</integer>
+// CHECK-NEXT: <key>line</key><integer>282</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>266</integer>
+// CHECK-NEXT: <key>line</key><integer>282</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5147,7 +5114,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>266</integer>
+// CHECK-NEXT: <key>line</key><integer>282</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5155,12 +5122,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>266</integer>
+// CHECK-NEXT: <key>line</key><integer>282</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>266</integer>
+// CHECK-NEXT: <key>line</key><integer>282</integer>
// CHECK-NEXT: <key>col</key><integer>12</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5184,7 +5151,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>issue_hash_function_offset</key><string>8</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>266</integer>
+// CHECK-NEXT: <key>line</key><integer>282</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5196,7 +5163,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>272</integer>
+// CHECK-NEXT: <key>line</key><integer>288</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5204,12 +5171,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>272</integer>
+// CHECK-NEXT: <key>line</key><integer>288</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>272</integer>
+// CHECK-NEXT: <key>line</key><integer>288</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5229,12 +5196,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>272</integer>
+// CHECK-NEXT: <key>line</key><integer>288</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>272</integer>
+// CHECK-NEXT: <key>line</key><integer>288</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5242,12 +5209,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>273</integer>
+// CHECK-NEXT: <key>line</key><integer>289</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>273</integer>
+// CHECK-NEXT: <key>line</key><integer>289</integer>
// CHECK-NEXT: <key>col</key><integer>4</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5263,12 +5230,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>273</integer>
+// CHECK-NEXT: <key>line</key><integer>289</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>273</integer>
+// CHECK-NEXT: <key>line</key><integer>289</integer>
// CHECK-NEXT: <key>col</key><integer>4</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5276,12 +5243,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>273</integer>
+// CHECK-NEXT: <key>line</key><integer>289</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>273</integer>
+// CHECK-NEXT: <key>line</key><integer>289</integer>
// CHECK-NEXT: <key>col</key><integer>16</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5293,7 +5260,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>273</integer>
+// CHECK-NEXT: <key>line</key><integer>289</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5301,12 +5268,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>273</integer>
+// CHECK-NEXT: <key>line</key><integer>289</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>273</integer>
+// CHECK-NEXT: <key>line</key><integer>289</integer>
// CHECK-NEXT: <key>col</key><integer>23</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5326,12 +5293,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>273</integer>
+// CHECK-NEXT: <key>line</key><integer>289</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>273</integer>
+// CHECK-NEXT: <key>line</key><integer>289</integer>
// CHECK-NEXT: <key>col</key><integer>16</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5339,12 +5306,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>274</integer>
+// CHECK-NEXT: <key>line</key><integer>290</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>274</integer>
+// CHECK-NEXT: <key>line</key><integer>290</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5360,12 +5327,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>274</integer>
+// CHECK-NEXT: <key>line</key><integer>290</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>274</integer>
+// CHECK-NEXT: <key>line</key><integer>290</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5373,12 +5340,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>275</integer>
+// CHECK-NEXT: <key>line</key><integer>291</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>275</integer>
+// CHECK-NEXT: <key>line</key><integer>291</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5390,7 +5357,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>275</integer>
+// CHECK-NEXT: <key>line</key><integer>291</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5398,12 +5365,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>275</integer>
+// CHECK-NEXT: <key>line</key><integer>291</integer>
// CHECK-NEXT: <key>col</key><integer>19</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>275</integer>
+// CHECK-NEXT: <key>line</key><integer>291</integer>
// CHECK-NEXT: <key>col</key><integer>41</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5427,7 +5394,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>issue_hash_function_offset</key><string>4</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>275</integer>
+// CHECK-NEXT: <key>line</key><integer>291</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5439,7 +5406,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>284</integer>
+// CHECK-NEXT: <key>line</key><integer>300</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5447,12 +5414,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>284</integer>
+// CHECK-NEXT: <key>line</key><integer>300</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>284</integer>
+// CHECK-NEXT: <key>line</key><integer>300</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5472,12 +5439,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>284</integer>
+// CHECK-NEXT: <key>line</key><integer>300</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>284</integer>
+// CHECK-NEXT: <key>line</key><integer>300</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5485,12 +5452,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>285</integer>
+// CHECK-NEXT: <key>line</key><integer>301</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>285</integer>
+// CHECK-NEXT: <key>line</key><integer>301</integer>
// CHECK-NEXT: <key>col</key><integer>4</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5506,12 +5473,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>285</integer>
+// CHECK-NEXT: <key>line</key><integer>301</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>285</integer>
+// CHECK-NEXT: <key>line</key><integer>301</integer>
// CHECK-NEXT: <key>col</key><integer>4</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5519,12 +5486,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>285</integer>
+// CHECK-NEXT: <key>line</key><integer>301</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>285</integer>
+// CHECK-NEXT: <key>line</key><integer>301</integer>
// CHECK-NEXT: <key>col</key><integer>16</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5536,7 +5503,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>285</integer>
+// CHECK-NEXT: <key>line</key><integer>301</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5544,12 +5511,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>285</integer>
+// CHECK-NEXT: <key>line</key><integer>301</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>285</integer>
+// CHECK-NEXT: <key>line</key><integer>301</integer>
// CHECK-NEXT: <key>col</key><integer>23</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5569,12 +5536,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>285</integer>
+// CHECK-NEXT: <key>line</key><integer>301</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>285</integer>
+// CHECK-NEXT: <key>line</key><integer>301</integer>
// CHECK-NEXT: <key>col</key><integer>16</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5582,12 +5549,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>286</integer>
+// CHECK-NEXT: <key>line</key><integer>302</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>286</integer>
+// CHECK-NEXT: <key>line</key><integer>302</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5599,7 +5566,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>286</integer>
+// CHECK-NEXT: <key>line</key><integer>302</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5607,12 +5574,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>286</integer>
+// CHECK-NEXT: <key>line</key><integer>302</integer>
// CHECK-NEXT: <key>col</key><integer>19</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>286</integer>
+// CHECK-NEXT: <key>line</key><integer>302</integer>
// CHECK-NEXT: <key>col</key><integer>41</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5636,7 +5603,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>issue_hash_function_offset</key><string>3</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>286</integer>
+// CHECK-NEXT: <key>line</key><integer>302</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5652,12 +5619,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>310</integer>
+// CHECK-NEXT: <key>line</key><integer>326</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>310</integer>
+// CHECK-NEXT: <key>line</key><integer>326</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5665,12 +5632,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>311</integer>
+// CHECK-NEXT: <key>line</key><integer>327</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>311</integer>
+// CHECK-NEXT: <key>line</key><integer>327</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5686,12 +5653,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>311</integer>
+// CHECK-NEXT: <key>line</key><integer>327</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>311</integer>
+// CHECK-NEXT: <key>line</key><integer>327</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5699,12 +5666,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>311</integer>
+// CHECK-NEXT: <key>line</key><integer>327</integer>
// CHECK-NEXT: <key>col</key><integer>28</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>311</integer>
+// CHECK-NEXT: <key>line</key><integer>327</integer>
// CHECK-NEXT: <key>col</key><integer>28</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5716,7 +5683,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>311</integer>
+// CHECK-NEXT: <key>line</key><integer>327</integer>
// CHECK-NEXT: <key>col</key><integer>28</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5724,12 +5691,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>311</integer>
+// CHECK-NEXT: <key>line</key><integer>327</integer>
// CHECK-NEXT: <key>col</key><integer>28</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>311</integer>
+// CHECK-NEXT: <key>line</key><integer>327</integer>
// CHECK-NEXT: <key>col</key><integer>39</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5745,7 +5712,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>311</integer>
+// CHECK-NEXT: <key>line</key><integer>327</integer>
// CHECK-NEXT: <key>col</key><integer>28</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5753,12 +5720,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>311</integer>
+// CHECK-NEXT: <key>line</key><integer>327</integer>
// CHECK-NEXT: <key>col</key><integer>28</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>311</integer>
+// CHECK-NEXT: <key>line</key><integer>327</integer>
// CHECK-NEXT: <key>col</key><integer>39</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5782,7 +5749,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>issue_hash_function_offset</key><string>2</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>311</integer>
+// CHECK-NEXT: <key>line</key><integer>327</integer>
// CHECK-NEXT: <key>col</key><integer>28</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5798,12 +5765,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>310</integer>
+// CHECK-NEXT: <key>line</key><integer>326</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>310</integer>
+// CHECK-NEXT: <key>line</key><integer>326</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5811,12 +5778,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>312</integer>
+// CHECK-NEXT: <key>line</key><integer>328</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>312</integer>
+// CHECK-NEXT: <key>line</key><integer>328</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5832,12 +5799,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>312</integer>
+// CHECK-NEXT: <key>line</key><integer>328</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>312</integer>
+// CHECK-NEXT: <key>line</key><integer>328</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5845,12 +5812,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>312</integer>
+// CHECK-NEXT: <key>line</key><integer>328</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>312</integer>
+// CHECK-NEXT: <key>line</key><integer>328</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5862,7 +5829,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>312</integer>
+// CHECK-NEXT: <key>line</key><integer>328</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5870,12 +5837,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>312</integer>
+// CHECK-NEXT: <key>line</key><integer>328</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>312</integer>
+// CHECK-NEXT: <key>line</key><integer>328</integer>
// CHECK-NEXT: <key>col</key><integer>19</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5891,7 +5858,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>312</integer>
+// CHECK-NEXT: <key>line</key><integer>328</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5899,12 +5866,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>312</integer>
+// CHECK-NEXT: <key>line</key><integer>328</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>312</integer>
+// CHECK-NEXT: <key>line</key><integer>328</integer>
// CHECK-NEXT: <key>col</key><integer>19</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5928,7 +5895,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>issue_hash_function_offset</key><string>3</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>312</integer>
+// CHECK-NEXT: <key>line</key><integer>328</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5940,7 +5907,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>316</integer>
+// CHECK-NEXT: <key>line</key><integer>332</integer>
// CHECK-NEXT: <key>col</key><integer>13</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5948,12 +5915,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>316</integer>
+// CHECK-NEXT: <key>line</key><integer>332</integer>
// CHECK-NEXT: <key>col</key><integer>13</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>316</integer>
+// CHECK-NEXT: <key>line</key><integer>332</integer>
// CHECK-NEXT: <key>col</key><integer>15</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5973,12 +5940,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>316</integer>
+// CHECK-NEXT: <key>line</key><integer>332</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>316</integer>
+// CHECK-NEXT: <key>line</key><integer>332</integer>
// CHECK-NEXT: <key>col</key><integer>4</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5986,12 +5953,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>317</integer>
+// CHECK-NEXT: <key>line</key><integer>333</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>317</integer>
+// CHECK-NEXT: <key>line</key><integer>333</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -6007,12 +5974,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>317</integer>
+// CHECK-NEXT: <key>line</key><integer>333</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>317</integer>
+// CHECK-NEXT: <key>line</key><integer>333</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -6020,12 +5987,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>317</integer>
+// CHECK-NEXT: <key>line</key><integer>333</integer>
// CHECK-NEXT: <key>col</key><integer>18</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>317</integer>
+// CHECK-NEXT: <key>line</key><integer>333</integer>
// CHECK-NEXT: <key>col</key><integer>21</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -6037,7 +6004,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>317</integer>
+// CHECK-NEXT: <key>line</key><integer>333</integer>
// CHECK-NEXT: <key>col</key><integer>18</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -6045,12 +6012,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>317</integer>
+// CHECK-NEXT: <key>line</key><integer>333</integer>
// CHECK-NEXT: <key>col</key><integer>18</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>317</integer>
+// CHECK-NEXT: <key>line</key><integer>333</integer>
// CHECK-NEXT: <key>col</key><integer>21</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -6074,7 +6041,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>issue_hash_function_offset</key><string>2</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>317</integer>
+// CHECK-NEXT: <key>line</key><integer>333</integer>
// CHECK-NEXT: <key>col</key><integer>18</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -6090,12 +6057,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>329</integer>
+// CHECK-NEXT: <key>line</key><integer>345</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>329</integer>
+// CHECK-NEXT: <key>line</key><integer>345</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -6103,12 +6070,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>330</integer>
+// CHECK-NEXT: <key>line</key><integer>346</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>330</integer>
+// CHECK-NEXT: <key>line</key><integer>346</integer>
// CHECK-NEXT: <key>col</key><integer>4</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -6120,7 +6087,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>330</integer>
+// CHECK-NEXT: <key>line</key><integer>346</integer>
// CHECK-NEXT: <key>col</key><integer>10</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -6128,12 +6095,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>330</integer>
+// CHECK-NEXT: <key>line</key><integer>346</integer>
// CHECK-NEXT: <key>col</key><integer>10</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>330</integer>
+// CHECK-NEXT: <key>line</key><integer>346</integer>
// CHECK-NEXT: <key>col</key><integer>29</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -6153,12 +6120,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>330</integer>
+// CHECK-NEXT: <key>line</key><integer>346</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>330</integer>
+// CHECK-NEXT: <key>line</key><integer>346</integer>
// CHECK-NEXT: <key>col</key><integer>4</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -6166,12 +6133,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>331</integer>
+// CHECK-NEXT: <key>line</key><integer>347</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>331</integer>
+// CHECK-NEXT: <key>line</key><integer>347</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -6187,12 +6154,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>331</integer>
+// CHECK-NEXT: <key>line</key><integer>347</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>331</integer>
+// CHECK-NEXT: <key>line</key><integer>347</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -6200,12 +6167,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>331</integer>
+// CHECK-NEXT: <key>line</key><integer>347</integer>
// CHECK-NEXT: <key>col</key><integer>30</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>331</integer>
+// CHECK-NEXT: <key>line</key><integer>347</integer>
// CHECK-NEXT: <key>col</key><integer>30</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -6217,7 +6184,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>331</integer>
+// CHECK-NEXT: <key>line</key><integer>347</integer>
// CHECK-NEXT: <key>col</key><integer>30</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -6225,12 +6192,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>331</integer>
+// CHECK-NEXT: <key>line</key><integer>347</integer>
// CHECK-NEXT: <key>col</key><integer>30</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>331</integer>
+// CHECK-NEXT: <key>line</key><integer>347</integer>
// CHECK-NEXT: <key>col</key><integer>30</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -6254,7 +6221,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>issue_hash_function_offset</key><string>3</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>331</integer>
+// CHECK-NEXT: <key>line</key><integer>347</integer>
// CHECK-NEXT: <key>col</key><integer>30</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -6270,12 +6237,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>335</integer>
+// CHECK-NEXT: <key>line</key><integer>351</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>335</integer>
+// CHECK-NEXT: <key>line</key><integer>351</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -6283,12 +6250,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>336</integer>
+// CHECK-NEXT: <key>line</key><integer>352</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>336</integer>
+// CHECK-NEXT: <key>line</key><integer>352</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -6300,7 +6267,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>336</integer>
+// CHECK-NEXT: <key>line</key><integer>352</integer>
// CHECK-NEXT: <key>col</key><integer>16</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -6308,12 +6275,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>336</integer>
+// CHECK-NEXT: <key>line</key><integer>352</integer>
// CHECK-NEXT: <key>col</key><integer>16</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>336</integer>
+// CHECK-NEXT: <key>line</key><integer>352</integer>
// CHECK-NEXT: <key>col</key><integer>35</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -6333,12 +6300,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>336</integer>
+// CHECK-NEXT: <key>line</key><integer>352</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>336</integer>
+// CHECK-NEXT: <key>line</key><integer>352</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -6346,12 +6313,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>337</integer>
+// CHECK-NEXT: <key>line</key><integer>353</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>337</integer>
+// CHECK-NEXT: <key>line</key><integer>353</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -6367,12 +6334,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>337</integer>
+// CHECK-NEXT: <key>line</key><integer>353</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>337</integer>
+// CHECK-NEXT: <key>line</key><integer>353</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -6380,12 +6347,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>337</integer>
+// CHECK-NEXT: <key>line</key><integer>353</integer>
// CHECK-NEXT: <key>col</key><integer>30</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>337</integer>
+// CHECK-NEXT: <key>line</key><integer>353</integer>
// CHECK-NEXT: <key>col</key><integer>30</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -6397,7 +6364,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>337</integer>
+// CHECK-NEXT: <key>line</key><integer>353</integer>
// CHECK-NEXT: <key>col</key><integer>30</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -6405,12 +6372,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>337</integer>
+// CHECK-NEXT: <key>line</key><integer>353</integer>
// CHECK-NEXT: <key>col</key><integer>30</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>337</integer>
+// CHECK-NEXT: <key>line</key><integer>353</integer>
// CHECK-NEXT: <key>col</key><integer>30</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -6434,7 +6401,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>issue_hash_function_offset</key><string>3</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>337</integer>
+// CHECK-NEXT: <key>line</key><integer>353</integer>
// CHECK-NEXT: <key>col</key><integer>30</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -6450,12 +6417,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>341</integer>
+// CHECK-NEXT: <key>line</key><integer>357</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>341</integer>
+// CHECK-NEXT: <key>line</key><integer>357</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -6463,12 +6430,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>342</integer>
+// CHECK-NEXT: <key>line</key><integer>358</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>342</integer>
+// CHECK-NEXT: <key>line</key><integer>358</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -6484,12 +6451,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>342</integer>
+// CHECK-NEXT: <key>line</key><integer>358</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>342</integer>
+// CHECK-NEXT: <key>line</key><integer>358</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -6497,12 +6464,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>342</integer>
+// CHECK-NEXT: <key>line</key><integer>358</integer>
// CHECK-NEXT: <key>col</key><integer>14</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>342</integer>
+// CHECK-NEXT: <key>line</key><integer>358</integer>
// CHECK-NEXT: <key>col</key><integer>14</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -6514,7 +6481,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>342</integer>
+// CHECK-NEXT: <key>line</key><integer>358</integer>
// CHECK-NEXT: <key>col</key><integer>14</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -6522,12 +6489,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>342</integer>
+// CHECK-NEXT: <key>line</key><integer>358</integer>
// CHECK-NEXT: <key>col</key><integer>14</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>342</integer>
+// CHECK-NEXT: <key>line</key><integer>358</integer>
// CHECK-NEXT: <key>col</key><integer>33</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -6543,7 +6510,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>342</integer>
+// CHECK-NEXT: <key>line</key><integer>358</integer>
// CHECK-NEXT: <key>col</key><integer>14</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -6551,12 +6518,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>342</integer>
+// CHECK-NEXT: <key>line</key><integer>358</integer>
// CHECK-NEXT: <key>col</key><integer>14</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>342</integer>
+// CHECK-NEXT: <key>line</key><integer>358</integer>
// CHECK-NEXT: <key>col</key><integer>33</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -6580,7 +6547,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>issue_hash_function_offset</key><string>2</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>342</integer>
+// CHECK-NEXT: <key>line</key><integer>358</integer>
// CHECK-NEXT: <key>col</key><integer>14</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -6596,12 +6563,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>347</integer>
+// CHECK-NEXT: <key>line</key><integer>363</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>347</integer>
+// CHECK-NEXT: <key>line</key><integer>363</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -6609,12 +6576,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>348</integer>
+// CHECK-NEXT: <key>line</key><integer>364</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>348</integer>
+// CHECK-NEXT: <key>line</key><integer>364</integer>
// CHECK-NEXT: <key>col</key><integer>4</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -6626,7 +6593,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>348</integer>
+// CHECK-NEXT: <key>line</key><integer>364</integer>
// CHECK-NEXT: <key>col</key><integer>10</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -6634,12 +6601,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>348</integer>
+// CHECK-NEXT: <key>line</key><integer>364</integer>
// CHECK-NEXT: <key>col</key><integer>10</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>348</integer>
+// CHECK-NEXT: <key>line</key><integer>364</integer>
// CHECK-NEXT: <key>col</key><integer>29</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -6659,12 +6626,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>348</integer>
+// CHECK-NEXT: <key>line</key><integer>364</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>348</integer>
+// CHECK-NEXT: <key>line</key><integer>364</integer>
// CHECK-NEXT: <key>col</key><integer>4</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -6672,12 +6639,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>349</integer>
+// CHECK-NEXT: <key>line</key><integer>365</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>349</integer>
+// CHECK-NEXT: <key>line</key><integer>365</integer>
// CHECK-NEXT: <key>col</key><integer>10</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -6693,12 +6660,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>349</integer>
+// CHECK-NEXT: <key>line</key><integer>365</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>349</integer>
+// CHECK-NEXT: <key>line</key><integer>365</integer>
// CHECK-NEXT: <key>col</key><integer>10</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -6706,12 +6673,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>349</integer>
+// CHECK-NEXT: <key>line</key><integer>365</integer>
// CHECK-NEXT: <key>col</key><integer>19</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>349</integer>
+// CHECK-NEXT: <key>line</key><integer>365</integer>
// CHECK-NEXT: <key>col</key><integer>19</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -6723,7 +6690,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>349</integer>
+// CHECK-NEXT: <key>line</key><integer>365</integer>
// CHECK-NEXT: <key>col</key><integer>19</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -6731,12 +6698,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>349</integer>
+// CHECK-NEXT: <key>line</key><integer>365</integer>
// CHECK-NEXT: <key>col</key><integer>19</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>349</integer>
+// CHECK-NEXT: <key>line</key><integer>365</integer>
// CHECK-NEXT: <key>col</key><integer>19</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -6760,7 +6727,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>issue_hash_function_offset</key><string>3</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>349</integer>
+// CHECK-NEXT: <key>line</key><integer>365</integer>
// CHECK-NEXT: <key>col</key><integer>19</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -6772,7 +6739,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>358</integer>
+// CHECK-NEXT: <key>line</key><integer>374</integer>
// CHECK-NEXT: <key>col</key><integer>12</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -6780,12 +6747,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>358</integer>
+// CHECK-NEXT: <key>line</key><integer>374</integer>
// CHECK-NEXT: <key>col</key><integer>12</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>358</integer>
+// CHECK-NEXT: <key>line</key><integer>374</integer>
// CHECK-NEXT: <key>col</key><integer>12</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -6805,12 +6772,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>358</integer>
+// CHECK-NEXT: <key>line</key><integer>374</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>358</integer>
+// CHECK-NEXT: <key>line</key><integer>374</integer>
// CHECK-NEXT: <key>col</key><integer>4</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -6818,12 +6785,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>359</integer>
+// CHECK-NEXT: <key>line</key><integer>375</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>359</integer>
+// CHECK-NEXT: <key>line</key><integer>375</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -6839,12 +6806,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>359</integer>
+// CHECK-NEXT: <key>line</key><integer>375</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>359</integer>
+// CHECK-NEXT: <key>line</key><integer>375</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -6852,12 +6819,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>359</integer>
+// CHECK-NEXT: <key>line</key><integer>375</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>359</integer>
+// CHECK-NEXT: <key>line</key><integer>375</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -6869,7 +6836,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>359</integer>
+// CHECK-NEXT: <key>line</key><integer>375</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -6877,12 +6844,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>359</integer>
+// CHECK-NEXT: <key>line</key><integer>375</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>359</integer>
+// CHECK-NEXT: <key>line</key><integer>375</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -6906,7 +6873,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>issue_hash_function_offset</key><string>2</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>359</integer>
+// CHECK-NEXT: <key>line</key><integer>375</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -6918,7 +6885,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>358</integer>
+// CHECK-NEXT: <key>line</key><integer>374</integer>
// CHECK-NEXT: <key>col</key><integer>12</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -6926,12 +6893,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>358</integer>
+// CHECK-NEXT: <key>line</key><integer>374</integer>
// CHECK-NEXT: <key>col</key><integer>12</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>358</integer>
+// CHECK-NEXT: <key>line</key><integer>374</integer>
// CHECK-NEXT: <key>col</key><integer>12</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -6951,12 +6918,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>358</integer>
+// CHECK-NEXT: <key>line</key><integer>374</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>358</integer>
+// CHECK-NEXT: <key>line</key><integer>374</integer>
// CHECK-NEXT: <key>col</key><integer>4</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -6964,12 +6931,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>364</integer>
+// CHECK-NEXT: <key>line</key><integer>380</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>364</integer>
+// CHECK-NEXT: <key>line</key><integer>380</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -6981,7 +6948,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>364</integer>
+// CHECK-NEXT: <key>line</key><integer>380</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -6989,12 +6956,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>364</integer>
+// CHECK-NEXT: <key>line</key><integer>380</integer>
// CHECK-NEXT: <key>col</key><integer>16</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>364</integer>
+// CHECK-NEXT: <key>line</key><integer>380</integer>
// CHECK-NEXT: <key>col</key><integer>38</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -7018,7 +6985,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>issue_hash_function_offset</key><string>7</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>364</integer>
+// CHECK-NEXT: <key>line</key><integer>380</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -7034,12 +7001,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>373</integer>
+// CHECK-NEXT: <key>line</key><integer>389</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>373</integer>
+// CHECK-NEXT: <key>line</key><integer>389</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -7047,12 +7014,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>375</integer>
+// CHECK-NEXT: <key>line</key><integer>391</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>375</integer>
+// CHECK-NEXT: <key>line</key><integer>391</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -7068,12 +7035,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>375</integer>
+// CHECK-NEXT: <key>line</key><integer>391</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>375</integer>
+// CHECK-NEXT: <key>line</key><integer>391</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -7081,12 +7048,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>375</integer>
+// CHECK-NEXT: <key>line</key><integer>391</integer>
// CHECK-NEXT: <key>col</key><integer>70</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>375</integer>
+// CHECK-NEXT: <key>line</key><integer>391</integer>
// CHECK-NEXT: <key>col</key><integer>79</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -7098,7 +7065,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>375</integer>
+// CHECK-NEXT: <key>line</key><integer>391</integer>
// CHECK-NEXT: <key>col</key><integer>70</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -7106,12 +7073,12 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>375</integer>
+// CHECK-NEXT: <key>line</key><integer>391</integer>
// CHECK-NEXT: <key>col</key><integer>70</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>375</integer>
+// CHECK-NEXT: <key>line</key><integer>391</integer>
// CHECK-NEXT: <key>col</key><integer>79</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -7135,7 +7102,7 @@ void testCallToMethodWithCovariantParameterOnInstanceOfSubclassWithInvariantPara
// CHECK-NEXT: <key>issue_hash_function_offset</key><string>3</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>375</integer>
+// CHECK-NEXT: <key>line</key><integer>391</integer>
// CHECK-NEXT: <key>col</key><integer>70</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
diff --git a/test/Analysis/gtest.cpp b/test/Analysis/gtest.cpp
index 5797a773b423..98f415eea456 100644
--- a/test/Analysis/gtest.cpp
+++ b/test/Analysis/gtest.cpp
@@ -151,3 +151,17 @@ void testConstrainState(int p) {
ASSERT_TRUE(false);
clang_analyzer_warnIfReached(); // no-warning
}
+
+void testAssertSymbolicPtr(const bool *b) {
+ ASSERT_TRUE(*b); // no-crash
+
+ // FIXME: Our solver doesn't handle this well yet.
+ clang_analyzer_eval(*b); // expected-warning{{UNKNOWN}}
+}
+
+void testAssertSymbolicRef(const bool &b) {
+ ASSERT_TRUE(b); // no-crash
+
+ // FIXME: Our solver doesn't handle this well yet.
+ clang_analyzer_eval(b); // expected-warning{{UNKNOWN}}
+}
diff --git a/test/Analysis/html-diag-singlefile.c b/test/Analysis/html-diag-singlefile.c
new file mode 100644
index 000000000000..fc0dcc7a4233
--- /dev/null
+++ b/test/Analysis/html-diag-singlefile.c
@@ -0,0 +1,14 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=html-single-file -o D30406.html %s 2>&1 | FileCheck %s
+
+// Check that single file HTML output does not process multi-file diagnostics.
+// (This used to test for PR12421, before the introduction of the html-single-file format)
+
+#include "html-diag-singlefile.h"
+
+int main(){
+ f();
+ return 0;
+}
+
+// CHECK: warning: Path diagnostic report is not generated.
diff --git a/test/Analysis/diagnostics/diag-cross-file-boundaries.h b/test/Analysis/html-diag-singlefile.h
index 1af7d1f1fbb4..1af7d1f1fbb4 100644
--- a/test/Analysis/diagnostics/diag-cross-file-boundaries.h
+++ b/test/Analysis/html-diag-singlefile.h
diff --git a/test/Analysis/html-diags-analyze-headers.c b/test/Analysis/html-diags-analyze-headers.c
new file mode 100644
index 000000000000..fa5f21de0478
--- /dev/null
+++ b/test/Analysis/html-diags-analyze-headers.c
@@ -0,0 +1,10 @@
+// RUN: mkdir -p %t.dir
+// RUN: %clang_analyze_cc1 -analyzer-opt-analyze-headers -analyzer-output=html -analyzer-checker=core -o %t.dir %s
+// RUN: ls %t.dir | grep report
+// RUN: rm -rf %t.dir
+
+// This tests that we emit HTML diagnostics for reports in headers when the
+// analyzer is run with -analyzer-opt-analyze-headers. This was handled
+// incorrectly in the first iteration of D30406.
+
+#include "html-diags-analyze-headers.h"
diff --git a/test/Analysis/html-diags-analyze-headers.h b/test/Analysis/html-diags-analyze-headers.h
new file mode 100644
index 000000000000..3641ca9c0400
--- /dev/null
+++ b/test/Analysis/html-diags-analyze-headers.h
@@ -0,0 +1,5 @@
+#include "html-diags-multifile.h"
+
+void test_call_macro() {
+ has_bug(0);
+}
diff --git a/test/Analysis/html-diags-multifile.c b/test/Analysis/html-diags-multifile.c
index ce1f72b6bb1a..ff7b625ad083 100644
--- a/test/Analysis/html-diags-multifile.c
+++ b/test/Analysis/html-diags-multifile.c
@@ -1,10 +1,9 @@
// RUN: mkdir -p %t.dir
// RUN: %clang_analyze_cc1 -analyzer-output=html -analyzer-checker=core -o %t.dir %s
-// RUN: ls %t.dir | not grep report
+// RUN: ls %t.dir | grep report
// RUN: rm -fR %t.dir
-// This tests that we do not currently emit HTML diagnostics for reports that
-// cross file boundaries.
+// This tests that we emit HTML diagnostics for reports that cross file boundaries.
#include "html-diags-multifile.h"
diff --git a/test/Analysis/html-diags.c b/test/Analysis/html-diags.c
index 182bcfbdfa12..89f1e8ba7930 100644
--- a/test/Analysis/html-diags.c
+++ b/test/Analysis/html-diags.c
@@ -1,12 +1,18 @@
-// RUN: rm -fR %T/dir
-// RUN: mkdir %T/dir
-// RUN: %clang_analyze_cc1 -analyzer-output=html -analyzer-checker=core -o %T/dir %s
-// RUN: ls %T/dir | grep report
+// RUN: rm -fR %t
+// RUN: mkdir %t
+// RUN: %clang_analyze_cc1 -analyzer-output=html -analyzer-checker=core -o %t %s
+// RUN: ls %t | grep report
+
+// D30406: Test new html-single-file output
+// RUN: rm -fR %t
+// RUN: mkdir %t
+// RUN: %clang_analyze_cc1 -analyzer-output=html-single-file -analyzer-checker=core -o %t %s
+// RUN: ls %t | grep report
// PR16547: Test relative paths
-// RUN: cd %T/dir
+// RUN: cd %t
// RUN: %clang_analyze_cc1 -analyzer-output=html -analyzer-checker=core -o testrelative %s
-// RUN: ls %T/dir/testrelative | grep report
+// RUN: ls %t/testrelative | grep report
// Currently this test mainly checks that the HTML diagnostics doesn't crash
// when handling macros will calls with macros. We should actually validate
diff --git a/test/Analysis/initializer.cpp b/test/Analysis/initializer.cpp
index c73635686d83..6359b93d0a29 100644
--- a/test/Analysis/initializer.cpp
+++ b/test/Analysis/initializer.cpp
@@ -1,7 +1,9 @@
-// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config c++-inlining=constructors -std=c++11 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,cplusplus.NewDeleteLeaks,debug.ExprInspection -analyzer-config c++-inlining=constructors -std=c++11 -verify %s
void clang_analyzer_eval(bool);
+#include "Inputs/system-header-simulator-cxx.h"
+
class A {
int x;
public:
@@ -204,3 +206,21 @@ struct C {
const char(&f)[2];
};
}
+
+namespace CXX_initializer_lists {
+struct C {
+ C(std::initializer_list<int *> list);
+};
+void testPointerEscapeIntoLists() {
+ C empty{}; // no-crash
+
+ // Do not warn that 'x' leaks. It might have been deleted by
+ // the destructor of 'c'.
+ int *x = new int;
+ C c{x}; // no-warning
+}
+
+void testPassListsWithExplicitConstructors() {
+ (void)(std::initializer_list<int>){12}; // no-crash
+}
+}
diff --git a/test/Analysis/inlining/inline-defensive-checks.c b/test/Analysis/inlining/inline-defensive-checks.c
index 010d3a774756..9f211b502bc0 100644
--- a/test/Analysis/inlining/inline-defensive-checks.c
+++ b/test/Analysis/inlining/inline-defensive-checks.c
@@ -169,6 +169,18 @@ void idcTrackZeroValueThroughUnaryPointerOperatorsWithAssignment(struct S *s) {
*x = 7; // no-warning
}
+void idcTrackZeroValueThroughManyUnaryPointerOperatorsWithAssignment(struct S *s) {
+ idc(s);
+ int *x = &*&(s->f1);
+ *x = 7; // no-warning
+}
+
+void idcTrackZeroValueThroughManyUnaryPointerOperatorsWithAssignmentAndUnaryIncrement(struct S *s) {
+ idc(s);
+ int *x = &*&((++s)->f1);
+ *x = 7; // no-warning
+}
+
struct S2 {
int a[1];
diff --git a/test/Analysis/lambdas.cpp b/test/Analysis/lambdas.cpp
index f3ff9b953938..38a2e3a84fb1 100644
--- a/test/Analysis/lambdas.cpp
+++ b/test/Analysis/lambdas.cpp
@@ -337,6 +337,16 @@ void captureByReference() {
lambda2();
}
+void testCapturedConstExprFloat() {
+ constexpr float localConstant = 4.0;
+ auto lambda = []{
+ // Don't treat localConstant as containing a garbage value
+ float copy = localConstant; // no-warning
+ (void)copy;
+ };
+
+ lambda();
+}
// CHECK: [B2 (ENTRY)]
// CHECK: Succs (1): B1
diff --git a/test/Analysis/loop-unrolling.cpp b/test/Analysis/loop-unrolling.cpp
new file mode 100644
index 000000000000..844d1f18ea57
--- /dev/null
+++ b/test/Analysis/loop-unrolling.cpp
@@ -0,0 +1,381 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -analyzer-config unroll-loops=true,cfg-loopexit=true -verify -std=c++11 %s
+
+void clang_analyzer_numTimesReached();
+void clang_analyzer_warnIfReached();
+
+int getNum();
+void foo(int &);
+
+int simple_unroll1() {
+ int a[9];
+ int k = 42;
+ for (int i = 0; i < 9; i++) {
+ clang_analyzer_numTimesReached(); // expected-warning {{9}}
+ a[i] = 42;
+ }
+ int b = 22 / (k - 42); // expected-warning {{Division by zero}}
+ return 0;
+}
+
+int simple_unroll2() {
+ int a[9];
+ int k = 42;
+ int i;
+ for (i = 0; i < 9; i++) {
+ clang_analyzer_numTimesReached(); // expected-warning {{9}}
+ a[i] = 42;
+ }
+
+ for (int j = 0; j <= 9; ++j) {
+ clang_analyzer_numTimesReached(); // expected-warning {{10}}
+ a[j] = 42;
+ }
+
+ int b = 22 / (k - 42); // expected-warning {{Division by zero}}
+ return 0;
+}
+
+int simple_no_unroll1() {
+ int a[9];
+ int k = 42;
+ for (int i = 0; i < 9; i++) {
+ clang_analyzer_numTimesReached(); // expected-warning {{4}}
+ a[i] = 42;
+ foo(i);
+ }
+ int b = 22 / (k - 42); // expected-warning {{Division by zero}}
+ return 0;
+}
+
+int simple_no_unroll2() {
+ int a[9];
+ int k = 42;
+ int i;
+ for (i = 0; i < 9; i++) {
+ clang_analyzer_numTimesReached(); // expected-warning {{4}}
+ a[i] = 42;
+ i += getNum();
+ }
+ int b = 22 / (k - 42); // expected-warning {{Division by zero}}
+ return 0;
+}
+
+int simple_no_unroll3() {
+ int a[9];
+ int k = 42;
+ for (int i = 0; i < 9; i++) {
+ clang_analyzer_numTimesReached(); // expected-warning {{4}}
+ a[i] = 42;
+ (void)&i;
+ }
+ int b = 22 / (k - 42); // no-warning
+ return 0;
+}
+
+int simple_no_unroll4() {
+ int a[9];
+ int k = 42;
+ int i;
+ for (i = 0; i < 9; i++) {
+ clang_analyzer_numTimesReached(); // expected-warning {{4}}
+ a[i] = 42;
+ int &j = i;
+ }
+ int b = 22 / (k - 42); // no-warning
+ return 0;
+}
+
+int simple_no_unroll5() {
+ int a[9];
+ int k = 42;
+ int i;
+ for (i = 0; i < 9; i++) {
+ clang_analyzer_numTimesReached(); // expected-warning {{4}}
+ a[i] = 42;
+ int &j{i};
+ }
+ int b = 22 / (k - 42); // no-warning
+ return 0;
+}
+
+int make_new_branches_loop_cached() {
+ for (int i = 0; i < 8; i++) {
+ clang_analyzer_numTimesReached(); // expected-warning {{4}}
+ if(getNum()){
+ (void) i; // Since this Stmt does not change the State the analyzer
+ // won't make a new execution path but reuse the earlier nodes.
+ }
+ }
+ clang_analyzer_warnIfReached(); // no-warning
+ return 0;
+}
+
+int make_new_branches_loop_uncached() {
+ int l = 2;
+ for (int i = 0; i < 8; i++) {
+ clang_analyzer_numTimesReached(); // expected-warning {{10}}
+ if(getNum()){
+ ++l;
+ }
+ }
+ clang_analyzer_warnIfReached(); // no-warning
+ return 0;
+}
+
+int make_new_branches_loop_uncached2() {
+ int l = 2;
+ for (int i = 0; i < 8; i++) {
+ clang_analyzer_numTimesReached(); // expected-warning {{10}}
+ if(getNum()){
+ ++l;
+ }
+ (void)&i; // This ensures that the loop won't be unrolled.
+ }
+ clang_analyzer_warnIfReached(); // no-warning
+ return 0;
+}
+
+
+int escape_before_loop_no_unroll1() {
+ int a[9];
+ int k = 42;
+ int i;
+ int &j = i;
+ for (i = 0; i < 9; i++) {
+ clang_analyzer_numTimesReached(); // expected-warning {{4}}
+ a[i] = 42;
+ }
+ int b = 22 / (k - 42); // no-warning
+ return 0;
+}
+
+int escape_before_loop_no_unroll2() {
+ int a[9];
+ int k = 42;
+ int i;
+ int *p = &i;
+ for (i = 0; i < 9; i++) {
+ clang_analyzer_numTimesReached(); // expected-warning {{4}}
+ a[i] = 42;
+ }
+ int b = 22 / (k - 42); // no-warning
+ return 0;
+}
+
+int escape_before_loop_no_unroll3() {
+ int a[9];
+ int k = 42;
+ int i;
+ foo(i);
+ for (i = 0; i < 9; i++) {
+ clang_analyzer_numTimesReached(); // expected-warning {{4}}
+ a[i] = 42;
+ }
+ int b = 22 / (k - 42); // no-warning
+ return 0;
+}
+
+int nested_outer_unrolled() {
+ int a[9];
+ int k = 42;
+ int j = 0;
+ for (int i = 0; i < 9; i++) {
+ clang_analyzer_numTimesReached(); // expected-warning {{1}}
+ for (j = 0; j < 9; ++j) {
+ clang_analyzer_numTimesReached(); // expected-warning {{4}}
+ a[j] = 22;
+ (void) &j; // ensures that the inner loop won't be unrolled
+ }
+ a[i] = 42;
+ }
+ int b = 22 / (k - 42); // no-warning
+ return 0;
+}
+
+int nested_inner_unrolled() {
+ int a[9];
+ int k = 42;
+ int j = 0;
+ for (int i = 0; i < getNum(); i++) {
+ clang_analyzer_numTimesReached(); // expected-warning {{4}}
+ for (j = 0; j < 8; ++j) {
+ clang_analyzer_numTimesReached(); // expected-warning {{32}}
+ a[j] = 22;
+ }
+ a[i] = 42;
+ }
+ int b = 22 / (k - 42); // expected-warning {{Division by zero}}
+ return 0;
+}
+
+int nested_both_unrolled() {
+ int a[9];
+ int k = 42;
+ int j = 0;
+ for (int i = 0; i < 7; i++) {
+ clang_analyzer_numTimesReached(); // expected-warning {{7}}
+ for (j = 0; j < 6; ++j) {
+ clang_analyzer_numTimesReached(); // expected-warning {{42}}
+ a[j] = 22;
+ }
+ a[i] = 42;
+ }
+ int b = 22 / (k - 42); // expected-warning {{Division by zero}}
+ return 0;
+}
+
+int simple_known_bound_loop() {
+ for (int i = 2; i < 12; i++) {
+ // This function is inlined in nested_inlined_unroll1()
+ clang_analyzer_numTimesReached(); // expected-warning {{90}}
+ }
+ return 0;
+}
+
+int simple_unknown_bound_loop() {
+ for (int i = 2; i < getNum(); i++) {
+ clang_analyzer_numTimesReached(); // expected-warning {{10}}
+ }
+ return 0;
+}
+
+int nested_inlined_unroll1() {
+ int k;
+ for (int i = 0; i < 9; i++) {
+ clang_analyzer_numTimesReached(); // expected-warning {{9}}
+ k = simple_known_bound_loop(); // no reevaluation without inlining
+ }
+ int a = 22 / k; // expected-warning {{Division by zero}}
+ return 0;
+}
+
+int nested_inlined_no_unroll1() {
+ int k;
+ for (int i = 0; i < 9; i++) {
+ clang_analyzer_numTimesReached(); // expected-warning {{15}}
+ k = simple_unknown_bound_loop(); // reevaluation without inlining, splits the state as well
+ }
+ int a = 22 / k; // no-warning
+ return 0;
+}
+
+int recursion_unroll1(bool b) {
+ int k = 2;
+ for (int i = 0; i < 5; i++) {
+ clang_analyzer_numTimesReached(); // expected-warning {{13}}
+ if(i == 0 && b) // Splits the state in the first iteration but the recursion
+ // call will be unrolled anyway since the condition is known there.
+ recursion_unroll1(false);
+ clang_analyzer_numTimesReached(); // expected-warning {{14}}
+ }
+ int a = 22 / k; // no-warning
+ return 0;
+}
+
+int recursion_unroll2(bool b) {
+ int k = 0;
+ for (int i = 0; i < 5; i++) {
+ clang_analyzer_numTimesReached(); // expected-warning {{9}}
+ if(i == 0 && b)
+ recursion_unroll2(false);
+ clang_analyzer_numTimesReached(); // expected-warning {{9}}
+ }
+ int a = 22 / k; // expected-warning {{Division by zero}}
+ return 0;
+}
+
+int recursion_unroll3(bool b) {
+ int k = 2;
+ for (int i = 0; i < 5; i++) {
+ clang_analyzer_numTimesReached(); // expected-warning {{10}}
+ if (i == 4 && b) {
+ recursion_unroll3(false);
+ break;
+ }
+ clang_analyzer_numTimesReached(); // expected-warning {{10}}
+ }
+ int a = 22 / k;
+ return 0;
+}
+
+int recursion_unroll4(bool b) {
+ int k = 2;
+ for (int i = 0; i < 5; i++) {
+ clang_analyzer_numTimesReached(); // expected-warning {{13}}
+ if(i == 0 && b) {
+ recursion_unroll4(false);
+ continue;
+ }
+ clang_analyzer_numTimesReached(); // expected-warning {{13}}
+ }
+ int a = 22 / k;
+ return 0;
+}
+
+int loop_exit_while_empty_loop_stack() {
+ if (getNum())
+ for (int i = 1; i < 8; i++)
+ ;
+ return 0;
+}
+
+int num_steps_on_limit() {
+ for (int i = 0; i < 128; i++) {
+ clang_analyzer_numTimesReached(); // expected-warning {{128}}
+ }
+ clang_analyzer_numTimesReached(); // expected-warning {{1}}
+ return 0;
+}
+
+int num_steps_over_limit1() {
+ for (int i = 0; i < 129; i++) {
+ clang_analyzer_numTimesReached(); // expected-warning {{4}}
+ }
+ return 0;
+}
+
+int num_steps_on_limit2() {
+ for (int i = 0; i < 2; i++) {
+ for (int j = 0; j < 64; j++) {
+ clang_analyzer_numTimesReached(); // expected-warning {{128}}
+ }
+ }
+ return 0;
+}
+
+int num_steps_over_limit2() {
+ for (int i = 0; i < 2; i++) {
+ clang_analyzer_numTimesReached(); // expected-warning {{1}}
+ for (int j = 0; j <= 64; j++) {
+ clang_analyzer_numTimesReached(); // expected-warning {{4}}
+ }
+ }
+ return 0;
+}
+
+int num_steps_on_limit3() {
+ for (int i = 0; i < getNum(); i++) {
+ clang_analyzer_numTimesReached(); // expected-warning {{4}}
+ for (int j = 0; j < 32; j++) {
+ clang_analyzer_numTimesReached(); // expected-warning {{128}}
+ }
+ }
+ return 0;
+}
+
+int num_steps_over_limit3() {
+ for (int i = 0; i < getNum(); i++) {
+ clang_analyzer_numTimesReached(); // expected-warning {{1}}
+ for (int j = 0; j < 33; j++) {
+ clang_analyzer_numTimesReached(); // expected-warning {{4}}
+ }
+ }
+ return 0;
+}
+
+
+void pr34943() {
+ for (int i = 0; i < 6L; ++i) {
+ clang_analyzer_numTimesReached(); // expected-warning {{6}}
+ }
+}
diff --git a/test/Analysis/loop-widening-notes.cpp b/test/Analysis/loop-widening-notes.cpp
new file mode 100644
index 000000000000..56bde7416af5
--- /dev/null
+++ b/test/Analysis/loop-widening-notes.cpp
@@ -0,0 +1,72 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha -analyzer-max-loop 2 -analyzer-config widen-loops=true -analyzer-output=text -verify %s
+
+int *p_a;
+int bar();
+int flag_a;
+int test_for_bug_25609() {
+ if (p_a == 0) // expected-note {{Assuming 'p_a' is equal to null}}
+ // expected-note@-1 {{Taking true branch}}
+ bar();
+ for (int i = 0; // expected-note {{Loop condition is true. Entering loop body}}
+ // expected-note@-1 {{Loop condition is false. Execution continues on line 16}}
+ ++i, // expected-note {{Value assigned to 'p_a'}}
+ i < flag_a;
+ ++i) {}
+
+ *p_a = 25609; // no-crash expected-warning {{Dereference of null pointer (loaded from variable 'p_a')}}
+ // expected-note@-1 {{Dereference of null pointer (loaded from variable 'p_a')}}
+ return *p_a;
+}
+
+int flag_b;
+int while_analyzer_output() {
+ flag_b = 100;
+ int num = 10;
+ while (flag_b-- > 0) { // expected-note {{Loop condition is true. Entering loop body}}
+ // expected-note@-1 {{Value assigned to 'num'}}
+ // expected-note@-2 {{Loop condition is false. Execution continues on line 30}}
+ num = flag_b;
+ }
+ if (num < 0) // expected-note {{Assuming 'num' is >= 0}}
+ // expected-note@-1 {{Taking false branch}}
+ flag_b = 0;
+ else if (num >= 1) // expected-note {{Assuming 'num' is < 1}}
+ // expected-note@-1 {{Taking false branch}}
+ flag_b = 50;
+ else
+ flag_b = 100;
+ return flag_b / num; // no-crash expected-warning {{Division by zero}}
+ // expected-note@-1 {{Division by zero}}
+}
+
+int flag_c;
+int do_while_analyzer_output() {
+ int num = 10;
+ do { // expected-note {{Loop condition is true. Execution continues on line 47}}
+ // expected-note@-1 {{Loop condition is false. Exiting loop}}
+ num--;
+ } while (flag_c-- > 0); //expected-note {{Value assigned to 'num'}}
+ int local = 0;
+ if (num == 0) // expected-note {{Assuming 'num' is equal to 0}}
+ // expected-note@-1 {{Taking true branch}}
+ local = 10 / num; // no-crash expected-warning {{Division by zero}}
+ // expected-note@-1 {{Division by zero}}
+ return local;
+}
+
+int flag_d;
+int test_for_loop() {
+ int num = 10;
+ for (int i = 0; // expected-note {{Loop condition is true. Entering loop body}}
+ // expected-note@-1 {{Loop condition is false. Execution continues on line 67}}
+ new int(10), // expected-note {{Value assigned to 'num'}}
+ i < flag_d;
+ ++i) {
+ ++num;
+ }
+ if (num == 0) // expected-note {{Assuming 'num' is equal to 0}}
+ // expected-note@-1 {{Taking true branch}}
+ flag_d += 10;
+ return flag_d / num; // no-crash expected-warning {{Division by zero}}
+ // expected-note@-1 {{Division by zero}}
+}
diff --git a/test/Analysis/loopexit-cfg-output.cpp b/test/Analysis/loopexit-cfg-output.cpp
new file mode 100644
index 000000000000..8e53ce3066b7
--- /dev/null
+++ b/test/Analysis/loopexit-cfg-output.cpp
@@ -0,0 +1,476 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=debug.DumpCFG -analyzer-config cfg-loopexit=true %s > %t 2>&1
+// RUN: FileCheck --input-file=%t %s
+
+// CHECK: [B6 (ENTRY)]
+// CHECK-NEXT: Succs (1): B5
+
+// CHECK: [B1]
+// CHECK-NEXT: 1: ForStmt (LoopExit)
+// CHECK-NEXT: 2: return;
+// CHECK-NEXT: Preds (1): B4
+// CHECK-NEXT: Succs (1): B0
+
+// CHECK: [B2]
+// CHECK-NEXT: 1: i
+// CHECK-NEXT: 2: [B2.1]++
+// CHECK-NEXT: Preds (1): B3
+// CHECK-NEXT: Succs (1): B4
+
+// CHECK: [B3]
+// CHECK-NEXT: 1: i
+// CHECK-NEXT: 2: [B3.1]++
+// CHECK-NEXT: Preds (1): B4
+// CHECK-NEXT: Succs (1): B2
+
+// CHECK: [B4]
+// CHECK-NEXT: 1: i
+// CHECK-NEXT: 2: [B4.1] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT: 3: 12
+// CHECK-NEXT: 4: [B4.2] < [B4.3]
+// CHECK-NEXT: T: for (...; [B4.4]; ...)
+// CHECK-NEXT: Preds (2): B2 B5
+// CHECK-NEXT: Succs (2): B3 B1
+
+// CHECK: [B5]
+// CHECK-NEXT: 1: 0
+// CHECK-NEXT: 2: int i = 0;
+// CHECK-NEXT: Preds (1): B6
+// CHECK-NEXT: Succs (1): B4
+
+// CHECK: [B0 (EXIT)]
+// CHECK-NEXT: Preds (1): B1
+void check_forloop1() {
+ for (int i = 0; i < 12; i++) {
+ i++;
+ }
+ return;
+}
+
+// CHECK: [B4 (ENTRY)]
+// CHECK-NEXT: Succs (1): B3
+
+// CHECK: [B1]
+// CHECK-NEXT: 1: ForStmt (LoopExit)
+// CHECK-NEXT: Succs (1): B0
+
+// CHECK: [B2]
+// CHECK-NEXT: Preds (1): B3
+// CHECK-NEXT: Succs (1): B3
+
+// CHECK: [B3]
+// CHECK-NEXT: T: for (; ; )
+// CHECK-NEXT: Preds (2): B2 B4
+// CHECK-NEXT: Succs (2): B2 NULL
+
+// CHECK: [B0 (EXIT)]
+// CHECK-NEXT: Preds (1): B1
+void check_forloop2() {
+ for (;;)
+ ;
+}
+
+// CHECK: [B5 (ENTRY)]
+// CHECK-NEXT: Succs (1): B4
+
+// CHECK: [B1]
+// CHECK-NEXT: 1: WhileStmt (LoopExit)
+// CHECK-NEXT: Succs (1): B0
+
+// CHECK: [B2]
+// CHECK-NEXT: Preds (1): B3
+// CHECK-NEXT: Succs (1): B4
+
+// CHECK: [B3]
+// CHECK-NEXT: 1: int i;
+// CHECK-NEXT: Preds (1): B4
+// CHECK-NEXT: Succs (1): B2
+
+// CHECK: [B4]
+// CHECK-NEXT: 1: true
+// CHECK-NEXT: T: while [B4.1]
+// CHECK-NEXT: Preds (2): B2 B5
+// CHECK-NEXT: Succs (2): B3 NULL
+
+// CHECK: [B0 (EXIT)]
+// CHECK-NEXT: Preds (1): B1
+void check_while1() {
+ while (true) {
+ int i;
+ }
+}
+
+// CHECK: [B5 (ENTRY)]
+// CHECK-NEXT: Succs (1): B4
+
+// CHECK: [B1]
+// CHECK-NEXT: 1: WhileStmt (LoopExit)
+// CHECK-NEXT: 2: 2
+// CHECK-NEXT: 3: int k = 2;
+// CHECK-NEXT: 4: return;
+// CHECK-NEXT: Preds (1): B3
+// CHECK-NEXT: Succs (1): B0
+
+// CHECK: [B2]
+// CHECK-NEXT: Preds (1): B3
+// CHECK-NEXT: Succs (1): B3
+
+// CHECK: [B3]
+// CHECK-NEXT: 1: l
+// CHECK-NEXT: 2: [B3.1] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT: 3: 42
+// CHECK-NEXT: 4: [B3.2] < [B3.3]
+// CHECK-NEXT: T: while [B3.4]
+// CHECK-NEXT: Preds (2): B2 B4
+// CHECK-NEXT: Succs (2): B2 B1
+
+// CHECK: [B4]
+// CHECK-NEXT: 1: int l;
+// CHECK-NEXT: Preds (1): B5
+// CHECK-NEXT: Succs (1): B3
+
+// CHECK: [B0 (EXIT)]
+// CHECK-NEXT: Preds (1): B1
+void check_while2() {
+ int l;
+ while (l < 42)
+ ;
+ int k = 2;
+ return;
+}
+
+// CHECK: [B4 (ENTRY)]
+// CHECK-NEXT: Succs (1): B3
+
+// CHECK: [B1]
+// CHECK-NEXT: 1: WhileStmt (LoopExit)
+// CHECK-NEXT: Preds (1): B3
+// CHECK-NEXT: Succs (1): B0
+
+// CHECK: [B2]
+// CHECK-NEXT: Succs (1): B3
+
+// CHECK: [B3]
+// CHECK-NEXT: 1: false
+// CHECK-NEXT: T: while [B3.1]
+// CHECK-NEXT: Preds (2): B2 B4
+// CHECK-NEXT: Succs (2): NULL B1
+
+// CHECK: [B0 (EXIT)]
+// CHECK-NEXT: Preds (1): B1
+void check_while3() {
+ while (false) {
+ ;
+ }
+}
+
+// CHECK: [B4 (ENTRY)]
+// CHECK-NEXT: Succs (1): B2
+
+// CHECK: [B1]
+// CHECK-NEXT: 1: DoStmt (LoopExit)
+// CHECK-NEXT: Preds (1): B2
+// CHECK-NEXT: Succs (1): B0
+
+// CHECK: [B2]
+// CHECK-NEXT: 1: false
+// CHECK-NEXT: T: do ... while [B2.1]
+// CHECK-NEXT: Preds (2): B3 B4
+// CHECK-NEXT: Succs (2): NULL B1
+
+// CHECK: [B3]
+// CHECK-NEXT: Succs (1): B2
+
+// CHECK: [B0 (EXIT)]
+// CHECK-NEXT: Preds (1): B1
+void check_dowhile1() {
+ do {
+ } while (false);
+}
+
+// CHECK: [B6 (ENTRY)]
+// CHECK-NEXT: Succs (1): B5
+
+// CHECK: [B1]
+// CHECK-NEXT: 1: DoStmt (LoopExit)
+// CHECK-NEXT: 2: j
+// CHECK-NEXT: 3: [B1.2]--
+// CHECK-NEXT: 4: return;
+// CHECK-NEXT: Preds (1): B2
+// CHECK-NEXT: Succs (1): B0
+
+// CHECK: [B2]
+// CHECK-NEXT: 1: j
+// CHECK-NEXT: 2: [B2.1] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT: 3: 20
+// CHECK-NEXT: 4: [B2.2] < [B2.3]
+// CHECK-NEXT: T: do ... while [B2.4]
+// CHECK-NEXT: Preds (1): B3
+// CHECK-NEXT: Succs (2): B4 B1
+
+// CHECK: [B3]
+// CHECK-NEXT: 1: j
+// CHECK-NEXT: 2: 2
+// CHECK-NEXT: 3: [B3.1] += [B3.2]
+// CHECK-NEXT: Preds (2): B4 B5
+// CHECK-NEXT: Succs (1): B2
+
+// CHECK: [B4]
+// CHECK-NEXT: Preds (1): B2
+// CHECK-NEXT: Succs (1): B3
+
+// CHECK: [B5]
+// CHECK-NEXT: 1: 2
+// CHECK-NEXT: 2: int j = 2;
+// CHECK-NEXT: Preds (1): B6
+// CHECK-NEXT: Succs (1): B3
+
+// CHECK: [B0 (EXIT)]
+// CHECK-NEXT: Preds (1): B1
+void check_dowhile2() {
+ int j = 2;
+ do {
+ j += 2;
+ } while (j < 20);
+ j--;
+ return;
+}
+
+// CHECK: [B10 (ENTRY)]
+// CHECK-NEXT: Succs (1): B9
+
+// CHECK: [B1]
+// CHECK-NEXT: 1: WhileStmt (LoopExit)
+// CHECK-NEXT: Preds (1): B8
+// CHECK-NEXT: Succs (1): B0
+
+// CHECK: [B2]
+// CHECK-NEXT: Preds (1): B3
+// CHECK-NEXT: Succs (1): B8
+
+// CHECK: [B3]
+// CHECK-NEXT: 1: ForStmt (LoopExit)
+// CHECK-NEXT: Preds (1): B6
+// CHECK-NEXT: Succs (1): B2
+
+// CHECK: [B4]
+// CHECK-NEXT: 1: j
+// CHECK-NEXT: 2: [B4.1]++
+// CHECK-NEXT: Preds (1): B5
+// CHECK-NEXT: Succs (1): B6
+
+// CHECK: [B5]
+// CHECK-NEXT: 1: i
+// CHECK-NEXT: 2: [B5.1]++
+// CHECK-NEXT: Preds (1): B6
+// CHECK-NEXT: Succs (1): B4
+
+// CHECK: [B6]
+// CHECK-NEXT: 1: j
+// CHECK-NEXT: 2: [B6.1] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT: 3: 6
+// CHECK-NEXT: 4: [B6.2] < [B6.3]
+// CHECK-NEXT: T: for (...; [B6.4]; ...)
+// CHECK-NEXT: Preds (2): B4 B7
+// CHECK-NEXT: Succs (2): B5 B3
+
+// CHECK: [B7]
+// CHECK-NEXT: 1: 1
+// CHECK-NEXT: 2: int j = 1;
+// CHECK-NEXT: Preds (1): B8
+// CHECK-NEXT: Succs (1): B6
+
+// CHECK: [B8]
+// CHECK-NEXT: 1: i
+// CHECK-NEXT: 2: [B8.1] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT: 3: 2
+// CHECK-NEXT: 4: [B8.2] < [B8.3]
+// CHECK-NEXT: T: while [B8.4]
+// CHECK-NEXT: Preds (2): B2 B9
+// CHECK-NEXT: Succs (2): B7 B1
+
+// CHECK: [B9]
+// CHECK-NEXT: 1: 40
+// CHECK-NEXT: 2: -[B9.1]
+// CHECK-NEXT: 3: int i = -40;
+// CHECK-NEXT: Preds (1): B10
+// CHECK-NEXT: Succs (1): B8
+
+// CHECK: [B0 (EXIT)]
+// CHECK-NEXT: Preds (1): B1
+void nested_loops1() {
+ int i = -40;
+ while (i < 2) {
+ for (int j = 1; j < 6; j++)
+ i++;
+ }
+}
+
+// CHECK: [B9 (ENTRY)]
+// CHECK-NEXT: Succs (1): B8
+
+// CHECK: [B1]
+// CHECK-NEXT: 1: ForStmt (LoopExit)
+// CHECK-NEXT: Preds (1): B7
+// CHECK-NEXT: Succs (1): B0
+
+// CHECK: [B2]
+// CHECK-NEXT: 1: j
+// CHECK-NEXT: 2: [B2.1]++
+// CHECK-NEXT: Preds (1): B3
+// CHECK-NEXT: Succs (1): B7
+
+// CHECK: [B3]
+// CHECK-NEXT: 1: DoStmt (LoopExit)
+// CHECK-NEXT: 2: i
+// CHECK-NEXT: 3: [B3.2]--
+// CHECK-NEXT: Preds (1): B4
+// CHECK-NEXT: Succs (1): B2
+
+// CHECK: [B4]
+// CHECK-NEXT: 1: i
+// CHECK-NEXT: 2: [B4.1] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT: 3: 2
+// CHECK-NEXT: 4: [B4.2] < [B4.3]
+// CHECK-NEXT: T: do ... while [B4.4]
+// CHECK-NEXT: Preds (1): B5
+// CHECK-NEXT: Succs (2): B6 B3
+
+// CHECK: [B5]
+// CHECK-NEXT: 1: i
+// CHECK-NEXT: 2: [B5.1]++
+// CHECK-NEXT: Preds (2): B6 B7
+// CHECK-NEXT: Succs (1): B4
+
+// CHECK: [B6]
+// CHECK-NEXT: Preds (1): B4
+// CHECK-NEXT: Succs (1): B5
+
+// CHECK: [B7]
+// CHECK-NEXT: 1: j
+// CHECK-NEXT: 2: [B7.1] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT: 3: 6
+// CHECK-NEXT: 4: [B7.2] < [B7.3]
+// CHECK-NEXT: T: for (...; [B7.4]; ...)
+// CHECK-NEXT: Preds (2): B2 B8
+// CHECK-NEXT: Succs (2): B5 B1
+
+// CHECK: [B8]
+// CHECK-NEXT: 1: 40
+// CHECK-NEXT: 2: -[B8.1]
+// CHECK-NEXT: 3: int i = -40;
+// CHECK-NEXT: 4: 1
+// CHECK-NEXT: 5: int j = 1;
+// CHECK-NEXT: Preds (1): B9
+// CHECK-NEXT: Succs (1): B7
+
+// CHECK: [B0 (EXIT)]
+// CHECK-NEXT: Preds (1): B1
+void nested_loops2() {
+ int i = -40;
+ for (int j = 1; j < 6; j++) {
+ do {
+ i++;
+ } while (i < 2);
+ i--;
+ }
+}
+
+// CHECK: [B12 (ENTRY)]
+// CHECK-NEXT: Succs (1): B11
+
+// CHECK: [B1]
+// CHECK-NEXT: 1: WhileStmt (LoopExit)
+// CHECK-NEXT: 2: return;
+// CHECK-NEXT: Preds (2): B3 B5
+// CHECK-NEXT: Succs (1): B0
+
+// CHECK: [B2]
+// CHECK-NEXT: Preds (1): B4
+// CHECK-NEXT: Succs (1): B5
+
+// CHECK: [B3]
+// CHECK-NEXT: T: break;
+// CHECK-NEXT: Preds (1): B4
+// CHECK-NEXT: Succs (1): B1
+
+// CHECK: [B4]
+// CHECK-NEXT: 1: i
+// CHECK-NEXT: 2: [B4.1]++
+// CHECK-NEXT: 3: i
+// CHECK-NEXT: 4: [B4.3] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT: 5: 2
+// CHECK-NEXT: 6: [B4.4] % [B4.5]
+// CHECK-NEXT: 7: [B4.6] (ImplicitCastExpr, IntegralToBoolean, _Bool)
+// CHECK-NEXT: T: if [B4.7]
+// CHECK-NEXT: Preds (1): B5
+// CHECK-NEXT: Succs (2): B3 B2
+
+// CHECK: [B5]
+// CHECK-NEXT: 1: i
+// CHECK-NEXT: 2: [B5.1] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT: 3: 5
+// CHECK-NEXT: 4: [B5.2] < [B5.3]
+// CHECK-NEXT: T: while [B5.4]
+// CHECK-NEXT: Preds (2): B2 B6
+// CHECK-NEXT: Succs (2): B4 B1
+
+// CHECK: [B6]
+// CHECK-NEXT: 1: ForStmt (LoopExit)
+// CHECK-NEXT: 2: 1
+// CHECK-NEXT: 3: int i = 1;
+// CHECK-NEXT: Preds (2): B8 B10
+// CHECK-NEXT: Succs (1): B5
+
+// CHECK: [B7]
+// CHECK-NEXT: 1: i
+// CHECK-NEXT: 2: [B7.1]++
+// CHECK-NEXT: Preds (1): B9
+// CHECK-NEXT: Succs (1): B10
+
+// CHECK: [B8]
+// CHECK-NEXT: T: break;
+// CHECK-NEXT: Preds (1): B9
+// CHECK-NEXT: Succs (1): B6
+
+// CHECK: [B9]
+// CHECK-NEXT: 1: i
+// CHECK-NEXT: 2: [B9.1] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT: 3: 4
+// CHECK-NEXT: 4: [B9.2] == [B9.3]
+// CHECK-NEXT: T: if [B9.4]
+// CHECK-NEXT: Preds (1): B10
+// CHECK-NEXT: Succs (2): B8 B7
+
+// CHECK: [B10]
+// CHECK-NEXT: 1: i
+// CHECK-NEXT: 2: [B10.1] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT: 3: 6
+// CHECK-NEXT: 4: [B10.2] < [B10.3]
+// CHECK-NEXT: T: for (...; [B10.4]; ...)
+// CHECK-NEXT: Preds (2): B7 B11
+// CHECK-NEXT: Succs (2): B9 B6
+
+// CHECK: [B11]
+// CHECK-NEXT: 1: 2
+// CHECK-NEXT: 2: int i = 2;
+// CHECK-NEXT: Preds (1): B12
+// CHECK-NEXT: Succs (1): B10
+
+// CHECK: [B0 (EXIT)]
+// CHECK-NEXT: Preds (1): B1
+void check_break()
+{
+ for(int i = 2; i < 6; i++) {
+ if(i == 4)
+ break;
+ }
+
+ int i = 1;
+ while(i<5){
+ i++;
+ if(i%2)
+ break;
+ }
+
+ return;
+}
diff --git a/test/Analysis/malloc-plist.c b/test/Analysis/malloc-plist.c
index e2062e858229..513bf7766706 100644
--- a/test/Analysis/malloc-plist.c
+++ b/test/Analysis/malloc-plist.c
@@ -10,6 +10,7 @@ void *realloc(void *ptr, size_t size);
void diagnosticTest(int in) {
if (in > 5) {
int *p = malloc(12);
+ *p = 0;
(*p)++;
}
in++; // expected-warning {{leak}}
@@ -106,6 +107,7 @@ void LeakedSymbol(int in) {
int *m = 0;
int *p;
p = (int*)malloc(12);
+ *p = 0;
(*p)++;
m = p;
p = 0;
@@ -392,12 +394,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>15</integer>
+// CHECK-NEXT: <key>line</key><integer>16</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>15</integer>
+// CHECK-NEXT: <key>line</key><integer>16</integer>
// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -409,7 +411,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>15</integer>
+// CHECK-NEXT: <key>line</key><integer>16</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -431,7 +433,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>issue_hash_function_offset</key><string>2</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>15</integer>
+// CHECK-NEXT: <key>line</key><integer>16</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -447,12 +449,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>19</integer>
+// CHECK-NEXT: <key>line</key><integer>20</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>19</integer>
+// CHECK-NEXT: <key>line</key><integer>20</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -460,12 +462,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>20</integer>
+// CHECK-NEXT: <key>line</key><integer>21</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>20</integer>
+// CHECK-NEXT: <key>line</key><integer>21</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -481,12 +483,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>20</integer>
+// CHECK-NEXT: <key>line</key><integer>21</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>20</integer>
+// CHECK-NEXT: <key>line</key><integer>21</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -494,12 +496,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>20</integer>
+// CHECK-NEXT: <key>line</key><integer>21</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>20</integer>
+// CHECK-NEXT: <key>line</key><integer>21</integer>
// CHECK-NEXT: <key>col</key><integer>14</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -511,7 +513,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>20</integer>
+// CHECK-NEXT: <key>line</key><integer>21</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -519,12 +521,12 @@ void testMyMalloc() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>20</integer>
+// CHECK-NEXT: <key>line</key><integer>21</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>20</integer>
+// CHECK-NEXT: <key>line</key><integer>21</integer>
// CHECK-NEXT: <key>col</key><integer>30</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -544,12 +546,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>20</integer>
+// CHECK-NEXT: <key>line</key><integer>21</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>20</integer>
+// CHECK-NEXT: <key>line</key><integer>21</integer>
// CHECK-NEXT: <key>col</key><integer>14</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -557,12 +559,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>22</integer>
+// CHECK-NEXT: <key>line</key><integer>23</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>22</integer>
+// CHECK-NEXT: <key>line</key><integer>23</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -574,7 +576,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>22</integer>
+// CHECK-NEXT: <key>line</key><integer>23</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -596,7 +598,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>issue_hash_function_offset</key><string>2</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>22</integer>
+// CHECK-NEXT: <key>line</key><integer>23</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -612,12 +614,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>25</integer>
+// CHECK-NEXT: <key>line</key><integer>26</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>25</integer>
+// CHECK-NEXT: <key>line</key><integer>26</integer>
// CHECK-NEXT: <key>col</key><integer>8</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -625,12 +627,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>25</integer>
+// CHECK-NEXT: <key>line</key><integer>26</integer>
// CHECK-NEXT: <key>col</key><integer>18</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>25</integer>
+// CHECK-NEXT: <key>line</key><integer>26</integer>
// CHECK-NEXT: <key>col</key><integer>23</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -642,7 +644,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>25</integer>
+// CHECK-NEXT: <key>line</key><integer>26</integer>
// CHECK-NEXT: <key>col</key><integer>18</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -650,12 +652,12 @@ void testMyMalloc() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>25</integer>
+// CHECK-NEXT: <key>line</key><integer>26</integer>
// CHECK-NEXT: <key>col</key><integer>18</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>25</integer>
+// CHECK-NEXT: <key>line</key><integer>26</integer>
// CHECK-NEXT: <key>col</key><integer>28</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -675,12 +677,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>25</integer>
+// CHECK-NEXT: <key>line</key><integer>26</integer>
// CHECK-NEXT: <key>col</key><integer>18</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>25</integer>
+// CHECK-NEXT: <key>line</key><integer>26</integer>
// CHECK-NEXT: <key>col</key><integer>23</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -688,12 +690,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
+// CHECK-NEXT: <key>line</key><integer>28</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
+// CHECK-NEXT: <key>line</key><integer>28</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -709,12 +711,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
+// CHECK-NEXT: <key>line</key><integer>28</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
+// CHECK-NEXT: <key>line</key><integer>28</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -722,12 +724,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
+// CHECK-NEXT: <key>line</key><integer>28</integer>
// CHECK-NEXT: <key>col</key><integer>18</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
+// CHECK-NEXT: <key>line</key><integer>28</integer>
// CHECK-NEXT: <key>col</key><integer>24</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -739,7 +741,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
+// CHECK-NEXT: <key>line</key><integer>28</integer>
// CHECK-NEXT: <key>col</key><integer>18</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -747,12 +749,12 @@ void testMyMalloc() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
+// CHECK-NEXT: <key>line</key><integer>28</integer>
// CHECK-NEXT: <key>col</key><integer>18</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
+// CHECK-NEXT: <key>line</key><integer>28</integer>
// CHECK-NEXT: <key>col</key><integer>40</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -772,12 +774,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
+// CHECK-NEXT: <key>line</key><integer>28</integer>
// CHECK-NEXT: <key>col</key><integer>18</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>27</integer>
+// CHECK-NEXT: <key>line</key><integer>28</integer>
// CHECK-NEXT: <key>col</key><integer>24</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -785,12 +787,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>28</integer>
+// CHECK-NEXT: <key>line</key><integer>29</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>28</integer>
+// CHECK-NEXT: <key>line</key><integer>29</integer>
// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -806,12 +808,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>28</integer>
+// CHECK-NEXT: <key>line</key><integer>29</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>28</integer>
+// CHECK-NEXT: <key>line</key><integer>29</integer>
// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -819,12 +821,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>28</integer>
+// CHECK-NEXT: <key>line</key><integer>29</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>28</integer>
+// CHECK-NEXT: <key>line</key><integer>29</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -836,7 +838,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>28</integer>
+// CHECK-NEXT: <key>line</key><integer>29</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -844,12 +846,12 @@ void testMyMalloc() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>28</integer>
+// CHECK-NEXT: <key>line</key><integer>29</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>28</integer>
+// CHECK-NEXT: <key>line</key><integer>29</integer>
// CHECK-NEXT: <key>col</key><integer>12</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -869,12 +871,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>28</integer>
+// CHECK-NEXT: <key>line</key><integer>29</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>28</integer>
+// CHECK-NEXT: <key>line</key><integer>29</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -882,12 +884,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>28</integer>
+// CHECK-NEXT: <key>line</key><integer>29</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>28</integer>
+// CHECK-NEXT: <key>line</key><integer>29</integer>
// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -899,7 +901,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>28</integer>
+// CHECK-NEXT: <key>line</key><integer>29</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -907,12 +909,12 @@ void testMyMalloc() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>28</integer>
+// CHECK-NEXT: <key>line</key><integer>29</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>28</integer>
+// CHECK-NEXT: <key>line</key><integer>29</integer>
// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -932,12 +934,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>28</integer>
+// CHECK-NEXT: <key>line</key><integer>29</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>28</integer>
+// CHECK-NEXT: <key>line</key><integer>29</integer>
// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -945,12 +947,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>29</integer>
+// CHECK-NEXT: <key>line</key><integer>30</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>29</integer>
+// CHECK-NEXT: <key>line</key><integer>30</integer>
// CHECK-NEXT: <key>col</key><integer>14</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -962,7 +964,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>29</integer>
+// CHECK-NEXT: <key>line</key><integer>30</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -984,7 +986,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>issue_hash_function_offset</key><string>1</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>29</integer>
+// CHECK-NEXT: <key>line</key><integer>30</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1000,12 +1002,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>44</integer>
+// CHECK-NEXT: <key>line</key><integer>45</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>44</integer>
+// CHECK-NEXT: <key>line</key><integer>45</integer>
// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1013,12 +1015,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>44</integer>
+// CHECK-NEXT: <key>line</key><integer>45</integer>
// CHECK-NEXT: <key>col</key><integer>15</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>44</integer>
+// CHECK-NEXT: <key>line</key><integer>45</integer>
// CHECK-NEXT: <key>col</key><integer>21</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1030,7 +1032,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>44</integer>
+// CHECK-NEXT: <key>line</key><integer>45</integer>
// CHECK-NEXT: <key>col</key><integer>15</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1038,12 +1040,12 @@ void testMyMalloc() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>44</integer>
+// CHECK-NEXT: <key>line</key><integer>45</integer>
// CHECK-NEXT: <key>col</key><integer>15</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>44</integer>
+// CHECK-NEXT: <key>line</key><integer>45</integer>
// CHECK-NEXT: <key>col</key><integer>23</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1059,7 +1061,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>35</integer>
+// CHECK-NEXT: <key>line</key><integer>36</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1077,12 +1079,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>35</integer>
+// CHECK-NEXT: <key>line</key><integer>36</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>35</integer>
+// CHECK-NEXT: <key>line</key><integer>36</integer>
// CHECK-NEXT: <key>col</key><integer>4</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1090,12 +1092,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>36</integer>
+// CHECK-NEXT: <key>line</key><integer>37</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>36</integer>
+// CHECK-NEXT: <key>line</key><integer>37</integer>
// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1111,12 +1113,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>36</integer>
+// CHECK-NEXT: <key>line</key><integer>37</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>36</integer>
+// CHECK-NEXT: <key>line</key><integer>37</integer>
// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1124,12 +1126,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>36</integer>
+// CHECK-NEXT: <key>line</key><integer>37</integer>
// CHECK-NEXT: <key>col</key><integer>13</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>36</integer>
+// CHECK-NEXT: <key>line</key><integer>37</integer>
// CHECK-NEXT: <key>col</key><integer>18</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1141,7 +1143,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>36</integer>
+// CHECK-NEXT: <key>line</key><integer>37</integer>
// CHECK-NEXT: <key>col</key><integer>13</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1149,12 +1151,12 @@ void testMyMalloc() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>36</integer>
+// CHECK-NEXT: <key>line</key><integer>37</integer>
// CHECK-NEXT: <key>col</key><integer>13</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>36</integer>
+// CHECK-NEXT: <key>line</key><integer>37</integer>
// CHECK-NEXT: <key>col</key><integer>23</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1174,12 +1176,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>36</integer>
+// CHECK-NEXT: <key>line</key><integer>37</integer>
// CHECK-NEXT: <key>col</key><integer>13</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>36</integer>
+// CHECK-NEXT: <key>line</key><integer>37</integer>
// CHECK-NEXT: <key>col</key><integer>18</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1187,12 +1189,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>38</integer>
+// CHECK-NEXT: <key>line</key><integer>39</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>38</integer>
+// CHECK-NEXT: <key>line</key><integer>39</integer>
// CHECK-NEXT: <key>col</key><integer>4</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1208,12 +1210,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>38</integer>
+// CHECK-NEXT: <key>line</key><integer>39</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>38</integer>
+// CHECK-NEXT: <key>line</key><integer>39</integer>
// CHECK-NEXT: <key>col</key><integer>4</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1221,12 +1223,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>38</integer>
+// CHECK-NEXT: <key>line</key><integer>39</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>38</integer>
+// CHECK-NEXT: <key>line</key><integer>39</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1238,7 +1240,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>38</integer>
+// CHECK-NEXT: <key>line</key><integer>39</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1246,12 +1248,12 @@ void testMyMalloc() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>38</integer>
+// CHECK-NEXT: <key>line</key><integer>39</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>38</integer>
+// CHECK-NEXT: <key>line</key><integer>39</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1271,12 +1273,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>38</integer>
+// CHECK-NEXT: <key>line</key><integer>39</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>38</integer>
+// CHECK-NEXT: <key>line</key><integer>39</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1284,12 +1286,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>39</integer>
+// CHECK-NEXT: <key>line</key><integer>40</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>39</integer>
+// CHECK-NEXT: <key>line</key><integer>40</integer>
// CHECK-NEXT: <key>col</key><integer>10</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1301,7 +1303,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>44</integer>
+// CHECK-NEXT: <key>line</key><integer>45</integer>
// CHECK-NEXT: <key>col</key><integer>15</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1309,12 +1311,12 @@ void testMyMalloc() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>44</integer>
+// CHECK-NEXT: <key>line</key><integer>45</integer>
// CHECK-NEXT: <key>col</key><integer>15</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>44</integer>
+// CHECK-NEXT: <key>line</key><integer>45</integer>
// CHECK-NEXT: <key>col</key><integer>23</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1334,12 +1336,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>44</integer>
+// CHECK-NEXT: <key>line</key><integer>45</integer>
// CHECK-NEXT: <key>col</key><integer>15</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>44</integer>
+// CHECK-NEXT: <key>line</key><integer>45</integer>
// CHECK-NEXT: <key>col</key><integer>21</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1347,12 +1349,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>46</integer>
+// CHECK-NEXT: <key>line</key><integer>47</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>46</integer>
+// CHECK-NEXT: <key>line</key><integer>47</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1364,7 +1366,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>46</integer>
+// CHECK-NEXT: <key>line</key><integer>47</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1386,7 +1388,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>issue_hash_function_offset</key><string>1</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>46</integer>
+// CHECK-NEXT: <key>line</key><integer>47</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1402,12 +1404,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>60</integer>
+// CHECK-NEXT: <key>line</key><integer>61</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>60</integer>
+// CHECK-NEXT: <key>line</key><integer>61</integer>
// CHECK-NEXT: <key>col</key><integer>8</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1415,12 +1417,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>61</integer>
+// CHECK-NEXT: <key>line</key><integer>62</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>61</integer>
+// CHECK-NEXT: <key>line</key><integer>62</integer>
// CHECK-NEXT: <key>col</key><integer>22</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1432,7 +1434,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>61</integer>
+// CHECK-NEXT: <key>line</key><integer>62</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1440,12 +1442,12 @@ void testMyMalloc() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>61</integer>
+// CHECK-NEXT: <key>line</key><integer>62</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>61</integer>
+// CHECK-NEXT: <key>line</key><integer>62</integer>
// CHECK-NEXT: <key>col</key><integer>28</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1461,7 +1463,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>53</integer>
+// CHECK-NEXT: <key>line</key><integer>54</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1479,12 +1481,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>53</integer>
+// CHECK-NEXT: <key>line</key><integer>54</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>53</integer>
+// CHECK-NEXT: <key>line</key><integer>54</integer>
// CHECK-NEXT: <key>col</key><integer>4</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1492,12 +1494,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>54</integer>
+// CHECK-NEXT: <key>line</key><integer>55</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>54</integer>
+// CHECK-NEXT: <key>line</key><integer>55</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1513,12 +1515,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>54</integer>
+// CHECK-NEXT: <key>line</key><integer>55</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>54</integer>
+// CHECK-NEXT: <key>line</key><integer>55</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1526,12 +1528,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>54</integer>
+// CHECK-NEXT: <key>line</key><integer>55</integer>
// CHECK-NEXT: <key>col</key><integer>10</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>54</integer>
+// CHECK-NEXT: <key>line</key><integer>55</integer>
// CHECK-NEXT: <key>col</key><integer>15</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1543,7 +1545,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>54</integer>
+// CHECK-NEXT: <key>line</key><integer>55</integer>
// CHECK-NEXT: <key>col</key><integer>10</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1551,12 +1553,12 @@ void testMyMalloc() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>54</integer>
+// CHECK-NEXT: <key>line</key><integer>55</integer>
// CHECK-NEXT: <key>col</key><integer>10</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>54</integer>
+// CHECK-NEXT: <key>line</key><integer>55</integer>
// CHECK-NEXT: <key>col</key><integer>20</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1576,12 +1578,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>54</integer>
+// CHECK-NEXT: <key>line</key><integer>55</integer>
// CHECK-NEXT: <key>col</key><integer>10</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>54</integer>
+// CHECK-NEXT: <key>line</key><integer>55</integer>
// CHECK-NEXT: <key>col</key><integer>15</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1589,12 +1591,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>55</integer>
+// CHECK-NEXT: <key>line</key><integer>56</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>55</integer>
+// CHECK-NEXT: <key>line</key><integer>56</integer>
// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1610,12 +1612,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>55</integer>
+// CHECK-NEXT: <key>line</key><integer>56</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>55</integer>
+// CHECK-NEXT: <key>line</key><integer>56</integer>
// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1623,12 +1625,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>55</integer>
+// CHECK-NEXT: <key>line</key><integer>56</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>55</integer>
+// CHECK-NEXT: <key>line</key><integer>56</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1640,7 +1642,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>55</integer>
+// CHECK-NEXT: <key>line</key><integer>56</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1648,12 +1650,12 @@ void testMyMalloc() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>55</integer>
+// CHECK-NEXT: <key>line</key><integer>56</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>55</integer>
+// CHECK-NEXT: <key>line</key><integer>56</integer>
// CHECK-NEXT: <key>col</key><integer>10</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1673,12 +1675,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>55</integer>
+// CHECK-NEXT: <key>line</key><integer>56</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>55</integer>
+// CHECK-NEXT: <key>line</key><integer>56</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1686,12 +1688,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>56</integer>
+// CHECK-NEXT: <key>line</key><integer>57</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>56</integer>
+// CHECK-NEXT: <key>line</key><integer>57</integer>
// CHECK-NEXT: <key>col</key><integer>13</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1703,7 +1705,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>56</integer>
+// CHECK-NEXT: <key>line</key><integer>57</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1711,12 +1713,12 @@ void testMyMalloc() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>56</integer>
+// CHECK-NEXT: <key>line</key><integer>57</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>56</integer>
+// CHECK-NEXT: <key>line</key><integer>57</integer>
// CHECK-NEXT: <key>col</key><integer>17</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1732,7 +1734,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>50</integer>
+// CHECK-NEXT: <key>line</key><integer>51</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1750,12 +1752,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>50</integer>
+// CHECK-NEXT: <key>line</key><integer>51</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>50</integer>
+// CHECK-NEXT: <key>line</key><integer>51</integer>
// CHECK-NEXT: <key>col</key><integer>4</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1763,12 +1765,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>51</integer>
+// CHECK-NEXT: <key>line</key><integer>52</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>51</integer>
+// CHECK-NEXT: <key>line</key><integer>52</integer>
// CHECK-NEXT: <key>col</key><integer>8</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1780,7 +1782,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>51</integer>
+// CHECK-NEXT: <key>line</key><integer>52</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1788,12 +1790,12 @@ void testMyMalloc() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>51</integer>
+// CHECK-NEXT: <key>line</key><integer>52</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>51</integer>
+// CHECK-NEXT: <key>line</key><integer>52</integer>
// CHECK-NEXT: <key>col</key><integer>11</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1809,7 +1811,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>56</integer>
+// CHECK-NEXT: <key>line</key><integer>57</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1817,12 +1819,12 @@ void testMyMalloc() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>56</integer>
+// CHECK-NEXT: <key>line</key><integer>57</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>56</integer>
+// CHECK-NEXT: <key>line</key><integer>57</integer>
// CHECK-NEXT: <key>col</key><integer>17</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1842,12 +1844,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>56</integer>
+// CHECK-NEXT: <key>line</key><integer>57</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>56</integer>
+// CHECK-NEXT: <key>line</key><integer>57</integer>
// CHECK-NEXT: <key>col</key><integer>13</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1855,12 +1857,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>57</integer>
+// CHECK-NEXT: <key>line</key><integer>58</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>57</integer>
+// CHECK-NEXT: <key>line</key><integer>58</integer>
// CHECK-NEXT: <key>col</key><integer>10</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1872,7 +1874,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>61</integer>
+// CHECK-NEXT: <key>line</key><integer>62</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1880,12 +1882,12 @@ void testMyMalloc() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>61</integer>
+// CHECK-NEXT: <key>line</key><integer>62</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>61</integer>
+// CHECK-NEXT: <key>line</key><integer>62</integer>
// CHECK-NEXT: <key>col</key><integer>28</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1905,12 +1907,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>61</integer>
+// CHECK-NEXT: <key>line</key><integer>62</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>61</integer>
+// CHECK-NEXT: <key>line</key><integer>62</integer>
// CHECK-NEXT: <key>col</key><integer>22</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1918,12 +1920,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>62</integer>
+// CHECK-NEXT: <key>line</key><integer>63</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>62</integer>
+// CHECK-NEXT: <key>line</key><integer>63</integer>
// CHECK-NEXT: <key>col</key><integer>10</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1935,7 +1937,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>62</integer>
+// CHECK-NEXT: <key>line</key><integer>63</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1943,12 +1945,12 @@ void testMyMalloc() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>62</integer>
+// CHECK-NEXT: <key>line</key><integer>63</integer>
// CHECK-NEXT: <key>col</key><integer>12</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>62</integer>
+// CHECK-NEXT: <key>line</key><integer>63</integer>
// CHECK-NEXT: <key>col</key><integer>14</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1972,7 +1974,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>issue_hash_function_offset</key><string>3</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>62</integer>
+// CHECK-NEXT: <key>line</key><integer>63</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1988,12 +1990,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>75</integer>
+// CHECK-NEXT: <key>line</key><integer>76</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>75</integer>
+// CHECK-NEXT: <key>line</key><integer>76</integer>
// CHECK-NEXT: <key>col</key><integer>8</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2001,12 +2003,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>75</integer>
+// CHECK-NEXT: <key>line</key><integer>76</integer>
// CHECK-NEXT: <key>col</key><integer>25</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>75</integer>
+// CHECK-NEXT: <key>line</key><integer>76</integer>
// CHECK-NEXT: <key>col</key><integer>30</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2018,7 +2020,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>75</integer>
+// CHECK-NEXT: <key>line</key><integer>76</integer>
// CHECK-NEXT: <key>col</key><integer>25</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2026,12 +2028,12 @@ void testMyMalloc() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>75</integer>
+// CHECK-NEXT: <key>line</key><integer>76</integer>
// CHECK-NEXT: <key>col</key><integer>25</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>75</integer>
+// CHECK-NEXT: <key>line</key><integer>76</integer>
// CHECK-NEXT: <key>col</key><integer>35</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2051,12 +2053,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>75</integer>
+// CHECK-NEXT: <key>line</key><integer>76</integer>
// CHECK-NEXT: <key>col</key><integer>25</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>75</integer>
+// CHECK-NEXT: <key>line</key><integer>76</integer>
// CHECK-NEXT: <key>col</key><integer>30</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2064,12 +2066,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>76</integer>
+// CHECK-NEXT: <key>line</key><integer>77</integer>
// CHECK-NEXT: <key>col</key><integer>11</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>76</integer>
+// CHECK-NEXT: <key>line</key><integer>77</integer>
// CHECK-NEXT: <key>col</key><integer>20</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2081,7 +2083,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>76</integer>
+// CHECK-NEXT: <key>line</key><integer>77</integer>
// CHECK-NEXT: <key>col</key><integer>11</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2089,12 +2091,12 @@ void testMyMalloc() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>76</integer>
+// CHECK-NEXT: <key>line</key><integer>77</integer>
// CHECK-NEXT: <key>col</key><integer>11</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>76</integer>
+// CHECK-NEXT: <key>line</key><integer>77</integer>
// CHECK-NEXT: <key>col</key><integer>25</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2110,7 +2112,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>66</integer>
+// CHECK-NEXT: <key>line</key><integer>67</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2128,12 +2130,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>66</integer>
+// CHECK-NEXT: <key>line</key><integer>67</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>66</integer>
+// CHECK-NEXT: <key>line</key><integer>67</integer>
// CHECK-NEXT: <key>col</key><integer>4</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2141,12 +2143,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>67</integer>
+// CHECK-NEXT: <key>line</key><integer>68</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>67</integer>
+// CHECK-NEXT: <key>line</key><integer>68</integer>
// CHECK-NEXT: <key>col</key><integer>8</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2162,12 +2164,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>67</integer>
+// CHECK-NEXT: <key>line</key><integer>68</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>67</integer>
+// CHECK-NEXT: <key>line</key><integer>68</integer>
// CHECK-NEXT: <key>col</key><integer>8</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2175,12 +2177,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>68</integer>
+// CHECK-NEXT: <key>line</key><integer>69</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>68</integer>
+// CHECK-NEXT: <key>line</key><integer>69</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2196,12 +2198,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>68</integer>
+// CHECK-NEXT: <key>line</key><integer>69</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>68</integer>
+// CHECK-NEXT: <key>line</key><integer>69</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2209,12 +2211,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>68</integer>
+// CHECK-NEXT: <key>line</key><integer>69</integer>
// CHECK-NEXT: <key>col</key><integer>18</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>68</integer>
+// CHECK-NEXT: <key>line</key><integer>69</integer>
// CHECK-NEXT: <key>col</key><integer>24</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2226,7 +2228,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>68</integer>
+// CHECK-NEXT: <key>line</key><integer>69</integer>
// CHECK-NEXT: <key>col</key><integer>18</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2234,12 +2236,12 @@ void testMyMalloc() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>68</integer>
+// CHECK-NEXT: <key>line</key><integer>69</integer>
// CHECK-NEXT: <key>col</key><integer>18</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>68</integer>
+// CHECK-NEXT: <key>line</key><integer>69</integer>
// CHECK-NEXT: <key>col</key><integer>40</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2259,12 +2261,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>68</integer>
+// CHECK-NEXT: <key>line</key><integer>69</integer>
// CHECK-NEXT: <key>col</key><integer>18</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>68</integer>
+// CHECK-NEXT: <key>line</key><integer>69</integer>
// CHECK-NEXT: <key>col</key><integer>24</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2272,12 +2274,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>69</integer>
+// CHECK-NEXT: <key>line</key><integer>70</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>69</integer>
+// CHECK-NEXT: <key>line</key><integer>70</integer>
// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2293,12 +2295,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>69</integer>
+// CHECK-NEXT: <key>line</key><integer>70</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>69</integer>
+// CHECK-NEXT: <key>line</key><integer>70</integer>
// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2306,12 +2308,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>69</integer>
+// CHECK-NEXT: <key>line</key><integer>70</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>69</integer>
+// CHECK-NEXT: <key>line</key><integer>70</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2323,7 +2325,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>69</integer>
+// CHECK-NEXT: <key>line</key><integer>70</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2331,12 +2333,12 @@ void testMyMalloc() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>69</integer>
+// CHECK-NEXT: <key>line</key><integer>70</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>69</integer>
+// CHECK-NEXT: <key>line</key><integer>70</integer>
// CHECK-NEXT: <key>col</key><integer>12</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2356,12 +2358,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>69</integer>
+// CHECK-NEXT: <key>line</key><integer>70</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>69</integer>
+// CHECK-NEXT: <key>line</key><integer>70</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2369,12 +2371,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>69</integer>
+// CHECK-NEXT: <key>line</key><integer>70</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>69</integer>
+// CHECK-NEXT: <key>line</key><integer>70</integer>
// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2386,7 +2388,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>69</integer>
+// CHECK-NEXT: <key>line</key><integer>70</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2394,12 +2396,12 @@ void testMyMalloc() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>69</integer>
+// CHECK-NEXT: <key>line</key><integer>70</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>69</integer>
+// CHECK-NEXT: <key>line</key><integer>70</integer>
// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2419,12 +2421,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>69</integer>
+// CHECK-NEXT: <key>line</key><integer>70</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>69</integer>
+// CHECK-NEXT: <key>line</key><integer>70</integer>
// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2432,12 +2434,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>70</integer>
+// CHECK-NEXT: <key>line</key><integer>71</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>70</integer>
+// CHECK-NEXT: <key>line</key><integer>71</integer>
// CHECK-NEXT: <key>col</key><integer>14</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2449,7 +2451,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>76</integer>
+// CHECK-NEXT: <key>line</key><integer>77</integer>
// CHECK-NEXT: <key>col</key><integer>11</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2457,12 +2459,12 @@ void testMyMalloc() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>76</integer>
+// CHECK-NEXT: <key>line</key><integer>77</integer>
// CHECK-NEXT: <key>col</key><integer>11</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>76</integer>
+// CHECK-NEXT: <key>line</key><integer>77</integer>
// CHECK-NEXT: <key>col</key><integer>25</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2482,12 +2484,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>76</integer>
+// CHECK-NEXT: <key>line</key><integer>77</integer>
// CHECK-NEXT: <key>col</key><integer>11</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>76</integer>
+// CHECK-NEXT: <key>line</key><integer>77</integer>
// CHECK-NEXT: <key>col</key><integer>20</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2495,12 +2497,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>77</integer>
+// CHECK-NEXT: <key>line</key><integer>78</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>77</integer>
+// CHECK-NEXT: <key>line</key><integer>78</integer>
// CHECK-NEXT: <key>col</key><integer>8</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2512,7 +2514,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>77</integer>
+// CHECK-NEXT: <key>line</key><integer>78</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2534,7 +2536,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>issue_hash_function_offset</key><string>1</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>77</integer>
+// CHECK-NEXT: <key>line</key><integer>78</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2550,12 +2552,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>85</integer>
+// CHECK-NEXT: <key>line</key><integer>86</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>85</integer>
+// CHECK-NEXT: <key>line</key><integer>86</integer>
// CHECK-NEXT: <key>col</key><integer>8</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2563,12 +2565,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>86</integer>
+// CHECK-NEXT: <key>line</key><integer>87</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>86</integer>
+// CHECK-NEXT: <key>line</key><integer>87</integer>
// CHECK-NEXT: <key>col</key><integer>26</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2580,7 +2582,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>86</integer>
+// CHECK-NEXT: <key>line</key><integer>87</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2588,12 +2590,12 @@ void testMyMalloc() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>86</integer>
+// CHECK-NEXT: <key>line</key><integer>87</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>86</integer>
+// CHECK-NEXT: <key>line</key><integer>87</integer>
// CHECK-NEXT: <key>col</key><integer>28</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2609,7 +2611,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>81</integer>
+// CHECK-NEXT: <key>line</key><integer>82</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2627,12 +2629,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>81</integer>
+// CHECK-NEXT: <key>line</key><integer>82</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>81</integer>
+// CHECK-NEXT: <key>line</key><integer>82</integer>
// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2640,12 +2642,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>82</integer>
+// CHECK-NEXT: <key>line</key><integer>83</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>82</integer>
+// CHECK-NEXT: <key>line</key><integer>83</integer>
// CHECK-NEXT: <key>col</key><integer>10</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2661,12 +2663,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>82</integer>
+// CHECK-NEXT: <key>line</key><integer>83</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>82</integer>
+// CHECK-NEXT: <key>line</key><integer>83</integer>
// CHECK-NEXT: <key>col</key><integer>10</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2674,12 +2676,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>82</integer>
+// CHECK-NEXT: <key>line</key><integer>83</integer>
// CHECK-NEXT: <key>col</key><integer>19</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>82</integer>
+// CHECK-NEXT: <key>line</key><integer>83</integer>
// CHECK-NEXT: <key>col</key><integer>24</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2691,7 +2693,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>82</integer>
+// CHECK-NEXT: <key>line</key><integer>83</integer>
// CHECK-NEXT: <key>col</key><integer>19</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2699,12 +2701,12 @@ void testMyMalloc() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>82</integer>
+// CHECK-NEXT: <key>line</key><integer>83</integer>
// CHECK-NEXT: <key>col</key><integer>19</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>82</integer>
+// CHECK-NEXT: <key>line</key><integer>83</integer>
// CHECK-NEXT: <key>col</key><integer>28</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2720,7 +2722,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>86</integer>
+// CHECK-NEXT: <key>line</key><integer>87</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2728,12 +2730,12 @@ void testMyMalloc() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>86</integer>
+// CHECK-NEXT: <key>line</key><integer>87</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>86</integer>
+// CHECK-NEXT: <key>line</key><integer>87</integer>
// CHECK-NEXT: <key>col</key><integer>28</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2753,12 +2755,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>86</integer>
+// CHECK-NEXT: <key>line</key><integer>87</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>86</integer>
+// CHECK-NEXT: <key>line</key><integer>87</integer>
// CHECK-NEXT: <key>col</key><integer>26</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2766,12 +2768,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>87</integer>
+// CHECK-NEXT: <key>line</key><integer>88</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>87</integer>
+// CHECK-NEXT: <key>line</key><integer>88</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2783,7 +2785,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>87</integer>
+// CHECK-NEXT: <key>line</key><integer>88</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2805,7 +2807,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>issue_hash_function_offset</key><string>2</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>87</integer>
+// CHECK-NEXT: <key>line</key><integer>88</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2821,12 +2823,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>97</integer>
+// CHECK-NEXT: <key>line</key><integer>98</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>97</integer>
+// CHECK-NEXT: <key>line</key><integer>98</integer>
// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2834,12 +2836,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>99</integer>
+// CHECK-NEXT: <key>line</key><integer>100</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>99</integer>
+// CHECK-NEXT: <key>line</key><integer>100</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2855,12 +2857,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>99</integer>
+// CHECK-NEXT: <key>line</key><integer>100</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>99</integer>
+// CHECK-NEXT: <key>line</key><integer>100</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2868,12 +2870,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>99</integer>
+// CHECK-NEXT: <key>line</key><integer>100</integer>
// CHECK-NEXT: <key>col</key><integer>12</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>99</integer>
+// CHECK-NEXT: <key>line</key><integer>100</integer>
// CHECK-NEXT: <key>col</key><integer>17</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2885,7 +2887,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>99</integer>
+// CHECK-NEXT: <key>line</key><integer>100</integer>
// CHECK-NEXT: <key>col</key><integer>12</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2893,12 +2895,12 @@ void testMyMalloc() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>99</integer>
+// CHECK-NEXT: <key>line</key><integer>100</integer>
// CHECK-NEXT: <key>col</key><integer>12</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>99</integer>
+// CHECK-NEXT: <key>line</key><integer>100</integer>
// CHECK-NEXT: <key>col</key><integer>30</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2918,12 +2920,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>99</integer>
+// CHECK-NEXT: <key>line</key><integer>100</integer>
// CHECK-NEXT: <key>col</key><integer>12</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>99</integer>
+// CHECK-NEXT: <key>line</key><integer>100</integer>
// CHECK-NEXT: <key>col</key><integer>17</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2931,12 +2933,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>100</integer>
+// CHECK-NEXT: <key>line</key><integer>101</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>100</integer>
+// CHECK-NEXT: <key>line</key><integer>101</integer>
// CHECK-NEXT: <key>col</key><integer>20</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2948,7 +2950,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>100</integer>
+// CHECK-NEXT: <key>line</key><integer>101</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2956,12 +2958,12 @@ void testMyMalloc() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>100</integer>
+// CHECK-NEXT: <key>line</key><integer>101</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>100</integer>
+// CHECK-NEXT: <key>line</key><integer>101</integer>
// CHECK-NEXT: <key>col</key><integer>35</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2977,7 +2979,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>92</integer>
+// CHECK-NEXT: <key>line</key><integer>93</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2995,12 +2997,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>92</integer>
+// CHECK-NEXT: <key>line</key><integer>93</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>92</integer>
+// CHECK-NEXT: <key>line</key><integer>93</integer>
// CHECK-NEXT: <key>col</key><integer>4</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3008,12 +3010,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>93</integer>
+// CHECK-NEXT: <key>line</key><integer>94</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>93</integer>
+// CHECK-NEXT: <key>line</key><integer>94</integer>
// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3025,7 +3027,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>93</integer>
+// CHECK-NEXT: <key>line</key><integer>94</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3033,12 +3035,12 @@ void testMyMalloc() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>93</integer>
+// CHECK-NEXT: <key>line</key><integer>94</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>93</integer>
+// CHECK-NEXT: <key>line</key><integer>94</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3054,7 +3056,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>100</integer>
+// CHECK-NEXT: <key>line</key><integer>101</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3062,12 +3064,12 @@ void testMyMalloc() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>100</integer>
+// CHECK-NEXT: <key>line</key><integer>101</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>100</integer>
+// CHECK-NEXT: <key>line</key><integer>101</integer>
// CHECK-NEXT: <key>col</key><integer>35</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3087,12 +3089,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>100</integer>
+// CHECK-NEXT: <key>line</key><integer>101</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>100</integer>
+// CHECK-NEXT: <key>line</key><integer>101</integer>
// CHECK-NEXT: <key>col</key><integer>20</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3100,12 +3102,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>101</integer>
+// CHECK-NEXT: <key>line</key><integer>102</integer>
// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>101</integer>
+// CHECK-NEXT: <key>line</key><integer>102</integer>
// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3117,7 +3119,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>101</integer>
+// CHECK-NEXT: <key>line</key><integer>102</integer>
// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3125,12 +3127,12 @@ void testMyMalloc() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>101</integer>
+// CHECK-NEXT: <key>line</key><integer>102</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>101</integer>
+// CHECK-NEXT: <key>line</key><integer>102</integer>
// CHECK-NEXT: <key>col</key><integer>4</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3154,7 +3156,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>issue_hash_function_offset</key><string>5</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>101</integer>
+// CHECK-NEXT: <key>line</key><integer>102</integer>
// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3170,12 +3172,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>106</integer>
+// CHECK-NEXT: <key>line</key><integer>107</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>106</integer>
+// CHECK-NEXT: <key>line</key><integer>107</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3183,12 +3185,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>108</integer>
+// CHECK-NEXT: <key>line</key><integer>109</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>108</integer>
+// CHECK-NEXT: <key>line</key><integer>109</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3204,12 +3206,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>108</integer>
+// CHECK-NEXT: <key>line</key><integer>109</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>108</integer>
+// CHECK-NEXT: <key>line</key><integer>109</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3217,12 +3219,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>108</integer>
+// CHECK-NEXT: <key>line</key><integer>109</integer>
// CHECK-NEXT: <key>col</key><integer>15</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>108</integer>
+// CHECK-NEXT: <key>line</key><integer>109</integer>
// CHECK-NEXT: <key>col</key><integer>20</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3234,7 +3236,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>108</integer>
+// CHECK-NEXT: <key>line</key><integer>109</integer>
// CHECK-NEXT: <key>col</key><integer>15</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3242,12 +3244,12 @@ void testMyMalloc() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>108</integer>
+// CHECK-NEXT: <key>line</key><integer>109</integer>
// CHECK-NEXT: <key>col</key><integer>15</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>108</integer>
+// CHECK-NEXT: <key>line</key><integer>109</integer>
// CHECK-NEXT: <key>col</key><integer>24</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3267,12 +3269,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>108</integer>
+// CHECK-NEXT: <key>line</key><integer>109</integer>
// CHECK-NEXT: <key>col</key><integer>15</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>108</integer>
+// CHECK-NEXT: <key>line</key><integer>109</integer>
// CHECK-NEXT: <key>col</key><integer>20</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3280,12 +3282,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>113</integer>
+// CHECK-NEXT: <key>line</key><integer>115</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>113</integer>
+// CHECK-NEXT: <key>line</key><integer>115</integer>
// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3297,7 +3299,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>113</integer>
+// CHECK-NEXT: <key>line</key><integer>115</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3319,7 +3321,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>issue_hash_function_offset</key><string>3</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>113</integer>
+// CHECK-NEXT: <key>line</key><integer>115</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3331,7 +3333,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>121</integer>
+// CHECK-NEXT: <key>line</key><integer>123</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3339,12 +3341,12 @@ void testMyMalloc() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>121</integer>
+// CHECK-NEXT: <key>line</key><integer>123</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>121</integer>
+// CHECK-NEXT: <key>line</key><integer>123</integer>
// CHECK-NEXT: <key>col</key><integer>25</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3360,7 +3362,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>117</integer>
+// CHECK-NEXT: <key>line</key><integer>119</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3378,12 +3380,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>117</integer>
+// CHECK-NEXT: <key>line</key><integer>119</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>117</integer>
+// CHECK-NEXT: <key>line</key><integer>119</integer>
// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3391,12 +3393,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>118</integer>
+// CHECK-NEXT: <key>line</key><integer>120</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>118</integer>
+// CHECK-NEXT: <key>line</key><integer>120</integer>
// CHECK-NEXT: <key>col</key><integer>8</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3412,12 +3414,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>118</integer>
+// CHECK-NEXT: <key>line</key><integer>120</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>118</integer>
+// CHECK-NEXT: <key>line</key><integer>120</integer>
// CHECK-NEXT: <key>col</key><integer>8</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3425,12 +3427,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>118</integer>
+// CHECK-NEXT: <key>line</key><integer>120</integer>
// CHECK-NEXT: <key>col</key><integer>22</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>118</integer>
+// CHECK-NEXT: <key>line</key><integer>120</integer>
// CHECK-NEXT: <key>col</key><integer>27</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3442,7 +3444,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>118</integer>
+// CHECK-NEXT: <key>line</key><integer>120</integer>
// CHECK-NEXT: <key>col</key><integer>22</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3450,12 +3452,12 @@ void testMyMalloc() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>118</integer>
+// CHECK-NEXT: <key>line</key><integer>120</integer>
// CHECK-NEXT: <key>col</key><integer>22</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>118</integer>
+// CHECK-NEXT: <key>line</key><integer>120</integer>
// CHECK-NEXT: <key>col</key><integer>31</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3475,12 +3477,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>118</integer>
+// CHECK-NEXT: <key>line</key><integer>120</integer>
// CHECK-NEXT: <key>col</key><integer>22</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>118</integer>
+// CHECK-NEXT: <key>line</key><integer>120</integer>
// CHECK-NEXT: <key>col</key><integer>27</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3488,12 +3490,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>119</integer>
+// CHECK-NEXT: <key>line</key><integer>121</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>119</integer>
+// CHECK-NEXT: <key>line</key><integer>121</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3505,7 +3507,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>119</integer>
+// CHECK-NEXT: <key>line</key><integer>121</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3527,7 +3529,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>issue_hash_function_offset</key><string>1</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>119</integer>
+// CHECK-NEXT: <key>line</key><integer>121</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3539,7 +3541,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>130</integer>
+// CHECK-NEXT: <key>line</key><integer>132</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3547,12 +3549,12 @@ void testMyMalloc() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>130</integer>
+// CHECK-NEXT: <key>line</key><integer>132</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>130</integer>
+// CHECK-NEXT: <key>line</key><integer>132</integer>
// CHECK-NEXT: <key>col</key><integer>25</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3568,7 +3570,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>125</integer>
+// CHECK-NEXT: <key>line</key><integer>127</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3586,12 +3588,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>125</integer>
+// CHECK-NEXT: <key>line</key><integer>127</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>125</integer>
+// CHECK-NEXT: <key>line</key><integer>127</integer>
// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3599,12 +3601,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>126</integer>
+// CHECK-NEXT: <key>line</key><integer>128</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>126</integer>
+// CHECK-NEXT: <key>line</key><integer>128</integer>
// CHECK-NEXT: <key>col</key><integer>8</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3620,12 +3622,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>126</integer>
+// CHECK-NEXT: <key>line</key><integer>128</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>126</integer>
+// CHECK-NEXT: <key>line</key><integer>128</integer>
// CHECK-NEXT: <key>col</key><integer>8</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3633,12 +3635,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>126</integer>
+// CHECK-NEXT: <key>line</key><integer>128</integer>
// CHECK-NEXT: <key>col</key><integer>22</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>126</integer>
+// CHECK-NEXT: <key>line</key><integer>128</integer>
// CHECK-NEXT: <key>col</key><integer>27</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3650,7 +3652,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>126</integer>
+// CHECK-NEXT: <key>line</key><integer>128</integer>
// CHECK-NEXT: <key>col</key><integer>22</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3658,12 +3660,12 @@ void testMyMalloc() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>126</integer>
+// CHECK-NEXT: <key>line</key><integer>128</integer>
// CHECK-NEXT: <key>col</key><integer>22</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>126</integer>
+// CHECK-NEXT: <key>line</key><integer>128</integer>
// CHECK-NEXT: <key>col</key><integer>31</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3683,12 +3685,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>126</integer>
+// CHECK-NEXT: <key>line</key><integer>128</integer>
// CHECK-NEXT: <key>col</key><integer>22</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>126</integer>
+// CHECK-NEXT: <key>line</key><integer>128</integer>
// CHECK-NEXT: <key>col</key><integer>27</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3696,12 +3698,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>127</integer>
+// CHECK-NEXT: <key>line</key><integer>129</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>127</integer>
+// CHECK-NEXT: <key>line</key><integer>129</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3713,7 +3715,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>127</integer>
+// CHECK-NEXT: <key>line</key><integer>129</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3735,7 +3737,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>issue_hash_function_offset</key><string>1</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>127</integer>
+// CHECK-NEXT: <key>line</key><integer>129</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3747,7 +3749,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>139</integer>
+// CHECK-NEXT: <key>line</key><integer>141</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3755,12 +3757,12 @@ void testMyMalloc() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>139</integer>
+// CHECK-NEXT: <key>line</key><integer>141</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>139</integer>
+// CHECK-NEXT: <key>line</key><integer>141</integer>
// CHECK-NEXT: <key>col</key><integer>26</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3776,7 +3778,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>133</integer>
+// CHECK-NEXT: <key>line</key><integer>135</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3794,12 +3796,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>133</integer>
+// CHECK-NEXT: <key>line</key><integer>135</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>133</integer>
+// CHECK-NEXT: <key>line</key><integer>135</integer>
// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3807,12 +3809,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>134</integer>
+// CHECK-NEXT: <key>line</key><integer>136</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>134</integer>
+// CHECK-NEXT: <key>line</key><integer>136</integer>
// CHECK-NEXT: <key>col</key><integer>8</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3828,12 +3830,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>134</integer>
+// CHECK-NEXT: <key>line</key><integer>136</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>134</integer>
+// CHECK-NEXT: <key>line</key><integer>136</integer>
// CHECK-NEXT: <key>col</key><integer>8</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3841,12 +3843,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>134</integer>
+// CHECK-NEXT: <key>line</key><integer>136</integer>
// CHECK-NEXT: <key>col</key><integer>22</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>134</integer>
+// CHECK-NEXT: <key>line</key><integer>136</integer>
// CHECK-NEXT: <key>col</key><integer>27</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3858,7 +3860,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>134</integer>
+// CHECK-NEXT: <key>line</key><integer>136</integer>
// CHECK-NEXT: <key>col</key><integer>22</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3866,12 +3868,12 @@ void testMyMalloc() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>134</integer>
+// CHECK-NEXT: <key>line</key><integer>136</integer>
// CHECK-NEXT: <key>col</key><integer>22</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>134</integer>
+// CHECK-NEXT: <key>line</key><integer>136</integer>
// CHECK-NEXT: <key>col</key><integer>31</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3891,12 +3893,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>134</integer>
+// CHECK-NEXT: <key>line</key><integer>136</integer>
// CHECK-NEXT: <key>col</key><integer>22</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>134</integer>
+// CHECK-NEXT: <key>line</key><integer>136</integer>
// CHECK-NEXT: <key>col</key><integer>27</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3904,12 +3906,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>135</integer>
+// CHECK-NEXT: <key>line</key><integer>137</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>135</integer>
+// CHECK-NEXT: <key>line</key><integer>137</integer>
// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3925,12 +3927,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>135</integer>
+// CHECK-NEXT: <key>line</key><integer>137</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>135</integer>
+// CHECK-NEXT: <key>line</key><integer>137</integer>
// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3938,12 +3940,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>135</integer>
+// CHECK-NEXT: <key>line</key><integer>137</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>135</integer>
+// CHECK-NEXT: <key>line</key><integer>137</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3955,7 +3957,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>135</integer>
+// CHECK-NEXT: <key>line</key><integer>137</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3963,12 +3965,12 @@ void testMyMalloc() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>135</integer>
+// CHECK-NEXT: <key>line</key><integer>137</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>135</integer>
+// CHECK-NEXT: <key>line</key><integer>137</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -3988,12 +3990,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>135</integer>
+// CHECK-NEXT: <key>line</key><integer>137</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>135</integer>
+// CHECK-NEXT: <key>line</key><integer>137</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4001,12 +4003,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>136</integer>
+// CHECK-NEXT: <key>line</key><integer>138</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>136</integer>
+// CHECK-NEXT: <key>line</key><integer>138</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4018,7 +4020,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>136</integer>
+// CHECK-NEXT: <key>line</key><integer>138</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4040,7 +4042,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>issue_hash_function_offset</key><string>1</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>136</integer>
+// CHECK-NEXT: <key>line</key><integer>138</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4052,7 +4054,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>150</integer>
+// CHECK-NEXT: <key>line</key><integer>152</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4060,12 +4062,12 @@ void testMyMalloc() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>150</integer>
+// CHECK-NEXT: <key>line</key><integer>152</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>150</integer>
+// CHECK-NEXT: <key>line</key><integer>152</integer>
// CHECK-NEXT: <key>col</key><integer>26</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4081,7 +4083,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>142</integer>
+// CHECK-NEXT: <key>line</key><integer>144</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4099,12 +4101,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>142</integer>
+// CHECK-NEXT: <key>line</key><integer>144</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>142</integer>
+// CHECK-NEXT: <key>line</key><integer>144</integer>
// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4112,12 +4114,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>143</integer>
+// CHECK-NEXT: <key>line</key><integer>145</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>143</integer>
+// CHECK-NEXT: <key>line</key><integer>145</integer>
// CHECK-NEXT: <key>col</key><integer>8</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4133,12 +4135,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>143</integer>
+// CHECK-NEXT: <key>line</key><integer>145</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>143</integer>
+// CHECK-NEXT: <key>line</key><integer>145</integer>
// CHECK-NEXT: <key>col</key><integer>8</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4146,12 +4148,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>143</integer>
+// CHECK-NEXT: <key>line</key><integer>145</integer>
// CHECK-NEXT: <key>col</key><integer>22</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>143</integer>
+// CHECK-NEXT: <key>line</key><integer>145</integer>
// CHECK-NEXT: <key>col</key><integer>27</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4163,7 +4165,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>143</integer>
+// CHECK-NEXT: <key>line</key><integer>145</integer>
// CHECK-NEXT: <key>col</key><integer>22</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4171,12 +4173,12 @@ void testMyMalloc() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>143</integer>
+// CHECK-NEXT: <key>line</key><integer>145</integer>
// CHECK-NEXT: <key>col</key><integer>22</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>143</integer>
+// CHECK-NEXT: <key>line</key><integer>145</integer>
// CHECK-NEXT: <key>col</key><integer>31</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4196,12 +4198,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>143</integer>
+// CHECK-NEXT: <key>line</key><integer>145</integer>
// CHECK-NEXT: <key>col</key><integer>22</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>143</integer>
+// CHECK-NEXT: <key>line</key><integer>145</integer>
// CHECK-NEXT: <key>col</key><integer>27</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4209,12 +4211,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>144</integer>
+// CHECK-NEXT: <key>line</key><integer>146</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>144</integer>
+// CHECK-NEXT: <key>line</key><integer>146</integer>
// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4230,12 +4232,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>144</integer>
+// CHECK-NEXT: <key>line</key><integer>146</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>144</integer>
+// CHECK-NEXT: <key>line</key><integer>146</integer>
// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4243,12 +4245,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>144</integer>
+// CHECK-NEXT: <key>line</key><integer>146</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>144</integer>
+// CHECK-NEXT: <key>line</key><integer>146</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4260,7 +4262,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>144</integer>
+// CHECK-NEXT: <key>line</key><integer>146</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4268,12 +4270,12 @@ void testMyMalloc() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>144</integer>
+// CHECK-NEXT: <key>line</key><integer>146</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>144</integer>
+// CHECK-NEXT: <key>line</key><integer>146</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4293,12 +4295,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>144</integer>
+// CHECK-NEXT: <key>line</key><integer>146</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>144</integer>
+// CHECK-NEXT: <key>line</key><integer>146</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4306,12 +4308,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>147</integer>
+// CHECK-NEXT: <key>line</key><integer>149</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>147</integer>
+// CHECK-NEXT: <key>line</key><integer>149</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4323,7 +4325,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>147</integer>
+// CHECK-NEXT: <key>line</key><integer>149</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4345,7 +4347,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>issue_hash_function_offset</key><string>1</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>147</integer>
+// CHECK-NEXT: <key>line</key><integer>149</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4357,7 +4359,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>161</integer>
+// CHECK-NEXT: <key>line</key><integer>163</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4365,12 +4367,12 @@ void testMyMalloc() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>161</integer>
+// CHECK-NEXT: <key>line</key><integer>163</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>161</integer>
+// CHECK-NEXT: <key>line</key><integer>163</integer>
// CHECK-NEXT: <key>col</key><integer>25</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4386,7 +4388,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>156</integer>
+// CHECK-NEXT: <key>line</key><integer>158</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4404,12 +4406,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>156</integer>
+// CHECK-NEXT: <key>line</key><integer>158</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>156</integer>
+// CHECK-NEXT: <key>line</key><integer>158</integer>
// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4417,12 +4419,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>157</integer>
+// CHECK-NEXT: <key>line</key><integer>159</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>157</integer>
+// CHECK-NEXT: <key>line</key><integer>159</integer>
// CHECK-NEXT: <key>col</key><integer>8</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4438,12 +4440,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>157</integer>
+// CHECK-NEXT: <key>line</key><integer>159</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>157</integer>
+// CHECK-NEXT: <key>line</key><integer>159</integer>
// CHECK-NEXT: <key>col</key><integer>8</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4451,12 +4453,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>157</integer>
+// CHECK-NEXT: <key>line</key><integer>159</integer>
// CHECK-NEXT: <key>col</key><integer>22</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>157</integer>
+// CHECK-NEXT: <key>line</key><integer>159</integer>
// CHECK-NEXT: <key>col</key><integer>27</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4468,7 +4470,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>157</integer>
+// CHECK-NEXT: <key>line</key><integer>159</integer>
// CHECK-NEXT: <key>col</key><integer>22</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4476,12 +4478,12 @@ void testMyMalloc() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>157</integer>
+// CHECK-NEXT: <key>line</key><integer>159</integer>
// CHECK-NEXT: <key>col</key><integer>22</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>157</integer>
+// CHECK-NEXT: <key>line</key><integer>159</integer>
// CHECK-NEXT: <key>col</key><integer>31</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4501,12 +4503,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>157</integer>
+// CHECK-NEXT: <key>line</key><integer>159</integer>
// CHECK-NEXT: <key>col</key><integer>22</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>157</integer>
+// CHECK-NEXT: <key>line</key><integer>159</integer>
// CHECK-NEXT: <key>col</key><integer>27</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4514,12 +4516,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>158</integer>
+// CHECK-NEXT: <key>line</key><integer>160</integer>
// CHECK-NEXT: <key>col</key><integer>12</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>158</integer>
+// CHECK-NEXT: <key>line</key><integer>160</integer>
// CHECK-NEXT: <key>col</key><integer>27</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4531,7 +4533,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>158</integer>
+// CHECK-NEXT: <key>line</key><integer>160</integer>
// CHECK-NEXT: <key>col</key><integer>12</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4553,7 +4555,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>issue_hash_function_offset</key><string>1</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>158</integer>
+// CHECK-NEXT: <key>line</key><integer>160</integer>
// CHECK-NEXT: <key>col</key><integer>12</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4565,7 +4567,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>172</integer>
+// CHECK-NEXT: <key>line</key><integer>174</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4573,12 +4575,12 @@ void testMyMalloc() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>172</integer>
+// CHECK-NEXT: <key>line</key><integer>174</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>172</integer>
+// CHECK-NEXT: <key>line</key><integer>174</integer>
// CHECK-NEXT: <key>col</key><integer>25</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4594,7 +4596,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>167</integer>
+// CHECK-NEXT: <key>line</key><integer>169</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4612,12 +4614,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>167</integer>
+// CHECK-NEXT: <key>line</key><integer>169</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>167</integer>
+// CHECK-NEXT: <key>line</key><integer>169</integer>
// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4625,12 +4627,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>168</integer>
+// CHECK-NEXT: <key>line</key><integer>170</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>168</integer>
+// CHECK-NEXT: <key>line</key><integer>170</integer>
// CHECK-NEXT: <key>col</key><integer>8</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4646,12 +4648,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>168</integer>
+// CHECK-NEXT: <key>line</key><integer>170</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>168</integer>
+// CHECK-NEXT: <key>line</key><integer>170</integer>
// CHECK-NEXT: <key>col</key><integer>8</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4659,12 +4661,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>168</integer>
+// CHECK-NEXT: <key>line</key><integer>170</integer>
// CHECK-NEXT: <key>col</key><integer>22</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>168</integer>
+// CHECK-NEXT: <key>line</key><integer>170</integer>
// CHECK-NEXT: <key>col</key><integer>27</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4676,7 +4678,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>168</integer>
+// CHECK-NEXT: <key>line</key><integer>170</integer>
// CHECK-NEXT: <key>col</key><integer>22</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4684,12 +4686,12 @@ void testMyMalloc() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>168</integer>
+// CHECK-NEXT: <key>line</key><integer>170</integer>
// CHECK-NEXT: <key>col</key><integer>22</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>168</integer>
+// CHECK-NEXT: <key>line</key><integer>170</integer>
// CHECK-NEXT: <key>col</key><integer>31</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4709,12 +4711,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>168</integer>
+// CHECK-NEXT: <key>line</key><integer>170</integer>
// CHECK-NEXT: <key>col</key><integer>22</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>168</integer>
+// CHECK-NEXT: <key>line</key><integer>170</integer>
// CHECK-NEXT: <key>col</key><integer>27</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4722,12 +4724,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>169</integer>
+// CHECK-NEXT: <key>line</key><integer>171</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>169</integer>
+// CHECK-NEXT: <key>line</key><integer>171</integer>
// CHECK-NEXT: <key>col</key><integer>20</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4739,7 +4741,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>169</integer>
+// CHECK-NEXT: <key>line</key><integer>171</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4761,7 +4763,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>issue_hash_function_offset</key><string>1</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>169</integer>
+// CHECK-NEXT: <key>line</key><integer>171</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4773,7 +4775,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>184</integer>
+// CHECK-NEXT: <key>line</key><integer>186</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4781,12 +4783,12 @@ void testMyMalloc() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>184</integer>
+// CHECK-NEXT: <key>line</key><integer>186</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>184</integer>
+// CHECK-NEXT: <key>line</key><integer>186</integer>
// CHECK-NEXT: <key>col</key><integer>25</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4802,7 +4804,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>180</integer>
+// CHECK-NEXT: <key>line</key><integer>182</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4820,12 +4822,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>180</integer>
+// CHECK-NEXT: <key>line</key><integer>182</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>180</integer>
+// CHECK-NEXT: <key>line</key><integer>182</integer>
// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4833,12 +4835,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>181</integer>
+// CHECK-NEXT: <key>line</key><integer>183</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>181</integer>
+// CHECK-NEXT: <key>line</key><integer>183</integer>
// CHECK-NEXT: <key>col</key><integer>10</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4854,12 +4856,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>181</integer>
+// CHECK-NEXT: <key>line</key><integer>183</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>181</integer>
+// CHECK-NEXT: <key>line</key><integer>183</integer>
// CHECK-NEXT: <key>col</key><integer>10</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4867,12 +4869,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>181</integer>
+// CHECK-NEXT: <key>line</key><integer>183</integer>
// CHECK-NEXT: <key>col</key><integer>19</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>181</integer>
+// CHECK-NEXT: <key>line</key><integer>183</integer>
// CHECK-NEXT: <key>col</key><integer>24</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4884,7 +4886,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>181</integer>
+// CHECK-NEXT: <key>line</key><integer>183</integer>
// CHECK-NEXT: <key>col</key><integer>19</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4892,12 +4894,12 @@ void testMyMalloc() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>181</integer>
+// CHECK-NEXT: <key>line</key><integer>183</integer>
// CHECK-NEXT: <key>col</key><integer>19</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>181</integer>
+// CHECK-NEXT: <key>line</key><integer>183</integer>
// CHECK-NEXT: <key>col</key><integer>28</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4913,7 +4915,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>184</integer>
+// CHECK-NEXT: <key>line</key><integer>186</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4921,12 +4923,12 @@ void testMyMalloc() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>184</integer>
+// CHECK-NEXT: <key>line</key><integer>186</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>184</integer>
+// CHECK-NEXT: <key>line</key><integer>186</integer>
// CHECK-NEXT: <key>col</key><integer>25</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4946,12 +4948,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>184</integer>
+// CHECK-NEXT: <key>line</key><integer>186</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>184</integer>
+// CHECK-NEXT: <key>line</key><integer>186</integer>
// CHECK-NEXT: <key>col</key><integer>23</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4959,12 +4961,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>185</integer>
+// CHECK-NEXT: <key>line</key><integer>187</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>185</integer>
+// CHECK-NEXT: <key>line</key><integer>187</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4976,7 +4978,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>185</integer>
+// CHECK-NEXT: <key>line</key><integer>187</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -4998,7 +5000,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>issue_hash_function_offset</key><string>1</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>185</integer>
+// CHECK-NEXT: <key>line</key><integer>187</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5010,7 +5012,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>194</integer>
+// CHECK-NEXT: <key>line</key><integer>196</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5018,12 +5020,12 @@ void testMyMalloc() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>194</integer>
+// CHECK-NEXT: <key>line</key><integer>196</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>194</integer>
+// CHECK-NEXT: <key>line</key><integer>196</integer>
// CHECK-NEXT: <key>col</key><integer>13</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5039,7 +5041,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>189</integer>
+// CHECK-NEXT: <key>line</key><integer>191</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5057,12 +5059,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>189</integer>
+// CHECK-NEXT: <key>line</key><integer>191</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>189</integer>
+// CHECK-NEXT: <key>line</key><integer>191</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5070,12 +5072,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>190</integer>
+// CHECK-NEXT: <key>line</key><integer>192</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>190</integer>
+// CHECK-NEXT: <key>line</key><integer>192</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5091,12 +5093,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>190</integer>
+// CHECK-NEXT: <key>line</key><integer>192</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>190</integer>
+// CHECK-NEXT: <key>line</key><integer>192</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5104,12 +5106,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>190</integer>
+// CHECK-NEXT: <key>line</key><integer>192</integer>
// CHECK-NEXT: <key>col</key><integer>12</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>190</integer>
+// CHECK-NEXT: <key>line</key><integer>192</integer>
// CHECK-NEXT: <key>col</key><integer>17</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5121,7 +5123,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>190</integer>
+// CHECK-NEXT: <key>line</key><integer>192</integer>
// CHECK-NEXT: <key>col</key><integer>12</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5129,12 +5131,12 @@ void testMyMalloc() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>190</integer>
+// CHECK-NEXT: <key>line</key><integer>192</integer>
// CHECK-NEXT: <key>col</key><integer>12</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>190</integer>
+// CHECK-NEXT: <key>line</key><integer>192</integer>
// CHECK-NEXT: <key>col</key><integer>21</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5150,7 +5152,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>194</integer>
+// CHECK-NEXT: <key>line</key><integer>196</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5158,12 +5160,12 @@ void testMyMalloc() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>194</integer>
+// CHECK-NEXT: <key>line</key><integer>196</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>194</integer>
+// CHECK-NEXT: <key>line</key><integer>196</integer>
// CHECK-NEXT: <key>col</key><integer>13</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5183,12 +5185,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>194</integer>
+// CHECK-NEXT: <key>line</key><integer>196</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>194</integer>
+// CHECK-NEXT: <key>line</key><integer>196</integer>
// CHECK-NEXT: <key>col</key><integer>11</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5196,12 +5198,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>195</integer>
+// CHECK-NEXT: <key>line</key><integer>197</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>195</integer>
+// CHECK-NEXT: <key>line</key><integer>197</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5213,7 +5215,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>195</integer>
+// CHECK-NEXT: <key>line</key><integer>197</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5235,7 +5237,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>issue_hash_function_offset</key><string>1</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>195</integer>
+// CHECK-NEXT: <key>line</key><integer>197</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5247,7 +5249,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>206</integer>
+// CHECK-NEXT: <key>line</key><integer>208</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5255,12 +5257,12 @@ void testMyMalloc() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>206</integer>
+// CHECK-NEXT: <key>line</key><integer>208</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>206</integer>
+// CHECK-NEXT: <key>line</key><integer>208</integer>
// CHECK-NEXT: <key>col</key><integer>25</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5276,7 +5278,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>200</integer>
+// CHECK-NEXT: <key>line</key><integer>202</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5294,12 +5296,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>200</integer>
+// CHECK-NEXT: <key>line</key><integer>202</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>200</integer>
+// CHECK-NEXT: <key>line</key><integer>202</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5307,12 +5309,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>201</integer>
+// CHECK-NEXT: <key>line</key><integer>203</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>201</integer>
+// CHECK-NEXT: <key>line</key><integer>203</integer>
// CHECK-NEXT: <key>col</key><integer>8</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5328,12 +5330,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>201</integer>
+// CHECK-NEXT: <key>line</key><integer>203</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>201</integer>
+// CHECK-NEXT: <key>line</key><integer>203</integer>
// CHECK-NEXT: <key>col</key><integer>8</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5341,12 +5343,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>202</integer>
+// CHECK-NEXT: <key>line</key><integer>204</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>202</integer>
+// CHECK-NEXT: <key>line</key><integer>204</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5362,12 +5364,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>202</integer>
+// CHECK-NEXT: <key>line</key><integer>204</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>202</integer>
+// CHECK-NEXT: <key>line</key><integer>204</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5375,12 +5377,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>202</integer>
+// CHECK-NEXT: <key>line</key><integer>204</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>202</integer>
+// CHECK-NEXT: <key>line</key><integer>204</integer>
// CHECK-NEXT: <key>col</key><integer>14</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5392,7 +5394,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>202</integer>
+// CHECK-NEXT: <key>line</key><integer>204</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5400,12 +5402,12 @@ void testMyMalloc() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>202</integer>
+// CHECK-NEXT: <key>line</key><integer>204</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>202</integer>
+// CHECK-NEXT: <key>line</key><integer>204</integer>
// CHECK-NEXT: <key>col</key><integer>18</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5421,7 +5423,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>206</integer>
+// CHECK-NEXT: <key>line</key><integer>208</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5429,12 +5431,12 @@ void testMyMalloc() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>206</integer>
+// CHECK-NEXT: <key>line</key><integer>208</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>206</integer>
+// CHECK-NEXT: <key>line</key><integer>208</integer>
// CHECK-NEXT: <key>col</key><integer>25</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5454,12 +5456,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>206</integer>
+// CHECK-NEXT: <key>line</key><integer>208</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>206</integer>
+// CHECK-NEXT: <key>line</key><integer>208</integer>
// CHECK-NEXT: <key>col</key><integer>23</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5467,12 +5469,12 @@ void testMyMalloc() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>207</integer>
+// CHECK-NEXT: <key>line</key><integer>209</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>207</integer>
+// CHECK-NEXT: <key>line</key><integer>209</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5484,7 +5486,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>207</integer>
+// CHECK-NEXT: <key>line</key><integer>209</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -5506,7 +5508,7 @@ void testMyMalloc() {
// CHECK-NEXT: <key>issue_hash_function_offset</key><string>1</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>207</integer>
+// CHECK-NEXT: <key>line</key><integer>209</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
diff --git a/test/Analysis/malloc.mm b/test/Analysis/malloc.mm
index f8a43b3b6a99..e3daa858be87 100644
--- a/test/Analysis/malloc.mm
+++ b/test/Analysis/malloc.mm
@@ -187,7 +187,7 @@ typedef volatile struct {
void *opaque1;
long opaque2;
} OSQueueHead;
-void OSAtomicEnqueue( OSQueueHead *__list, void *__new, size_t __offset) __attribute__((weak_import));
+extern "C" void OSAtomicEnqueue( OSQueueHead *__list, void *__new, size_t __offset) __attribute__((weak_import));
static inline void radar11111210(OSQueueHead *pool) {
void *newItem = malloc(4);
OSAtomicEnqueue(pool, newItem, 4);
diff --git a/test/Analysis/max-nodes-suppress-on-sink.c b/test/Analysis/max-nodes-suppress-on-sink.c
index 8d955b91c1e3..da1e7bf02284 100644
--- a/test/Analysis/max-nodes-suppress-on-sink.c
+++ b/test/Analysis/max-nodes-suppress-on-sink.c
@@ -15,6 +15,8 @@ extern void exit(int) __attribute__ ((__noreturn__));
void clang_analyzer_warnIfReached(void);
+int coin();
+
void test_single_cfg_block_sink() {
void *p = malloc(1); // no-warning (wherever the leak warning may occur here)
@@ -29,3 +31,53 @@ void test_single_cfg_block_sink() {
// the leak report.
exit(0);
}
+
+// A similar test with more complicated control flow before the no-return thing,
+// so that the no-return thing wasn't in the same CFG block.
+void test_more_complex_control_flow_before_sink() {
+ void *p = malloc(1); // no-warning
+
+ clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
+ clang_analyzer_warnIfReached(); // no-warning
+
+ if (coin())
+ exit(0);
+ else
+ exit(1);
+}
+
+// A loop before the no-return function, to make sure that
+// the dominated-by-sink analysis doesn't hang.
+void test_loop_before_sink(int n) {
+ void *p = malloc(1); // no-warning
+
+ clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
+ clang_analyzer_warnIfReached(); // no-warning
+
+ for (int i = 0; i < n; ++i) {
+ }
+ exit(1);
+}
+
+// We're not sure if this is no-return.
+void test_loop_with_sink(int n) {
+ void *p = malloc(1); // expected-warning@+2{{Potential leak of memory}}
+
+ clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
+ clang_analyzer_warnIfReached(); // no-warning
+
+ for (int i = 0; i < n; ++i)
+ if (i == 0)
+ exit(1);
+}
+
+// Handle unreachable blocks correctly.
+void test_unreachable_successor_blocks() {
+ void *p = malloc(1); // no-warning
+
+ clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
+ clang_analyzer_warnIfReached(); // no-warning
+
+ if (1) // no-crash
+ exit(1);
+}
diff --git a/test/Analysis/max-nodes-suppress-on-sink.cpp b/test/Analysis/max-nodes-suppress-on-sink.cpp
new file mode 100644
index 000000000000..814b302789d9
--- /dev/null
+++ b/test/Analysis/max-nodes-suppress-on-sink.cpp
@@ -0,0 +1,34 @@
+// RUN: %clang_analyze_cc1 -x c++ -fcxx-exceptions -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config max-nodes=12 -verify %s
+
+// Here we test how "suppress on sink" feature of certain bugtypes interacts
+// with reaching analysis limits. See comments in max-nodes-suppress-on-sink.c
+// for more discussion.
+
+typedef __typeof(sizeof(int)) size_t;
+void *malloc(size_t);
+
+void clang_analyzer_warnIfReached(void);
+
+// Because we don't have a better approach, we currently treat throw as
+// noreturn.
+void test_throw_treated_as_noreturn() {
+ void *p = malloc(1); // no-warning
+
+ clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
+ clang_analyzer_warnIfReached(); // no-warning
+
+ throw 0;
+}
+
+// FIXME: Handled throws shouldn't be suppressing us!
+void test_handled_throw_treated_as_noreturn() {
+ void *p = malloc(1); // no-warning
+
+ clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
+ clang_analyzer_warnIfReached(); // no-warning
+
+ try {
+ throw 0;
+ } catch (int i) {
+ }
+}
diff --git a/test/Analysis/nonnull-global-constants.mm b/test/Analysis/nonnull-global-constants.mm
new file mode 100644
index 000000000000..7900b9dd1286
--- /dev/null
+++ b/test/Analysis/nonnull-global-constants.mm
@@ -0,0 +1,103 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify %s
+
+// Nullability of const string-like globals, testing
+// NonnullGlobalConstantsChecker.
+
+void clang_analyzer_eval(bool);
+
+@class NSString;
+typedef const struct __CFString *CFStringRef;
+typedef const struct __CFBoolean * CFBooleanRef;
+
+// Global NSString* is non-null.
+extern NSString *const StringConstGlobal;
+void stringConstGlobal() {
+ clang_analyzer_eval(StringConstGlobal); // expected-warning{{TRUE}}
+}
+
+// The logic does not apply to local variables though.
+extern NSString *stringGetter();
+void stringConstLocal() {
+ NSString *const local = stringGetter();
+ clang_analyzer_eval(local); // expected-warning{{UNKNOWN}}
+}
+
+// Global const CFStringRef's are also assumed to be non-null.
+extern const CFStringRef CFStringConstGlobal;
+void cfStringCheckGlobal() {
+ clang_analyzer_eval(CFStringConstGlobal); // expected-warning{{TRUE}}
+}
+
+// But only "const" ones.
+extern CFStringRef CFStringNonConstGlobal;
+void cfStringCheckMutableGlobal() {
+ clang_analyzer_eval(CFStringNonConstGlobal); // expected-warning{{UNKNOWN}}
+}
+
+// char* const is also assumed to be non-null.
+extern const char *const ConstCharStarConst;
+void constCharStarCheckGlobal() {
+ clang_analyzer_eval(ConstCharStarConst); // expected-warning{{TRUE}}
+}
+
+// Pointer value can be mutable.
+extern char *const CharStarConst;
+void charStarCheckGlobal() {
+ clang_analyzer_eval(CharStarConst); // expected-warning{{TRUE}}
+}
+
+// But the pointer itself should be immutable.
+extern char *CharStar;
+void charStartCheckMutableGlobal() {
+ clang_analyzer_eval(CharStar); // expected-warning{{UNKNOWN}}
+}
+
+// Type definitions should also work across typedefs, for pointers:
+typedef char *const str;
+extern str globalStr;
+void charStarCheckTypedef() {
+ clang_analyzer_eval(globalStr); // expected-warning{{TRUE}}
+}
+
+// And for types.
+typedef NSString *const NStr;
+extern NStr globalNSString;
+void NSStringCheckTypedef() {
+ clang_analyzer_eval(globalNSString); // expected-warning{{TRUE}}
+}
+
+// Note that constness could be either inside
+// the var declaration, or in a typedef.
+typedef NSString *NStr2;
+extern const NStr2 globalNSString2;
+void NSStringCheckConstTypedef() {
+ clang_analyzer_eval(globalNSString2); // expected-warning{{TRUE}}
+}
+
+// Nested typedefs should work as well.
+typedef const CFStringRef str1;
+typedef str1 str2;
+extern str2 globalStr2;
+void testNestedTypedefs() {
+ clang_analyzer_eval(globalStr2); // expected-warning{{TRUE}}
+}
+
+// And for NSString *.
+typedef NSString *const nstr1;
+typedef nstr1 nstr2;
+extern nstr2 nglobalStr2;
+void testNestedTypedefsForNSString() {
+ clang_analyzer_eval(nglobalStr2); // expected-warning{{TRUE}}
+}
+
+// And for CFBooleanRefs.
+extern const CFBooleanRef kBool;
+void testNonnullBool() {
+ clang_analyzer_eval(kBool); // expected-warning{{TRUE}}
+}
+
+// And again, only for const one.
+extern CFBooleanRef kBoolMutable;
+void testNonnullNonconstBool() {
+ clang_analyzer_eval(kBoolMutable); // expected-warning{{UNKNOWN}}
+}
diff --git a/test/Analysis/null-deref-path-notes.c b/test/Analysis/null-deref-path-notes.c
new file mode 100644
index 000000000000..a1477a6226a7
--- /dev/null
+++ b/test/Analysis/null-deref-path-notes.c
@@ -0,0 +1,9 @@
+// RUN: %clang_analyze_cc1 -w -x c -analyzer-checker=core -analyzer-output=text -verify %s
+
+// Avoid the crash when finding the expression for tracking the origins
+// of the null pointer for path notes.
+void pr34373() {
+ int *a = 0; // expected-note{{'a' initialized to a null pointer value}}
+ (a + 0)[0]; // expected-warning{{Array access results in a null pointer dereference}}
+ // expected-note@-1{{Array access results in a null pointer dereference}}
+}
diff --git a/test/Analysis/null-deref-path-notes.cpp b/test/Analysis/null-deref-path-notes.cpp
new file mode 100644
index 000000000000..617f5def150a
--- /dev/null
+++ b/test/Analysis/null-deref-path-notes.cpp
@@ -0,0 +1,25 @@
+// RUN: %clang_analyze_cc1 -w -x c++ -analyzer-checker=core -analyzer-output=text -analyzer-eagerly-assume -verify %s
+
+namespace pr34731 {
+int b;
+class c {
+ class B {
+ public:
+ double ***d;
+ B();
+ };
+ void e(double **, int);
+ void f(B &, int &);
+};
+
+// Properly track the null pointer in the array field back to the default
+// constructor of 'h'.
+void c::f(B &g, int &i) {
+ e(g.d[9], i); // expected-warning{{Array access (via field 'd') results in a null pointer dereference}}
+ // expected-note@-1{{Array access (via field 'd') results in a null pointer dereference}}
+ B h, a; // expected-note{{Value assigned to 'h.d'}}
+ a.d == __null; // expected-note{{Assuming the condition is true}}
+ a.d != h.d; // expected-note{{Assuming pointer value is null}}
+ f(h, b); // expected-note{{Calling 'c::f'}}
+}
+}
diff --git a/test/Analysis/null-deref-path-notes.m b/test/Analysis/null-deref-path-notes.m
index 242b5daa9bfc..39cf9c79f311 100644
--- a/test/Analysis/null-deref-path-notes.m
+++ b/test/Analysis/null-deref-path-notes.m
@@ -50,6 +50,23 @@ void repeatedStores(int coin) {
*p = 1; // expected-warning{{Dereference of null pointer}} expected-note{{Dereference of null pointer}}
}
+@interface WithArrayPtr
+- (void) useArray;
+@end
+
+@implementation WithArrayPtr {
+@public int *p;
+}
+- (void)useArray {
+ p[1] = 2; // expected-warning{{Array access (via ivar 'p') results in a null pointer dereference}}
+ // expected-note@-1{{Array access (via ivar 'p') results in a null pointer dereference}}
+}
+@end
+
+void testWithArrayPtr(WithArrayPtr *w) {
+ w->p = 0; // expected-note{{Null pointer value stored to 'p'}}
+ [w useArray]; // expected-note{{Calling 'useArray'}}
+}
// CHECK: <key>diagnostics</key>
// CHECK-NEXT: <array>
@@ -801,4 +818,227 @@ void repeatedStores(int coin) {
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>path</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>67</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>67</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>67</integer>
+// CHECK-NEXT: <key>col</key><integer>10</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Null pointer value stored to &apos;p&apos;</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Null pointer value stored to &apos;p&apos;</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>67</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>67</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>68</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>68</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>68</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>68</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>68</integer>
+// CHECK-NEXT: <key>col</key><integer>14</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Calling &apos;useArray&apos;</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Calling &apos;useArray&apos;</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>60</integer>
+// CHECK-NEXT: <key>col</key><integer>1</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>depth</key><integer>1</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Entered call from &apos;testWithArrayPtr&apos;</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Entered call from &apos;testWithArrayPtr&apos;</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>60</integer>
+// CHECK-NEXT: <key>col</key><integer>1</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>60</integer>
+// CHECK-NEXT: <key>col</key><integer>1</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>61</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>61</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>61</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>61</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>61</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>61</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>61</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>61</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>61</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>1</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Array access (via ivar &apos;p&apos;) results in a null pointer dereference</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Array access (via ivar &apos;p&apos;) results in a null pointer dereference</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>description</key><string>Array access (via ivar &apos;p&apos;) results in a null pointer dereference</string>
+// CHECK-NEXT: <key>category</key><string>Logic error</string>
+// CHECK-NEXT: <key>type</key><string>Dereference of null pointer</string>
+// CHECK-NEXT: <key>check_name</key><string>core.NullDereference</string>
+// CHECK-NEXT: <!-- This hash is experimental and going to change! -->
+// CHECK-NEXT: <key>issue_hash_content_of_line_in_context</key><string>fb0ad1e4e3090d9834d542eb54bc9d2e</string>
+// CHECK-NEXT: <key>issue_context_kind</key><string>Objective-C method</string>
+// CHECK-NEXT: <key>issue_context</key><string>useArray</string>
+// CHECK-NEXT: <key>issue_hash_function_offset</key><string>1</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>61</integer>
+// CHECK-NEXT: <key>col</key><integer>8</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
diff --git a/test/Analysis/null-deref-ps.c b/test/Analysis/null-deref-ps.c
index 5dee308a003d..d0e1f9f5cc33 100644
--- a/test/Analysis/null-deref-ps.c
+++ b/test/Analysis/null-deref-ps.c
@@ -1,5 +1,5 @@
-// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -analyzer-checker=core,deadcode,alpha.core -std=gnu99 -analyzer-store=region -analyzer-purge=none -verify %s -Wno-error=return-type
-// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -analyzer-checker=core,deadcode,alpha.core -std=gnu99 -analyzer-store=region -verify %s -Wno-error=return-type
+// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -Wno-tautological-constant-compare -Wtautological-unsigned-zero-compare -analyzer-checker=core,deadcode,alpha.core -std=gnu99 -analyzer-store=region -analyzer-purge=none -verify %s -Wno-error=return-type
+// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -Wno-tautological-constant-compare -Wtautological-unsigned-zero-compare -analyzer-checker=core,deadcode,alpha.core -std=gnu99 -analyzer-store=region -verify %s -Wno-error=return-type
typedef unsigned uintptr_t;
diff --git a/test/Analysis/nullptr.cpp b/test/Analysis/nullptr.cpp
index 229ad7bbb555..b3e61c9defb9 100644
--- a/test/Analysis/nullptr.cpp
+++ b/test/Analysis/nullptr.cpp
@@ -1,11 +1,12 @@
-// RUN: %clang_analyze_cc1 -std=c++11 -Wno-conversion-null -analyzer-checker=core,debug.ExprInspection -analyzer-store region -verify %s
+// RUN: %clang_analyze_cc1 -std=c++11 -Wno-conversion-null -analyzer-checker=core,debug.ExprInspection -analyzer-store region -analyzer-output=text -verify %s
void clang_analyzer_eval(int);
// test to see if nullptr is detected as a null pointer
void foo1(void) {
- char *np = nullptr;
+ char *np = nullptr; // expected-note{{'np' initialized to a null pointer value}}
*np = 0; // expected-warning{{Dereference of null pointer}}
+ // expected-note@-1{{Dereference of null pointer}}
}
// check if comparing nullptr to nullptr is detected properly
@@ -23,10 +24,11 @@ void foo3(void) {
struct foo {
int a, f;
};
- char *np = nullptr;
+ char *np = nullptr; // expected-note{{'np' initialized to a null pointer value}}
// casting a nullptr to anything should be caught eventually
- int *ip = &(((struct foo *)np)->f);
+ int *ip = &(((struct foo *)np)->f); // expected-note{{'ip' initialized to a null pointer value}}
*ip = 0; // expected-warning{{Dereference of null pointer}}
+ // expected-note@-1{{Dereference of null pointer}}
// should be error here too, but analysis gets stopped
// *np = 0;
}
@@ -49,16 +51,31 @@ int pr10372(void *& x) {
}
void zoo1() {
- char **p = 0;
+ char **p = 0; // expected-note{{'p' initialized to a null pointer value}}
delete *(p + 0); // expected-warning{{Dereference of null pointer}}
+ // expected-note@-1{{Dereference of null pointer}}
+}
+
+void zoo1backwards() {
+ char **p = 0; // expected-note{{'p' initialized to a null pointer value}}
+ delete *(0 + p); // expected-warning{{Dereference of null pointer}}
+ // expected-note@-1{{Dereference of null pointer}}
+}
+
+typedef __INTPTR_TYPE__ intptr_t;
+void zoo1multiply() {
+ char **p = 0; // FIXME-should-be-note:{{'p' initialized to a null pointer value}}
+ delete *((char **)((intptr_t)p * 2)); // expected-warning{{Dereference of null pointer}}
+ // expected-note@-1{{Dereference of null pointer}}
}
void zoo2() {
int **a = 0;
- int **b = 0;
+ int **b = 0; // expected-note{{'b' initialized to a null pointer value}}
asm ("nop"
:"=r"(*a)
:"0"(*b) // expected-warning{{Dereference of null pointer}}
+ // expected-note@-1{{Dereference of null pointer}}
);
}
@@ -70,17 +87,19 @@ int exprWithCleanups() {
int a;
};
- int *x = 0;
+ int *x = 0; // expected-note{{'x' initialized to a null pointer value}}
return S(*x).a; // expected-warning{{Dereference of null pointer}}
+ // expected-note@-1{{Dereference of null pointer}}
}
int materializeTempExpr() {
- int *n = 0;
+ int *n = 0; // expected-note{{'n' initialized to a null pointer value}}
struct S {
int a;
S(int i): a(i) {}
};
const S &s = S(*n); // expected-warning{{Dereference of null pointer}}
+ // expected-note@-1{{Dereference of null pointer}}
return s.a;
}
@@ -98,6 +117,7 @@ struct X {
void invokeF(X* x) {
x->f(); // expected-warning{{Called C++ object pointer is null}}
+ // expected-note@-1{{Called C++ object pointer is null}}
}
struct Type {
@@ -105,26 +125,41 @@ struct Type {
};
void shouldNotCrash() {
- decltype(nullptr) p;
- if (getSymbol())
- invokeF(p); // expected-warning{{1st function call argument is an uninit}}
- if (getSymbol())
- invokeF(nullptr);
- if (getSymbol()) {
- X *x = Type().x;
+ decltype(nullptr) p; // expected-note{{'p' declared without an initial value}}
+ if (getSymbol()) // expected-note {{Assuming the condition is false}}
+ // expected-note@-1{{Taking false branch}}
+ // expected-note@-2{{Assuming the condition is false}}
+ // expected-note@-3{{Taking false branch}}
+ // expected-note@-4{{Assuming the condition is true}}
+ // expected-note@-5{{Taking true branch}}
+ invokeF(p); // expected-warning{{1st function call argument is an uninitialized value}}
+ // expected-note@-1{{1st function call argument is an uninitialized value}}
+ if (getSymbol()) // expected-note {{Assuming the condition is false}}
+ // expected-note@-1{{Taking false branch}}
+ // expected-note@-2{{Assuming the condition is true}}
+ // expected-note@-3{{Taking true branch}}
+ invokeF(nullptr); // expected-note {{Calling 'invokeF'}}
+ // expected-note@-1{{Passing null pointer value via 1st parameter 'x'}}
+ if (getSymbol()) { // expected-note {{Assuming the condition is true}}
+ // expected-note@-1{{Taking true branch}}
+ X *x = Type().x; // expected-note{{'x' initialized to a null pointer value}}
x->f(); // expected-warning{{Called C++ object pointer is null}}
+ // expected-note@-1{{Called C++ object pointer is null}}
}
}
void f(decltype(nullptr) p) {
int *q = nullptr;
clang_analyzer_eval(p == 0); // expected-warning{{TRUE}}
+ // expected-note@-1{{TRUE}}
clang_analyzer_eval(q == 0); // expected-warning{{TRUE}}
+ // expected-note@-1{{TRUE}}
}
decltype(nullptr) returnsNullPtrType();
void fromReturnType() {
((X *)returnsNullPtrType())->f(); // expected-warning{{Called C++ object pointer is null}}
+ // expected-note@-1{{Called C++ object pointer is null}}
}
#define AS_ATTRIBUTE __attribute__((address_space(256)))
diff --git a/test/Analysis/objc-boxing.m b/test/Analysis/objc-boxing.m
index 963374b3ef3c..66f24ddf77b3 100644
--- a/test/Analysis/objc-boxing.m
+++ b/test/Analysis/objc-boxing.m
@@ -5,6 +5,16 @@ void clang_analyzer_eval(int);
typedef signed char BOOL;
typedef long NSInteger;
typedef unsigned long NSUInteger;
+
+@protocol NSObject
+@end
+@interface NSObject <NSObject> {}
+@end
+@protocol NSCopying
+@end
+@protocol NSCoding
+@end
+
@interface NSString @end
@interface NSString (NSStringExtensionMethods)
+ (id)stringWithUTF8String:(const char *)nullTerminatedCString;
@@ -28,7 +38,15 @@ typedef unsigned long NSUInteger;
+ (NSNumber *)numberWithUnsignedInteger:(NSUInteger)value ;
@end
+@interface NSValue : NSObject <NSCopying, NSCoding>
+- (void)getValue:(void *)value;
++ (NSValue *)valueWithBytes:(const void *)value
+ objCType:(const char *)type;
+@end
+typedef typeof(sizeof(int)) size_t;
+extern void *malloc(size_t);
+extern void free(void *);
extern char *strdup(const char *str);
id constant_string() {
@@ -39,6 +57,23 @@ id dynamic_string() {
return @(strdup("boxed dynamic string")); // expected-warning{{Potential memory leak}}
}
+typedef struct __attribute__((objc_boxable)) {
+ const char *str;
+} BoxableStruct;
+
+id leak_within_boxed_struct() {
+ BoxableStruct bs;
+ bs.str = strdup("dynamic string"); // The duped string shall be owned by val.
+ NSValue *val = @(bs); // no-warning
+ return val;
+}
+
+id leak_of_boxed_struct() {
+ BoxableStruct *bs = malloc(sizeof(BoxableStruct)); // The pointer stored in bs isn't owned by val.
+ NSValue *val = @(*bs); // expected-warning{{Potential leak of memory pointed to by 'bs'}}
+ return val;
+}
+
id const_char_pointer(int *x) {
if (x)
return @(3);
diff --git a/test/Analysis/objc-encode.m b/test/Analysis/objc-encode.m
new file mode 100644
index 000000000000..b2379e96d9db
--- /dev/null
+++ b/test/Analysis/objc-encode.m
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=debug.ExprInspection -verify %s
+// expected-no-diagnostics
+
+void clang_analyzer_eval(int);
+
+// rdar://problem/34831581: Used to crash.
+void foo(void) {
+ char buf1[] = @encode(int **);
+}
diff --git a/test/Analysis/objc-for.m b/test/Analysis/objc-for.m
index 41709bee359e..f191e86cc4e4 100644
--- a/test/Analysis/objc-for.m
+++ b/test/Analysis/objc-for.m
@@ -1,6 +1,7 @@
// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.Loops,debug.ExprInspection -verify %s
void clang_analyzer_eval(int);
+void clang_analyzer_warnIfReached();
#define nil ((id)0)
@@ -20,11 +21,13 @@ typedef unsigned long NSUInteger;
@interface NSArray : NSObject <NSFastEnumeration>
- (NSUInteger)count;
- (NSEnumerator *)objectEnumerator;
++ (NSArray *)arrayWithObjects:(const id [])objects count:(NSUInteger)count;
@end
@interface NSDictionary : NSObject <NSFastEnumeration>
- (NSUInteger)count;
- (id)objectForKey:(id)key;
++ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id /* <NSCopying> */ [])keys count:(NSUInteger)count;
@end
@interface NSDictionary (SomeCategory)
@@ -125,7 +128,7 @@ int collectionIsNotEmptyNSArray(NSArray *A) {
int count = [A count];
if (count > 0) {
int i;
- int j;
+ int j = 0;
for (NSString *a in A) {
i = 1;
j++;
@@ -138,7 +141,7 @@ int collectionIsNotEmptyNSArray(NSArray *A) {
void onlySuppressExitAfterZeroIterations(NSMutableDictionary *D) {
if (D.count > 0) {
int *x;
- int i;
+ int i = 0;
for (NSString *key in D) {
x = 0;
i++;
@@ -152,7 +155,7 @@ void onlySuppressExitAfterZeroIterations(NSMutableDictionary *D) {
void onlySuppressLoopExitAfterZeroIterations_WithContinue(NSMutableDictionary *D) {
if (D.count > 0) {
int *x;
- int i;
+ int i = 0;
for (NSString *key in D) {
x = 0;
i++;
@@ -324,3 +327,19 @@ void protocolMethods(NSMutableArray *array) {
for (id key in array)
clang_analyzer_eval(0); // expected-warning{{FALSE}}
}
+
+NSArray *globalArray;
+NSDictionary *globalDictionary;
+void boxedArrayEscape(NSMutableArray *array) {
+ if ([array count])
+ return;
+ globalArray = @[array];
+ for (id key in array)
+ clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
+
+ if ([array count])
+ return;
+ globalDictionary = @{ @"array" : array };
+ for (id key in array)
+ clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
+}
diff --git a/test/Analysis/pointer-arithmetic.c b/test/Analysis/pointer-arithmetic.c
new file mode 100644
index 000000000000..575dfffc01e8
--- /dev/null
+++ b/test/Analysis/pointer-arithmetic.c
@@ -0,0 +1,30 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -verify %s
+
+int test1() {
+ int *p = (int *)sizeof(int);
+ p -= 1;
+ return *p; // expected-warning {{Dereference of null pointer}}
+}
+
+int test2() {
+ int *p = (int *)sizeof(int);
+ p -= 2;
+ p += 1;
+ return *p; // expected-warning {{Dereference of null pointer}}
+}
+
+int test3() {
+ int *p = (int *)sizeof(int);
+ p++;
+ p--;
+ p--;
+ return *p; // expected-warning {{Dereference of null pointer}}
+}
+
+int test4() {
+ // This is a special case where pointer arithmetic is not calculated to
+ // preserve useful warnings on dereferences of null pointers.
+ int *p = 0;
+ p += 1;
+ return *p; // expected-warning {{Dereference of null pointer}}
+}
diff --git a/test/Analysis/pointer-to-member.cpp b/test/Analysis/pointer-to-member.cpp
index 0fbb992dd82a..65882527d2da 100644
--- a/test/Analysis/pointer-to-member.cpp
+++ b/test/Analysis/pointer-to-member.cpp
@@ -230,3 +230,42 @@ void double_diamond() {
clang_analyzer_eval(d2.*(static_cast<int D2::*>(static_cast<int R2::*>(static_cast<int R1::*>(&B::f)))) == 4); // expected-warning {{TRUE}}
}
} // end of testPointerToMemberDiamond namespace
+
+namespace testAnonymousMember {
+struct A {
+ struct {
+ int x;
+ };
+ struct {
+ struct {
+ int y;
+ };
+ };
+ struct {
+ union {
+ int z;
+ };
+ };
+};
+
+void test() {
+ clang_analyzer_eval(&A::x); // expected-warning{{TRUE}}
+ clang_analyzer_eval(&A::y); // expected-warning{{TRUE}}
+ clang_analyzer_eval(&A::z); // expected-warning{{TRUE}}
+
+ // FIXME: These should be true.
+ int A::*l = &A::x, A::*m = &A::y, A::*n = &A::z;
+ clang_analyzer_eval(l); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(m); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(n); // expected-warning{{UNKNOWN}}
+
+ // FIXME: These should be true as well.
+ A a;
+ a.x = 1;
+ clang_analyzer_eval(a.*l == 1); // expected-warning{{UNKNOWN}}
+ a.y = 2;
+ clang_analyzer_eval(a.*m == 2); // expected-warning{{UNKNOWN}}
+ a.z = 3;
+ clang_analyzer_eval(a.*n == 3); // expected-warning{{UNKNOWN}}
+}
+} // end of testAnonymousMember namespace
diff --git a/test/Analysis/ptr-arith.c b/test/Analysis/ptr-arith.c
index b78ec503a1ca..93cb4ee9a66a 100644
--- a/test/Analysis/ptr-arith.c
+++ b/test/Analysis/ptr-arith.c
@@ -342,3 +342,8 @@ void negativeIndex(char *str) {
clang_analyzer_eval(*ptr3 == 'a'); // expected-warning{{UNKNOWN}}
}
+void test_no_crash_on_pointer_to_label() {
+ char *a = &&label;
+ a[0] = 0;
+label:;
+}
diff --git a/test/Analysis/ptr-arith.cpp b/test/Analysis/ptr-arith.cpp
index e1860f4268e0..1eec83c643e1 100644
--- a/test/Analysis/ptr-arith.cpp
+++ b/test/Analysis/ptr-arith.cpp
@@ -98,3 +98,22 @@ void checkMultiDimansionalArray() {
int a[5][5];
*(*(a+1)+2) = 2;
}
+
+unsigned ptrSubtractionNoCrash(char *Begin, char *End) {
+ auto N = End - Begin;
+ if (Begin)
+ return 0;
+ return N;
+}
+
+// Bug 34309
+bool ptrAsIntegerSubtractionNoCrash(__UINTPTR_TYPE__ x, char *p) {
+ __UINTPTR_TYPE__ y = (__UINTPTR_TYPE__)p - 1;
+ return y == x;
+}
+
+// Bug 34374
+bool integerAsPtrSubtractionNoCrash(char *p, __UINTPTR_TYPE__ m) {
+ auto n = p - reinterpret_cast<char*>((__UINTPTR_TYPE__)1);
+ return n == m;
+}
diff --git a/test/Analysis/reference.cpp b/test/Analysis/reference.cpp
index b323b966610a..c269dd7bad10 100644
--- a/test/Analysis/reference.cpp
+++ b/test/Analysis/reference.cpp
@@ -117,6 +117,11 @@ void testRetroactiveNullReference(int *x) {
y = 5; // expected-warning{{Dereference of null pointer}}
}
+namespace TestReferenceAddress {
+struct S { int &x; };
+S getS();
+S *getSP();
+
void testReferenceAddress(int &x) {
// FIXME: Move non-zero reference assumption out of RangeConstraintManager.cpp:422
#ifdef ANALYZER_CM_Z3
@@ -127,23 +132,19 @@ void testReferenceAddress(int &x) {
clang_analyzer_eval(&ref() != 0); // expected-warning{{TRUE}}
#endif
- struct S { int &x; };
-
- extern S getS();
#ifdef ANALYZER_CM_Z3
clang_analyzer_eval(&getS().x != 0); // expected-warning{{UNKNOWN}}
#else
clang_analyzer_eval(&getS().x != 0); // expected-warning{{TRUE}}
#endif
- extern S *getSP();
#ifdef ANALYZER_CM_Z3
clang_analyzer_eval(&getSP()->x != 0); // expected-warning{{UNKNOWN}}
#else
clang_analyzer_eval(&getSP()->x != 0); // expected-warning{{TRUE}}
#endif
}
-
+}
void testFunctionPointerReturn(void *opaque) {
typedef int &(*RefFn)();
diff --git a/test/Analysis/retain-release-inline.m b/test/Analysis/retain-release-inline.m
index 388c55f6be23..4fe6bca4a44a 100644
--- a/test/Analysis/retain-release-inline.m
+++ b/test/Analysis/retain-release-inline.m
@@ -299,15 +299,18 @@ void test_neg() {
bar(s);
}
-__attribute__((cf_returns_retained)) isl_basic_map *isl_basic_map_cow(__attribute__((cf_consumed)) isl_basic_map *bmap);
+__attribute__((annotate("rc_ownership_returns_retained"))) isl_basic_map *isl_basic_map_cow(__attribute__((annotate("rc_ownership_consumed"))) isl_basic_map *bmap);
void free(void *);
+void callee_side_parameter_checking_leak(__attribute__((annotate("rc_ownership_consumed"))) isl_basic_map *bmap) { // expected-warning {{Potential leak of an object}}
+}
+
// As 'isl_basic_map_free' is annotated with 'rc_ownership_trusted_implementation', RetainCountChecker trusts its
// implementation and doesn't analyze its body. If the annotation 'rc_ownership_trusted_implementation' is removed,
// a leak warning is raised by RetainCountChecker as the analyzer is unable to detect a decrement in the reference
// count of 'bmap' along the path in 'isl_basic_map_free' assuming the predicate of the second 'if' branch to be
// true or assuming both the predicates in the function to be false.
-__attribute__((annotate("rc_ownership_trusted_implementation"))) isl_basic_map *isl_basic_map_free(__attribute__((cf_consumed)) isl_basic_map *bmap) {
+__attribute__((annotate("rc_ownership_trusted_implementation"))) isl_basic_map *isl_basic_map_free(__attribute__((annotate("rc_ownership_consumed"))) isl_basic_map *bmap) {
if (!bmap)
return NULL;
@@ -322,7 +325,7 @@ __attribute__((annotate("rc_ownership_trusted_implementation"))) isl_basic_map *
// implementation and doesn't analyze its body. If that annotation is removed, a 'use-after-release' warning might
// be raised by RetainCountChecker as the pointer which is passed as an argument to this function and the pointer
// which is returned from the function point to the same memory location.
-__attribute__((annotate("rc_ownership_trusted_implementation"))) __attribute__((cf_returns_retained)) isl_basic_map *isl_basic_map_copy(isl_basic_map *bmap) {
+__attribute__((annotate("rc_ownership_trusted_implementation"))) __attribute__((annotate("rc_ownership_returns_retained"))) isl_basic_map *isl_basic_map_copy(isl_basic_map *bmap) {
if (!bmap)
return NULL;
@@ -330,7 +333,7 @@ __attribute__((annotate("rc_ownership_trusted_implementation"))) __attribute__((
return bmap;
}
-void test_use_after_release_with_trusted_implementation_annotate_attribute(__attribute__((cf_consumed)) isl_basic_map *bmap) {
+void test_use_after_release_with_trusted_implementation_annotate_attribute(__attribute__((annotate("rc_ownership_consumed"))) isl_basic_map *bmap) {
// After this call, 'bmap' has a +1 reference count.
bmap = isl_basic_map_cow(bmap);
// After the call to 'isl_basic_map_copy', 'bmap' has a +1 reference count.
@@ -341,13 +344,44 @@ void test_use_after_release_with_trusted_implementation_annotate_attribute(__att
isl_basic_map_free(temp);
}
-void test_leak_with_trusted_implementation_annotate_attribute(__attribute__((cf_consumed)) isl_basic_map *bmap) {
+void test_leak_with_trusted_implementation_annotate_attribute(__attribute__((annotate("rc_ownership_consumed"))) isl_basic_map *bmap) {
// After this call, 'bmap' has a +1 reference count.
bmap = isl_basic_map_cow(bmap); // no-warning
// After this call, 'bmap' has a +0 reference count.
isl_basic_map_free(bmap);
}
+void callee_side_parameter_checking_incorrect_rc_decrement(isl_basic_map *bmap) {
+ isl_basic_map_free(bmap); // expected-warning {{Incorrect decrement of the reference count}}
+}
+
+__attribute__((annotate("rc_ownership_returns_retained"))) isl_basic_map *callee_side_parameter_checking_return_notowned_object(isl_basic_map *bmap) {
+ return bmap; // expected-warning {{Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected}}
+}
+
+__attribute__((annotate("rc_ownership_returns_retained"))) isl_basic_map *callee_side_parameter_checking_assign_consumed_parameter_leak_return(__attribute__((annotate("rc_ownership_consumed"))) isl_basic_map *bmap1, __attribute__((annotate("rc_ownership_consumed"))) isl_basic_map *bmap2) { // expected-warning {{Potential leak of an object}}
+ bmap1 = bmap2;
+ isl_basic_map_free(bmap2);
+ return bmap1;
+}
+
+__attribute__((annotate("rc_ownership_returns_retained"))) isl_basic_map *callee_side_parameter_checking_assign_consumed_parameter_leak(__attribute__((annotate("rc_ownership_consumed"))) isl_basic_map *bmap1, __attribute__((annotate("rc_ownership_consumed"))) isl_basic_map *bmap2) { // expected-warning {{Potential leak of an object}}
+ bmap1 = bmap2;
+ isl_basic_map_free(bmap1);
+ return bmap2;
+}
+
+__attribute__((annotate("rc_ownership_returns_retained"))) isl_basic_map *error_path_leak(__attribute__((annotate("rc_ownership_consumed"))) isl_basic_map *bmap1, __attribute__((annotate("rc_ownership_consumed"))) isl_basic_map *bmap2) { // expected-warning {{Potential leak of an object}}
+ bmap1 = isl_basic_map_cow(bmap1);
+ if (!bmap1 || !bmap2)
+ goto error;
+
+ isl_basic_map_free(bmap2);
+ return bmap1;
+error:
+ return isl_basic_map_free(bmap1);
+}
+
//===----------------------------------------------------------------------===//
// Test returning retained and not-retained values.
//===----------------------------------------------------------------------===//
diff --git a/test/Analysis/retain-release-safe.c b/test/Analysis/retain-release-safe.c
new file mode 100644
index 000000000000..de743552428c
--- /dev/null
+++ b/test/Analysis/retain-release-safe.c
@@ -0,0 +1,72 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.RetainCount -verify %s
+
+#pragma clang arc_cf_code_audited begin
+typedef const void * CFTypeRef;
+extern CFTypeRef CFRetain(CFTypeRef cf);
+extern void CFRelease(CFTypeRef cf);
+#pragma clang arc_cf_code_audited end
+
+#define CF_RETURNS_RETAINED __attribute__((cf_returns_retained))
+#define CF_CONSUMED __attribute__((cf_consumed))
+
+extern CFTypeRef CFCreate() CF_RETURNS_RETAINED;
+
+// A "safe" variant of CFRetain that doesn't crash when a null pointer is
+// retained. This is often defined by users in a similar manner. The
+// CF_RETURNS_RETAINED annotation is misleading here, because the function
+// is not supposed to return an object with a +1 retain count. Instead, it
+// is supposed to return an object with +(N+1) retain count, where N is
+// the original retain count of 'cf'. However, there is no good annotation
+// to use in this case, and it is pointless to provide such annotation
+// because the only use cases would be CFRetain and SafeCFRetain.
+// So instead we teach the analyzer to be able to accept such code
+// and ignore the misplaced annotation.
+CFTypeRef SafeCFRetain(CFTypeRef cf) CF_RETURNS_RETAINED {
+ if (cf) {
+ return CFRetain(cf);
+ }
+ return cf;
+}
+
+// A "safe" variant of CFRelease that doesn't crash when a null pointer is
+// released. The CF_CONSUMED annotation seems reasonable here.
+void SafeCFRelease(CFTypeRef CF_CONSUMED cf) {
+ if (cf)
+ CFRelease(cf); // no-warning (when inlined)
+}
+
+void escape(CFTypeRef cf);
+
+void makeSureTestsWork() {
+ CFTypeRef cf = CFCreate();
+ CFRelease(cf);
+ CFRelease(cf); // expected-warning{{Reference-counted object is used after it is released}}
+}
+
+// Make sure we understand that the second SafeCFRetain doesn't return an
+// object with +1 retain count, which we won't be able to release twice.
+void falseOverrelease(CFTypeRef cf) {
+ SafeCFRetain(cf);
+ SafeCFRetain(cf);
+ SafeCFRelease(cf);
+ SafeCFRelease(cf); // no-warning after inlining this.
+}
+
+// Regular CFRelease() should behave similarly.
+void sameWithNormalRelease(CFTypeRef cf) {
+ SafeCFRetain(cf);
+ SafeCFRetain(cf);
+ CFRelease(cf);
+ CFRelease(cf); // no-warning
+}
+
+// Make sure we understand that the second SafeCFRetain doesn't return an
+// object with +1 retain count, which would no longer be owned by us after
+// it escapes to escape() and released once.
+void falseReleaseNotOwned(CFTypeRef cf) {
+ SafeCFRetain(cf);
+ SafeCFRetain(cf);
+ escape(cf);
+ SafeCFRelease(cf);
+ SafeCFRelease(cf); // no-warning after inlining this.
+}
diff --git a/test/Analysis/retain-release.m b/test/Analysis/retain-release.m
index 29af194a3d67..4add50eb5d0d 100644
--- a/test/Analysis/retain-release.m
+++ b/test/Analysis/retain-release.m
@@ -325,6 +325,9 @@ typedef const struct __CFUUID * CFUUIDRef;
extern
void *CFPlugInInstanceCreate(CFAllocatorRef allocator, CFUUIDRef factoryUUID, CFUUIDRef typeUUID);
+typedef struct {
+ int ref;
+} isl_basic_map;
//===----------------------------------------------------------------------===//
// Test cases.
@@ -447,6 +450,51 @@ void f10(io_service_t media, DADiskRef d, CFStringRef s) {
if (session) NSLog(@"ok");
}
+
+// Handle CoreMedia API
+
+struct CMFoo;
+typedef struct CMFoo *CMFooRef;
+
+CMFooRef CMCreateFooRef();
+CMFooRef CMGetFooRef();
+
+typedef signed long SInt32;
+typedef SInt32 OSStatus;
+OSStatus CMCreateFooAndReturnViaOutParameter(CMFooRef * CF_RETURNS_RETAINED fooOut);
+
+void testLeakCoreMediaReferenceType() {
+ CMFooRef f = CMCreateFooRef(); // expected-warning{{leak}}
+}
+
+void testOverReleaseMediaReferenceType() {
+ CMFooRef f = CMGetFooRef();
+ CFRelease(f); // expected-warning{{Incorrect decrement of the reference count}}
+}
+
+void testOkToReleaseReturnsRetainedOutParameter() {
+ CMFooRef foo = 0;
+ OSStatus status = CMCreateFooAndReturnViaOutParameter(&foo);
+
+ if (status != 0)
+ return;
+
+ CFRelease(foo); // no-warning
+}
+
+void testLeakWithReturnsRetainedOutParameter() {
+ CMFooRef foo = 0;
+ OSStatus status = CMCreateFooAndReturnViaOutParameter(&foo);
+
+ if (status != 0)
+ return;
+
+ // FIXME: Ideally we would report a leak here since it is the caller's
+ // responsibility to release 'foo'. However, we don't currently have
+ // a mechanism in this checker to only require a release when a successful
+ // status is returned.
+}
+
// Test retain/release checker with CFString and CFMutableArray.
void f11() {
// Create the array.
@@ -574,6 +622,14 @@ void f17(int x, CFTypeRef p) {
}
}
+__attribute__((annotate("rc_ownership_returns_retained"))) isl_basic_map *isl_basic_map_cow(__attribute__((annotate("rc_ownership_consumed"))) isl_basic_map *bmap);
+
+// Test custom diagnostics for generalized objects.
+void f18(__attribute__((annotate("rc_ownership_consumed"))) isl_basic_map *bmap) {
+ // After this call, 'bmap' has a +1 reference count.
+ bmap = isl_basic_map_cow(bmap); // expected-warning {{Potential leak of an object}}
+}
+
// Test basic tracking of ivars associated with 'self'. For the retain/release
// checker we currently do not want to flag leaks associated with stores
// of tracked objects to ivars.
@@ -1776,15 +1832,15 @@ CFArrayRef camel_copymachine() {
// rdar://problem/8024350
@protocol F18P
-- (id) clone;
+- (id) clone; // expected-note 2 {{method declared here}}
@end
@interface F18 : NSObject<F18P> @end
@interface F18(Cat)
-- (id) clone NS_RETURNS_RETAINED;
+- (id) clone NS_RETURNS_RETAINED; // expected-warning {{overriding method has mismatched ns_returns_retained attributes}}
@end
@implementation F18
-- (id) clone {
+- (id) clone { // expected-warning {{overriding method has mismatched ns_returns_retained attributes}}
return [F18 alloc];
}
@end
diff --git a/test/Analysis/retain-release.mm b/test/Analysis/retain-release.mm
index c9817005c2c5..ac83c1a48e36 100644
--- a/test/Analysis/retain-release.mm
+++ b/test/Analysis/retain-release.mm
@@ -461,3 +461,12 @@ void radar13722286::PrepareBitmap() {
}
}
+// rdar://34210609
+void _() { _(); }; // no-warning
+
+// Do not assume that IOBSDNameMatching increments a reference counter,
+// unless return type is CFMutableDictionaryRef.
+void* IOBSDNameMatching();
+void rdar33832412() {
+ void* x = IOBSDNameMatching(); // no-warning
+}
diff --git a/test/Analysis/stack-capture-leak-arc.mm b/test/Analysis/stack-capture-leak-arc.mm
new file mode 100644
index 000000000000..1ffee934c890
--- /dev/null
+++ b/test/Analysis/stack-capture-leak-arc.mm
@@ -0,0 +1,189 @@
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,alpha.core.StackAddressAsyncEscape -fblocks -fobjc-arc -verify %s
+
+typedef struct dispatch_queue_s *dispatch_queue_t;
+typedef void (^dispatch_block_t)(void);
+void dispatch_async(dispatch_queue_t queue, dispatch_block_t block);
+typedef long dispatch_once_t;
+void dispatch_once(dispatch_once_t *predicate, dispatch_block_t block);
+typedef long dispatch_time_t;
+void dispatch_after(dispatch_time_t when, dispatch_queue_t queue, dispatch_block_t block);
+void dispatch_barrier_sync(dispatch_queue_t queue, dispatch_block_t block);
+
+extern dispatch_queue_t queue;
+extern dispatch_once_t *predicate;
+extern dispatch_time_t when;
+
+void test_block_expr_async() {
+ int x = 123;
+ int *p = &x;
+
+ dispatch_async(queue, ^{
+ *p = 321;
+ });
+ // expected-warning@-3 {{Address of stack memory associated with local variable 'x' \
+is captured by an asynchronously-executed block}}
+}
+
+void test_block_expr_once_no_leak() {
+ int x = 123;
+ int *p = &x;
+ // synchronous, no warning
+ dispatch_once(predicate, ^{
+ *p = 321;
+ });
+}
+
+void test_block_expr_after() {
+ int x = 123;
+ int *p = &x;
+ dispatch_after(when, queue, ^{
+ *p = 321;
+ });
+ // expected-warning@-3 {{Address of stack memory associated with local variable 'x' \
+is captured by an asynchronously-executed block}}
+}
+
+void test_block_expr_async_no_leak() {
+ int x = 123;
+ int *p = &x;
+ // no leak
+ dispatch_async(queue, ^{
+ int y = x;
+ ++y;
+ });
+}
+
+void test_block_var_async() {
+ int x = 123;
+ int *p = &x;
+ void (^b)(void) = ^void(void) {
+ *p = 1;
+ };
+ dispatch_async(queue, b);
+ // expected-warning@-1 {{Address of stack memory associated with local variable 'x' \
+is captured by an asynchronously-executed block}}
+}
+
+void test_block_with_ref_async() {
+ int x = 123;
+ int &r = x;
+ void (^b)(void) = ^void(void) {
+ r = 1;
+ };
+ dispatch_async(queue, b);
+ // expected-warning@-1 {{Address of stack memory associated with local variable 'x' \
+is captured by an asynchronously-executed block}}
+}
+
+dispatch_block_t get_leaking_block() {
+ int leaked_x = 791;
+ int *p = &leaked_x;
+ return ^void(void) {
+ *p = 1;
+ };
+ // expected-warning@-3 {{Address of stack memory associated with local variable 'leaked_x' \
+is captured by a returned block}}
+}
+
+void test_returned_from_func_block_async() {
+ dispatch_async(queue, get_leaking_block());
+ // expected-warning@-1 {{Address of stack memory associated with local variable 'leaked_x' \
+is captured by an asynchronously-executed block}}
+}
+
+// synchronous, no leak
+void test_block_var_once() {
+ int x = 123;
+ int *p = &x;
+ void (^b)(void) = ^void(void) {
+ *p = 1;
+ };
+ dispatch_once(predicate, b); // no-warning
+}
+
+void test_block_var_after() {
+ int x = 123;
+ int *p = &x;
+ void (^b)(void) = ^void(void) {
+ *p = 1;
+ };
+ dispatch_after(when, queue, b);
+ // expected-warning@-1 {{Address of stack memory associated with local variable 'x' \
+is captured by an asynchronously-executed block}}
+}
+
+void test_block_var_async_no_leak() {
+ int x = 123;
+ int *p = &x;
+ void (^b)(void) = ^void(void) {
+ int y = x;
+ ++y;
+ };
+ dispatch_async(queue, b); // no-warning
+}
+
+void test_block_inside_block_async_no_leak() {
+ int x = 123;
+ int *p = &x;
+ void (^inner)(void) = ^void(void) {
+ int y = x;
+ ++y;
+ };
+ void (^outer)(void) = ^void(void) {
+ int z = x;
+ ++z;
+ inner();
+ };
+ dispatch_async(queue, outer); // no-warning
+}
+
+dispatch_block_t accept_and_pass_back_block(dispatch_block_t block) {
+ block();
+ return block; // no-warning
+}
+
+void test_passing_continuation_no_leak() {
+ int x = 123;
+ int *p = &x;
+ void (^cont)(void) = ^void(void) {
+ *p = 128;
+ };
+ accept_and_pass_back_block(cont); // no-warning
+}
+
+@interface NSObject
+@end
+@protocol OS_dispatch_semaphore
+@end
+typedef NSObject<OS_dispatch_semaphore> *dispatch_semaphore_t;
+dispatch_semaphore_t dispatch_semaphore_create(long value);
+long dispatch_semaphore_wait(dispatch_semaphore_t dsema, dispatch_time_t timeout);
+long dispatch_semaphore_signal(dispatch_semaphore_t dsema);
+
+void test_no_leaks_on_semaphore_pattern() {
+ int x = 0;
+ int *p = &x;
+ dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
+ dispatch_async(queue, ^{
+ *p = 1;
+ // Some work.
+ dispatch_semaphore_signal(semaphore);
+ }); // no-warning
+
+ // Do some other work concurrently with the asynchronous work
+ // Wait for the asynchronous work to finish
+ dispatch_semaphore_wait(semaphore, 1000);
+}
+
+void test_dispatch_barrier_sync() {
+ int buf[16];
+ for (int n = 0; n < 16; ++n) {
+ int *ptr = &buf[n];
+ // FIXME: Should not warn. The dispatch_barrier_sync() call ensures
+ // that the block does not outlive 'buf'.
+ dispatch_async(queue, ^{ // expected-warning{{Address of stack memory associated with local variable 'buf' is captured by an asynchronously-executed block}}
+ (void)ptr;
+ });
+ }
+ dispatch_barrier_sync(queue, ^{});
+}
diff --git a/test/Analysis/stack-capture-leak-no-arc.mm b/test/Analysis/stack-capture-leak-no-arc.mm
new file mode 100644
index 000000000000..33829f52e727
--- /dev/null
+++ b/test/Analysis/stack-capture-leak-no-arc.mm
@@ -0,0 +1,37 @@
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,alpha.core.StackAddressAsyncEscape -fblocks -verify %s
+
+typedef struct dispatch_queue_s *dispatch_queue_t;
+typedef void (^dispatch_block_t)(void);
+void dispatch_async(dispatch_queue_t queue, dispatch_block_t block);
+extern dispatch_queue_t queue;
+
+void test_block_inside_block_async_no_leak() {
+ int x = 123;
+ int *p = &x;
+ void (^inner)(void) = ^void(void) {
+ int y = x;
+ ++y;
+ };
+ // Block_copy(...) copies the captured block ("inner") too,
+ // there is no leak in this case.
+ dispatch_async(queue, ^void(void) {
+ int z = x;
+ ++z;
+ inner();
+ }); // no-warning
+}
+
+dispatch_block_t test_block_inside_block_async_leak() {
+ int x = 123;
+ void (^inner)(void) = ^void(void) {
+ int y = x;
+ ++y;
+ };
+ void (^outer)(void) = ^void(void) {
+ int z = x;
+ ++z;
+ inner();
+ };
+ return outer; // expected-warning-re{{Address of stack-allocated block declared on line {{.+}} is captured by a returned block}}
+}
+
diff --git a/test/Analysis/string-with-signedness.c b/test/Analysis/string-with-signedness.c
new file mode 100644
index 000000000000..1b00971a834c
--- /dev/null
+++ b/test/Analysis/string-with-signedness.c
@@ -0,0 +1,10 @@
+// RUN: %clang_analyze_cc1 -Wno-incompatible-library-redeclaration -analyzer-checker=core,unix.cstring,alpha.unix.cstring -verify %s
+
+// expected-no-diagnostics
+
+void *strcpy(unsigned char *, unsigned char *);
+
+unsigned char a, b;
+void testUnsignedStrcpy() {
+ strcpy(&a, &b);
+}
diff --git a/test/Analysis/taint-tester.c b/test/Analysis/taint-tester.c
index 1b59e7bc8e90..3a8cc1825a02 100644
--- a/test/Analysis/taint-tester.c
+++ b/test/Analysis/taint-tester.c
@@ -189,3 +189,10 @@ void atoiTest() {
}
+char *pointer1;
+void *pointer2;
+void noCrashTest() {
+ if (!*pointer1) {
+ __builtin___memcpy_chk(pointer2, pointer1, 0, 0); // no-crash
+ }
+}
diff --git a/test/Analysis/temp-obj-dtors-cfg-output.cpp b/test/Analysis/temp-obj-dtors-cfg-output.cpp
index 372443bedffa..05b6a31059b4 100644
--- a/test/Analysis/temp-obj-dtors-cfg-output.cpp
+++ b/test/Analysis/temp-obj-dtors-cfg-output.cpp
@@ -834,7 +834,8 @@ int testConsistencyNestedNormalReturn(bool value) {
// CHECK: Preds (1): B4
// CHECK: Succs (1): B1
// CHECK: [B4]
-// CHECK: 1: [B7.2] ?: [B6.6]
+// CXX98: 1: [B7.2] ?: [B6.6]
+// CXX11: 1: [B7.3] ?: [B6.6]
// CHECK: 2: [B4.1] (ImplicitCastExpr, NoOp, const class A)
// CHECK: 3: [B4.2]
// CHECK: 4: [B4.3] (CXXConstructExpr, class A)
@@ -843,10 +844,13 @@ int testConsistencyNestedNormalReturn(bool value) {
// CHECK: Preds (2): B5 B6
// CHECK: Succs (2): B3 B2
// CHECK: [B5]
-// CHECK: 1: [B7.2] (ImplicitCastExpr, NoOp, const class A)
-// CHECK: 2: [B5.1]
-// CHECK: 3: [B5.2] (CXXConstructExpr, class A)
-// CHECK: 4: [B5.3] (BindTemporary)
+// CXX98: 1: [B7.2] (ImplicitCastExpr, NoOp, const class A)
+// CXX98: 2: [B5.1]
+// CXX98: 3: [B5.2] (CXXConstructExpr, class A)
+// CXX98: 4: [B5.3] (BindTemporary)
+// CXX11: 1: [B7.3] (ImplicitCastExpr, NoOp, const class A)
+// CXX11: 2: [B5.1] (CXXConstructExpr, class A)
+// CXX11: 3: [B5.2] (BindTemporary)
// CHECK: Preds (1): B7
// CHECK: Succs (1): B4
// CHECK: [B6]
@@ -861,10 +865,15 @@ int testConsistencyNestedNormalReturn(bool value) {
// CHECK: [B7]
// CHECK: 1: A() (CXXConstructExpr, class A)
// CHECK: 2: [B7.1] (BindTemporary)
-// CHECK: 3: [B7.2].operator bool
-// CHECK: 4: [B7.2]
-// CHECK: 5: [B7.4] (ImplicitCastExpr, UserDefinedConversion, _Bool)
-// CHECK: T: [B7.5] ? ... : ...
+// CXX98: 3: [B7.2].operator bool
+// CXX98: 4: [B7.2]
+// CXX98: 5: [B7.4] (ImplicitCastExpr, UserDefinedConversion, _Bool)
+// CXX98: T: [B7.5] ? ... : ...
+// CXX11: 3: [B7.2]
+// CXX11: 4: [B7.3].operator bool
+// CXX11: 5: [B7.3]
+// CXX11: 6: [B7.5] (ImplicitCastExpr, UserDefinedConversion, _Bool)
+// CXX11: T: [B7.6] ? ... : ...
// CHECK: Preds (1): B8
// CHECK: Succs (2): B5 B6
// CHECK: [B0 (EXIT)]
@@ -886,7 +895,8 @@ int testConsistencyNestedNormalReturn(bool value) {
// CHECK: Preds (1): B4
// CHECK: Succs (1): B1
// CHECK: [B4]
-// CHECK: 1: [B7.4] ?: [B6.6]
+// CXX98: 1: [B7.4] ?: [B6.6]
+// CXX11: 1: [B7.5] ?: [B6.6]
// CHECK: 2: [B4.1] (ImplicitCastExpr, NoOp, const class A)
// CHECK: 3: [B4.2]
// CHECK: 4: [B7.2]([B4.3])
@@ -894,10 +904,13 @@ int testConsistencyNestedNormalReturn(bool value) {
// CHECK: Preds (2): B5 B6
// CHECK: Succs (2): B3 B2
// CHECK: [B5]
-// CHECK: 1: [B7.4] (ImplicitCastExpr, NoOp, const class A)
-// CHECK: 2: [B5.1]
-// CHECK: 3: [B5.2] (CXXConstructExpr, class A)
-// CHECK: 4: [B5.3] (BindTemporary)
+// CXX98: 1: [B7.4] (ImplicitCastExpr, NoOp, const class A)
+// CXX98: 2: [B5.1]
+// CXX98: 3: [B5.2] (CXXConstructExpr, class A)
+// CXX98: 4: [B5.3] (BindTemporary)
+// CXX11: 1: [B7.5] (ImplicitCastExpr, NoOp, const class A)
+// CXX11: 2: [B5.1] (CXXConstructExpr, class A)
+// CXX11: 3: [B5.2] (BindTemporary)
// CHECK: Preds (1): B7
// CHECK: Succs (1): B4
// CHECK: [B6]
@@ -914,10 +927,15 @@ int testConsistencyNestedNormalReturn(bool value) {
// CHECK: 2: [B7.1] (ImplicitCastExpr, FunctionToPointerDecay, void (*)(const class A &))
// CHECK: 3: A() (CXXConstructExpr, class A)
// CHECK: 4: [B7.3] (BindTemporary)
-// CHECK: 5: [B7.4].operator bool
-// CHECK: 6: [B7.4]
-// CHECK: 7: [B7.6] (ImplicitCastExpr, UserDefinedConversion, _Bool)
-// CHECK: T: [B7.7] ? ... : ...
+// CXX98: 5: [B7.4].operator bool
+// CXX98: 6: [B7.4]
+// CXX98: 7: [B7.6] (ImplicitCastExpr, UserDefinedConversion, _Bool)
+// CXX98: T: [B7.7] ? ... : ...
+// CXX11: 5: [B7.4]
+// CXX11: 6: [B7.5].operator bool
+// CXX11: 7: [B7.5]
+// CXX11: 8: [B7.7] (ImplicitCastExpr, UserDefinedConversion, _Bool)
+// CXX11: T: [B7.8] ? ... : ...
// CHECK: Preds (2): B8 B9
// CHECK: Succs (2): B5 B6
// CHECK: [B8]
@@ -925,7 +943,8 @@ int testConsistencyNestedNormalReturn(bool value) {
// CHECK: Preds (1): B9
// CHECK: Succs (1): B7
// CHECK: [B9]
-// CHECK: 1: [B12.2] ?: [B11.6]
+// CXX98: 1: [B12.2] ?: [B11.6]
+// CXX11: 1: [B12.3] ?: [B11.6]
// CHECK: 2: [B9.1] (ImplicitCastExpr, NoOp, const class A)
// CHECK: 3: [B9.2]
// CHECK: 4: const A &a = A() ?: A();
@@ -933,10 +952,13 @@ int testConsistencyNestedNormalReturn(bool value) {
// CHECK: Preds (2): B10 B11
// CHECK: Succs (2): B8 B7
// CHECK: [B10]
-// CHECK: 1: [B12.2] (ImplicitCastExpr, NoOp, const class A)
-// CHECK: 2: [B10.1]
-// CHECK: 3: [B10.2] (CXXConstructExpr, class A)
-// CHECK: 4: [B10.3] (BindTemporary)
+// CXX98: 1: [B12.2] (ImplicitCastExpr, NoOp, const class A)
+// CXX98: 2: [B10.1]
+// CXX98: 3: [B10.2] (CXXConstructExpr, class A)
+// CXX98: 4: [B10.3] (BindTemporary)
+// CXX11: 1: [B12.3] (ImplicitCastExpr, NoOp, const class A)
+// CXX11: 2: [B10.1] (CXXConstructExpr, class A)
+// CXX11: 3: [B10.2] (BindTemporary)
// CHECK: Preds (1): B12
// CHECK: Succs (1): B9
// CHECK: [B11]
@@ -951,10 +973,15 @@ int testConsistencyNestedNormalReturn(bool value) {
// CHECK: [B12]
// CHECK: 1: A() (CXXConstructExpr, class A)
// CHECK: 2: [B12.1] (BindTemporary)
-// CHECK: 3: [B12.2].operator bool
-// CHECK: 4: [B12.2]
-// CHECK: 5: [B12.4] (ImplicitCastExpr, UserDefinedConversion, _Bool)
-// CHECK: T: [B12.5] ? ... : ...
+// CXX98: 3: [B12.2].operator bool
+// CXX98: 4: [B12.2]
+// CXX98: 5: [B12.4] (ImplicitCastExpr, UserDefinedConversion, _Bool)
+// CXX98: T: [B12.5] ? ... : ...
+// CXX11: 3: [B12.2]
+// CXX11: 4: [B12.3].operator bool
+// CXX11: 5: [B12.3]
+// CXX11: 6: [B12.5] (ImplicitCastExpr, UserDefinedConversion, _Bool)
+// CXX11: T: [B12.6] ? ... : ...
// CHECK: Preds (1): B13
// CHECK: Succs (2): B10 B11
// CHECK: [B0 (EXIT)]
diff --git a/test/Analysis/uninit-const.c b/test/Analysis/uninit-const.c
index 9a6529a772a7..407c28a5e8ba 100644
--- a/test/Analysis/uninit-const.c
+++ b/test/Analysis/uninit-const.c
@@ -1,4 +1,6 @@
-// RUN: %clang_analyze_cc1 -analyzer-checker=unix.Malloc,core,alpha.core.CallAndMessageUnInitRefArg -analyzer-output=text -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=unix.Malloc,core,alpha.core.CallAndMessageUnInitRefArg,debug.ExprInspection -analyzer-output=text -verify %s
+
+void clang_analyzer_warnIfReached();
// Passing uninitialized const data to function
#include "Inputs/system-header-simulator.h"
@@ -121,6 +123,32 @@ void f_12(void) {
}
+// https://bugs.llvm.org/show_bug.cgi?id=35419
+void f11_0(void) {
+ int x; // expected-note {{'x' declared without an initial value}}
+ x++; // expected-warning {{The expression is an uninitialized value. The computed value will also be garbage}}
+ // expected-note@-1 {{The expression is an uninitialized value. The computed value will also be garbage}}
+ clang_analyzer_warnIfReached(); // no-warning
+}
+void f11_1(void) {
+ int x; // expected-note {{'x' declared without an initial value}}
+ ++x; // expected-warning {{The expression is an uninitialized value. The computed value will also be garbage}}
+ // expected-note@-1 {{The expression is an uninitialized value. The computed value will also be garbage}}
+ clang_analyzer_warnIfReached(); // no-warning
+}
+void f11_2(void) {
+ int x; // expected-note {{'x' declared without an initial value}}
+ x--; // expected-warning {{The expression is an uninitialized value. The computed value will also be garbage}}
+ // expected-note@-1 {{The expression is an uninitialized value. The computed value will also be garbage}}
+ clang_analyzer_warnIfReached(); // no-warning
+}
+void f11_3(void) {
+ int x; // expected-note {{'x' declared without an initial value}}
+ --x; // expected-warning {{The expression is an uninitialized value. The computed value will also be garbage}}
+ // expected-note@-1 {{The expression is an uninitialized value. The computed value will also be garbage}}
+ clang_analyzer_warnIfReached(); // no-warning
+}
+
int f_malloc_1(void) {
int *ptr;
diff --git a/test/Analysis/unix-fns.c b/test/Analysis/unix-fns.c
index 481f545e28bc..9126e1bb39b4 100644
--- a/test/Analysis/unix-fns.c
+++ b/test/Analysis/unix-fns.c
@@ -34,11 +34,40 @@ typedef union {
struct dispatch_disk_s *_ddisk;
} dispatch_object_t __attribute__((__transparent_union__));
typedef void (^dispatch_block_t)(void);
-typedef long dispatch_once_t;
typedef struct dispatch_queue_s *dispatch_queue_t;
-void dispatch_once(dispatch_once_t *predicate, dispatch_block_t block);
void dispatch_sync(dispatch_queue_t queue, dispatch_block_t block);
+typedef long dispatch_once_t;
+
+extern
+__attribute__((__nonnull__))
+__attribute__((__nothrow__))
+void dispatch_once(dispatch_once_t *predicate,
+ __attribute__((__noescape__)) dispatch_block_t block);
+
+// Inlined fast-path dispatch_once defers to the real dispatch_once
+// on the slow path.
+static
+__inline__
+__attribute__((__always_inline__))
+__attribute__((__nonnull__))
+__attribute__((__nothrow__))
+void _dispatch_once(dispatch_once_t *predicate,
+ __attribute__((__noescape__)) dispatch_block_t block)
+{
+ if (__builtin_expect((*predicate), (~0l)) != ~0l) {
+ dispatch_once(predicate, block);
+ } else {
+ __asm__ __volatile__("" ::: "memory");
+ }
+ __builtin_assume(*predicate == ~0l);
+}
+
+// Macro so that user calls to dispatch_once() call the inlined fast-path
+// variant.
+#undef dispatch_once
+#define dispatch_once _dispatch_once
+
#ifndef O_CREAT
#define O_CREAT 0x0200
#define O_RDONLY 0x0000
@@ -181,16 +210,6 @@ void test_valloc_nowarn(size_t sz) {
}
}
-// Test dispatch_once being a macro that wraps a call to _dispatch_once, which in turn
-// calls the real dispatch_once.
-
-static inline void _dispatch_once(dispatch_once_t *predicate, dispatch_block_t block)
-{
- dispatch_once(predicate, block);
-}
-
-#define dispatch_once _dispatch_once
-
void test_dispatch_once_in_macro() {
dispatch_once_t pred = 0;
dispatch_once(&pred, ^(){}); // expected-warning {{Call to 'dispatch_once' uses the local variable 'pred' for the predicate value}}
@@ -206,7 +225,7 @@ void test_dispatch_sync(dispatch_queue_t queue, int *q) {
});
}
-// Test inlining if dispatch_once.
+// Test inlining of dispatch_once.
void test_inline_dispatch_once() {
static dispatch_once_t pred;
int *p = 0;
@@ -215,6 +234,17 @@ void test_inline_dispatch_once() {
});
}
+// Make sure code after call to dispatch once is reached.
+void test_inline_dispatch_once_reachable() {
+ static dispatch_once_t pred;
+ __block int *p;
+ dispatch_once(&pred, ^(void) {
+ p = 0;
+ });
+
+ *p = 7; // expected-warning {{Dereference of null pointer (loaded from variable 'p')}}
+}
+
// CHECK: <key>diagnostics</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
@@ -228,12 +258,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>51</integer>
+// CHECK-NEXT: <key>line</key><integer>80</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>51</integer>
+// CHECK-NEXT: <key>line</key><integer>80</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -241,12 +271,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>53</integer>
+// CHECK-NEXT: <key>line</key><integer>82</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>53</integer>
+// CHECK-NEXT: <key>line</key><integer>82</integer>
// CHECK-NEXT: <key>col</key><integer>4</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -262,12 +292,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>53</integer>
+// CHECK-NEXT: <key>line</key><integer>82</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>53</integer>
+// CHECK-NEXT: <key>line</key><integer>82</integer>
// CHECK-NEXT: <key>col</key><integer>4</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -275,12 +305,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>53</integer>
+// CHECK-NEXT: <key>line</key><integer>82</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>53</integer>
+// CHECK-NEXT: <key>line</key><integer>82</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -292,7 +322,7 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>53</integer>
+// CHECK-NEXT: <key>line</key><integer>82</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -300,12 +330,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>53</integer>
+// CHECK-NEXT: <key>line</key><integer>82</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>53</integer>
+// CHECK-NEXT: <key>line</key><integer>82</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -325,12 +355,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>53</integer>
+// CHECK-NEXT: <key>line</key><integer>82</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>53</integer>
+// CHECK-NEXT: <key>line</key><integer>82</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -338,12 +368,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>56</integer>
+// CHECK-NEXT: <key>line</key><integer>85</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>56</integer>
+// CHECK-NEXT: <key>line</key><integer>85</integer>
// CHECK-NEXT: <key>col</key><integer>4</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -359,12 +389,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>56</integer>
+// CHECK-NEXT: <key>line</key><integer>85</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>56</integer>
+// CHECK-NEXT: <key>line</key><integer>85</integer>
// CHECK-NEXT: <key>col</key><integer>4</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -372,12 +402,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>56</integer>
+// CHECK-NEXT: <key>line</key><integer>85</integer>
// CHECK-NEXT: <key>col</key><integer>8</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>56</integer>
+// CHECK-NEXT: <key>line</key><integer>85</integer>
// CHECK-NEXT: <key>col</key><integer>11</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -389,7 +419,7 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>56</integer>
+// CHECK-NEXT: <key>line</key><integer>85</integer>
// CHECK-NEXT: <key>col</key><integer>8</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -397,12 +427,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>56</integer>
+// CHECK-NEXT: <key>line</key><integer>85</integer>
// CHECK-NEXT: <key>col</key><integer>19</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>56</integer>
+// CHECK-NEXT: <key>line</key><integer>85</integer>
// CHECK-NEXT: <key>col</key><integer>25</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -426,7 +456,7 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>issue_hash_function_offset</key><string>6</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>56</integer>
+// CHECK-NEXT: <key>line</key><integer>85</integer>
// CHECK-NEXT: <key>col</key><integer>8</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -442,12 +472,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>62</integer>
+// CHECK-NEXT: <key>line</key><integer>91</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>62</integer>
+// CHECK-NEXT: <key>line</key><integer>91</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -455,12 +485,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>64</integer>
+// CHECK-NEXT: <key>line</key><integer>93</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>64</integer>
+// CHECK-NEXT: <key>line</key><integer>93</integer>
// CHECK-NEXT: <key>col</key><integer>4</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -476,12 +506,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>64</integer>
+// CHECK-NEXT: <key>line</key><integer>93</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>64</integer>
+// CHECK-NEXT: <key>line</key><integer>93</integer>
// CHECK-NEXT: <key>col</key><integer>4</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -489,12 +519,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>64</integer>
+// CHECK-NEXT: <key>line</key><integer>93</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>64</integer>
+// CHECK-NEXT: <key>line</key><integer>93</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -506,7 +536,7 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>64</integer>
+// CHECK-NEXT: <key>line</key><integer>93</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -514,12 +544,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>64</integer>
+// CHECK-NEXT: <key>line</key><integer>93</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>64</integer>
+// CHECK-NEXT: <key>line</key><integer>93</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -539,12 +569,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>64</integer>
+// CHECK-NEXT: <key>line</key><integer>93</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>64</integer>
+// CHECK-NEXT: <key>line</key><integer>93</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -552,12 +582,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>67</integer>
+// CHECK-NEXT: <key>line</key><integer>96</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>67</integer>
+// CHECK-NEXT: <key>line</key><integer>96</integer>
// CHECK-NEXT: <key>col</key><integer>4</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -573,12 +603,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>67</integer>
+// CHECK-NEXT: <key>line</key><integer>96</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>67</integer>
+// CHECK-NEXT: <key>line</key><integer>96</integer>
// CHECK-NEXT: <key>col</key><integer>4</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -586,12 +616,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>67</integer>
+// CHECK-NEXT: <key>line</key><integer>96</integer>
// CHECK-NEXT: <key>col</key><integer>8</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>67</integer>
+// CHECK-NEXT: <key>line</key><integer>96</integer>
// CHECK-NEXT: <key>col</key><integer>13</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -603,7 +633,7 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>67</integer>
+// CHECK-NEXT: <key>line</key><integer>96</integer>
// CHECK-NEXT: <key>col</key><integer>8</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -611,12 +641,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>67</integer>
+// CHECK-NEXT: <key>line</key><integer>96</integer>
// CHECK-NEXT: <key>col</key><integer>44</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>67</integer>
+// CHECK-NEXT: <key>line</key><integer>96</integer>
// CHECK-NEXT: <key>col</key><integer>50</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -640,7 +670,7 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>issue_hash_function_offset</key><string>6</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>67</integer>
+// CHECK-NEXT: <key>line</key><integer>96</integer>
// CHECK-NEXT: <key>col</key><integer>8</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -656,12 +686,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>73</integer>
+// CHECK-NEXT: <key>line</key><integer>102</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>73</integer>
+// CHECK-NEXT: <key>line</key><integer>102</integer>
// CHECK-NEXT: <key>col</key><integer>17</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -669,12 +699,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>74</integer>
+// CHECK-NEXT: <key>line</key><integer>103</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>74</integer>
+// CHECK-NEXT: <key>line</key><integer>103</integer>
// CHECK-NEXT: <key>col</key><integer>4</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -690,12 +720,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>74</integer>
+// CHECK-NEXT: <key>line</key><integer>103</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>74</integer>
+// CHECK-NEXT: <key>line</key><integer>103</integer>
// CHECK-NEXT: <key>col</key><integer>4</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -703,12 +733,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>74</integer>
+// CHECK-NEXT: <key>line</key><integer>103</integer>
// CHECK-NEXT: <key>col</key><integer>8</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>74</integer>
+// CHECK-NEXT: <key>line</key><integer>103</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -724,12 +754,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>74</integer>
+// CHECK-NEXT: <key>line</key><integer>103</integer>
// CHECK-NEXT: <key>col</key><integer>8</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>74</integer>
+// CHECK-NEXT: <key>line</key><integer>103</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -737,12 +767,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>74</integer>
+// CHECK-NEXT: <key>line</key><integer>103</integer>
// CHECK-NEXT: <key>col</key><integer>52</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>74</integer>
+// CHECK-NEXT: <key>line</key><integer>103</integer>
// CHECK-NEXT: <key>col</key><integer>64</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -754,7 +784,7 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>74</integer>
+// CHECK-NEXT: <key>line</key><integer>103</integer>
// CHECK-NEXT: <key>col</key><integer>52</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -762,12 +792,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>74</integer>
+// CHECK-NEXT: <key>line</key><integer>103</integer>
// CHECK-NEXT: <key>col</key><integer>66</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>74</integer>
+// CHECK-NEXT: <key>line</key><integer>103</integer>
// CHECK-NEXT: <key>col</key><integer>72</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -791,7 +821,7 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>issue_hash_function_offset</key><string>2</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>74</integer>
+// CHECK-NEXT: <key>line</key><integer>103</integer>
// CHECK-NEXT: <key>col</key><integer>52</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -807,12 +837,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>84</integer>
+// CHECK-NEXT: <key>line</key><integer>113</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>84</integer>
+// CHECK-NEXT: <key>line</key><integer>113</integer>
// CHECK-NEXT: <key>col</key><integer>16</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -820,12 +850,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>85</integer>
+// CHECK-NEXT: <key>line</key><integer>114</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>85</integer>
+// CHECK-NEXT: <key>line</key><integer>114</integer>
// CHECK-NEXT: <key>col</key><integer>14</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -837,7 +867,7 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>85</integer>
+// CHECK-NEXT: <key>line</key><integer>114</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -845,12 +875,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>85</integer>
+// CHECK-NEXT: <key>line</key><integer>114</integer>
// CHECK-NEXT: <key>col</key><integer>16</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>85</integer>
+// CHECK-NEXT: <key>line</key><integer>114</integer>
// CHECK-NEXT: <key>col</key><integer>20</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -874,7 +904,7 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>issue_hash_function_offset</key><string>2</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>85</integer>
+// CHECK-NEXT: <key>line</key><integer>114</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -890,12 +920,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>94</integer>
+// CHECK-NEXT: <key>line</key><integer>123</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>94</integer>
+// CHECK-NEXT: <key>line</key><integer>123</integer>
// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -903,12 +933,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>94</integer>
+// CHECK-NEXT: <key>line</key><integer>123</integer>
// CHECK-NEXT: <key>col</key><integer>15</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>94</integer>
+// CHECK-NEXT: <key>line</key><integer>123</integer>
// CHECK-NEXT: <key>col</key><integer>20</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -920,7 +950,7 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>94</integer>
+// CHECK-NEXT: <key>line</key><integer>123</integer>
// CHECK-NEXT: <key>col</key><integer>15</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -928,12 +958,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>94</integer>
+// CHECK-NEXT: <key>line</key><integer>123</integer>
// CHECK-NEXT: <key>col</key><integer>22</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>94</integer>
+// CHECK-NEXT: <key>line</key><integer>123</integer>
// CHECK-NEXT: <key>col</key><integer>22</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -957,7 +987,7 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>issue_hash_function_offset</key><string>1</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>94</integer>
+// CHECK-NEXT: <key>line</key><integer>123</integer>
// CHECK-NEXT: <key>col</key><integer>15</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -973,12 +1003,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>106</integer>
+// CHECK-NEXT: <key>line</key><integer>135</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>106</integer>
+// CHECK-NEXT: <key>line</key><integer>135</integer>
// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -986,12 +1016,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>106</integer>
+// CHECK-NEXT: <key>line</key><integer>135</integer>
// CHECK-NEXT: <key>col</key><integer>15</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>106</integer>
+// CHECK-NEXT: <key>line</key><integer>135</integer>
// CHECK-NEXT: <key>col</key><integer>20</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1003,7 +1033,7 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>106</integer>
+// CHECK-NEXT: <key>line</key><integer>135</integer>
// CHECK-NEXT: <key>col</key><integer>15</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1011,12 +1041,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>106</integer>
+// CHECK-NEXT: <key>line</key><integer>135</integer>
// CHECK-NEXT: <key>col</key><integer>22</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>106</integer>
+// CHECK-NEXT: <key>line</key><integer>135</integer>
// CHECK-NEXT: <key>col</key><integer>22</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1040,7 +1070,7 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>issue_hash_function_offset</key><string>1</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>106</integer>
+// CHECK-NEXT: <key>line</key><integer>135</integer>
// CHECK-NEXT: <key>col</key><integer>15</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1056,12 +1086,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>112</integer>
+// CHECK-NEXT: <key>line</key><integer>141</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>112</integer>
+// CHECK-NEXT: <key>line</key><integer>141</integer>
// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1069,12 +1099,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>112</integer>
+// CHECK-NEXT: <key>line</key><integer>141</integer>
// CHECK-NEXT: <key>col</key><integer>15</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>112</integer>
+// CHECK-NEXT: <key>line</key><integer>141</integer>
// CHECK-NEXT: <key>col</key><integer>20</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1086,7 +1116,7 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>112</integer>
+// CHECK-NEXT: <key>line</key><integer>141</integer>
// CHECK-NEXT: <key>col</key><integer>15</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1094,12 +1124,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>112</integer>
+// CHECK-NEXT: <key>line</key><integer>141</integer>
// CHECK-NEXT: <key>col</key><integer>26</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>112</integer>
+// CHECK-NEXT: <key>line</key><integer>141</integer>
// CHECK-NEXT: <key>col</key><integer>26</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1123,7 +1153,7 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>issue_hash_function_offset</key><string>1</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>112</integer>
+// CHECK-NEXT: <key>line</key><integer>141</integer>
// CHECK-NEXT: <key>col</key><integer>15</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1139,12 +1169,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>124</integer>
+// CHECK-NEXT: <key>line</key><integer>153</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>124</integer>
+// CHECK-NEXT: <key>line</key><integer>153</integer>
// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1152,12 +1182,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>124</integer>
+// CHECK-NEXT: <key>line</key><integer>153</integer>
// CHECK-NEXT: <key>col</key><integer>15</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>124</integer>
+// CHECK-NEXT: <key>line</key><integer>153</integer>
// CHECK-NEXT: <key>col</key><integer>21</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1169,7 +1199,7 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>124</integer>
+// CHECK-NEXT: <key>line</key><integer>153</integer>
// CHECK-NEXT: <key>col</key><integer>15</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1177,12 +1207,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>124</integer>
+// CHECK-NEXT: <key>line</key><integer>153</integer>
// CHECK-NEXT: <key>col</key><integer>28</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>124</integer>
+// CHECK-NEXT: <key>line</key><integer>153</integer>
// CHECK-NEXT: <key>col</key><integer>28</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1206,7 +1236,7 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>issue_hash_function_offset</key><string>1</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>124</integer>
+// CHECK-NEXT: <key>line</key><integer>153</integer>
// CHECK-NEXT: <key>col</key><integer>15</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1222,12 +1252,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>130</integer>
+// CHECK-NEXT: <key>line</key><integer>159</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>130</integer>
+// CHECK-NEXT: <key>line</key><integer>159</integer>
// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1235,12 +1265,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>130</integer>
+// CHECK-NEXT: <key>line</key><integer>159</integer>
// CHECK-NEXT: <key>col</key><integer>15</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>130</integer>
+// CHECK-NEXT: <key>line</key><integer>159</integer>
// CHECK-NEXT: <key>col</key><integer>22</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1252,7 +1282,7 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>130</integer>
+// CHECK-NEXT: <key>line</key><integer>159</integer>
// CHECK-NEXT: <key>col</key><integer>15</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1260,12 +1290,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>130</integer>
+// CHECK-NEXT: <key>line</key><integer>159</integer>
// CHECK-NEXT: <key>col</key><integer>29</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>130</integer>
+// CHECK-NEXT: <key>line</key><integer>159</integer>
// CHECK-NEXT: <key>col</key><integer>29</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1289,7 +1319,7 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>issue_hash_function_offset</key><string>1</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>130</integer>
+// CHECK-NEXT: <key>line</key><integer>159</integer>
// CHECK-NEXT: <key>col</key><integer>15</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1305,12 +1335,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>148</integer>
+// CHECK-NEXT: <key>line</key><integer>177</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>148</integer>
+// CHECK-NEXT: <key>line</key><integer>177</integer>
// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1318,12 +1348,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>148</integer>
+// CHECK-NEXT: <key>line</key><integer>177</integer>
// CHECK-NEXT: <key>col</key><integer>15</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>148</integer>
+// CHECK-NEXT: <key>line</key><integer>177</integer>
// CHECK-NEXT: <key>col</key><integer>20</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1335,7 +1365,7 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>148</integer>
+// CHECK-NEXT: <key>line</key><integer>177</integer>
// CHECK-NEXT: <key>col</key><integer>15</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1343,12 +1373,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>148</integer>
+// CHECK-NEXT: <key>line</key><integer>177</integer>
// CHECK-NEXT: <key>col</key><integer>22</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>148</integer>
+// CHECK-NEXT: <key>line</key><integer>177</integer>
// CHECK-NEXT: <key>col</key><integer>22</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1372,7 +1402,7 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>issue_hash_function_offset</key><string>1</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>148</integer>
+// CHECK-NEXT: <key>line</key><integer>177</integer>
// CHECK-NEXT: <key>col</key><integer>15</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1388,12 +1418,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>160</integer>
+// CHECK-NEXT: <key>line</key><integer>189</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>160</integer>
+// CHECK-NEXT: <key>line</key><integer>189</integer>
// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1401,12 +1431,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>160</integer>
+// CHECK-NEXT: <key>line</key><integer>189</integer>
// CHECK-NEXT: <key>col</key><integer>16</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>160</integer>
+// CHECK-NEXT: <key>line</key><integer>189</integer>
// CHECK-NEXT: <key>col</key><integer>31</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1418,7 +1448,7 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>160</integer>
+// CHECK-NEXT: <key>line</key><integer>189</integer>
// CHECK-NEXT: <key>col</key><integer>16</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1426,12 +1456,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>160</integer>
+// CHECK-NEXT: <key>line</key><integer>189</integer>
// CHECK-NEXT: <key>col</key><integer>33</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>160</integer>
+// CHECK-NEXT: <key>line</key><integer>189</integer>
// CHECK-NEXT: <key>col</key><integer>33</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1455,7 +1485,7 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>issue_hash_function_offset</key><string>1</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>160</integer>
+// CHECK-NEXT: <key>line</key><integer>189</integer>
// CHECK-NEXT: <key>col</key><integer>16</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1471,12 +1501,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>172</integer>
+// CHECK-NEXT: <key>line</key><integer>201</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>172</integer>
+// CHECK-NEXT: <key>line</key><integer>201</integer>
// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1484,12 +1514,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>172</integer>
+// CHECK-NEXT: <key>line</key><integer>201</integer>
// CHECK-NEXT: <key>col</key><integer>15</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>172</integer>
+// CHECK-NEXT: <key>line</key><integer>201</integer>
// CHECK-NEXT: <key>col</key><integer>20</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1501,7 +1531,7 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>172</integer>
+// CHECK-NEXT: <key>line</key><integer>201</integer>
// CHECK-NEXT: <key>col</key><integer>15</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1509,12 +1539,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>172</integer>
+// CHECK-NEXT: <key>line</key><integer>201</integer>
// CHECK-NEXT: <key>col</key><integer>22</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>172</integer>
+// CHECK-NEXT: <key>line</key><integer>201</integer>
// CHECK-NEXT: <key>col</key><integer>22</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1538,7 +1568,7 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>issue_hash_function_offset</key><string>1</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>172</integer>
+// CHECK-NEXT: <key>line</key><integer>201</integer>
// CHECK-NEXT: <key>col</key><integer>15</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1554,12 +1584,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>195</integer>
+// CHECK-NEXT: <key>line</key><integer>214</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>195</integer>
+// CHECK-NEXT: <key>line</key><integer>214</integer>
// CHECK-NEXT: <key>col</key><integer>17</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1567,12 +1597,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>196</integer>
+// CHECK-NEXT: <key>line</key><integer>215</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>196</integer>
+// CHECK-NEXT: <key>line</key><integer>215</integer>
// CHECK-NEXT: <key>col</key><integer>15</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1584,7 +1614,7 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>196</integer>
+// CHECK-NEXT: <key>line</key><integer>215</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1592,12 +1622,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>196</integer>
+// CHECK-NEXT: <key>line</key><integer>215</integer>
// CHECK-NEXT: <key>col</key><integer>17</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>196</integer>
+// CHECK-NEXT: <key>line</key><integer>215</integer>
// CHECK-NEXT: <key>col</key><integer>21</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1621,7 +1651,7 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>issue_hash_function_offset</key><string>2</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>196</integer>
+// CHECK-NEXT: <key>line</key><integer>215</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1633,7 +1663,7 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>201</integer>
+// CHECK-NEXT: <key>line</key><integer>220</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1641,12 +1671,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>201</integer>
+// CHECK-NEXT: <key>line</key><integer>220</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>201</integer>
+// CHECK-NEXT: <key>line</key><integer>220</integer>
// CHECK-NEXT: <key>col</key><integer>8</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1666,12 +1696,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>201</integer>
+// CHECK-NEXT: <key>line</key><integer>220</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>201</integer>
+// CHECK-NEXT: <key>line</key><integer>220</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1679,12 +1709,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>202</integer>
+// CHECK-NEXT: <key>line</key><integer>221</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>202</integer>
+// CHECK-NEXT: <key>line</key><integer>221</integer>
// CHECK-NEXT: <key>col</key><integer>15</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1700,12 +1730,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>202</integer>
+// CHECK-NEXT: <key>line</key><integer>221</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>202</integer>
+// CHECK-NEXT: <key>line</key><integer>221</integer>
// CHECK-NEXT: <key>col</key><integer>15</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1713,12 +1743,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>202</integer>
+// CHECK-NEXT: <key>line</key><integer>221</integer>
// CHECK-NEXT: <key>col</key><integer>24</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>202</integer>
+// CHECK-NEXT: <key>line</key><integer>221</integer>
// CHECK-NEXT: <key>col</key><integer>24</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1730,7 +1760,7 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>202</integer>
+// CHECK-NEXT: <key>line</key><integer>221</integer>
// CHECK-NEXT: <key>col</key><integer>24</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1738,12 +1768,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>202</integer>
+// CHECK-NEXT: <key>line</key><integer>221</integer>
// CHECK-NEXT: <key>col</key><integer>24</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>206</integer>
+// CHECK-NEXT: <key>line</key><integer>225</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1759,7 +1789,7 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>202</integer>
+// CHECK-NEXT: <key>line</key><integer>221</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1767,12 +1797,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>202</integer>
+// CHECK-NEXT: <key>line</key><integer>221</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>206</integer>
+// CHECK-NEXT: <key>line</key><integer>225</integer>
// CHECK-NEXT: <key>col</key><integer>4</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1788,7 +1818,7 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>202</integer>
+// CHECK-NEXT: <key>line</key><integer>221</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1796,12 +1826,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>202</integer>
+// CHECK-NEXT: <key>line</key><integer>221</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>206</integer>
+// CHECK-NEXT: <key>line</key><integer>225</integer>
// CHECK-NEXT: <key>col</key><integer>4</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1817,7 +1847,7 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>202</integer>
+// CHECK-NEXT: <key>line</key><integer>221</integer>
// CHECK-NEXT: <key>col</key><integer>24</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1835,12 +1865,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>202</integer>
+// CHECK-NEXT: <key>line</key><integer>221</integer>
// CHECK-NEXT: <key>col</key><integer>24</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>202</integer>
+// CHECK-NEXT: <key>line</key><integer>221</integer>
// CHECK-NEXT: <key>col</key><integer>24</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1848,12 +1878,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>203</integer>
+// CHECK-NEXT: <key>line</key><integer>222</integer>
// CHECK-NEXT: <key>col</key><integer>4</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>203</integer>
+// CHECK-NEXT: <key>line</key><integer>222</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1869,12 +1899,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>203</integer>
+// CHECK-NEXT: <key>line</key><integer>222</integer>
// CHECK-NEXT: <key>col</key><integer>4</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>203</integer>
+// CHECK-NEXT: <key>line</key><integer>222</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1882,12 +1912,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>203</integer>
+// CHECK-NEXT: <key>line</key><integer>222</integer>
// CHECK-NEXT: <key>col</key><integer>8</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>203</integer>
+// CHECK-NEXT: <key>line</key><integer>222</integer>
// CHECK-NEXT: <key>col</key><integer>8</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1899,7 +1929,7 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>203</integer>
+// CHECK-NEXT: <key>line</key><integer>222</integer>
// CHECK-NEXT: <key>col</key><integer>8</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1907,12 +1937,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>203</integer>
+// CHECK-NEXT: <key>line</key><integer>222</integer>
// CHECK-NEXT: <key>col</key><integer>8</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>203</integer>
+// CHECK-NEXT: <key>line</key><integer>222</integer>
// CHECK-NEXT: <key>col</key><integer>8</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1932,12 +1962,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>203</integer>
+// CHECK-NEXT: <key>line</key><integer>222</integer>
// CHECK-NEXT: <key>col</key><integer>8</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>203</integer>
+// CHECK-NEXT: <key>line</key><integer>222</integer>
// CHECK-NEXT: <key>col</key><integer>8</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1945,12 +1975,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>204</integer>
+// CHECK-NEXT: <key>line</key><integer>223</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>204</integer>
+// CHECK-NEXT: <key>line</key><integer>223</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1966,12 +1996,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>204</integer>
+// CHECK-NEXT: <key>line</key><integer>223</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>204</integer>
+// CHECK-NEXT: <key>line</key><integer>223</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1979,12 +2009,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>204</integer>
+// CHECK-NEXT: <key>line</key><integer>223</integer>
// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>204</integer>
+// CHECK-NEXT: <key>line</key><integer>223</integer>
// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -1996,7 +2026,7 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>204</integer>
+// CHECK-NEXT: <key>line</key><integer>223</integer>
// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2004,12 +2034,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>204</integer>
+// CHECK-NEXT: <key>line</key><integer>223</integer>
// CHECK-NEXT: <key>col</key><integer>4</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>204</integer>
+// CHECK-NEXT: <key>line</key><integer>223</integer>
// CHECK-NEXT: <key>col</key><integer>4</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2030,7 +2060,7 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>issue_hash_content_of_line_in_context</key><string>5d3f4c433004c7a6d4a06aa30cc3ea85</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>204</integer>
+// CHECK-NEXT: <key>line</key><integer>223</integer>
// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2046,12 +2076,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>211</integer>
+// CHECK-NEXT: <key>line</key><integer>230</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>211</integer>
+// CHECK-NEXT: <key>line</key><integer>230</integer>
// CHECK-NEXT: <key>col</key><integer>8</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2059,12 +2089,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>212</integer>
+// CHECK-NEXT: <key>line</key><integer>231</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>212</integer>
+// CHECK-NEXT: <key>line</key><integer>231</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2076,7 +2106,7 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>212</integer>
+// CHECK-NEXT: <key>line</key><integer>231</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2084,12 +2114,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>212</integer>
+// CHECK-NEXT: <key>line</key><integer>231</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>212</integer>
+// CHECK-NEXT: <key>line</key><integer>231</integer>
// CHECK-NEXT: <key>col</key><integer>8</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2109,12 +2139,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>212</integer>
+// CHECK-NEXT: <key>line</key><integer>231</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>212</integer>
+// CHECK-NEXT: <key>line</key><integer>231</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2122,12 +2152,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>213</integer>
+// CHECK-NEXT: <key>line</key><integer>232</integer>
// CHECK-NEXT: <key>col</key><integer>24</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>213</integer>
+// CHECK-NEXT: <key>line</key><integer>232</integer>
// CHECK-NEXT: <key>col</key><integer>24</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2139,7 +2169,7 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>213</integer>
+// CHECK-NEXT: <key>line</key><integer>232</integer>
// CHECK-NEXT: <key>col</key><integer>24</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2147,12 +2177,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>213</integer>
+// CHECK-NEXT: <key>line</key><integer>232</integer>
// CHECK-NEXT: <key>col</key><integer>24</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>215</integer>
+// CHECK-NEXT: <key>line</key><integer>234</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2168,7 +2198,7 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>213</integer>
+// CHECK-NEXT: <key>line</key><integer>232</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2176,12 +2206,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>213</integer>
+// CHECK-NEXT: <key>line</key><integer>232</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>215</integer>
+// CHECK-NEXT: <key>line</key><integer>234</integer>
// CHECK-NEXT: <key>col</key><integer>4</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2197,7 +2227,7 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>187</integer>
+// CHECK-NEXT: <key>line</key><integer>50</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2215,12 +2245,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>187</integer>
+// CHECK-NEXT: <key>line</key><integer>50</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>187</integer>
+// CHECK-NEXT: <key>line</key><integer>50</integer>
// CHECK-NEXT: <key>col</key><integer>6</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2228,12 +2258,46 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>189</integer>
+// CHECK-NEXT: <key>line</key><integer>58</integer>
+// CHECK-NEXT: <key>col</key><integer>2</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>58</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>189</integer>
+// CHECK-NEXT: <key>line</key><integer>58</integer>
+// CHECK-NEXT: <key>col</key><integer>2</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>58</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>59</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>59</integer>
// CHECK-NEXT: <key>col</key><integer>15</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2245,7 +2309,7 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>189</integer>
+// CHECK-NEXT: <key>line</key><integer>59</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2253,12 +2317,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>189</integer>
+// CHECK-NEXT: <key>line</key><integer>59</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>189</integer>
+// CHECK-NEXT: <key>line</key><integer>59</integer>
// CHECK-NEXT: <key>col</key><integer>33</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2274,7 +2338,7 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>189</integer>
+// CHECK-NEXT: <key>line</key><integer>59</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2282,12 +2346,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>189</integer>
+// CHECK-NEXT: <key>line</key><integer>59</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>189</integer>
+// CHECK-NEXT: <key>line</key><integer>59</integer>
// CHECK-NEXT: <key>col</key><integer>33</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2303,7 +2367,7 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>213</integer>
+// CHECK-NEXT: <key>line</key><integer>232</integer>
// CHECK-NEXT: <key>col</key><integer>24</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2321,12 +2385,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>213</integer>
+// CHECK-NEXT: <key>line</key><integer>232</integer>
// CHECK-NEXT: <key>col</key><integer>24</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>213</integer>
+// CHECK-NEXT: <key>line</key><integer>232</integer>
// CHECK-NEXT: <key>col</key><integer>24</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2334,12 +2398,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>214</integer>
+// CHECK-NEXT: <key>line</key><integer>233</integer>
// CHECK-NEXT: <key>col</key><integer>4</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>214</integer>
+// CHECK-NEXT: <key>line</key><integer>233</integer>
// CHECK-NEXT: <key>col</key><integer>4</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2355,12 +2419,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>214</integer>
+// CHECK-NEXT: <key>line</key><integer>233</integer>
// CHECK-NEXT: <key>col</key><integer>4</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>214</integer>
+// CHECK-NEXT: <key>line</key><integer>233</integer>
// CHECK-NEXT: <key>col</key><integer>4</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2368,12 +2432,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>214</integer>
+// CHECK-NEXT: <key>line</key><integer>233</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>214</integer>
+// CHECK-NEXT: <key>line</key><integer>233</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2385,7 +2449,7 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>214</integer>
+// CHECK-NEXT: <key>line</key><integer>233</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2393,12 +2457,12 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>214</integer>
+// CHECK-NEXT: <key>line</key><integer>233</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>214</integer>
+// CHECK-NEXT: <key>line</key><integer>233</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@@ -2419,9 +2483,459 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>issue_hash_content_of_line_in_context</key><string>265c4fd608dafee211bfa93d21c28866</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
-// CHECK-NEXT: <key>line</key><integer>214</integer>
+// CHECK-NEXT: <key>line</key><integer>233</integer>
// CHECK-NEXT: <key>col</key><integer>7</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>path</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>241</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>241</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>243</integer>
+// CHECK-NEXT: <key>col</key><integer>4</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Calling &apos;_dispatch_once&apos;</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Calling &apos;_dispatch_once&apos;</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>50</integer>
+// CHECK-NEXT: <key>col</key><integer>1</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>depth</key><integer>1</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Entered call from &apos;test_inline_dispatch_once_reachable&apos;</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Entered call from &apos;test_inline_dispatch_once_reachable&apos;</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>50</integer>
+// CHECK-NEXT: <key>col</key><integer>1</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>50</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>58</integer>
+// CHECK-NEXT: <key>col</key><integer>2</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>58</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>58</integer>
+// CHECK-NEXT: <key>col</key><integer>2</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>58</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>59</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>59</integer>
+// CHECK-NEXT: <key>col</key><integer>15</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>59</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>59</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>59</integer>
+// CHECK-NEXT: <key>col</key><integer>33</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>1</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Calling &apos;dispatch_once&apos;</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Calling &apos;dispatch_once&apos;</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>59</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>59</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>59</integer>
+// CHECK-NEXT: <key>col</key><integer>33</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>2</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Calling anonymous block</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Calling anonymous block</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>241</integer>
+// CHECK-NEXT: <key>col</key><integer>24</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>depth</key><integer>3</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Entered call from &apos;dispatch_once&apos;</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Entered call from &apos;dispatch_once&apos;</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>241</integer>
+// CHECK-NEXT: <key>col</key><integer>24</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>241</integer>
+// CHECK-NEXT: <key>col</key><integer>24</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>242</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>242</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>242</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>242</integer>
+// CHECK-NEXT: <key>col</key><integer>7</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>242</integer>
+// CHECK-NEXT: <key>col</key><integer>11</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>3</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Null pointer value stored to &apos;p&apos;</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Null pointer value stored to &apos;p&apos;</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>59</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>59</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>59</integer>
+// CHECK-NEXT: <key>col</key><integer>33</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>2</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Returning to caller</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Returning to caller</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>59</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>59</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>59</integer>
+// CHECK-NEXT: <key>col</key><integer>33</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>1</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Returning from &apos;dispatch_once&apos;</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Returning from &apos;dispatch_once&apos;</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>59</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>59</integer>
+// CHECK-NEXT: <key>col</key><integer>15</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>63</integer>
+// CHECK-NEXT: <key>col</key><integer>2</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>63</integer>
+// CHECK-NEXT: <key>col</key><integer>17</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>241</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>241</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>243</integer>
+// CHECK-NEXT: <key>col</key><integer>4</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Returning from &apos;_dispatch_once&apos;</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Returning from &apos;_dispatch_once&apos;</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>241</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>241</integer>
+// CHECK-NEXT: <key>col</key><integer>15</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>245</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>245</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>245</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>245</integer>
+// CHECK-NEXT: <key>col</key><integer>4</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>245</integer>
+// CHECK-NEXT: <key>col</key><integer>4</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Dereference of null pointer (loaded from variable &apos;p&apos;)</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Dereference of null pointer (loaded from variable &apos;p&apos;)</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>description</key><string>Dereference of null pointer (loaded from variable &apos;p&apos;)</string>
+// CHECK-NEXT: <key>category</key><string>Logic error</string>
+// CHECK-NEXT: <key>type</key><string>Dereference of null pointer</string>
+// CHECK-NEXT: <key>check_name</key><string>core.NullDereference</string>
+// CHECK-NEXT: <!-- This hash is experimental and going to change! -->
+// CHECK-NEXT: <key>issue_hash_content_of_line_in_context</key><string>1e83bd4361a2351df0b4e77eb3a9109b</string>
+// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
+// CHECK-NEXT: <key>issue_context</key><string>test_inline_dispatch_once_reachable</string>
+// CHECK-NEXT: <key>issue_hash_function_offset</key><string>7</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>245</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
diff --git a/test/Analysis/unreachable-code-path.c b/test/Analysis/unreachable-code-path.c
index ff58587be2da..effa4d9bfa6f 100644
--- a/test/Analysis/unreachable-code-path.c
+++ b/test/Analysis/unreachable-code-path.c
@@ -213,3 +213,13 @@ void macro(void) {
RETURN(1); // no-warning
}
+// Avoid FP when macro argument is known
+void writeSomething(int *x);
+#define MACRO(C) \
+ if (!C) { \
+ static int x; \
+ writeSomething(&x); \
+ }
+void macro2(void) {
+ MACRO(1);
+}
diff --git a/test/Analysis/vector.m b/test/Analysis/vector.m
new file mode 100644
index 000000000000..e74c487d3a60
--- /dev/null
+++ b/test/Analysis/vector.m
@@ -0,0 +1,61 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify %s
+
+typedef int __attribute__((ext_vector_type(2))) V;
+
+void clang_analyzer_warnIfReached();
+void clang_analyzer_numTimesReached();
+void clang_analyzer_eval(int);
+
+int flag;
+
+V pass_through_and_set_flag(V v) {
+ flag = 1;
+ return v;
+}
+
+V dont_crash_and_dont_split_state(V x, V y) {
+ flag = 0;
+ V z = x && pass_through_and_set_flag(y);
+ clang_analyzer_eval(flag); // expected-warning{{TRUE}}
+ // FIXME: For now we treat vector operator && as short-circuit,
+ // but in fact it is not. It should always evaluate
+ // pass_through_and_set_flag(). It should not split state.
+ // Now we also get FALSE on the other path.
+ // expected-warning@-5{{FALSE}}
+
+ // FIXME: Should be 1 since we should not split state.
+ clang_analyzer_numTimesReached(); // expected-warning{{2}}
+ return z;
+}
+
+void test_read() {
+ V x;
+ x[0] = 0;
+ x[1] = 1;
+
+ clang_analyzer_eval(x[0] == 0); // expected-warning{{TRUE}}
+}
+
+V return_vector() {
+ V z;
+ z[0] = 0;
+ z[1] = 0;
+ return z;
+}
+
+int test_vector_access() {
+ return return_vector()[0]; // no-crash no-warning
+}
+
+@interface I
+@property V v;
+@end
+
+// Do not crash on subscript operations into ObjC properties.
+int myfunc(I *i2) {
+ int out = i2.v[0]; // no-crash no-warning
+
+ // Check that the analysis continues.
+ clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
+ return out;
+}
diff --git a/test/Analysis/virtualcall.cpp b/test/Analysis/virtualcall.cpp
index 56bd32446ee7..c22a8463c04a 100644
--- a/test/Analysis/virtualcall.cpp
+++ b/test/Analysis/virtualcall.cpp
@@ -1,98 +1,83 @@
-// RUN: %clang_analyze_cc1 -analyzer-checker=optin.cplusplus.VirtualCall -analyzer-store region -verify -std=c++11 %s
-// RUN: %clang_analyze_cc1 -analyzer-checker=optin.cplusplus.VirtualCall -analyzer-store region -analyzer-config optin.cplusplus.VirtualCall:Interprocedural=true -DINTERPROCEDURAL=1 -verify -std=c++11 %s
-// RUN: %clang_analyze_cc1 -analyzer-checker=optin.cplusplus.VirtualCall -analyzer-store region -analyzer-config optin.cplusplus.VirtualCall:PureOnly=true -DPUREONLY=1 -verify -std=c++11 %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=optin.cplusplus.VirtualCall -analyzer-store region -analyzer-output=text -verify -std=c++11 %s
-/* When INTERPROCEDURAL is set, we expect diagnostics in all functions reachable
- from a constructor or destructor. If it is not set, we expect diagnostics
- only in the constructor or destructor.
+// RUN: %clang_analyze_cc1 -analyzer-checker=optin.cplusplus.VirtualCall -analyzer-store region -analyzer-config optin.cplusplus.VirtualCall:PureOnly=true -DPUREONLY=1 -analyzer-output=text -verify -std=c++11 %s
- When PUREONLY is set, we expect diagnostics only for calls to pure virtual
- functions not to non-pure virtual functions.
-*/
+#include "virtualcall.h"
class A {
public:
A();
- A(int i);
- ~A() {};
-
- virtual int foo() = 0; // from Sema: expected-note {{'foo' declared here}}
+ ~A(){};
+
+ virtual int foo() = 0;
virtual void bar() = 0;
void f() {
foo();
-#if INTERPROCEDURAL
- // expected-warning-re@-2 {{{{^}}Call Path : foo <-- fCall to pure virtual function during construction has undefined behavior}}
-#endif
+ // expected-warning-re@-1 {{{{^}}Call to pure virtual function during construction}}
+ // expected-note-re@-2 {{{{^}}Call to pure virtual function during construction}}
}
};
class B : public A {
public:
- B() {
- foo();
+ B() { // expected-note {{Calling default constructor for 'A'}}
+ foo();
#if !PUREONLY
-#if INTERPROCEDURAL
- // expected-warning-re@-3 {{{{^}}Call Path : fooCall to virtual function during construction will not dispatch to derived class}}
-#else
- // expected-warning-re@-5 {{{{^}}Call to virtual function during construction will not dispatch to derived class}}
-#endif
+ // expected-warning-re@-2 {{{{^}}Call to virtual function during construction}}
+ // expected-note-re@-3 {{{{^}}This constructor of an object of type 'B' has not returned when the virtual method was called}}
+ // expected-note-re@-4 {{{{^}}Call to virtual function during construction}}
#endif
-
}
~B();
-
+
virtual int foo();
- virtual void bar() { foo(); }
-#if INTERPROCEDURAL
- // expected-warning-re@-2 {{{{^}}Call Path : foo <-- barCall to virtual function during destruction will not dispatch to derived class}}
+ virtual void bar() {
+ foo();
+#if !PUREONLY
+ // expected-warning-re@-2 {{{{^}}Call to virtual function during destruction}}
+ // expected-note-re@-3 {{{{^}}Call to virtual function during destruction}}
#endif
+ }
};
-A::A() {
- f();
-}
-
-A::A(int i) {
- foo(); // From Sema: expected-warning {{call to pure virtual member function 'foo' has undefined behavior}}
-#if INTERPROCEDURAL
- // expected-warning-re@-2 {{{{^}}Call Path : fooCall to pure virtual function during construction has undefined behavior}}
-#else
- // expected-warning-re@-4 {{{{^}}Call to pure virtual function during construction has undefined behavior}}
-#endif
+A::A() {
+ f();
+// expected-note-re@-1 {{{{^}}This constructor of an object of type 'A' has not returned when the virtual method was called}}
+// expected-note-re@-2 {{{{^}}Calling 'A::f'}}
}
B::~B() {
this->B::foo(); // no-warning
this->B::bar();
- this->foo();
#if !PUREONLY
-#if INTERPROCEDURAL
- // expected-warning-re@-3 {{{{^}}Call Path : fooCall to virtual function during destruction will not dispatch to derived class}}
-#else
- // expected-warning-re@-5 {{{{^}}Call to virtual function during destruction will not dispatch to derived class}}
+ // expected-note-re@-2 {{{{^}}This destructor of an object of type '~B' has not returned when the virtual method was called}}
+ // expected-note-re@-3 {{{{^}}Calling 'B::bar'}}
#endif
+ this->foo();
+#if !PUREONLY
+ // expected-warning-re@-2 {{{{^}}Call to virtual function during destruction}}
+ // expected-note-re@-3 {{{{^}}This destructor of an object of type '~B' has not returned when the virtual method was called}}
+ // expected-note-re@-4 {{{{^}}Call to virtual function during destruction}}
#endif
-
+
}
class C : public B {
public:
C();
~C();
-
+
virtual int foo();
void f(int i);
};
C::C() {
- f(foo());
+ f(foo());
#if !PUREONLY
-#if INTERPROCEDURAL
- // expected-warning-re@-3 {{{{^}}Call Path : fooCall to virtual function during construction will not dispatch to derived class}}
-#else
- // expected-warning-re@-5 {{{{^}}Call to virtual function during construction will not dispatch to derived class}}
-#endif
+ // expected-warning-re@-2 {{{{^}}Call to virtual function during construction}}
+ // expected-note-re@-3 {{{{^}}This constructor of an object of type 'C' has not returned when the virtual method was called}}
+ // expected-note-re@-4 {{{{^}}Call to virtual function during construction}}
#endif
}
@@ -112,30 +97,198 @@ public:
foo(); // no-warning
}
~E() { bar(); }
+#if !PUREONLY
+ // expected-note-re@-2 2{{{{^}}Calling '~B'}}
+#endif
int foo() override;
};
-// Regression test: don't crash when there's no direct callee.
class F {
public:
F() {
- void (F::* ptr)() = &F::foo;
+ void (F::*ptr)() = &F::foo;
(this->*ptr)();
}
void foo();
};
+class G {
+public:
+ G() {}
+ virtual void bar();
+ void foo() {
+ bar(); // no warning
+ }
+};
+
+class H {
+public:
+ H() : initState(0) { init(); }
+ int initState;
+ virtual void f() const;
+ void init() {
+ if (initState)
+ f(); // no warning
+ }
+
+ H(int i) {
+ G g;
+ g.foo();
+ g.bar(); // no warning
+ f();
+#if !PUREONLY
+ // expected-warning-re@-2 {{{{^}}Call to virtual function during construction}}
+ // expected-note-re@-3 {{{{^}}This constructor of an object of type 'H' has not returned when the virtual method was called}}
+ // expected-note-re@-4 {{{{^}}Call to virtual function during construction}}
+#endif
+ H &h = *this;
+ h.f();
+#if !PUREONLY
+ // expected-warning-re@-2 {{{{^}}Call to virtual function during construction}}
+ // expected-note-re@-3 {{{{^}}This constructor of an object of type 'H' has not returned when the virtual method was called}}
+ // expected-note-re@-4 {{{{^}}Call to virtual function during construction}}
+#endif
+ }
+};
+
+class X {
+public:
+ X() {
+ g();
+#if !PUREONLY
+ // expected-warning-re@-2 {{{{^}}Call to virtual function during construction}}
+ // expected-note-re@-3 {{{{^}}This constructor of an object of type 'X' has not returned when the virtual method was called}}
+ // expected-note-re@-4 {{{{^}}Call to virtual function during construction}}
+#endif
+ }
+ X(int i) {
+ if (i > 0) {
+#if !PUREONLY
+ // expected-note-re@-2 {{{{^}}Taking true branch}}
+ // expected-note-re@-3 {{{{^}}Taking false branch}}
+#endif
+ X x(i - 1);
+#if !PUREONLY
+ // expected-note-re@-2 {{{{^}}Calling constructor for 'X'}}
+#endif
+ x.g(); // no warning
+ }
+ g();
+#if !PUREONLY
+ // expected-warning-re@-2 {{{{^}}Call to virtual function during construction}}
+ // expected-note-re@-3 {{{{^}}This constructor of an object of type 'X' has not returned when the virtual method was called}}
+ // expected-note-re@-4 {{{{^}}Call to virtual function during construction}}
+#endif
+ }
+ virtual void g();
+};
+
+class M;
+class N {
+public:
+ virtual void virtualMethod();
+ void callFooOfM(M *);
+};
+class M {
+public:
+ M() {
+ N n;
+ n.virtualMethod(); // no warning
+ n.callFooOfM(this);
+#if !PUREONLY
+ // expected-note-re@-2 {{{{^}}This constructor of an object of type 'M' has not returned when the virtual method was called}}
+ // expected-note-re@-3 {{{{^}}Calling 'N::callFooOfM'}}
+#endif
+ }
+ virtual void foo();
+};
+void N::callFooOfM(M *m) {
+ m->foo();
+#if !PUREONLY
+ // expected-warning-re@-2 {{{{^}}Call to virtual function during construction}}
+ // expected-note-re@-3 {{{{^}}Call to virtual function during construction}}
+#endif
+}
+
+class Y {
+public:
+ virtual void foobar();
+ void fooY() {
+ F f1;
+ foobar();
+#if !PUREONLY
+ // expected-warning-re@-2 {{{{^}}Call to virtual function during construction}}
+ // expected-note-re@-3 {{{{^}}Call to virtual function during construction}}
+#endif
+ }
+ Y() { fooY(); }
+#if !PUREONLY
+ // expected-note-re@-2 {{{{^}}This constructor of an object of type 'Y' has not returned when the virtual method was called}}
+ // expected-note-re@-3 {{{{^}}Calling 'Y::fooY'}}
+#endif
+};
+
int main() {
- A *a;
- B *b;
- C *c;
- D *d;
- E *e;
- F *f;
+ B b;
+#if PUREONLY
+ //expected-note-re@-2 {{{{^}}Calling default constructor for 'B'}}
+#else
+ //expected-note-re@-4 2{{{{^}}Calling default constructor for 'B'}}
+#endif
+ C c;
+#if !PUREONLY
+ //expected-note-re@-2 {{{{^}}Calling default constructor for 'C'}}
+#endif
+ D d;
+ E e;
+ F f;
+ G g;
+ H h;
+ H h1(1);
+#if !PUREONLY
+ //expected-note-re@-2 {{{{^}}Calling constructor for 'H'}}
+ //expected-note-re@-3 {{{{^}}Calling constructor for 'H'}}
+#endif
+ X x;
+#if !PUREONLY
+ //expected-note-re@-2 {{{{^}}Calling default constructor for 'X'}}
+#endif
+ X x1(1);
+#if !PUREONLY
+ //expected-note-re@-2 {{{{^}}Calling constructor for 'X'}}
+#endif
+ M m;
+#if !PUREONLY
+ //expected-note-re@-2 {{{{^}}Calling default constructor for 'M'}}
+#endif
+ Y *y = new Y;
+ delete y;
+ header::Z z;
+#if !PUREONLY
+ // expected-note-re@-2 {{{{^}}Calling default constructor for 'Z'}}
+#endif
}
+#if !PUREONLY
+ //expected-note-re@-2 2{{{{^}}Calling '~E'}}
+#endif
-#include "virtualcall.h"
+namespace PR34451 {
+struct a {
+ void b() {
+ a c[1];
+ c->b();
+ }
+};
-#define AS_SYSTEM
-#include "virtualcall.h"
-#undef AS_SYSTEM
+class e {
+ public:
+ void b() const;
+};
+
+class c {
+ void m_fn2() const;
+ e d[];
+};
+
+void c::m_fn2() const { d->b(); }
+}
diff --git a/test/Analysis/virtualcall.h b/test/Analysis/virtualcall.h
index c2ad8a6444c1..e2fde2415ec1 100644
--- a/test/Analysis/virtualcall.h
+++ b/test/Analysis/virtualcall.h
@@ -1,36 +1,14 @@
-#ifdef AS_SYSTEM
-#pragma clang system_header
-
-namespace system {
- class A {
- public:
- A() {
- foo(); // no-warning
- }
-
- virtual int foo();
- };
-}
-
-#else
-
namespace header {
- class A {
+ class Z {
public:
- A() {
+ Z() {
foo();
#if !PUREONLY
-#if INTERPROCEDURAL
- // expected-warning-re@-3 {{{{^}}Call Path : fooCall to virtual function during construction will not dispatch to derived class}}
-#else
- // expected-warning-re@-5 {{{{^}}Call to virtual function during construction will not dispatch to derived class}}
-#endif
+ // expected-warning-re@-2 {{{{^}}Call to virtual function during construction}}
+ // expected-note-re@-3 {{{{^}}This constructor of an object of type 'Z' has not returned when the virtual method was called}}
+ // expected-note-re@-4 {{{{^}}Call to virtual function during construction}}
#endif
-
}
-
virtual int foo();
};
}
-
-#endif
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index fa926c584f8e..4b0e94b666b4 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -26,13 +26,17 @@ llvm_canonicalize_cmake_booleans(
HAVE_LIBZ)
configure_lit_site_cfg(
- ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in
- ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg
+ ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.py.in
+ ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg.py
+ MAIN_CONFIG
+ ${CMAKE_CURRENT_SOURCE_DIR}/lit.cfg.py
)
configure_lit_site_cfg(
- ${CMAKE_CURRENT_SOURCE_DIR}/Unit/lit.site.cfg.in
- ${CMAKE_CURRENT_BINARY_DIR}/Unit/lit.site.cfg
+ ${CMAKE_CURRENT_SOURCE_DIR}/Unit/lit.site.cfg.py.in
+ ${CMAKE_CURRENT_BINARY_DIR}/Unit/lit.site.cfg.py
+ MAIN_CONFIG
+ ${CMAKE_CURRENT_SOURCE_DIR}/Unit/lit.cfg.py
)
option(CLANG_TEST_USE_VG "Run Clang tests under Valgrind" OFF)
@@ -48,11 +52,14 @@ list(APPEND CLANG_TEST_DEPS
clang-offload-bundler
clang-import-test
clang-rename
+ clang-refactor
+ clang-diff
)
if(CLANG_ENABLE_STATIC_ANALYZER)
list(APPEND CLANG_TEST_DEPS
clang-check
+ clang-func-mapping
)
endif()
@@ -124,3 +131,12 @@ add_lit_testsuites(CLANG ${CMAKE_CURRENT_SOURCE_DIR}
add_custom_target(clang-test)
add_dependencies(clang-test check-clang)
set_target_properties(clang-test PROPERTIES FOLDER "Clang tests")
+
+# FIXME: This logic can be removed once all buildbots have moved
+# debuginfo-test from clang/test to llvm/projects or monorepo.
+if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/debuginfo-tests)
+ message(WARNING "Including debuginfo-tests in clang/test is deprecated. Move to llvm/projects or use monorepo.")
+ if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/debuginfo-tests/CMakeLists.txt)
+ add_subdirectory(debuginfo-tests)
+ endif()
+endif()
diff --git a/test/CXX/basic/basic.link/p8.cpp b/test/CXX/basic/basic.link/p8.cpp
new file mode 100644
index 000000000000..54b977d77f68
--- /dev/null
+++ b/test/CXX/basic/basic.link/p8.cpp
@@ -0,0 +1,78 @@
+// RUN: %clang_cc1 -std=c++2a -verify %s -pedantic
+
+template<typename T> struct Template {};
+
+struct Linkage1 { struct Inner {}; };
+typedef struct { struct Inner {}; } Linkage2;
+
+typedef struct {} const NoLinkage1;
+auto x = [] {};
+typedef decltype(x) NoLinkage2;
+auto f() { return [] {}; }
+typedef decltype(f()) NoLinkage3;
+
+inline auto g() { return [] {}; }
+typedef decltype(g()) VisibleNoLinkage1;
+inline auto y = [] {};
+typedef decltype(y) VisibleNoLinkage2;
+inline auto h() { struct {} x; return x; }
+typedef decltype(h()) VisibleNoLinkage3;
+
+extern Linkage1 linkage1v;
+extern Linkage1::Inner linkage1iv;
+extern Linkage2 linkage2v;
+extern Linkage2::Inner linkage2iv;
+extern Template<Linkage1> linkaget1v;
+extern Linkage1 linkage1f();
+void linkage2f(Linkage2);
+
+void use_linkage() {
+ &linkage1v, &linkage1iv, &linkage2v, &linkage2iv, &linkaget1v; // expected-warning 5{{unused}}
+ linkage1f();
+ linkage2f({});
+}
+
+extern NoLinkage1 no_linkage1(); // expected-error {{function 'no_linkage1' is used but not defined in this translation unit}}
+extern NoLinkage2 no_linkage2(); // expected-error {{function 'no_linkage2' is used but not defined in this translation unit}}
+extern NoLinkage3 no_linkage3(); // expected-error {{function 'no_linkage3' is used but not defined in this translation unit}}
+
+void use_no_linkage() {
+ no_linkage1(); // expected-note {{used here}}
+ no_linkage2(); // expected-note {{used here}}
+ no_linkage3(); // expected-note {{used here}}
+}
+
+extern VisibleNoLinkage1 visible_no_linkage1(); // expected-warning {{ISO C++ requires a definition}}
+extern VisibleNoLinkage2 visible_no_linkage2(); // expected-warning {{ISO C++ requires a definition}}
+extern VisibleNoLinkage3 visible_no_linkage3(); // expected-warning {{ISO C++ requires a definition}}
+
+void use_visible_no_linkage() {
+ visible_no_linkage1(); // expected-note {{used here}}
+ visible_no_linkage2(); // expected-note {{used here}}
+ visible_no_linkage3(); // expected-note {{used here}}
+}
+
+namespace {
+ struct InternalLinkage {};
+}
+InternalLinkage internal_linkage(); // expected-error {{used but not defined}}
+void use_internal_linkage() {
+ internal_linkage(); // expected-note {{used here}}
+}
+
+extern inline int not_defined; // expected-error {{not defined}}
+extern inline int defined_after_use;
+void use_inline_vars() {
+ not_defined = 1; // expected-note {{used here}}
+ defined_after_use = 2;
+}
+inline int defined_after_use;
+
+namespace {
+ template<typename T> struct A {
+ static const int n;
+ };
+ template<typename T> const int A<T>::n = 3;
+ static_assert(A<int>::n == 3);
+ int k = A<float>::n;
+}
diff --git a/test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp b/test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp
index 18b18834bb48..cf58a85d849c 100644
--- a/test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp
+++ b/test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp
@@ -73,6 +73,7 @@ void other_contexts() {
int a;
{
X0::X0(a); // expected-error{{qualified reference to 'X0' is a constructor name rather than a type in this context}}
+ // expected-warning@-1 {{redundant parentheses around declaration of variable named 'a'}} expected-note@-1 2{{}}
}
}
diff --git a/test/CXX/basic/basic.scope/basic.scope.declarative/p4.cpp b/test/CXX/basic/basic.scope/basic.scope.declarative/p4.cpp
new file mode 100644
index 000000000000..8c14546edc74
--- /dev/null
+++ b/test/CXX/basic/basic.scope/basic.scope.declarative/p4.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -std=c++2a -verify %s
+
+namespace TagVs {
+ struct Bindable { int a; };
+ struct binding_a {}; // expected-note {{previous}}
+ auto [binding_a] = Bindable{}; // expected-error {{redefinition}}
+ auto [binding_b] = Bindable{}; // expected-note {{previous}}
+ struct binding_b {}; // expected-error {{redefinition}}
+
+ struct vartemplate_a {}; // expected-note {{previous}}
+ template<typename T> int vartemplate_a; // expected-error {{redefinition}}
+ template<typename T> int vartemplate_b; // expected-note {{previous}}
+ struct vartemplate_b {}; // expected-error {{redefinition}}
+
+ struct aliastemplate_a {}; // expected-note {{previous}}
+ template<typename T> using aliastemplate_a = int; // expected-error {{redefinition}}
+ template<typename T> using aliastemplate_b = int; // expected-note {{previous}}
+ struct aliastemplate_b {}; // expected-error {{redefinition}}
+}
diff --git a/test/CXX/class/class.static/class.static.data/p3.cpp b/test/CXX/class/class.static/class.static.data/p3.cpp
index 413017d13351..5640bc30ad4c 100644
--- a/test/CXX/class/class.static/class.static.data/p3.cpp
+++ b/test/CXX/class/class.static/class.static.data/p3.cpp
@@ -50,4 +50,4 @@ U<NonLit> u2; // expected-note {{here}}
static_assert(U<int>::a == 0, "");
-constexpr int outofline = (U<NonLit>::d, 0); // expected-note {{here}} expected-warning {{unused}}
+constexpr int outofline = (U<NonLit>::d, 0); // expected-note {{here}}
diff --git a/test/CXX/concepts-ts/dcl.dcl/lit.cfg.py b/test/CXX/concepts-ts/dcl.dcl/lit.cfg.py
new file mode 100644
index 000000000000..c705e3cb93b4
--- /dev/null
+++ b/test/CXX/concepts-ts/dcl.dcl/lit.cfg.py
@@ -0,0 +1,26 @@
+# -*- Python -*-
+
+import os
+import lit.formats
+
+from lit.llvm import llvm_config
+
+# Configuration file for the 'lit' test runner.
+
+# name: The name of this test suite.
+config.name = 'Clang-Concepts-TS-Unsupported'
+
+# testFormat: The test format to use to interpret tests.
+#
+# For now we require '&&' between commands, until they get globally killed and
+# the test runner updated.
+config.test_format = lit.formats.ShTest(not llvm_config.use_lit_shell)
+
+# suffixes: A list of file extensions to treat as test files.
+config.suffixes = ['.c', '.cpp', '.cppm', '.m', '.mm', '.cu',
+ '.ll', '.cl', '.s', '.S', '.modulemap', '.test', '.rs']
+
+config.unsupported = True
+
+# test_source_root: The root path where tests are located.
+config.test_source_root = os.path.dirname(__file__)
diff --git a/test/CXX/conv/conv.prom/p2.cpp b/test/CXX/conv/conv.prom/p2.cpp
index ca64cfa8d0ec..c5ac9112d887 100644
--- a/test/CXX/conv/conv.prom/p2.cpp
+++ b/test/CXX/conv/conv.prom/p2.cpp
@@ -1,5 +1,5 @@
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x -triple x86_64-pc-linux-gnu -ffreestanding %s
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x -triple x86_64-pc-linux-gnu -ffreestanding -fshort-wchar %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x -triple x86_64-pc-linux-gnu -ffreestanding -fwchar-type=short -fno-signed-wchar %s
// expected-no-diagnostics
#include <stdint.h>
diff --git a/test/CXX/dcl.dcl/dcl.attr/dcl.attr.depend/p1.cpp b/test/CXX/dcl.dcl/dcl.attr/dcl.attr.depend/p1.cpp
index 9f7ef3ace9c2..6cf27af3230b 100644
--- a/test/CXX/dcl.dcl/dcl.attr/dcl.attr.depend/p1.cpp
+++ b/test/CXX/dcl.dcl/dcl.attr/dcl.attr.depend/p1.cpp
@@ -7,8 +7,8 @@
[[carries_dependency]] void f1(); // FIXME: warn here
[[carries_dependency]] int f2(); // ok
int f3(int param [[carries_dependency]]); // ok
-[[carries_dependency]] int (*f4)(); // expected-error {{'carries_dependency' attribute only applies to functions, methods, and parameters}}
-int (*f5 [[carries_dependency]])(); // expected-error {{'carries_dependency' attribute only applies to functions, methods, and parameters}}
+[[carries_dependency]] int (*f4)(); // expected-error {{'carries_dependency' attribute only applies to parameters, Objective-C methods, and functions}}
+int (*f5 [[carries_dependency]])(); // expected-error {{'carries_dependency' attribute only applies to}}
int (*f6)() [[carries_dependency]]; // expected-error {{'carries_dependency' attribute cannot be applied to types}}
int (*f7)(int n [[carries_dependency]]); // expected-error {{'[[carries_dependency]]' attribute only allowed on parameter in a function declaration}}
int (((f8)))(int n [[carries_dependency]]); // ok
@@ -21,7 +21,7 @@ struct S {
};
void f() {
[[carries_dependency]] int f(int n [[carries_dependency]]); // ok
- [[carries_dependency]] // expected-error {{'carries_dependency' attribute only applies to functions, methods, and parameters}}
+ [[carries_dependency]] // expected-error {{'carries_dependency' attribute only applies to}}
int (*p)(int n [[carries_dependency]]); // expected-error {{'[[carries_dependency]]' attribute only allowed on parameter in a function declaration}}
}
diff --git a/test/CXX/dcl.dcl/dcl.attr/dcl.attr.fallthrough/p1.cpp b/test/CXX/dcl.dcl/dcl.attr/dcl.attr.fallthrough/p1.cpp
index e7c90339a214..f267d9067bcc 100644
--- a/test/CXX/dcl.dcl/dcl.attr/dcl.attr.fallthrough/p1.cpp
+++ b/test/CXX/dcl.dcl/dcl.attr/dcl.attr.fallthrough/p1.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++1z -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++1z -verify %s
void f(int n) {
switch (n) {
diff --git a/test/CXX/dcl.dcl/dcl.attr/dcl.attr.nodiscard/p1.cpp b/test/CXX/dcl.dcl/dcl.attr/dcl.attr.nodiscard/p1.cpp
index e7a238241295..4425416650ea 100644
--- a/test/CXX/dcl.dcl/dcl.attr/dcl.attr.nodiscard/p1.cpp
+++ b/test/CXX/dcl.dcl/dcl.attr/dcl.attr.nodiscard/p1.cpp
@@ -7,4 +7,4 @@ struct [[nodiscard("Wrong")]] S3 {}; // expected-error {{'nodiscard' cannot have
[[nodiscard]] int f();
enum [[nodiscard]] E {};
-namespace [[nodiscard]] N {} // expected-warning {{'nodiscard' attribute only applies to functions, methods, enums, and classes}}
+namespace [[nodiscard]] N {} // expected-warning {{'nodiscard' attribute only applies to Objective-C methods, enums, structs, unions, classes, functions, and function pointers}}
diff --git a/test/CXX/dcl.dcl/dcl.attr/dcl.attr.nodiscard/p2.cpp b/test/CXX/dcl.dcl/dcl.attr/dcl.attr.nodiscard/p2.cpp
index 072f5e74aabb..49c418a68764 100644
--- a/test/CXX/dcl.dcl/dcl.attr/dcl.attr.nodiscard/p2.cpp
+++ b/test/CXX/dcl.dcl/dcl.attr/dcl.attr.nodiscard/p2.cpp
@@ -9,21 +9,33 @@ enum [[nodiscard]] E {};
E get_e();
[[nodiscard]] int get_i();
+[[nodiscard]] volatile int &get_vi();
void f() {
get_s(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
get_i(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ get_vi(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
get_e(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
// Okay, warnings are not encouraged
get_s_ref();
(void)get_s();
(void)get_i();
+ (void)get_vi();
(void)get_e();
}
+[[nodiscard]] volatile char &(*fp)();
+void g() {
+ fp(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ // OK, warning suppressed.
+ (void)fp();
+}
#ifdef EXT
// expected-warning@4 {{use of the 'nodiscard' attribute is a C++17 extension}}
// expected-warning@8 {{use of the 'nodiscard' attribute is a C++17 extension}}
// expected-warning@11 {{use of the 'nodiscard' attribute is a C++17 extension}}
+// expected-warning@12 {{use of the 'nodiscard' attribute is a C++17 extension}}
+// expected-warning@28 {{use of the 'nodiscard' attribute is a C++17 extension}}
#endif
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p2.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p2.cpp
index 0b7a902f9378..13721518e6f9 100644
--- a/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p2.cpp
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p2.cpp
@@ -39,6 +39,7 @@ struct S {
void foo(auto int ap, register int rp) {
#if __cplusplus >= 201103L // C++11 or later
// expected-warning@-2 {{'auto' storage class specifier is not permitted in C++11, and will not be supported in future releases}}
+// expected-warning@-3 {{'register' storage class specifier is deprecated}}
#endif
auto int abo;
#if __cplusplus >= 201103L // C++11 or later
diff --git a/test/CXX/drs/dr11xx.cpp b/test/CXX/drs/dr11xx.cpp
new file mode 100644
index 000000000000..81fbc1e3ef1b
--- /dev/null
+++ b/test/CXX/drs/dr11xx.cpp
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++14 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++17 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++2a %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+
+namespace dr1113 { // dr1113: partial
+ namespace named {
+ extern int a; // expected-note {{previous}}
+ static int a; // expected-error {{static declaration of 'a' follows non-static}}
+ }
+ namespace {
+ extern int a;
+ static int a; // ok, both declarations have internal linkage
+ int b = a;
+ }
+
+ // FIXME: Per DR1113 and DR4, this is ill-formed due to ambiguity: the second
+ // 'f' has internal linkage, and so does not have C language linkage, so is
+ // not a redeclaration of the first 'f'.
+ //
+ // To avoid a breaking change here, Clang ignores the "internal linkage" effect
+ // of anonymous namespaces on declarations declared within an 'extern "C"'
+ // linkage-specification.
+ extern "C" void f();
+ namespace {
+ extern "C" void f();
+ }
+ void g() { f(); }
+}
diff --git a/test/CXX/drs/dr4xx.cpp b/test/CXX/drs/dr4xx.cpp
index 1a5976eadaff..d27adc428d51 100644
--- a/test/CXX/drs/dr4xx.cpp
+++ b/test/CXX/drs/dr4xx.cpp
@@ -22,6 +22,9 @@ namespace dr401 { // dr401: yes
class B {
protected:
typedef int type; // expected-note {{protected}}
+#if __cplusplus == 199711L
+ // expected-note@-2 {{protected}}
+#endif
};
class C {
@@ -593,10 +596,10 @@ namespace dr447 { // dr447: yes
U<__builtin_offsetof(A, n)>::type a;
U<__builtin_offsetof(T, n)>::type b; // expected-error +{{}} expected-warning 0+{{}}
// as an extension, we allow the member-designator to include array indices
- g(__builtin_offsetof(A, a[0])).h<int>(); // expected-error {{extension}}
- g(__builtin_offsetof(A, a[N])).h<int>(); // expected-error {{extension}}
- U<__builtin_offsetof(A, a[0])>::type c; // expected-error {{extension}}
- U<__builtin_offsetof(A, a[N])>::type d; // expected-error {{extension}} expected-error +{{}} expected-warning 0+{{}}
+ g(__builtin_offsetof(A, a[0])).h<int>();
+ g(__builtin_offsetof(A, a[N])).h<int>();
+ U<__builtin_offsetof(A, a[0])>::type c;
+ U<__builtin_offsetof(A, a[N])>::type d; // expected-error +{{}} expected-warning 0+{{}}
}
}
diff --git a/test/CXX/except/except.spec/p1.cpp b/test/CXX/except/except.spec/p1.cpp
index fa53c9f5d23f..03d75326a643 100644
--- a/test/CXX/except/except.spec/p1.cpp
+++ b/test/CXX/except/except.spec/p1.cpp
@@ -86,3 +86,12 @@ namespace PR11084 {
f<0>(); // expected-note{{in instantiation of function template specialization}}
}
}
+
+namespace FuncTmplNoexceptError {
+ int a = 0;
+ // expected-error@+1{{argument to noexcept specifier must be a constant expression}}
+ template <class T> T f() noexcept(a++){ return {};}
+ void g(){
+ f<int>();
+ }
+};
diff --git a/test/CXX/expr/expr.const/p2-0x.cpp b/test/CXX/expr/expr.const/p2-0x.cpp
index 6d46bf5d77dd..4daed23bf9c6 100644
--- a/test/CXX/expr/expr.const/p2-0x.cpp
+++ b/test/CXX/expr/expr.const/p2-0x.cpp
@@ -145,19 +145,19 @@ namespace UndefinedBehavior {
constexpr int int_min = ~0x7fffffff;
constexpr int minus_int_min = -int_min; // expected-error {{constant expression}} expected-note {{value 2147483648 is outside the range}}
- constexpr int div0 = 3 / 0; // expected-error {{constant expression}} expected-note {{division by zero}} expected-warning {{undefined}}
- constexpr int mod0 = 3 % 0; // expected-error {{constant expression}} expected-note {{division by zero}} expected-warning {{undefined}}
+ constexpr int div0 = 3 / 0; // expected-error {{constant expression}} expected-note {{division by zero}}
+ constexpr int mod0 = 3 % 0; // expected-error {{constant expression}} expected-note {{division by zero}}
constexpr int int_min_div_minus_1 = int_min / -1; // expected-error {{constant expression}} expected-note {{value 2147483648 is outside the range}}
constexpr int int_min_mod_minus_1 = int_min % -1; // expected-error {{constant expression}} expected-note {{value 2147483648 is outside the range}}
- constexpr int shl_m1 = 0 << -1; // expected-error {{constant expression}} expected-note {{negative shift count -1}} expected-warning {{negative}}
+ constexpr int shl_m1 = 0 << -1; // expected-error {{constant expression}} expected-note {{negative shift count -1}}
constexpr int shl_0 = 0 << 0; // ok
constexpr int shl_31 = 0 << 31; // ok
- constexpr int shl_32 = 0 << 32; // expected-error {{constant expression}} expected-note {{shift count 32 >= width of type 'int' (32}} expected-warning {{>= width of type}}
+ constexpr int shl_32 = 0 << 32; // expected-error {{constant expression}} expected-note {{shift count 32 >= width of type 'int' (32}}
constexpr int shl_unsigned_negative = unsigned(-3) << 1; // ok
constexpr int shl_unsigned_into_sign = 1u << 31; // ok
constexpr int shl_unsigned_overflow = 1024u << 31; // ok
- constexpr int shl_signed_negative = (-3) << 1; // expected-warning {{shifting a negative signed value is undefined}} // expected-error {{constant expression}} expected-note {{left shift of negative value -3}}
+ constexpr int shl_signed_negative = (-3) << 1; // expected-error {{constant expression}} expected-note {{left shift of negative value -3}}
constexpr int shl_signed_ok = 1 << 30; // ok
constexpr int shl_signed_into_sign = 1 << 31; // ok (DR1457)
constexpr int shl_signed_into_sign_2 = 0x7fffffff << 1; // ok (DR1457)
@@ -166,10 +166,10 @@ namespace UndefinedBehavior {
constexpr int shl_signed_overflow = 1024 << 31; // expected-error {{constant expression}} expected-note {{signed left shift discards bits}} expected-warning {{requires 43 bits to represent}}
constexpr int shl_signed_ok2 = 1024 << 20; // ok
- constexpr int shr_m1 = 0 >> -1; // expected-error {{constant expression}} expected-note {{negative shift count -1}} expected-warning {{negative}}
+ constexpr int shr_m1 = 0 >> -1; // expected-error {{constant expression}} expected-note {{negative shift count -1}}
constexpr int shr_0 = 0 >> 0; // ok
constexpr int shr_31 = 0 >> 31; // ok
- constexpr int shr_32 = 0 >> 32; // expected-error {{constant expression}} expected-note {{shift count 32 >= width of type}} expected-warning {{>= width of type}}
+ constexpr int shr_32 = 0 >> 32; // expected-error {{constant expression}} expected-note {{shift count 32 >= width of type}}
struct S {
int m;
diff --git a/test/CXX/expr/expr.prim/expr.prim.lambda/p8.cpp b/test/CXX/expr/expr.prim/expr.prim.lambda/p8.cpp
index b9b8cd76c011..1cc1fd974ca5 100644
--- a/test/CXX/expr/expr.prim/expr.prim.lambda/p8.cpp
+++ b/test/CXX/expr/expr.prim/expr.prim.lambda/p8.cpp
@@ -8,7 +8,7 @@ class X0 {
(void)[this, this] () {}; // expected-error {{'this' can appear only once}}
(void)[=, foo] () {}; // expected-error {{'&' must precede a capture when}}
(void)[=, &foo] () {};
- (void)[=, this] () {}; // expected-error {{'this' cannot be explicitly captured}}
+ (void)[=, this] () {}; // expected-warning {{C++2a extension}}
(void)[&, foo] () {};
(void)[&, &foo] () {}; // expected-error {{'&' cannot precede a capture when}}
(void)[&, this] () {};
@@ -23,7 +23,7 @@ struct S2 {
void S2::f(int i) {
(void)[&, i]{ };
(void)[&, &i]{ }; // expected-error{{'&' cannot precede a capture when the capture default is '&'}}
- (void)[=, this]{ }; // expected-error{{'this' cannot be explicitly captured}}
+ (void)[=, this]{ }; // expected-warning{{C++2a extension}}
(void)[=]{ this->g(i); };
(void)[i, i]{ }; // expected-error{{'i' can appear only once in a capture list}}
(void)[i(0), i(1)]{ }; // expected-error{{'i' can appear only once in a capture list}}
diff --git a/test/CXX/expr/expr.unary/expr.new/p2-cxx0x.cpp b/test/CXX/expr/expr.unary/expr.new/p2-cxx0x.cpp
index 7305bd1f53e2..a3a2f712c800 100644
--- a/test/CXX/expr/expr.unary/expr.new/p2-cxx0x.cpp
+++ b/test/CXX/expr/expr.unary/expr.new/p2-cxx0x.cpp
@@ -9,12 +9,14 @@ struct only {
void f() {
only<const int*> p = new const auto (0);
only<double*> q = new (auto) (0.0);
+ only<char*> r = new auto {'a'};
new auto; // expected-error{{new expression for type 'auto' requires a constructor argument}}
new (const auto)(); // expected-error{{new expression for type 'const auto' requires a constructor argument}}
new (auto) (1,2,3); // expected-error{{new expression for type 'auto' contains multiple constructor arguments}}
- new auto {1,2,3}; // expected-error{{new expression for type 'auto' cannot use list-initialization}}
- new auto ({1,2,3}); // expected-error{{new expression for type 'auto' cannot use list-initialization}}
+ new auto {}; // expected-error{{new expression for type 'auto' requires a constructor argument}}
+ new auto {1,2,3}; // expected-error{{new expression for type 'auto' contains multiple constructor arguments}}
+ new auto ({1,2,3}); // expected-error{{new expression for type 'auto' contains multiple constructor arguments}}
}
void p2example() {
diff --git a/test/CXX/expr/expr.unary/expr.new/p2-cxx14.cpp b/test/CXX/expr/expr.unary/expr.new/p2-cxx14.cpp
new file mode 100644
index 000000000000..70bbc4805c43
--- /dev/null
+++ b/test/CXX/expr/expr.unary/expr.new/p2-cxx14.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++14 -pedantic
+
+void f() {
+ new auto('a');
+ new auto {2}; // expected-warning {{ISO C++ standards before C++17 do not allow new expression for type 'auto' to use list-initialization}}
+ new auto {1, 2}; // expected-error{{new expression for type 'auto' contains multiple constructor arguments}}
+ new auto {}; // expected-error{{new expression for type 'auto' requires a constructor argument}}
+ new decltype(auto)({1}); // expected-warning {{ISO C++ standards before C++17 do not allow new expression for type 'decltype(auto)' to use list-initialization}}
+ new decltype(auto)({1, 2}); // expected-error{{new expression for type 'decltype(auto)' contains multiple constructor arguments}}
+}
diff --git a/test/CXX/expr/expr.unary/expr.new/p2-cxx1z.cpp b/test/CXX/expr/expr.unary/expr.new/p2-cxx1z.cpp
new file mode 100644
index 000000000000..6e76075ab16f
--- /dev/null
+++ b/test/CXX/expr/expr.unary/expr.new/p2-cxx1z.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++14
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++17 -pedantic
+
+void f() {
+ new auto('a');
+ new auto {2};
+ new auto {1, 2}; // expected-error{{new expression for type 'auto' contains multiple constructor arguments}}
+ new auto {}; // expected-error{{new expression for type 'auto' requires a constructor argument}}
+ new decltype(auto)({1});
+ new decltype(auto)({1, 2}); // expected-error{{new expression for type 'decltype(auto)' contains multiple constructor arguments}}
+}
diff --git a/test/CXX/modules-ts/basic/basic.def.odr/p4/module.cpp b/test/CXX/modules-ts/basic/basic.def.odr/p4/module.cpp
index dc6a3635a8ee..79e68655b45b 100644
--- a/test/CXX/modules-ts/basic/basic.def.odr/p4/module.cpp
+++ b/test/CXX/modules-ts/basic/basic.def.odr/p4/module.cpp
@@ -2,17 +2,14 @@
// RUN: %clang_cc1 -fmodules-ts %s -triple %itanium_abi_triple -fmodule-file=%t -emit-llvm -o - | FileCheck %s --implicit-check-not=unused --implicit-check-not=global_module
// CHECK-DAG: @extern_var_exported = external global
-// FIXME: Should this be 'external global'?
// CHECK-DAG: @inline_var_exported = linkonce_odr global
-// CHECK-DAG: @_ZL19static_var_exported = external global
-// CHECK-DAG: @const_var_exported = external constant
+// CHECK-DAG: @_ZW6ModuleE19static_var_exported = available_externally global i32 0,
+// CHECK-DAG: @const_var_exported = available_externally constant i32 3,
//
-// FIXME: The module name should be mangled into all of these.
-// CHECK-DAG: @extern_var_module_linkage = external global
-// FIXME: Should this be 'external global'?
-// CHECK-DAG: @inline_var_module_linkage = linkonce_odr global
-// CHECK-DAG: @_ZL25static_var_module_linkage = external global
-// CHECK-DAG: @_ZL24const_var_module_linkage = external constant
+// CHECK-DAG: @_ZW6ModuleE25extern_var_module_linkage = external global
+// CHECK-DAG: @_ZW6ModuleE25inline_var_module_linkage = linkonce_odr global
+// CHECK-DAG: @_ZW6ModuleE25static_var_module_linkage = available_externally global i32 0,
+// CHECK-DAG: @_ZW6ModuleE24const_var_module_linkage = available_externally constant i32 3,
module Module;
@@ -28,15 +25,13 @@ void use() {
(void)&const_var_exported;
// FIXME: This symbol should not be visible here.
- // CHECK: declare {{.*}}@_ZL26used_static_module_linkagev
+ // CHECK: declare {{.*}}@_ZW6ModuleE26used_static_module_linkagev
used_static_module_linkage();
- // FIXME: The module name should be mangled into the name of this function.
- // CHECK: define linkonce_odr {{.*}}@_Z26used_inline_module_linkagev
+ // CHECK: define linkonce_odr {{.*}}@_ZW6ModuleE26used_inline_module_linkagev
used_inline_module_linkage();
- // FIXME: The module name should be mangled into the name of this function.
- // CHECK: declare {{.*}}@_Z24noninline_module_linkagev
+ // CHECK: declare {{.*}}@_ZW6ModuleE24noninline_module_linkagev
noninline_module_linkage();
(void)&extern_var_module_linkage;
diff --git a/test/CXX/modules-ts/basic/basic.def.odr/p4/module.cppm b/test/CXX/modules-ts/basic/basic.def.odr/p4/module.cppm
index d452f741a0fb..15d1114fb03f 100644
--- a/test/CXX/modules-ts/basic/basic.def.odr/p4/module.cppm
+++ b/test/CXX/modules-ts/basic/basic.def.odr/p4/module.cppm
@@ -11,17 +11,20 @@
// can discard this global and its initializer (if any), and other TUs are not
// permitted to run the initializer for this variable.
// CHECK-DAG: @inline_var_exported = linkonce_odr global
-// CHECK-DAG: @_ZL19static_var_exported = global
+// CHECK-DAG: @_ZW6ModuleE19static_var_exported = global
// CHECK-DAG: @const_var_exported = constant
//
-// FIXME: The module name should be mangled into all of these.
-// CHECK-DAG: @extern_var_module_linkage = external global
+// CHECK-DAG: @_ZW6ModuleE25extern_var_module_linkage = external global
// FIXME: Should this be 'weak_odr global'? Presumably it must be, since we
// can discard this global and its initializer (if any), and other TUs are not
// permitted to run the initializer for this variable.
-// CHECK-DAG: @inline_var_module_linkage = linkonce_odr global
-// CHECK-DAG: @_ZL25static_var_module_linkage = global
-// CHECK-DAG: @_ZL24const_var_module_linkage = constant
+// CHECK-DAG: @_ZW6ModuleE25inline_var_module_linkage = linkonce_odr global
+// CHECK-DAG: @_ZW6ModuleE25static_var_module_linkage = global
+// CHECK-DAG: @_ZW6ModuleE24const_var_module_linkage = constant
+//
+// CHECK-DAG: @_ZW6ModuleE25unused_var_module_linkage = global i32 4
+// CHECK-DAG: @_ZW6ModuleE32unused_static_var_module_linkage = global i32 5
+// CHECK-DAG: @_ZW6ModuleE31unused_const_var_module_linkage = constant i32 7
static void unused_static_global_module() {}
static void used_static_global_module() {}
@@ -57,9 +60,9 @@ export module Module;
export {
// FIXME: These should be ill-formed: you can't export an internal linkage
// symbol, per [dcl.module.interface]p2.
- // CHECK: define void {{.*}}@_ZL22unused_static_exportedv
+ // CHECK: define void {{.*}}@_ZW6ModuleE22unused_static_exportedv
static void unused_static_exported() {}
- // CHECK: define void {{.*}}@_ZL20used_static_exportedv
+ // CHECK: define void {{.*}}@_ZW6ModuleE20used_static_exportedv
static void used_static_exported() {}
inline void unused_inline_exported() {}
@@ -88,11 +91,9 @@ export {
// FIXME: Ideally we wouldn't emit this as its name is not visible outside this
// TU, but this module interface might contain a template that can use this
// function so we conservatively emit it for now.
-// FIXME: The module name should be mangled into the name of this function.
-// CHECK: define void {{.*}}@_ZL28unused_static_module_linkagev
+// CHECK: define void {{.*}}@_ZW6ModuleE28unused_static_module_linkagev
static void unused_static_module_linkage() {}
-// FIXME: The module name should be mangled into the name of this function.
-// CHECK: define void {{.*}}@_ZL26used_static_module_linkagev
+// CHECK: define void {{.*}}@_ZW6ModuleE26used_static_module_linkagev
static void used_static_module_linkage() {}
inline void unused_inline_module_linkage() {}
@@ -103,12 +104,10 @@ inline int inline_var_module_linkage;
static int static_var_module_linkage;
const int const_var_module_linkage = 3;
-// FIXME: The module name should be mangled into the name of this function.
-// CHECK: define void {{.*}}@_Z24noninline_module_linkagev
+// CHECK: define void {{.*}}@_ZW6ModuleE24noninline_module_linkagev
void noninline_module_linkage() {
used_static_module_linkage();
- // FIXME: The module name should be mangled into the name of this function.
- // CHECK: define linkonce_odr {{.*}}@_Z26used_inline_module_linkagev
+ // CHECK: define linkonce_odr {{.*}}@_ZW6ModuleE26used_inline_module_linkagev
used_inline_module_linkage();
(void)&extern_var_module_linkage;
@@ -116,3 +115,15 @@ void noninline_module_linkage() {
(void)&static_var_module_linkage;
(void)&const_var_module_linkage;
}
+
+int unused_var_module_linkage = 4;
+static int unused_static_var_module_linkage = 5;
+inline int unused_inline_var_module_linkage = 6;
+const int unused_const_var_module_linkage = 7;
+
+struct a {
+ struct b {};
+ struct c {};
+};
+// CHECK: define void @_ZW6ModuleE1fW_0EN1a1bEW_0ENS_1cE(
+void f(a::b, a::c) {}
diff --git a/test/CXX/modules-ts/basic/basic.def.odr/p4/user.cpp b/test/CXX/modules-ts/basic/basic.def.odr/p4/user.cpp
index f6e0238c6b4b..5e9f7ecf5bab 100644
--- a/test/CXX/modules-ts/basic/basic.def.odr/p4/user.cpp
+++ b/test/CXX/modules-ts/basic/basic.def.odr/p4/user.cpp
@@ -2,11 +2,9 @@
// RUN: %clang_cc1 -fmodules-ts %s -triple %itanium_abi_triple -fmodule-file=%t -emit-llvm -o - | FileCheck %s --implicit-check-not=unused --implicit-check-not=global_module
// CHECK-DAG: @extern_var_exported = external global
-// FIXME: Should this be 'external global'?
// CHECK-DAG: @inline_var_exported = linkonce_odr global
-// FIXME: These should be 'extern global' and 'extern constant'.
-// CHECK-DAG: @_ZL19static_var_exported = global
-// CHECK-DAG: @const_var_exported = constant
+// CHECK-DAG: @_ZW6ModuleE19static_var_exported = available_externally global i32 0
+// CHECK-DAG: @const_var_exported = available_externally constant i32 3
import Module;
diff --git a/test/CXX/modules-ts/basic/basic.def.odr/p6/global-vs-module.cpp b/test/CXX/modules-ts/basic/basic.def.odr/p6/global-vs-module.cpp
new file mode 100644
index 000000000000..cceca5106cae
--- /dev/null
+++ b/test/CXX/modules-ts/basic/basic.def.odr/p6/global-vs-module.cpp
@@ -0,0 +1,55 @@
+// RUN: %clang_cc1 -fmodules-ts -verify -std=c++17 %s
+// RUN: %clang_cc1 -fmodules-ts -verify -std=c++17 %s -DEXPORT
+// RUN: %clang_cc1 -fmodules-ts -verify -std=c++17 %s -DUSING
+
+#ifndef NO_GLOBAL
+extern int var; // expected-note {{previous declaration is here}}
+int func(); // expected-note {{previous declaration is here}}
+struct str; // expected-note {{previous declaration is here}}
+using type = int;
+
+template<typename> extern int var_tpl; // expected-note {{previous declaration is here}}
+template<typename> int func_tpl(); // expected-note-re {{{{previous declaration is here|target of using declaration}}}}
+template<typename> struct str_tpl; // expected-note {{previous declaration is here}}
+template<typename> using type_tpl = int; // expected-note {{previous declaration is here}}
+
+typedef int type;
+namespace ns { using ::func; }
+namespace ns_alias = ns;
+#endif
+
+export module M;
+
+#ifdef USING
+using ::var;
+using ::func;
+using ::str;
+using ::type;
+using ::var_tpl;
+using ::func_tpl; // expected-note {{using declaration}}
+using ::str_tpl;
+using ::type_tpl;
+#endif
+
+#ifdef EXPORT
+export {
+#endif
+
+extern int var; // expected-error {{declaration of 'var' in module M follows declaration in the global module}}
+int func(); // expected-error {{declaration of 'func' in module M follows declaration in the global module}}
+struct str; // expected-error {{declaration of 'str' in module M follows declaration in the global module}}
+using type = int;
+
+template<typename> extern int var_tpl; // expected-error {{declaration of 'var_tpl' in module M follows declaration in the global module}}
+// FIXME: Is this the right diagnostic in the -DUSING case?
+template<typename> int func_tpl(); // expected-error-re {{{{declaration of 'func_tpl' in module M follows declaration in the global module|conflicts with target of using declaration}}}}
+template<typename> struct str_tpl; // expected-error {{declaration of 'str_tpl' in module M follows declaration in the global module}}
+template<typename> using type_tpl = int; // expected-error {{declaration of 'type_tpl' in module M follows declaration in the global module}}
+
+typedef int type;
+namespace ns { using ::func; }
+namespace ns_alias = ns;
+
+#ifdef EXPORT
+}
+#endif
diff --git a/test/CXX/modules-ts/basic/basic.def.odr/p6/module-vs-global.cpp b/test/CXX/modules-ts/basic/basic.def.odr/p6/module-vs-global.cpp
new file mode 100644
index 000000000000..f58506dd9c46
--- /dev/null
+++ b/test/CXX/modules-ts/basic/basic.def.odr/p6/module-vs-global.cpp
@@ -0,0 +1,19 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules-ts -emit-module-interface -std=c++17 %S/global-vs-module.cpp -o %t -DNO_GLOBAL -DEXPORT
+// RUN: %clang_cc1 -fmodules-ts -verify -std=c++17 %s -fmodule-file=%t
+
+import M;
+
+extern int var; // expected-error {{declaration of 'var' in the global module follows declaration in module M}} expected-note@global-vs-module.cpp:38 {{previous}}
+int func(); // expected-error {{declaration of 'func' in the global module follows declaration in module M}} expected-note@global-vs-module.cpp:39 {{previous}}
+struct str; // expected-error {{declaration of 'str' in the global module follows declaration in module M}} expected-note@global-vs-module.cpp:40 {{previous}}
+using type = int;
+
+template<typename> extern int var_tpl; // expected-error {{declaration of 'var_tpl' in the global module follows declaration in module M}} expected-note@global-vs-module.cpp:43 {{previous}}
+template<typename> int func_tpl(); // expected-error {{declaration of 'func_tpl' in the global module follows declaration in module M}} expected-note@global-vs-module.cpp:45 {{previous}}
+template<typename> struct str_tpl; // expected-error {{declaration of 'str_tpl' in the global module follows declaration in module M}} expected-note@global-vs-module.cpp:46 {{previous}}
+template<typename> using type_tpl = int; // expected-error {{declaration of 'type_tpl' in the global module follows declaration in module M}} expected-note@global-vs-module.cpp:47 {{previous}}
+
+typedef int type;
+namespace ns { using ::func; }
+namespace ns_alias = ns;
diff --git a/test/CXX/modules-ts/basic/basic.def.odr/p6/module-vs-module.cpp b/test/CXX/modules-ts/basic/basic.def.odr/p6/module-vs-module.cpp
new file mode 100644
index 000000000000..39e210c4ad80
--- /dev/null
+++ b/test/CXX/modules-ts/basic/basic.def.odr/p6/module-vs-module.cpp
@@ -0,0 +1,44 @@
+// RUN: rm -rf %t
+// RUN: mkdir %t
+//
+// Some of the following tests intentionally have no -verify in their RUN
+// lines; we are testing that those cases do not produce errors.
+//
+// RUN: %clang_cc1 -fmodules-ts -std=c++17 %S/global-vs-module.cpp -emit-module-interface -o %t/M.pcm -DNO_GLOBAL -DEXPORT
+// RUN: %clang_cc1 -fmodules-ts -std=c++17 %s -fmodule-file=%t/M.pcm -DMODULE_INTERFACE -verify
+// RUN: %clang_cc1 -fmodules-ts -std=c++17 %s -fmodule-file=%t/M.pcm -DMODULE_INTERFACE -DNO_IMPORT
+//
+// RUN: %clang_cc1 -fmodules-ts -std=c++17 %s -fmodule-file=%t/M.pcm -emit-module-interface -o %t/N.pcm -DMODULE_INTERFACE -DNO_ERRORS
+// RUN: %clang_cc1 -fmodules-ts -std=c++17 %s -fmodule-file=%t/N.pcm -verify
+// FIXME: Once we start importing "import" declarations properly, this should
+// be rejected (-verify should be added to the following line).
+// RUN: %clang_cc1 -fmodules-ts -std=c++17 %s -fmodule-file=%t/N.pcm -DNO_IMPORT
+//
+// RUN: %clang_cc1 -fmodules-ts -std=c++17 %s -fmodule-file=%t/M.pcm -emit-module-interface -o %t/N-no-M.pcm -DMODULE_INTERFACE -DNO_ERRORS -DNO_IMPORT
+// RUN: %clang_cc1 -fmodules-ts -std=c++17 %s -fmodule-file=%t/N-no-M.pcm -verify
+// RUN: %clang_cc1 -fmodules-ts -std=c++17 %s -fmodule-file=%t/N-no-M.pcm -DNO_IMPORT
+
+#ifdef MODULE_INTERFACE
+export
+#endif
+module N;
+
+#ifndef NO_IMPORT
+import M;
+#endif
+
+#ifndef NO_ERRORS
+extern int var; // expected-error {{declaration of 'var' in module N follows declaration in module M}} expected-note@global-vs-module.cpp:38 {{previous}}
+int func(); // expected-error {{declaration of 'func' in module N follows declaration in module M}} expected-note@global-vs-module.cpp:39 {{previous}}
+struct str; // expected-error {{declaration of 'str' in module N follows declaration in module M}} expected-note@global-vs-module.cpp:40 {{previous}}
+using type = int;
+
+template<typename> extern int var_tpl; // expected-error {{declaration of 'var_tpl' in module N follows declaration in module M}} expected-note@global-vs-module.cpp:43 {{previous}}
+template<typename> int func_tpl(); // expected-error {{declaration of 'func_tpl' in module N follows declaration in module M}} expected-note@global-vs-module.cpp:45 {{previous}}
+template<typename> struct str_tpl; // expected-error {{declaration of 'str_tpl' in module N follows declaration in module M}} expected-note@global-vs-module.cpp:46 {{previous}}
+template<typename> using type_tpl = int; // expected-error {{declaration of 'type_tpl' in module N follows declaration in module M}} expected-note@global-vs-module.cpp:47 {{previous}}
+
+typedef int type;
+namespace ns { using ::func; }
+namespace ns_alias = ns;
+#endif
diff --git a/test/CXX/modules-ts/basic/basic.link/module-declaration.cpp b/test/CXX/modules-ts/basic/basic.link/module-declaration.cpp
index ee696d14585c..feb0afdda07b 100644
--- a/test/CXX/modules-ts/basic/basic.link/module-declaration.cpp
+++ b/test/CXX/modules-ts/basic/basic.link/module-declaration.cpp
@@ -9,7 +9,6 @@
// RUN: %clang_cc1 -std=c++1z -fmodules-ts -emit-module-interface -fmodule-file=%t/x.pcm %t/x.y.cppm -o %t/x.y.pcm
//
// Module implementation for unknown and known module. (The former is ill-formed.)
-// FIXME: TEST=1 should fail because we don't have an interface for module z.
// RUN: %clang_cc1 -std=c++1z -fmodules-ts -I%t -fmodule-file=%t/x.y.pcm -verify %s \
// RUN: -DTEST=1 -DEXPORT= -DPARTITION= -DMODULE_NAME=z
// RUN: %clang_cc1 -std=c++1z -fmodules-ts -I%t -fmodule-file=%t/x.y.pcm -verify %s \
@@ -32,24 +31,26 @@
// RUN: %clang_cc1 -std=c++1z -fmodules-ts -I%t -fmodule-file=%t/x.y.pcm -verify %s \
// RUN: -DTEST=7 -DEXPORT= -DPARTITION=elderberry -DMODULE_NAME=z
// RUN: %clang_cc1 -std=c++1z -fmodules-ts -I%t -fmodule-file=%t/x.y.pcm -verify %s \
-// RUN: -DTEST=8 -DEXPORT= -DPARTITION= -DMODULE_NAME='z [[]]'
+// RUN: -DTEST=8 -DEXPORT=export -DPARTITION= -DMODULE_NAME='z [[]]'
// RUN: %clang_cc1 -std=c++1z -fmodules-ts -I%t -fmodule-file=%t/x.y.pcm -verify %s \
-// RUN: -DTEST=9 -DEXPORT= -DPARTITION= -DMODULE_NAME='z [[fancy]]'
+// RUN: -DTEST=9 -DEXPORT=export -DPARTITION= -DMODULE_NAME='z [[fancy]]'
// RUN: %clang_cc1 -std=c++1z -fmodules-ts -I%t -fmodule-file=%t/x.y.pcm -verify %s \
-// RUN: -DTEST=10 -DEXPORT= -DPARTITION= -DMODULE_NAME='z [[maybe_unused]]'
+// RUN: -DTEST=10 -DEXPORT=export -DPARTITION= -DMODULE_NAME='z [[maybe_unused]]'
EXPORT module PARTITION MODULE_NAME;
#if TEST == 4
// expected-error@-2 {{redefinition of module 'x'}}
-// expected-note-re@module-declaration.cpp:* {{loaded from '{{.*}}/x.pcm'}}
+// expected-note-re@module-declaration.cpp:* {{loaded from '{{.*[/\\]}}x.pcm'}}
#elif TEST == 6
// expected-error@-5 {{module partition must be declared 'export'}}
#elif TEST == 7
-// expected-error@-7 {{expected ';'}} expected-error@-7 {{requires a type specifier}}
+// expected-error@-7 {{expected ';'}} expected-error@-7 {{requires a type specifier}} expected-error@-7 {{definition of module 'elderberry' is not available}}
#elif TEST == 9
// expected-warning@-9 {{unknown attribute 'fancy' ignored}}
#elif TEST == 10
// expected-error-re@-11 {{'maybe_unused' attribute cannot be applied to a module{{$}}}}
+#elif TEST == 1
+// expected-error@-13 {{definition of module 'z' is not available}}
#else
// expected-no-diagnostics
#endif
diff --git a/test/CXX/modules-ts/basic/basic.link/p3.cppm b/test/CXX/modules-ts/basic/basic.link/p3.cppm
new file mode 100644
index 000000000000..8ff141c5ff6b
--- /dev/null
+++ b/test/CXX/modules-ts/basic/basic.link/p3.cppm
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -fmodules-ts -triple x86_64-linux %s -emit-module-interface -o %t
+// RUN: %clang_cc1 -fmodules-ts -triple x86_64-linux -x pcm %t -emit-llvm -o - | FileCheck %s
+
+export module M;
+
+// CHECK-DAG: @_ZW1ME1a = constant i32 1
+const int a = 1;
+// CHECK-DAG: @b = constant i32 2
+export const int b = 2;
+
+export int f() { return a + b; }
diff --git a/test/CXX/modules-ts/basic/basic.search/module-import.cpp b/test/CXX/modules-ts/basic/basic.search/module-import.cpp
new file mode 100644
index 000000000000..0b5f39d072a3
--- /dev/null
+++ b/test/CXX/modules-ts/basic/basic.search/module-import.cpp
@@ -0,0 +1,39 @@
+// Tests for imported module search.
+//
+// RUN: rm -rf %t
+// RUN: mkdir -p %t
+// RUN: echo 'export module x; int a, b;' > %t/x.cppm
+// RUN: echo 'export module y; import x; int c;' > %t/y.cppm
+// RUN: echo 'export module z; import y; int d;' > %t/z.cppm
+//
+// RUN: %clang_cc1 -std=c++1z -fmodules-ts -emit-module-interface %t/x.cppm -o %t/x.pcm
+// RUN: %clang_cc1 -std=c++1z -fmodules-ts -emit-module-interface -fmodule-file=%t/x.pcm %t/y.cppm -o %t/y.pcm
+//
+// RUN: %clang_cc1 -std=c++1z -fmodules-ts -I%t -fmodule-file=%t/x.pcm -verify %s \
+// RUN: -DMODULE_NAME=x
+// RUN: %clang_cc1 -std=c++1z -fmodules-ts -I%t -fmodule-file=%t/y.pcm -verify %s \
+// RUN: -DMODULE_NAME=y
+//
+// RUN: %clang_cc1 -std=c++1z -fmodules-ts -I%t -fmodule-file=x=%t/x.pcm -verify %s \
+// RUN: -DMODULE_NAME=x
+// RUN: %clang_cc1 -std=c++1z -fmodules-ts -I%t -fmodule-file=y=%t/y.pcm -verify %s \
+// RUN: -DMODULE_NAME=y
+//
+// RUN: mv %t/x.pcm %t/a.pcm
+//
+// RUN: %clang_cc1 -std=c++1z -fmodules-ts -I%t -fmodule-file=x=%t/a.pcm -verify %s \
+// RUN: -DMODULE_NAME=x
+// RUN: %clang_cc1 -std=c++1z -fmodules-ts -I%t -fmodule-file=%t/y.pcm -fmodule-file=x=%t/a.pcm -verify %s \
+// RUN: -DMODULE_NAME=y
+// RUN: %clang_cc1 -std=c++1z -fmodules-ts -I%t -fmodule-file=y=%t/y.pcm -fmodule-file=x=%t/a.pcm -verify %s \
+// RUN: -DMODULE_NAME=y
+//
+// RUN: %clang_cc1 -std=c++1z -fmodules-ts -emit-module-interface -fmodule-file=y=%t/y.pcm -fmodule-file=x=%t/a.pcm %t/z.cppm -o %t/z.pcm
+//
+// RUN: %clang_cc1 -std=c++1z -fmodules-ts -I%t -fmodule-file=z=%t/z.pcm -fmodule-file=y=%t/y.pcm -fmodule-file=x=%t/a.pcm -verify %s \
+// RUN: -DMODULE_NAME=z
+//
+
+import MODULE_NAME;
+
+// expected-no-diagnostics
diff --git a/test/CXX/modules-ts/codegen-basics.cppm b/test/CXX/modules-ts/codegen-basics.cppm
index d1552d9edd26..a85e12df26f6 100644
--- a/test/CXX/modules-ts/codegen-basics.cppm
+++ b/test/CXX/modules-ts/codegen-basics.cppm
@@ -4,20 +4,18 @@
export module FooBar;
export {
- // CHECK-LABEL: define i32 @_Z1fv(
+ // CHECK-DAG: define i32 @_Z1fv(
int f() { return 0; }
}
-// CHECK-LABEL: define weak_odr void @_Z2f2v(
+// CHECK-DAG: define weak_odr void @_ZW6FooBarE2f2v(
inline void f2() { }
-// FIXME: Emit global variables and their initializers with this TU.
-// Emit an initialization function that other TUs can call, with guard variable.
-
-// FIXME: Mangle non-exported symbols so they don't collide with
-// non-exported symbols from other modules?
+// CHECK-DAG: define void @_ZW6FooBarE2f3v(
+static void f3() {}
+export void use_f3() { f3(); }
-// FIXME: Formally-internal-linkage symbols that are used from an exported
-// symbol need a mangled name and external linkage.
+// FIXME: Emit global variables and their initializers with this TU.
+// Emit an initialization function that other TUs can call, with guard variable?
// FIXME: const-qualified variables don't have implicit internal linkage when owned by a module.
diff --git a/test/CXX/modules-ts/dcl.dcl/dcl.module/dcl.module.export/p1.cpp b/test/CXX/modules-ts/dcl.dcl/dcl.module/dcl.module.export/p1.cpp
new file mode 100644
index 000000000000..ab8c690441ca
--- /dev/null
+++ b/test/CXX/modules-ts/dcl.dcl/dcl.module/dcl.module.export/p1.cpp
@@ -0,0 +1,40 @@
+// RUN: rm -rf %t
+// RUN: mkdir -p %t
+//
+// RUN: echo 'export module a; export class A{};' | %clang_cc1 -x c++ -fmodules-ts -emit-module-interface - -o %t/a.pcm
+// RUN: echo 'export module b; export class B{};' | %clang_cc1 -x c++ -fmodules-ts -emit-module-interface - -o %t/b.pcm
+// RUN: echo 'export module c; export class C{};' | %clang_cc1 -x c++ -fmodules-ts -emit-module-interface - -o %t/c.pcm
+//
+// RUN: %clang_cc1 -fmodules-ts -fprebuilt-module-path=%t -emit-module-interface %s -o %t/aggregate.internal.pcm -DAGGREGATE_INTERNAL
+// RUN: %clang_cc1 -fmodules-ts -fprebuilt-module-path=%t -emit-module-interface %s -o %t/aggregate.pcm -DAGGREGATE
+//
+// RUN: %clang_cc1 -fmodules-ts -fprebuilt-module-path=%t %s -verify -DTEST
+// expected-no-diagnostics
+
+
+#ifdef AGGREGATE_INTERNAL
+export module aggregate.internal;
+export import a;
+export {
+ import b;
+ import c;
+}
+#endif
+
+
+// Export the above aggregate module.
+// This is done to ensure that re-exports are transitive.
+#ifdef AGGREGATE
+export module aggregate;
+export import aggregate.internal;
+#endif
+
+
+// For the actual test, just try using the classes from the exported modules
+// and hope that they're accessible.
+#ifdef TEST
+import aggregate;
+A a;
+B b;
+C c;
+#endif
diff --git a/test/CXX/modules-ts/dcl.dcl/dcl.module/dcl.module.import/p1.cpp b/test/CXX/modules-ts/dcl.dcl/dcl.module/dcl.module.import/p1.cpp
index aad31b4b46d1..15900c1f6a3a 100644
--- a/test/CXX/modules-ts/dcl.dcl/dcl.module/dcl.module.import/p1.cpp
+++ b/test/CXX/modules-ts/dcl.dcl/dcl.module/dcl.module.import/p1.cpp
@@ -2,15 +2,22 @@
// RUN: mkdir -p %t
// RUN: echo 'export module x; export int a, b;' > %t/x.cppm
// RUN: echo 'export module x.y; export int c;' > %t/x.y.cppm
+// RUN: echo 'export module a.b; export int d;' > %t/a.b.cppm
//
// RUN: %clang_cc1 -std=c++1z -fmodules-ts -emit-module-interface %t/x.cppm -o %t/x.pcm
// RUN: %clang_cc1 -std=c++1z -fmodules-ts -emit-module-interface -fmodule-file=%t/x.pcm %t/x.y.cppm -o %t/x.y.pcm
+// RUN: %clang_cc1 -std=c++1z -fmodules-ts -emit-module-interface %t/a.b.cppm -o %t/a.b.pcm
//
-// RUN: %clang_cc1 -std=c++1z -fmodules-ts -I%t -fmodule-file=%t/x.y.pcm -verify %s \
-// RUN: -DMODULE_NAME=z
-// RUN: %clang_cc1 -std=c++1z -fmodules-ts -I%t -fmodule-file=%t/x.y.pcm -verify %s \
+// RUN: %clang_cc1 -std=c++1z -fmodules-ts -I%t -fmodule-file=%t/x.y.pcm -fmodule-file=%t/a.b.pcm -verify %s \
+// RUN: -DMODULE_NAME=z -DINTERFACE
+// RUN: %clang_cc1 -std=c++1z -fmodules-ts -I%t -fmodule-file=%t/x.y.pcm -fmodule-file=%t/a.b.pcm -verify %s \
+// RUN: -DMODULE_NAME=a.b
+// RUN: %clang_cc1 -std=c++1z -fmodules-ts -I%t -fmodule-file=%t/x.y.pcm -fmodule-file=%t/a.b.pcm -verify %s \
// RUN: -DMODULE_X -DMODULE_NAME=x
+#ifdef INTERFACE
+export
+#endif
module MODULE_NAME;
int use_1 = a;
@@ -33,6 +40,7 @@ import x [[noreturn]]; // expected-error {{'noreturn' attribute cannot be applie
import x [[blarg::noreturn]]; // expected-warning {{unknown attribute 'noreturn' ignored}}
import x.y;
+import a.b; // Does not imply existence of module a.
import x.; // expected-error {{expected a module name after 'import'}}
import .x; // expected-error {{expected a module name after 'import'}}
diff --git a/test/CXX/modules-ts/dcl.dcl/dcl.module/dcl.module.interface/p1.cpp b/test/CXX/modules-ts/dcl.dcl/dcl.module/dcl.module.interface/p1.cpp
index afe3a7a48589..68f2570dd3e6 100644
--- a/test/CXX/modules-ts/dcl.dcl/dcl.module/dcl.module.interface/p1.cpp
+++ b/test/CXX/modules-ts/dcl.dcl/dcl.module/dcl.module.interface/p1.cpp
@@ -1,27 +1,28 @@
// RUN: %clang_cc1 -fmodules-ts %s -verify -o /dev/null
-// RUN: %clang_cc1 -fmodules-ts %s -DINTERFACE -verify -o /dev/null
-// RUN: %clang_cc1 -fmodules-ts %s -DIMPLEMENTATION -verify -o /dev/null
+// RUN: %clang_cc1 -fmodules-ts %s -DINTERFACE -verify -emit-module-interface -o %t
+// RUN: %clang_cc1 -fmodules-ts %s -DIMPLEMENTATION -verify -fmodule-file=%t -o /dev/null
//
// RUN: %clang_cc1 -fmodules-ts %s -DBUILT_AS_INTERFACE -emit-module-interface -verify -o /dev/null
// RUN: %clang_cc1 -fmodules-ts %s -DINTERFACE -DBUILT_AS_INTERFACE -emit-module-interface -verify -o /dev/null
// RUN: %clang_cc1 -fmodules-ts %s -DIMPLEMENTATION -DBUILT_AS_INTERFACE -emit-module-interface -verify -o /dev/null
#if INTERFACE
+// expected-no-diagnostics
export module A;
#elif IMPLEMENTATION
module A;
#ifdef BUILT_AS_INTERFACE
// expected-error@-2 {{missing 'export' specifier in module declaration while building module interface}}
+ #define INTERFACE
#endif
#else
#ifdef BUILT_AS_INTERFACE
- // FIXME: Diagnose missing module declaration (at end of TU)
+ // expected-error@1 {{missing 'export module' declaration in module interface unit}}
#endif
#endif
-export int a;
#ifndef INTERFACE
-// expected-error@-2 {{export declaration can only be used within a module interface unit}}
+export int b; // expected-error {{export declaration can only be used within a module interface unit}}
#else
-// expected-no-diagnostics
+export int a;
#endif
diff --git a/test/CXX/modules-ts/dcl.dcl/dcl.module/p1.cpp b/test/CXX/modules-ts/dcl.dcl/dcl.module/p1.cpp
new file mode 100644
index 000000000000..2393aa184317
--- /dev/null
+++ b/test/CXX/modules-ts/dcl.dcl/dcl.module/p1.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -std=c++17 -fmodules-ts -verify %s -DFOO=export -DBAR=export
+// RUN: %clang_cc1 -std=c++17 -fmodules-ts -verify %s -DFOO=export -DBAR=
+// RUN: %clang_cc1 -std=c++17 -fmodules-ts %s -DFOO=export -emit-module-interface -o %t
+// RUN: %clang_cc1 -std=c++17 -fmodules-ts %s -fmodule-file=%t -DFOO=
+// RUN: %clang_cc1 -std=c++17 -fmodules-ts %s -fmodule-file=%t -DBAR=export
+// RUN: %clang_cc1 -std=c++17 -fmodules-ts -verify %s -fmodule-file=%t -DFOO= -DBAR=export
+
+#ifdef FOO
+FOO module foo; // expected-note {{previous module declaration is here}}
+#endif
+
+#ifdef BAR
+BAR module bar; // expected-error {{translation unit contains multiple module declarations}}
+#endif
diff --git a/test/CXX/modules-ts/dcl.dcl/dcl.module/p2.cpp b/test/CXX/modules-ts/dcl.dcl/dcl.module/p2.cpp
new file mode 100644
index 000000000000..992715e6b102
--- /dev/null
+++ b/test/CXX/modules-ts/dcl.dcl/dcl.module/p2.cpp
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -fmodules-ts -verify %s
+
+// A named module shall contain exactly one module interface unit.
+module M; // expected-error {{definition of module 'M' is not available; use -fmodule-file= to specify path to precompiled module interface}}
+
+// FIXME: How do we ensure there is not more than one?
diff --git a/test/CXX/over/over.match/over.match.best/p1.cpp b/test/CXX/over/over.match/over.match.best/p1.cpp
index fad5bf9a72ee..a933f62a3061 100644
--- a/test/CXX/over/over.match/over.match.best/p1.cpp
+++ b/test/CXX/over/over.match/over.match.best/p1.cpp
@@ -25,13 +25,13 @@ namespace deduction_guide_example {
// FIXME: The standard's example is wrong; we add a remove_ref<...> here to
// fix it.
- template<typename T, int N = remove_ref<T>::value> A(T&&, int*) -> A<T>;
+ template<typename T, int N = remove_ref<T>::value> A(T&&, int*) -> A<T**>;
A a{1, 0};
extern A<int> a;
- A b{a, 0};
+ A b{a, 0}; // uses the implicit ctor that is more specialized
A<int> *pa = &a;
- A<A<int>&> *pb = &b;
+ A<int> *pb = &b;
}
// Partial ordering of function template specializations will be tested
diff --git a/test/CXX/over/over.match/over.match.funcs/over.match.class.deduct/p2.cpp b/test/CXX/over/over.match/over.match.funcs/over.match.class.deduct/p2.cpp
index fe1b6a63d75b..cb9541caaddd 100644
--- a/test/CXX/over/over.match/over.match.funcs/over.match.class.deduct/p2.cpp
+++ b/test/CXX/over/over.match/over.match.funcs/over.match.class.deduct/p2.cpp
@@ -6,9 +6,10 @@ namespace Explicit {
template<typename T> struct A {
A(T);
A(T*);
+ A(...);
};
template<typename T> A(T) -> A<T>;
- template<typename T> explicit A(T*) -> A<T>; // expected-note {{explicit}}
+ template<typename T> explicit A(T*) -> A<T**>; // expected-note {{explicit}}
int *p;
A a(p);
@@ -16,10 +17,71 @@ namespace Explicit {
A c{p};
A d = {p}; // expected-error {{selected an explicit deduction guide}}
- using X = A<int>;
- using Y = A<int*>;
+ using X = A<int**>;
+ using Y = A<int>; // uses the implicit guide, being more specialized than the eligible user-defined deduction guides.
using X = decltype(a);
using Y = decltype(b);
using X = decltype(c);
}
+
+
+namespace std {
+ template<typename T> struct initializer_list {
+ const T *ptr;
+ __SIZE_TYPE__ size;
+ initializer_list();
+ };
+}
+
+namespace p0702r1 {
+ template<typename T> struct X { // expected-note {{candidate}}
+ X(std::initializer_list<T>); // expected-note {{candidate}}
+ };
+
+ X xi = {0};
+ X xxi = {xi};
+ extern X<int> xi;
+ // Prior to P0702R1, this is X<X<int>>.
+ extern X<int> xxi;
+
+ struct Y : X<int> {};
+ Y y {{0}};
+ X xy {y};
+ extern X<int> xy;
+
+ struct Z : X<int>, X<float> {};
+ Z z = {{0}, {0.0f}};
+ // This is not X<Z> even though that would work. Instead, it's ambiguous
+ // between X<int> and X<float>.
+ X xz = {z}; // expected-error {{no viable constructor or deduction guide}}
+}
+namespace pr34970 {
+//https://bugs.llvm.org/show_bug.cgi?id=34970
+
+template <typename X, typename Y> struct IsSame {
+ static constexpr bool value = false;
+};
+
+template <typename Z> struct IsSame<Z, Z> {
+ static constexpr bool value = true;
+};
+
+template <typename T> struct Optional {
+ template <typename U> Optional(U&&) { }
+};
+
+template <typename A> Optional(A) -> Optional<A>;
+
+int main() {
+ Optional opt(1729);
+ Optional dupe(opt);
+
+ static_assert(IsSame<decltype(opt), Optional<int>>::value);
+ static_assert(IsSame<decltype(dupe), Optional<int>>::value);
+ static_assert(!IsSame<decltype(dupe), Optional<Optional<int>>>::value);
+ return 0;
+}
+
+
+} \ No newline at end of file
diff --git a/test/CXX/special/class.dtor/p5-implicit.cpp b/test/CXX/special/class.dtor/p5-implicit.cpp
new file mode 100644
index 000000000000..703be15b70cd
--- /dev/null
+++ b/test/CXX/special/class.dtor/p5-implicit.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -std=c++11 %s -ast-dump | FileCheck %s
+
+struct A { ~A() = delete; };
+// CHECK-LABEL: CXXRecordDecl {{.*}} struct A
+// CHECK: Destructor trivial user_declared
+
+struct B : A {};
+// CHECK-LABEL: CXXRecordDecl {{.*}} struct B
+// CHECK: Destructor trivial needs_overload_resolution
+
+struct C : B {};
+// CHECK-LABEL: CXXRecordDecl {{.*}} struct C
+// CHECK: Destructor trivial needs_overload_resolution
+
+struct D { ~D(); };
+struct E : D {};
+union U {
+ E e;
+};
+// CHECK-LABEL: CXXRecordDecl {{.*}} union U
+// CHECK: Destructor non_trivial needs_implicit defaulted_is_deleted
diff --git a/test/CXX/temp/temp.decls/temp.variadic/p4.cpp b/test/CXX/temp/temp.decls/temp.variadic/p4.cpp
index d8294a1f154a..1681325f2e6c 100644
--- a/test/CXX/temp/temp.decls/temp.variadic/p4.cpp
+++ b/test/CXX/temp/temp.decls/temp.variadic/p4.cpp
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -std=c++11 -fsyntax-only -fexceptions -fcxx-exceptions -verify %s
+// RUN: %clang_cc1 -std=c++2a -fsyntax-only -fexceptions -fcxx-exceptions -verify %s
template<typename... Types> struct tuple;
template<int I> struct int_c;
@@ -174,6 +175,7 @@ int check_temp_arg_1[is_same<tuple_of_ints<1, 2, 3, 4, 5>::type,
tuple<int_c<1>, int_c<2>, int_c<3>, int_c<4>,
int_c<5>>>::value? 1 : -1];
+#if __cplusplus < 201703L
// In a dynamic-exception-specification (15.4); the pattern is a type-id.
template<typename ...Types>
struct f_with_except {
@@ -191,3 +193,99 @@ struct check_f_with_except_2 : f_with_except<int, float> {
struct check_f_with_except_3 : f_with_except<int, float> {
virtual void f() throw(int, float, double); // expected-error{{exception specification of overriding function is more lax than base version}}
};
+#endif
+
+namespace PackExpansionWithinLambda {
+ void swallow(...);
+ template<typename ...T, typename ...U> void f(U ...u) {
+ swallow([=] {
+ // C++17 [temp.variadic]p4:
+ // Pack expansions can occur in the following contexts:
+
+ // - in a function parameter pack
+ void g(T...);
+
+#if __cplusplus >= 201703L
+ struct A : T... {
+ // - in a using-declaration
+ using T::x...;
+ using typename T::U...;
+ };
+#endif
+
+ // - in a template parameter pack that is a pack expansion
+ // FIXME: We do not support any way to reach this case yet.
+
+ // - in an initializer-list
+ int arr[] = {T().x...};
+
+ // - in a base-specifier-list
+ struct B : T... {
+ // - in a mem-initializer-list
+ B() : T{0}... {}
+ };
+
+ // - in a template-argument-list
+ f<T...>();
+
+ // - in an attribute-list
+ // FIXME: We do not support any such attributes yet.
+
+ // - in an alignment-specifier
+ alignas(T...) int y;
+
+ // - in a capture-list
+ [](T ...t) { [t...]{}(); } (T()...);
+
+ // - in a sizeof... expression
+ const int k1 = sizeof...(T);
+
+#if __cplusplus >= 201703L
+ // - in a fold-expression
+ const int k2 = ((sizeof(T)/sizeof(T)) + ...);
+
+ static_assert(k1 == k2);
+#endif
+
+ // Trigger clang to look in here for unexpanded packs.
+ U u;
+ } ...);
+ }
+
+ template<typename ...T> void nested() {
+ swallow([=] {
+ [](T ...t) { [t]{}(); } (T()...); // expected-error {{unexpanded parameter pack 't'}}
+ }...); // expected-error {{does not contain any unexpanded}}
+ }
+
+ template <typename ...T> void g() {
+ // Check that we do detect the above cases when the pack is not expanded.
+ swallow([=] { void h(T); }); // expected-error {{unexpanded parameter pack 'T'}}
+ swallow([=] { struct A : T {}; }); // expected-error {{unexpanded parameter pack 'T'}}
+#if __cplusplus >= 201703L
+ swallow([=] { struct A : T... { using T::x; }; }); // expected-error {{unexpanded parameter pack 'T'}}
+ swallow([=] { struct A : T... { using typename T::U; }; }); // expected-error {{unexpanded parameter pack 'T'}}
+#endif
+
+ swallow([=] { int arr[] = {T().x}; }); // expected-error {{unexpanded parameter pack 'T'}}
+ swallow([=] { struct B : T... { B() : T{0} {} }; }); // expected-error {{unexpanded parameter pack 'T'}}
+ swallow([=] { f<T>(); }); // expected-error {{unexpanded parameter pack 'T'}}
+ swallow([=] { alignas(T) int y; }); // expected-error {{unexpanded parameter pack 'T'}}
+ swallow([=] { [](T ...t) {
+ [t]{}(); // expected-error {{unexpanded parameter pack 't'}}
+ } (T()...); });
+ }
+
+ struct T { int x; using U = int; };
+ void g() { f<T>(1, 2, 3); }
+
+ template<typename ...T, typename ...U> void pack_in_lambda(U ...u) { // expected-note {{here}}
+ // FIXME: Move this test into 'f' above once we support this syntax.
+ []<T *...v, template<T *> typename ...U>(U<v> ...uv) {}; // expected-error {{expected body of lambda}} expected-error {{does not refer to a value}}
+ }
+
+ template<typename ...T> void pack_expand_attr() {
+ // FIXME: Move this test into 'f' above once we support this.
+ [[gnu::aligned(alignof(T))...]] int x; // expected-error {{cannot be used as an attribute pack}} expected-error {{unexpanded}}
+ }
+}
diff --git a/test/CodeCompletion/call.cpp b/test/CodeCompletion/call.cpp
index 40a72ba83602..3e062109a9aa 100644
--- a/test/CodeCompletion/call.cpp
+++ b/test/CodeCompletion/call.cpp
@@ -19,10 +19,10 @@ void test() {
f(Y(), 0, 0);
// RUN: %clang_cc1 -fsyntax-only -code-completion-patterns -code-completion-at=%s:19:9 %s -o - | FileCheck -check-prefix=CHECK-CC1 %s
// CHECK-CC1: COMPLETION: Pattern : dynamic_cast<<#type#>>(<#expression#>)
- // CHECK-CC1: f(N::Y y, <#int ZZ#>)
+ // CHECK-CC1: f(Y y, <#int ZZ#>)
// CHECK-CC1-NEXT: f(int i, <#int j#>, int k)
// CHECK-CC1-NEXT: f(float x, <#float y#>)
// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:19:13 %s -o - | FileCheck -check-prefix=CHECK-CC2 %s
- // CHECK-CC2-NOT: f(N::Y y, int ZZ)
+ // CHECK-CC2-NOT: f(Y y, int ZZ)
// CHECK-CC2: f(int i, int j, <#int k#>)
}
diff --git a/test/CodeCompletion/crash-func-init.cpp b/test/CodeCompletion/crash-func-init.cpp
new file mode 100644
index 000000000000..6d84b843ea18
--- /dev/null
+++ b/test/CodeCompletion/crash-func-init.cpp
@@ -0,0 +1,4 @@
+int (*foo(int a))(flo
+// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:1:21 %s -o - \
+// RUN: | FileCheck %s
+// CHECK: COMPLETION: float
diff --git a/test/CodeCompletion/ignore-ns-level-decls.cpp b/test/CodeCompletion/ignore-ns-level-decls.cpp
new file mode 100644
index 000000000000..59cee6536a5d
--- /dev/null
+++ b/test/CodeCompletion/ignore-ns-level-decls.cpp
@@ -0,0 +1,21 @@
+namespace ns {
+ struct bar {
+ };
+
+ struct baz {
+ };
+
+ int func(int a, bar b, baz c);
+}
+
+void test() {
+ ns::
+// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:12:7 %s -o - | FileCheck %s --check-prefix=CHECK-1
+// CHECK-1-DAG: COMPLETION: bar : bar
+// CHECK-1-DAG: COMPLETION: baz : baz
+// CHECK-1-DAG: COMPLETION: func : [#int#]func(<#int a#>, <#bar b#>, <#baz c#>)
+
+// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:12:7 -no-code-completion-ns-level-decls %s -o - | FileCheck %s --allow-empty --check-prefix=CHECK-EMPTY
+// CHECK-EMPTY-NOT: COMPLETION: bar : bar
+// CHECK-EMPTY: {{^}}{{$}}
+}
diff --git a/test/CodeCompletion/qualifiers-as-written.cpp b/test/CodeCompletion/qualifiers-as-written.cpp
new file mode 100644
index 000000000000..90530ec65c97
--- /dev/null
+++ b/test/CodeCompletion/qualifiers-as-written.cpp
@@ -0,0 +1,31 @@
+struct foo {
+ typedef int type;
+
+ type method(type, foo::type, ::foo::type, ::foo::foo::type);
+};
+
+namespace ns {
+ struct bar {
+ };
+
+ struct baz {
+ };
+
+ int func(foo::type a, bar b, baz c);
+}
+
+typedef ns::bar bar;
+
+int func(foo a, bar b, ns::bar c, ns::baz d);
+using ns::func;
+
+void test() {
+ foo().method(0, 0, 0, 0);
+ // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:23:9 %s -o - | FileCheck %s --check-prefix=CHECK-1
+ // CHECK-1: COMPLETION: method : [#type#]method(<#type#>, <#foo::type#>, <#::foo::type#>, <#::foo::foo::type#>)
+ f
+ // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:26:3 %s -o - | FileCheck %s --check-prefix=CHECK-2
+ // FIXME(ibiryukov): We should get rid of CHECK-DAGs here when completion output is made deterministic (see PR35244).
+ // CHECK-2-DAG: COMPLETION: func : [#int#]func(<#foo a#>, <#bar b#>, <#ns::bar c#>, <#ns::baz d#>
+ // CHECK-2-DAG: COMPLETION: func : [#int#]func(<#foo::type a#>, <#bar b#>, <#baz c#>
+}
diff --git a/test/CodeCompletion/uninstantiated_params.cpp b/test/CodeCompletion/uninstantiated_params.cpp
index 57a520dd5712..643f2f72553b 100644
--- a/test/CodeCompletion/uninstantiated_params.cpp
+++ b/test/CodeCompletion/uninstantiated_params.cpp
@@ -9,5 +9,5 @@ void test() {
unique_ptr<int> x;
x.
// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:10:5 %s -o - | FileCheck -check-prefix=CHECK-CC1 %s
- // CHECK-CC1: [#void#]reset({#<#unique_ptr<int>::pointer ptr = pointer()#>#})
+ // CHECK-CC1: [#void#]reset({#<#pointer ptr = pointer()#>#})
}
diff --git a/test/CodeGen/2004-02-20-Builtins.c b/test/CodeGen/2004-02-20-Builtins.c
index 9be0523b4afd..13f970127d60 100644
--- a/test/CodeGen/2004-02-20-Builtins.c
+++ b/test/CodeGen/2004-02-20-Builtins.c
@@ -1,5 +1,8 @@
-// RUN: %clang_cc1 %s -emit-llvm -o - | not grep builtin
+// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
double sqrt(double x);
+
+// CHECK-LABEL: @zsqrtxxx
+// CHECK-NOT: builtin
void zsqrtxxx(float num) {
num = sqrt(num);
}
diff --git a/test/CodeGen/2005-07-20-SqrtNoErrno.c b/test/CodeGen/2005-07-20-SqrtNoErrno.c
deleted file mode 100644
index 96761e4cfb2e..000000000000
--- a/test/CodeGen/2005-07-20-SqrtNoErrno.c
+++ /dev/null
@@ -1,10 +0,0 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin %s -emit-llvm -o - | FileCheck %s
-// llvm.sqrt has undefined behavior on negative inputs, so it is
-// inappropriate to translate C/C++ sqrt to this.
-float sqrtf(float x);
-float foo(float X) {
- // CHECK: foo
- // CHECK: call float @sqrtf(float %
- // Check that this is marked readonly when errno is ignored.
- return sqrtf(X);
-}
diff --git a/test/CodeGen/2009-10-20-GlobalDebug.c b/test/CodeGen/2009-10-20-GlobalDebug.c
index 0d7c759f905e..c8c247f6b041 100644
--- a/test/CodeGen/2009-10-20-GlobalDebug.c
+++ b/test/CodeGen/2009-10-20-GlobalDebug.c
@@ -10,11 +10,11 @@ int main() {
return 0;
}
-// CHECK: [[L]] = !DIGlobalVariableExpression(var: [[LV:.*]])
+// CHECK: [[L]] = !DIGlobalVariableExpression(var: [[LV:.*]], expr: !DIExpression())
// CHECK: [[LV]] = distinct !DIGlobalVariable(name: "localstatic"
// CHECK-NOT: linkageName:
// CHECK-SAME: line: 9,
-// CHECK: [[G]] = !DIGlobalVariableExpression(var: [[GV:.*]])
+// CHECK: [[G]] = !DIGlobalVariableExpression(var: [[GV:.*]], expr: !DIExpression())
// CHECK: [[GV]] = distinct !DIGlobalVariable(name: "global"
// CHECK-NOT: linkageName:
// CHECK-SAME: line: 7,
diff --git a/test/CodeGen/2010-08-10-DbgConstant.c b/test/CodeGen/2010-08-10-DbgConstant.c
index 68947edd526a..ad9d56618687 100644
--- a/test/CodeGen/2010-08-10-DbgConstant.c
+++ b/test/CodeGen/2010-08-10-DbgConstant.c
@@ -1,6 +1,5 @@
// RUN: %clang_cc1 -S -emit-llvm -debug-info-kind=limited %s -o - | FileCheck %s
-// CHECK: !DIGlobalVariableExpression(var: [[VAR:.*]], expr: [[EXPR:![0-9]+]])
-// CHECK: [[EXPR]] = !DIExpression(DW_OP_constu, 201, DW_OP_stack_value)
+// CHECK: !DIGlobalVariableExpression(var: [[VAR:.*]], expr: !DIExpression(DW_OP_constu, 201, DW_OP_stack_value))
static const unsigned int ro = 201;
void bar(int);
diff --git a/test/CodeGen/Inputs/sanitizer-special-case-list.sanitized.txt b/test/CodeGen/Inputs/sanitizer-special-case-list.sanitized.txt
new file mode 100644
index 000000000000..a2afde027b45
--- /dev/null
+++ b/test/CodeGen/Inputs/sanitizer-special-case-list.sanitized.txt
@@ -0,0 +1,4 @@
+[unsigned-integer-overflow]
+fun:*cfi*
+[cfi]
+fun:*overflow*
diff --git a/test/CodeGen/Inputs/sanitizer-special-case-list.unsanitized1.txt b/test/CodeGen/Inputs/sanitizer-special-case-list.unsanitized1.txt
new file mode 100644
index 000000000000..45ad57bbebff
--- /dev/null
+++ b/test/CodeGen/Inputs/sanitizer-special-case-list.unsanitized1.txt
@@ -0,0 +1,2 @@
+fun:*cfi*
+fun:*overflow*
diff --git a/test/CodeGen/Inputs/sanitizer-special-case-list.unsanitized2.txt b/test/CodeGen/Inputs/sanitizer-special-case-list.unsanitized2.txt
new file mode 100644
index 000000000000..375b246f16c5
--- /dev/null
+++ b/test/CodeGen/Inputs/sanitizer-special-case-list.unsanitized2.txt
@@ -0,0 +1,4 @@
+[cfi]
+fun:*cfi*
+[unsigned-integer-overflow]
+fun:*overflow*
diff --git a/test/CodeGen/Inputs/sanitizer-special-case-list.unsanitized3.txt b/test/CodeGen/Inputs/sanitizer-special-case-list.unsanitized3.txt
new file mode 100644
index 000000000000..b038fee52b20
--- /dev/null
+++ b/test/CodeGen/Inputs/sanitizer-special-case-list.unsanitized3.txt
@@ -0,0 +1,4 @@
+[cfi-icall]
+fun:*cfi*
+[unsigned-integer-overflow]
+fun:*overflow*
diff --git a/test/CodeGen/Inputs/sanitizer-special-case-list.unsanitized4.txt b/test/CodeGen/Inputs/sanitizer-special-case-list.unsanitized4.txt
new file mode 100644
index 000000000000..b31747ec3e10
--- /dev/null
+++ b/test/CodeGen/Inputs/sanitizer-special-case-list.unsanitized4.txt
@@ -0,0 +1,4 @@
+[c*]
+fun:*cfi*
+[u*]
+fun:*overflow*
diff --git a/test/CodeGen/adc-builtins.c b/test/CodeGen/adc-builtins.c
index 0d8d6fa03476..d41fa8f446e6 100644
--- a/test/CodeGen/adc-builtins.c
+++ b/test/CodeGen/adc-builtins.c
@@ -1,6 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s | FileCheck %s
-
-#define __MM_MALLOC_H
+// RUN: %clang_cc1 -ffreestanding -triple x86_64-unknown-unknown -emit-llvm -o - %s | FileCheck %s
#include <x86intrin.h>
diff --git a/test/CodeGen/address-safety-attr-kasan-hwasan.cpp b/test/CodeGen/address-safety-attr-kasan-hwasan.cpp
new file mode 100644
index 000000000000..7a84b798e4b9
--- /dev/null
+++ b/test/CodeGen/address-safety-attr-kasan-hwasan.cpp
@@ -0,0 +1,53 @@
+// Make sure the sanitize_address attribute is emitted when using both ASan and KASan.
+// Also document that __attribute__((no_sanitize_address)) doesn't disable KASan instrumentation.
+
+/// RUN: %clang_cc1 -triple i386-unknown-linux -disable-O0-optnone -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-NOASAN %s
+/// RUN: %clang_cc1 -triple i386-unknown-linux -fsanitize=address -disable-O0-optnone -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-ASAN %s
+/// RUN: %clang_cc1 -triple i386-unknown-linux -fsanitize=kernel-address -disable-O0-optnone -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-KASAN %s
+/// RUN: %clang_cc1 -triple i386-unknown-linux -fsanitize=hwaddress -disable-O0-optnone -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-HWASAN %s
+
+int HasSanitizeAddress() {
+ return 1;
+}
+// CHECK-NOASAN: {{Function Attrs: noinline nounwind$}}
+// CHECK-ASAN: Function Attrs: noinline nounwind sanitize_address
+// CHECK-KASAN: Function Attrs: noinline nounwind sanitize_address
+// CHECK-HWASAN: Function Attrs: noinline nounwind sanitize_hwaddress
+
+__attribute__((no_sanitize("address")))
+int NoSanitizeQuoteAddress() {
+ return 0;
+}
+// CHECK-NOASAN: {{Function Attrs: noinline nounwind$}}
+// CHECK-ASAN: {{Function Attrs: noinline nounwind$}}
+// CHECK-KASAN: {{Function Attrs: noinline nounwind sanitize_address$}}
+// CHECK-HWASAN: {{Function Attrs: noinline nounwind sanitize_hwaddress$}}
+
+__attribute__((no_sanitize_address))
+int NoSanitizeAddress() {
+ return 0;
+}
+// CHECK-NOASAN: {{Function Attrs: noinline nounwind$}}
+// CHECK-ASAN: {{Function Attrs: noinline nounwind$}}
+// CHECK-KASAN: {{Function Attrs: noinline nounwind sanitize_address$}}
+// CHECK-HWASAN: {{Function Attrs: noinline nounwind sanitize_hwaddress$}}
+
+__attribute__((no_sanitize("kernel-address")))
+int NoSanitizeKernelAddress() {
+ return 0;
+}
+
+// CHECK-NOASAN: {{Function Attrs: noinline nounwind$}}
+// CHECK-ASAN: {{Function Attrs: noinline nounwind sanitize_address$}}
+// CHECK-KASAN: {{Function Attrs: noinline nounwind$}}
+// CHECK-HWASAN: {{Function Attrs: noinline nounwind sanitize_hwaddress$}}
+
+__attribute__((no_sanitize("hwaddress")))
+int NoSanitizeHWAddress() {
+ return 0;
+}
+
+// CHECK-NOASAN: {{Function Attrs: noinline nounwind$}}
+// CHECK-ASAN: {{Function Attrs: noinline nounwind sanitize_address$}}
+// CHECK-KASAN: {{Function Attrs: noinline nounwind sanitize_address$}}
+// CHECK-HWASAN: {{Function Attrs: noinline nounwind$}}
diff --git a/test/CodeGen/arm-metadata.c b/test/CodeGen/arm-metadata.c
index 1f7756cc8d48..4f3e2dba219b 100644
--- a/test/CodeGen/arm-metadata.c
+++ b/test/CodeGen/arm-metadata.c
@@ -1,6 +1,6 @@
// RUN: %clang_cc1 -triple armv7a-linux-gnueabi -emit-llvm -o - %s | FileCheck -check-prefix=DEFAULT %s
// RUN: %clang_cc1 -triple armv7a-linux-gnueabi -emit-llvm -o - %s -fshort-enums | FileCheck -check-prefix=SHORT-ENUM %s
-// RUN: %clang_cc1 -triple armv7a-linux-gnueabi -emit-llvm -o - %s -fshort-wchar | FileCheck -check-prefix=SHORT-WCHAR %s
+// RUN: %clang_cc1 -triple armv7a-linux-gnueabi -emit-llvm -o - %s -fwchar-type=short -fno-signed-wchar | FileCheck -check-prefix=SHORT-WCHAR %s
// DEFAULT: !{{[0-9]+}} = !{i32 1, !"wchar_size", i32 4}
// DEFAULT: !{{[0-9]+}} = !{i32 1, !"min_enum_size", i32 4}
diff --git a/test/CodeGen/arm64-microsoft-intrinsics.c b/test/CodeGen/arm64-microsoft-intrinsics.c
new file mode 100644
index 000000000000..ff802e7f9b85
--- /dev/null
+++ b/test/CodeGen/arm64-microsoft-intrinsics.c
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -triple arm64-windows -fms-compatibility -emit-llvm -o - %s \
+// RUN: | FileCheck %s -check-prefix CHECK-MSVC
+
+// RUN: not %clang_cc1 -triple arm64-linux -Werror -S -o /dev/null %s 2>&1 \
+// RUN: | FileCheck %s -check-prefix CHECK-LINUX
+
+void check__dmb(void) {
+ __dmb(0);
+}
+
+// CHECK-MSVC: @llvm.aarch64.dmb(i32 0)
+// CHECK-LINUX: error: implicit declaration of function '__dmb'
+
+void check__dsb(void) {
+ __dsb(0);
+}
+
+// CHECK-MSVC: @llvm.aarch64.dsb(i32 0)
+// CHECK-LINUX: error: implicit declaration of function '__dsb'
+
+void check__isb(void) {
+ __isb(0);
+}
+
+// CHECK-MSVC: @llvm.aarch64.isb(i32 0)
+// CHECK-LINUX: error: implicit declaration of function '__isb'
diff --git a/test/CodeGen/attr-availability.c b/test/CodeGen/attr-availability.c
index ccbbb62f8c1f..87e137cfe965 100644
--- a/test/CodeGen/attr-availability.c
+++ b/test/CodeGen/attr-availability.c
@@ -8,9 +8,9 @@
void f2();
void f2() { }
-// CHECK-10_4-LABEL: define void @f3
-// CHECK-10_5-LABEL: define void @f3
-// CHECK-10_6-LABEL: define void @f3
+// CHECK-10_4-LABEL: define hidden void @f3
+// CHECK-10_5-LABEL: define hidden void @f3
+// CHECK-10_6-LABEL: define hidden void @f3
void f3() __attribute__((availability(macosx,introduced=10.5)));
void f3() { }
diff --git a/test/CodeGen/attr-mprefer-vector-width.c b/test/CodeGen/attr-mprefer-vector-width.c
new file mode 100644
index 000000000000..30edba5852f9
--- /dev/null
+++ b/test/CodeGen/attr-mprefer-vector-width.c
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -mprefer-vector-width=128 -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK128
+// RUN: %clang_cc1 -mprefer-vector-width=256 -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK256
+// RUN: %clang_cc1 -mprefer-vector-width=none -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECKNONE
+
+int baz(int a) { return 4; }
+
+// CHECK128: baz{{.*}} #0
+// CHECK128: #0 = {{.*}}"prefer-vector-width"="128"
+
+// CHECK256: baz{{.*}} #0
+// CHECK256: #0 = {{.*}}"prefer-vector-width"="256"
+
+// CHECKNONE: baz{{.*}} #0
+// CHECKNONE-NOT: #0 = {{.*}}"prefer-vector-width"="none"
diff --git a/test/CodeGen/attr-target-x86.c b/test/CodeGen/attr-target-x86.c
index f2777679aec1..6ec2d6578dc4 100644
--- a/test/CodeGen/attr-target-x86.c
+++ b/test/CodeGen/attr-target-x86.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-linux-gnu -target-cpu x86-64 -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple i686-linux-gnu -target-cpu i686 -emit-llvm %s -o - | FileCheck %s
int baz(int a) { return 4; }
@@ -10,6 +10,7 @@ int __attribute__((target("fpmath=387"))) koala(int a) { return 4; }
int __attribute__((target("no-sse2"))) echidna(int a) { return 4; }
int __attribute__((target("sse4"))) panda(int a) { return 4; }
+int __attribute__((target("no-sse4"))) narwhal(int a) { return 4; }
int bar(int a) { return baz(a) + foo(a); }
@@ -18,7 +19,7 @@ int __attribute__((target("no-aes, arch=ivybridge"))) qax(int a) { return 4; }
int __attribute__((target("no-mmx"))) qq(int a) { return 40; }
-int __attribute__((target("arch=lakemont"))) lake(int a) { return 4; }
+int __attribute__((target("arch=lakemont,mmx"))) lake(int a) { return 4; }
// Check that we emit the additional subtarget and cpu features for foo and not for baz or bar.
// CHECK: baz{{.*}} #0
@@ -29,15 +30,17 @@ int __attribute__((target("arch=lakemont"))) lake(int a) { return 4; }
// CHECK: koala{{.*}} #0
// CHECK: echidna{{.*}} #2
// CHECK: panda{{.*}} #3
+// CHECK: narwhal{{.*}} #4
// CHECK: bar{{.*}} #0
// CHECK: qux{{.*}} #1
-// CHECK: qax{{.*}} #4
-// CHECK: qq{{.*}} #5
-// CHECK: lake{{.*}} #6
-// CHECK: #0 = {{.*}}"target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87"
+// CHECK: qax{{.*}} #5
+// CHECK: qq{{.*}} #6
+// CHECK: lake{{.*}} #7
+// CHECK: #0 = {{.*}}"target-cpu"="i686" "target-features"="+x87"
// CHECK: #1 = {{.*}}"target-cpu"="ivybridge" "target-features"="+aes,+avx,+cx16,+f16c,+fsgsbase,+fxsr,+mmx,+pclmul,+popcnt,+rdrnd,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt"
-// CHECK: #2 = {{.*}}"target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+x87,-aes,-avx,-avx2,-avx512bw,-avx512cd,-avx512dq,-avx512er,-avx512f,-avx512ifma,-avx512pf,-avx512vbmi,-avx512vl,-avx512vpopcntdq,-f16c,-fma,-fma4,-pclmul,-sha,-sse2,-sse3,-sse4.1,-sse4.2,-sse4a,-ssse3,-xop,-xsave,-xsaveopt"
-// CHECK: #3 = {{.*}}"target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+popcnt,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87"
-// CHECK: #4 = {{.*}}"target-cpu"="ivybridge" "target-features"="+avx,+cx16,+f16c,+fsgsbase,+fxsr,+mmx,+pclmul,+popcnt,+rdrnd,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt,-aes"
-// CHECK: #5 = {{.*}}"target-cpu"="x86-64" "target-features"="+fxsr,+sse,+sse2,+x87,-3dnow,-3dnowa,-mmx"
-// CHECK: #6 = {{.*}}"target-cpu"="lakemont" "target-features"="+mmx,+sse,+sse2"
+// CHECK: #2 = {{.*}}"target-cpu"="i686" "target-features"="+x87,-aes,-avx,-avx2,-avx512bw,-avx512cd,-avx512dq,-avx512er,-avx512f,-avx512ifma,-avx512pf,-avx512vbmi,-avx512vl,-avx512vpopcntdq,-f16c,-fma,-fma4,-pclmul,-sha,-sse2,-sse3,-sse4.1,-sse4.2,-sse4a,-ssse3,-xop,-xsave,-xsaveopt"
+// CHECK: #3 = {{.*}}"target-cpu"="i686" "target-features"="+mmx,+popcnt,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87"
+// CHECK: #4 = {{.*}}"target-cpu"="i686" "target-features"="+x87,-avx,-avx2,-avx512bw,-avx512cd,-avx512dq,-avx512er,-avx512f,-avx512ifma,-avx512pf,-avx512vbmi,-avx512vl,-avx512vpopcntdq,-f16c,-fma,-fma4,-sse4.1,-sse4.2,-xop,-xsave,-xsaveopt"
+// CHECK: #5 = {{.*}}"target-cpu"="ivybridge" "target-features"="+avx,+cx16,+f16c,+fsgsbase,+fxsr,+mmx,+pclmul,+popcnt,+rdrnd,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt,-aes"
+// CHECK: #6 = {{.*}}"target-cpu"="i686" "target-features"="+x87,-3dnow,-3dnowa,-mmx"
+// CHECK: #7 = {{.*}}"target-cpu"="lakemont" "target-features"="+mmx"
diff --git a/test/CodeGen/avx-builtins.c b/test/CodeGen/avx-builtins.c
index 31a08440d061..4e77ad166ce0 100644
--- a/test/CodeGen/avx-builtins.c
+++ b/test/CodeGen/avx-builtins.c
@@ -678,19 +678,19 @@ __m256 test_mm256_permute_ps(__m256 A) {
__m256d test_mm256_permute2f128_pd(__m256d A, __m256d B) {
// CHECK-LABEL: test_mm256_permute2f128_pd
- // CHECK: call <4 x double> @llvm.x86.avx.vperm2f128.pd.256(<4 x double> %{{.*}}, <4 x double> %{{.*}}, i8 49)
+ // CHECK: shufflevector <4 x double> %{{.*}}, <4 x double> %{{.*}}, <4 x i32> <i32 2, i32 3, i32 6, i32 7>
return _mm256_permute2f128_pd(A, B, 0x31);
}
__m256 test_mm256_permute2f128_ps(__m256 A, __m256 B) {
// CHECK-LABEL: test_mm256_permute2f128_ps
- // CHECK: call <8 x float> @llvm.x86.avx.vperm2f128.ps.256(<8 x float> %{{.*}}, <8 x float> %{{.*}}, i8 19)
+ // CHECK: shufflevector <8 x float> %{{.*}}, <8 x float> %{{.*}}, <8 x i32> <i32 4, i32 5, i32 6, i32 7, i32 12, i32 13, i32 14, i32 15>
return _mm256_permute2f128_ps(A, B, 0x13);
}
__m256i test_mm256_permute2f128_si256(__m256i A, __m256i B) {
// CHECK-LABEL: test_mm256_permute2f128_si256
- // CHECK: call <8 x i32> @llvm.x86.avx.vperm2f128.si.256(<8 x i32> %{{.*}}, <8 x i32> %{{.*}}, i8 32)
+ // CHECK: shufflevector <8 x i32> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 8, i32 9, i32 10, i32 11>
return _mm256_permute2f128_si256(A, B, 0x20);
}
diff --git a/test/CodeGen/avx2-builtins.c b/test/CodeGen/avx2-builtins.c
index 10f3e715de9b..f79f60e6db78 100644
--- a/test/CodeGen/avx2-builtins.c
+++ b/test/CodeGen/avx2-builtins.c
@@ -8,19 +8,25 @@
__m256i test_mm256_abs_epi8(__m256i a) {
// CHECK-LABEL: test_mm256_abs_epi8
- // CHECK: call <32 x i8> @llvm.x86.avx2.pabs.b(<32 x i8> %{{.*}})
+ // CHECK: [[SUB:%.*]] = sub <32 x i8> zeroinitializer, %{{.*}}
+ // CHECK: [[CMP:%.*]] = icmp sgt <32 x i8> %{{.*}}, zeroinitializer
+ // CHECK: select <32 x i1> [[CMP]], <32 x i8> %{{.*}}, <32 x i8> [[SUB]]
return _mm256_abs_epi8(a);
}
__m256i test_mm256_abs_epi16(__m256i a) {
// CHECK-LABEL: test_mm256_abs_epi16
- // CHECK: call <16 x i16> @llvm.x86.avx2.pabs.w(<16 x i16> %{{.*}})
+ // CHECK: [[SUB:%.*]] = sub <16 x i16> zeroinitializer, %{{.*}}
+ // CHECK: [[CMP:%.*]] = icmp sgt <16 x i16> %{{.*}}, zeroinitializer
+ // CHECK: select <16 x i1> [[CMP]], <16 x i16> %{{.*}}, <16 x i16> [[SUB]]
return _mm256_abs_epi16(a);
}
__m256i test_mm256_abs_epi32(__m256i a) {
// CHECK-LABEL: test_mm256_abs_epi32
- // CHECK: call <8 x i32> @llvm.x86.avx2.pabs.d(<8 x i32> %{{.*}})
+ // CHECK: [[SUB:%.*]] = sub <8 x i32> zeroinitializer, %{{.*}}
+ // CHECK: [[CMP:%.*]] = icmp sgt <8 x i32> %{{.*}}, zeroinitializer
+ // CHECK: select <8 x i1> [[CMP]], <8 x i32> %{{.*}}, <8 x i32> [[SUB]]
return _mm256_abs_epi32(a);
}
@@ -99,13 +105,25 @@ __m256i test_mm256_andnot_si256(__m256i a, __m256i b) {
__m256i test_mm256_avg_epu8(__m256i a, __m256i b) {
// CHECK-LABEL: test_mm256_avg_epu8
- // CHECK: call <32 x i8> @llvm.x86.avx2.pavg.b(<32 x i8> %{{.*}}, <32 x i8> %{{.*}})
+ // CHECK-NOT: call <32 x i8> @llvm.x86.avx2.pavg.b(<32 x i8> %{{.*}}, <32 x i8> %{{.*}})
+ // CHECK: zext <32 x i8> %{{.*}} to <32 x i16>
+ // CHECK: zext <32 x i8> %{{.*}} to <32 x i16>
+ // CHECK: add <32 x i16> %{{.*}}, %{{.*}}
+ // CHECK: add <32 x i16> %{{.*}}, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
+ // CHECK: lshr <32 x i16> %{{.*}}, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
+ // CHECK: trunc <32 x i16> %{{.*}} to <32 x i8>
return _mm256_avg_epu8(a, b);
}
__m256i test_mm256_avg_epu16(__m256i a, __m256i b) {
// CHECK-LABEL: test_mm256_avg_epu16
- // CHECK: call <16 x i16> @llvm.x86.avx2.pavg.w(<16 x i16> %{{.*}}, <16 x i16> %{{.*}})
+ // CHECK-NOT: call <16 x i16> @llvm.x86.avx2.pavg.w(<16 x i16> %{{.*}}, <16 x i16> %{{.*}})
+ // CHECK: zext <16 x i16> %{{.*}} to <16 x i32>
+ // CHECK: zext <16 x i16> %{{.*}} to <16 x i32>
+ // CHECK: add <16 x i32> %{{.*}}, %{{.*}}
+ // CHECK: add <16 x i32> %{{.*}}, <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1>
+ // CHECK: lshr <16 x i32> %{{.*}}, <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1>
+ // CHECK: trunc <16 x i32> %{{.*}} to <16 x i16>
return _mm256_avg_epu16(a, b);
}
@@ -889,8 +907,8 @@ __m256i test_mm256_packs_epu32(__m256i a, __m256i b) {
__m256i test_mm256_permute2x128_si256(__m256i a, __m256i b) {
// CHECK-LABEL: test_mm256_permute2x128_si256
- // CHECK: call <4 x i64> @llvm.x86.avx2.vperm2i128(<4 x i64> %{{.*}}, <4 x i64> %{{.*}}, i8 49)
- return _mm256_permute2x128_si256(a, b, 0x31);
+ // CHECK: shufflevector <4 x i64> zeroinitializer, <4 x i64> %{{.*}}, <4 x i32> <i32 0, i32 1, i32 6, i32 7>
+ return _mm256_permute2x128_si256(a, b, 0x38);
}
__m256i test_mm256_permute4x64_epi64(__m256i a) {
diff --git a/test/CodeGen/avx512-reduceMinMaxIntrin.c b/test/CodeGen/avx512-reduceMinMaxIntrin.c
index 993e2964a19b..2081cef75460 100644
--- a/test/CodeGen/avx512-reduceMinMaxIntrin.c
+++ b/test/CodeGen/avx512-reduceMinMaxIntrin.c
@@ -1,439 +1,2611 @@
-// FIXME: We should not be testing with -O2 (ie, a dependency on the entire IR optimizer).
-
-// RUN: %clang_cc1 -ffreestanding %s -O2 -triple=x86_64-apple-darwin -target-cpu skylake-avx512 -emit-llvm -o - -Wall -Werror |opt -instnamer -S |FileCheck %s
+// RUN: %clang_cc1 -ffreestanding %s -O0 -triple=x86_64-apple-darwin -target-cpu skylake-avx512 -emit-llvm -o - -Wall -Werror | FileCheck %s
#include <immintrin.h>
+// CHECK-LABEL: define i64 @test_mm512_reduce_max_epi64(<8 x i64> %__W) #0 {
+// CHECK: [[_COMPOUNDLITERAL_I_I11_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__A_ADDR_I12_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__B_ADDR_I13_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[_COMPOUNDLITERAL_I_I8_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__A_ADDR_I9_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__B_ADDR_I10_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[_COMPOUNDLITERAL_I_I_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__A_ADDR_I_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__B_ADDR_I_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__V_ADDR_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__W_ADDR:%.*]] = alloca <8 x i64>, align 64
+// CHECK: store <8 x i64> %__W, <8 x i64>* [[__W_ADDR]], align 64
+// CHECK: [[TMP0:%.*]] = load <8 x i64>, <8 x i64>* [[__W_ADDR]], align 64
+// CHECK: store <8 x i64> [[TMP0]], <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP1:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP2:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE_I:%.*]] = shufflevector <8 x i64> [[TMP1]], <8 x i64> [[TMP2]], <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP3:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE1_I:%.*]] = shufflevector <8 x i64> [[TMP3]], <8 x i64> [[TMP4]], <8 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: store <8 x i64> [[SHUFFLE_I]], <8 x i64>* [[__A_ADDR_I_I]], align 64
+// CHECK: store <8 x i64> [[SHUFFLE1_I]], <8 x i64>* [[__B_ADDR_I_I]], align 64
+// CHECK: [[TMP5:%.*]] = load <8 x i64>, <8 x i64>* [[__A_ADDR_I_I]], align 64
+// CHECK: [[TMP6:%.*]] = load <8 x i64>, <8 x i64>* [[__B_ADDR_I_I]], align 64
+// CHECK: store <8 x i64> zeroinitializer, <8 x i64>* [[_COMPOUNDLITERAL_I_I_I]], align 64
+// CHECK: [[TMP7:%.*]] = load <8 x i64>, <8 x i64>* [[_COMPOUNDLITERAL_I_I_I]], align 64
+// CHECK: [[TMP8:%.*]] = icmp sgt <8 x i64> [[TMP5]], [[TMP6]]
+// CHECK: [[TMP9:%.*]] = select <8 x i1> [[TMP8]], <8 x i64> [[TMP5]], <8 x i64> [[TMP6]]
+// CHECK: store <8 x i64> [[TMP9]], <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP10:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP11:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE2_I:%.*]] = shufflevector <8 x i64> [[TMP10]], <8 x i64> [[TMP11]], <8 x i32> <i32 0, i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP12:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP13:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE3_I:%.*]] = shufflevector <8 x i64> [[TMP12]], <8 x i64> [[TMP13]], <8 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: store <8 x i64> [[SHUFFLE2_I]], <8 x i64>* [[__A_ADDR_I12_I]], align 64
+// CHECK: store <8 x i64> [[SHUFFLE3_I]], <8 x i64>* [[__B_ADDR_I13_I]], align 64
+// CHECK: [[TMP14:%.*]] = load <8 x i64>, <8 x i64>* [[__A_ADDR_I12_I]], align 64
+// CHECK: [[TMP15:%.*]] = load <8 x i64>, <8 x i64>* [[__B_ADDR_I13_I]], align 64
+// CHECK: store <8 x i64> zeroinitializer, <8 x i64>* [[_COMPOUNDLITERAL_I_I11_I]], align 64
+// CHECK: [[TMP16:%.*]] = load <8 x i64>, <8 x i64>* [[_COMPOUNDLITERAL_I_I11_I]], align 64
+// CHECK: [[TMP17:%.*]] = icmp sgt <8 x i64> [[TMP14]], [[TMP15]]
+// CHECK: [[TMP18:%.*]] = select <8 x i1> [[TMP17]], <8 x i64> [[TMP14]], <8 x i64> [[TMP15]]
+// CHECK: store <8 x i64> [[TMP18]], <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP19:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP20:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE5_I:%.*]] = shufflevector <8 x i64> [[TMP19]], <8 x i64> [[TMP20]], <8 x i32> <i32 0, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP21:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP22:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE6_I:%.*]] = shufflevector <8 x i64> [[TMP21]], <8 x i64> [[TMP22]], <8 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: store <8 x i64> [[SHUFFLE5_I]], <8 x i64>* [[__A_ADDR_I9_I]], align 64
+// CHECK: store <8 x i64> [[SHUFFLE6_I]], <8 x i64>* [[__B_ADDR_I10_I]], align 64
+// CHECK: [[TMP23:%.*]] = load <8 x i64>, <8 x i64>* [[__A_ADDR_I9_I]], align 64
+// CHECK: [[TMP24:%.*]] = load <8 x i64>, <8 x i64>* [[__B_ADDR_I10_I]], align 64
+// CHECK: store <8 x i64> zeroinitializer, <8 x i64>* [[_COMPOUNDLITERAL_I_I8_I]], align 64
+// CHECK: [[TMP25:%.*]] = load <8 x i64>, <8 x i64>* [[_COMPOUNDLITERAL_I_I8_I]], align 64
+// CHECK: [[TMP26:%.*]] = icmp sgt <8 x i64> [[TMP23]], [[TMP24]]
+// CHECK: [[TMP27:%.*]] = select <8 x i1> [[TMP26]], <8 x i64> [[TMP23]], <8 x i64> [[TMP24]]
+// CHECK: store <8 x i64> [[TMP27]], <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP28:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[VECEXT_I:%.*]] = extractelement <8 x i64> [[TMP28]], i32 0
+// CHECK: ret i64 [[VECEXT_I]]
long long test_mm512_reduce_max_epi64(__m512i __W){
- // CHECK: %shuffle1.i = shufflevector <8 x i64> %__W, <8 x i64> undef, <8 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp = icmp slt <8 x i64> %shuffle1.i, %__W
- // CHECK: %tmp1 = select <8 x i1> %tmp, <8 x i64> %__W, <8 x i64> %shuffle1.i
- // CHECK: %shuffle3.i = shufflevector <8 x i64> %tmp1, <8 x i64> undef, <8 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp2 = icmp sgt <8 x i64> %tmp1, %shuffle3.i
- // CHECK: %tmp3 = select <8 x i1> %tmp2, <8 x i64> %tmp1, <8 x i64> %shuffle3.i
- // CHECK: %shuffle6.i = shufflevector <8 x i64> %tmp3, <8 x i64> undef, <8 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp4 = icmp sgt <8 x i64> %tmp3, %shuffle6.i
- // CHECK: %.elt.i = extractelement <8 x i1> %tmp4, i32 0
- // CHECK: %.elt20.i = extractelement <8 x i64> %tmp3, i32 0
- // CHECK: %shuffle6.elt.i = extractelement <8 x i64> %tmp3, i32 1
- // CHECK: %vecext.i = select i1 %.elt.i, i64 %.elt20.i, i64 %shuffle6.elt.i
- // CHECK: ret i64 %vecext.i
return _mm512_reduce_max_epi64(__W);
}
+// CHECK-LABEL: define i64 @test_mm512_reduce_max_epu64(<8 x i64> %__W) #0 {
+// CHECK: [[_COMPOUNDLITERAL_I_I11_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__A_ADDR_I12_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__B_ADDR_I13_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[_COMPOUNDLITERAL_I_I8_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__A_ADDR_I9_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__B_ADDR_I10_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[_COMPOUNDLITERAL_I_I_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__A_ADDR_I_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__B_ADDR_I_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__V_ADDR_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__W_ADDR:%.*]] = alloca <8 x i64>, align 64
+// CHECK: store <8 x i64> %__W, <8 x i64>* [[__W_ADDR]], align 64
+// CHECK: [[TMP0:%.*]] = load <8 x i64>, <8 x i64>* [[__W_ADDR]], align 64
+// CHECK: store <8 x i64> [[TMP0]], <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP1:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP2:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE_I:%.*]] = shufflevector <8 x i64> [[TMP1]], <8 x i64> [[TMP2]], <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP3:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE1_I:%.*]] = shufflevector <8 x i64> [[TMP3]], <8 x i64> [[TMP4]], <8 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: store <8 x i64> [[SHUFFLE_I]], <8 x i64>* [[__A_ADDR_I_I]], align 64
+// CHECK: store <8 x i64> [[SHUFFLE1_I]], <8 x i64>* [[__B_ADDR_I_I]], align 64
+// CHECK: [[TMP5:%.*]] = load <8 x i64>, <8 x i64>* [[__A_ADDR_I_I]], align 64
+// CHECK: [[TMP6:%.*]] = load <8 x i64>, <8 x i64>* [[__B_ADDR_I_I]], align 64
+// CHECK: store <8 x i64> zeroinitializer, <8 x i64>* [[_COMPOUNDLITERAL_I_I_I]], align 64
+// CHECK: [[TMP7:%.*]] = load <8 x i64>, <8 x i64>* [[_COMPOUNDLITERAL_I_I_I]], align 64
+// CHECK: [[TMP8:%.*]] = icmp ugt <8 x i64> [[TMP5]], [[TMP6]]
+// CHECK: [[TMP9:%.*]] = select <8 x i1> [[TMP8]], <8 x i64> [[TMP5]], <8 x i64> [[TMP6]]
+// CHECK: store <8 x i64> [[TMP9]], <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP10:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP11:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE2_I:%.*]] = shufflevector <8 x i64> [[TMP10]], <8 x i64> [[TMP11]], <8 x i32> <i32 0, i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP12:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP13:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE3_I:%.*]] = shufflevector <8 x i64> [[TMP12]], <8 x i64> [[TMP13]], <8 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: store <8 x i64> [[SHUFFLE2_I]], <8 x i64>* [[__A_ADDR_I12_I]], align 64
+// CHECK: store <8 x i64> [[SHUFFLE3_I]], <8 x i64>* [[__B_ADDR_I13_I]], align 64
+// CHECK: [[TMP14:%.*]] = load <8 x i64>, <8 x i64>* [[__A_ADDR_I12_I]], align 64
+// CHECK: [[TMP15:%.*]] = load <8 x i64>, <8 x i64>* [[__B_ADDR_I13_I]], align 64
+// CHECK: store <8 x i64> zeroinitializer, <8 x i64>* [[_COMPOUNDLITERAL_I_I11_I]], align 64
+// CHECK: [[TMP16:%.*]] = load <8 x i64>, <8 x i64>* [[_COMPOUNDLITERAL_I_I11_I]], align 64
+// CHECK: [[TMP17:%.*]] = icmp ugt <8 x i64> [[TMP14]], [[TMP15]]
+// CHECK: [[TMP18:%.*]] = select <8 x i1> [[TMP17]], <8 x i64> [[TMP14]], <8 x i64> [[TMP15]]
+// CHECK: store <8 x i64> [[TMP18]], <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP19:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP20:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE5_I:%.*]] = shufflevector <8 x i64> [[TMP19]], <8 x i64> [[TMP20]], <8 x i32> <i32 0, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP21:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP22:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE6_I:%.*]] = shufflevector <8 x i64> [[TMP21]], <8 x i64> [[TMP22]], <8 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: store <8 x i64> [[SHUFFLE5_I]], <8 x i64>* [[__A_ADDR_I9_I]], align 64
+// CHECK: store <8 x i64> [[SHUFFLE6_I]], <8 x i64>* [[__B_ADDR_I10_I]], align 64
+// CHECK: [[TMP23:%.*]] = load <8 x i64>, <8 x i64>* [[__A_ADDR_I9_I]], align 64
+// CHECK: [[TMP24:%.*]] = load <8 x i64>, <8 x i64>* [[__B_ADDR_I10_I]], align 64
+// CHECK: store <8 x i64> zeroinitializer, <8 x i64>* [[_COMPOUNDLITERAL_I_I8_I]], align 64
+// CHECK: [[TMP25:%.*]] = load <8 x i64>, <8 x i64>* [[_COMPOUNDLITERAL_I_I8_I]], align 64
+// CHECK: [[TMP26:%.*]] = icmp ugt <8 x i64> [[TMP23]], [[TMP24]]
+// CHECK: [[TMP27:%.*]] = select <8 x i1> [[TMP26]], <8 x i64> [[TMP23]], <8 x i64> [[TMP24]]
+// CHECK: store <8 x i64> [[TMP27]], <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP28:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[VECEXT_I:%.*]] = extractelement <8 x i64> [[TMP28]], i32 0
+// CHECK: ret i64 [[VECEXT_I]]
unsigned long long test_mm512_reduce_max_epu64(__m512i __W){
- // CHECK: %shuffle1.i = shufflevector <8 x i64> %__W, <8 x i64> undef, <8 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp = icmp ult <8 x i64> %shuffle1.i, %__W
- // CHECK: %tmp1 = select <8 x i1> %tmp, <8 x i64> %__W, <8 x i64> %shuffle1.i
- // CHECK: %shuffle3.i = shufflevector <8 x i64> %tmp1, <8 x i64> undef, <8 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp2 = icmp ugt <8 x i64> %tmp1, %shuffle3.i
- // CHECK: %tmp3 = select <8 x i1> %tmp2, <8 x i64> %tmp1, <8 x i64> %shuffle3.i
- // CHECK: %shuffle6.i = shufflevector <8 x i64> %tmp3, <8 x i64> undef, <8 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp4 = icmp ugt <8 x i64> %tmp3, %shuffle6.i
- // CHECK: %.elt.i = extractelement <8 x i1> %tmp4, i32 0
- // CHECK: %.elt20.i = extractelement <8 x i64> %tmp3, i32 0
- // CHECK: %shuffle6.elt.i = extractelement <8 x i64> %tmp3, i32 1
- // CHECK: %vecext.i = select i1 %.elt.i, i64 %.elt20.i, i64 %shuffle6.elt.i
- // CHECK: ret i64 %vecext.i
return _mm512_reduce_max_epu64(__W);
}
+// CHECK-LABEL: define double @test_mm512_reduce_max_pd(<8 x double> %__W) #0 {
+// CHECK: [[_COMPOUNDLITERAL_I_I11_I:%.*]] = alloca <8 x double>, align 64
+// CHECK: [[__A_ADDR_I12_I:%.*]] = alloca <8 x double>, align 64
+// CHECK: [[__B_ADDR_I13_I:%.*]] = alloca <8 x double>, align 64
+// CHECK: [[_COMPOUNDLITERAL_I_I8_I:%.*]] = alloca <8 x double>, align 64
+// CHECK: [[__A_ADDR_I9_I:%.*]] = alloca <8 x double>, align 64
+// CHECK: [[__B_ADDR_I10_I:%.*]] = alloca <8 x double>, align 64
+// CHECK: [[_COMPOUNDLITERAL_I_I_I:%.*]] = alloca <8 x double>, align 64
+// CHECK: [[__A_ADDR_I_I:%.*]] = alloca <8 x double>, align 64
+// CHECK: [[__B_ADDR_I_I:%.*]] = alloca <8 x double>, align 64
+// CHECK: [[__V_ADDR_I:%.*]] = alloca <8 x double>, align 64
+// CHECK: [[__W_ADDR:%.*]] = alloca <8 x double>, align 64
+// CHECK: store <8 x double> %__W, <8 x double>* [[__W_ADDR]], align 64
+// CHECK: [[TMP0:%.*]] = load <8 x double>, <8 x double>* [[__W_ADDR]], align 64
+// CHECK: store <8 x double> [[TMP0]], <8 x double>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP1:%.*]] = load <8 x double>, <8 x double>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP2:%.*]] = load <8 x double>, <8 x double>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE_I:%.*]] = shufflevector <8 x double> [[TMP1]], <8 x double> [[TMP2]], <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP3:%.*]] = load <8 x double>, <8 x double>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP4:%.*]] = load <8 x double>, <8 x double>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE1_I:%.*]] = shufflevector <8 x double> [[TMP3]], <8 x double> [[TMP4]], <8 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: store <8 x double> [[SHUFFLE_I]], <8 x double>* [[__A_ADDR_I_I]], align 64
+// CHECK: store <8 x double> [[SHUFFLE1_I]], <8 x double>* [[__B_ADDR_I_I]], align 64
+// CHECK: [[TMP5:%.*]] = load <8 x double>, <8 x double>* [[__A_ADDR_I_I]], align 64
+// CHECK: [[TMP6:%.*]] = load <8 x double>, <8 x double>* [[__B_ADDR_I_I]], align 64
+// CHECK: store <8 x double> zeroinitializer, <8 x double>* [[_COMPOUNDLITERAL_I_I_I]], align 64
+// CHECK: [[TMP7:%.*]] = load <8 x double>, <8 x double>* [[_COMPOUNDLITERAL_I_I_I]], align 64
+// CHECK: [[TMP8:%.*]] = call <8 x double> @llvm.x86.avx512.mask.max.pd.512(<8 x double> [[TMP5]], <8 x double> [[TMP6]], <8 x double> [[TMP7]], i8 -1, i32 4) #2
+// CHECK: store <8 x double> [[TMP8]], <8 x double>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP9:%.*]] = load <8 x double>, <8 x double>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP10:%.*]] = load <8 x double>, <8 x double>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE2_I:%.*]] = shufflevector <8 x double> [[TMP9]], <8 x double> [[TMP10]], <8 x i32> <i32 0, i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP11:%.*]] = load <8 x double>, <8 x double>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP12:%.*]] = load <8 x double>, <8 x double>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE3_I:%.*]] = shufflevector <8 x double> [[TMP11]], <8 x double> [[TMP12]], <8 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: store <8 x double> [[SHUFFLE2_I]], <8 x double>* [[__A_ADDR_I12_I]], align 64
+// CHECK: store <8 x double> [[SHUFFLE3_I]], <8 x double>* [[__B_ADDR_I13_I]], align 64
+// CHECK: [[TMP13:%.*]] = load <8 x double>, <8 x double>* [[__A_ADDR_I12_I]], align 64
+// CHECK: [[TMP14:%.*]] = load <8 x double>, <8 x double>* [[__B_ADDR_I13_I]], align 64
+// CHECK: store <8 x double> zeroinitializer, <8 x double>* [[_COMPOUNDLITERAL_I_I11_I]], align 64
+// CHECK: [[TMP15:%.*]] = load <8 x double>, <8 x double>* [[_COMPOUNDLITERAL_I_I11_I]], align 64
+// CHECK: [[TMP16:%.*]] = call <8 x double> @llvm.x86.avx512.mask.max.pd.512(<8 x double> [[TMP13]], <8 x double> [[TMP14]], <8 x double> [[TMP15]], i8 -1, i32 4) #2
+// CHECK: store <8 x double> [[TMP16]], <8 x double>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP17:%.*]] = load <8 x double>, <8 x double>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP18:%.*]] = load <8 x double>, <8 x double>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE5_I:%.*]] = shufflevector <8 x double> [[TMP17]], <8 x double> [[TMP18]], <8 x i32> <i32 0, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP19:%.*]] = load <8 x double>, <8 x double>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP20:%.*]] = load <8 x double>, <8 x double>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE6_I:%.*]] = shufflevector <8 x double> [[TMP19]], <8 x double> [[TMP20]], <8 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: store <8 x double> [[SHUFFLE5_I]], <8 x double>* [[__A_ADDR_I9_I]], align 64
+// CHECK: store <8 x double> [[SHUFFLE6_I]], <8 x double>* [[__B_ADDR_I10_I]], align 64
+// CHECK: [[TMP21:%.*]] = load <8 x double>, <8 x double>* [[__A_ADDR_I9_I]], align 64
+// CHECK: [[TMP22:%.*]] = load <8 x double>, <8 x double>* [[__B_ADDR_I10_I]], align 64
+// CHECK: store <8 x double> zeroinitializer, <8 x double>* [[_COMPOUNDLITERAL_I_I8_I]], align 64
+// CHECK: [[TMP23:%.*]] = load <8 x double>, <8 x double>* [[_COMPOUNDLITERAL_I_I8_I]], align 64
+// CHECK: [[TMP24:%.*]] = call <8 x double> @llvm.x86.avx512.mask.max.pd.512(<8 x double> [[TMP21]], <8 x double> [[TMP22]], <8 x double> [[TMP23]], i8 -1, i32 4) #2
+// CHECK: store <8 x double> [[TMP24]], <8 x double>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP25:%.*]] = load <8 x double>, <8 x double>* [[__V_ADDR_I]], align 64
+// CHECK: [[VECEXT_I:%.*]] = extractelement <8 x double> [[TMP25]], i32 0
+// CHECK: ret double [[VECEXT_I]]
double test_mm512_reduce_max_pd(__m512d __W){
- // CHECK: %shuffle1.i = shufflevector <8 x double> %__W, <8 x double> undef, <8 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp = tail call <8 x double> @llvm.x86.avx512.mask.max.pd.512(<8 x double> %__W, <8 x double> %shuffle1.i, <8 x double> zeroinitializer, i8 -1, i32 4) #3
- // CHECK: %shuffle3.i = shufflevector <8 x double> %tmp, <8 x double> undef, <8 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp1 = tail call <8 x double> @llvm.x86.avx512.mask.max.pd.512(<8 x double> %tmp, <8 x double> %shuffle3.i, <8 x double> zeroinitializer, i8 -1, i32 4) #3
- // CHECK: %shuffle6.i = shufflevector <8 x double> %tmp1, <8 x double> undef, <8 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp2 = tail call <8 x double> @llvm.x86.avx512.mask.max.pd.512(<8 x double> %tmp1, <8 x double> %shuffle6.i, <8 x double> zeroinitializer, i8 -1, i32 4) #3
- // CHECK: %vecext.i = extractelement <8 x double> %tmp2, i32 0
- // CHECK: ret double %vecext.i
return _mm512_reduce_max_pd(__W);
}
+// CHECK-LABEL: define i64 @test_mm512_reduce_min_epi64(<8 x i64> %__W) #0 {
+// CHECK: [[_COMPOUNDLITERAL_I_I11_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__A_ADDR_I12_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__B_ADDR_I13_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[_COMPOUNDLITERAL_I_I8_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__A_ADDR_I9_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__B_ADDR_I10_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[_COMPOUNDLITERAL_I_I_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__A_ADDR_I_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__B_ADDR_I_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__V_ADDR_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__W_ADDR:%.*]] = alloca <8 x i64>, align 64
+// CHECK: store <8 x i64> %__W, <8 x i64>* [[__W_ADDR]], align 64
+// CHECK: [[TMP0:%.*]] = load <8 x i64>, <8 x i64>* [[__W_ADDR]], align 64
+// CHECK: store <8 x i64> [[TMP0]], <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP1:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP2:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE_I:%.*]] = shufflevector <8 x i64> [[TMP1]], <8 x i64> [[TMP2]], <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP3:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE1_I:%.*]] = shufflevector <8 x i64> [[TMP3]], <8 x i64> [[TMP4]], <8 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: store <8 x i64> [[SHUFFLE_I]], <8 x i64>* [[__A_ADDR_I_I]], align 64
+// CHECK: store <8 x i64> [[SHUFFLE1_I]], <8 x i64>* [[__B_ADDR_I_I]], align 64
+// CHECK: [[TMP5:%.*]] = load <8 x i64>, <8 x i64>* [[__A_ADDR_I_I]], align 64
+// CHECK: [[TMP6:%.*]] = load <8 x i64>, <8 x i64>* [[__B_ADDR_I_I]], align 64
+// CHECK: store <8 x i64> zeroinitializer, <8 x i64>* [[_COMPOUNDLITERAL_I_I_I]], align 64
+// CHECK: [[TMP7:%.*]] = load <8 x i64>, <8 x i64>* [[_COMPOUNDLITERAL_I_I_I]], align 64
+// CHECK: [[TMP8:%.*]] = icmp sgt <8 x i64> [[TMP5]], [[TMP6]]
+// CHECK: [[TMP9:%.*]] = select <8 x i1> [[TMP8]], <8 x i64> [[TMP5]], <8 x i64> [[TMP6]]
+// CHECK: store <8 x i64> [[TMP9]], <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP10:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP11:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE2_I:%.*]] = shufflevector <8 x i64> [[TMP10]], <8 x i64> [[TMP11]], <8 x i32> <i32 0, i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP12:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP13:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE3_I:%.*]] = shufflevector <8 x i64> [[TMP12]], <8 x i64> [[TMP13]], <8 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: store <8 x i64> [[SHUFFLE2_I]], <8 x i64>* [[__A_ADDR_I12_I]], align 64
+// CHECK: store <8 x i64> [[SHUFFLE3_I]], <8 x i64>* [[__B_ADDR_I13_I]], align 64
+// CHECK: [[TMP14:%.*]] = load <8 x i64>, <8 x i64>* [[__A_ADDR_I12_I]], align 64
+// CHECK: [[TMP15:%.*]] = load <8 x i64>, <8 x i64>* [[__B_ADDR_I13_I]], align 64
+// CHECK: store <8 x i64> zeroinitializer, <8 x i64>* [[_COMPOUNDLITERAL_I_I11_I]], align 64
+// CHECK: [[TMP16:%.*]] = load <8 x i64>, <8 x i64>* [[_COMPOUNDLITERAL_I_I11_I]], align 64
+// CHECK: [[TMP17:%.*]] = icmp sgt <8 x i64> [[TMP14]], [[TMP15]]
+// CHECK: [[TMP18:%.*]] = select <8 x i1> [[TMP17]], <8 x i64> [[TMP14]], <8 x i64> [[TMP15]]
+// CHECK: store <8 x i64> [[TMP18]], <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP19:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP20:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE5_I:%.*]] = shufflevector <8 x i64> [[TMP19]], <8 x i64> [[TMP20]], <8 x i32> <i32 0, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP21:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP22:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE6_I:%.*]] = shufflevector <8 x i64> [[TMP21]], <8 x i64> [[TMP22]], <8 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: store <8 x i64> [[SHUFFLE5_I]], <8 x i64>* [[__A_ADDR_I9_I]], align 64
+// CHECK: store <8 x i64> [[SHUFFLE6_I]], <8 x i64>* [[__B_ADDR_I10_I]], align 64
+// CHECK: [[TMP23:%.*]] = load <8 x i64>, <8 x i64>* [[__A_ADDR_I9_I]], align 64
+// CHECK: [[TMP24:%.*]] = load <8 x i64>, <8 x i64>* [[__B_ADDR_I10_I]], align 64
+// CHECK: store <8 x i64> zeroinitializer, <8 x i64>* [[_COMPOUNDLITERAL_I_I8_I]], align 64
+// CHECK: [[TMP25:%.*]] = load <8 x i64>, <8 x i64>* [[_COMPOUNDLITERAL_I_I8_I]], align 64
+// CHECK: [[TMP26:%.*]] = icmp sgt <8 x i64> [[TMP23]], [[TMP24]]
+// CHECK: [[TMP27:%.*]] = select <8 x i1> [[TMP26]], <8 x i64> [[TMP23]], <8 x i64> [[TMP24]]
+// CHECK: store <8 x i64> [[TMP27]], <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP28:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[VECEXT_I:%.*]] = extractelement <8 x i64> [[TMP28]], i32 0
+// CHECK: ret i64 [[VECEXT_I]]
long long test_mm512_reduce_min_epi64(__m512i __W){
- // CHECK: %shuffle1.i = shufflevector <8 x i64> %__W, <8 x i64> undef, <8 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp = icmp slt <8 x i64> %shuffle1.i, %__W
- // CHECK: %tmp1 = select <8 x i1> %tmp, <8 x i64> %__W, <8 x i64> %shuffle1.i
- // CHECK: %shuffle3.i = shufflevector <8 x i64> %tmp1, <8 x i64> undef, <8 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp2 = icmp sgt <8 x i64> %tmp1, %shuffle3.i
- // CHECK: %tmp3 = select <8 x i1> %tmp2, <8 x i64> %tmp1, <8 x i64> %shuffle3.i
- // CHECK: %shuffle6.i = shufflevector <8 x i64> %tmp3, <8 x i64> undef, <8 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp4 = icmp sgt <8 x i64> %tmp3, %shuffle6.i
- // CHECK: %.elt.i = extractelement <8 x i1> %tmp4, i32 0
- // CHECK: %.elt20.i = extractelement <8 x i64> %tmp3, i32 0
- // CHECK: %shuffle6.elt.i = extractelement <8 x i64> %tmp3, i32 1
- // CHECK: %vecext.i = select i1 %.elt.i, i64 %.elt20.i, i64 %shuffle6.elt.i
- // CHECK: ret i64 %vecext.i
return _mm512_reduce_max_epi64(__W);
}
+// CHECK-LABEL: define i64 @test_mm512_reduce_min_epu64(<8 x i64> %__W) #0 {
+// CHECK: [[_COMPOUNDLITERAL_I_I11_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__A_ADDR_I12_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__B_ADDR_I13_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[_COMPOUNDLITERAL_I_I8_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__A_ADDR_I9_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__B_ADDR_I10_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[_COMPOUNDLITERAL_I_I_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__A_ADDR_I_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__B_ADDR_I_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__V_ADDR_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__W_ADDR:%.*]] = alloca <8 x i64>, align 64
+// CHECK: store <8 x i64> %__W, <8 x i64>* [[__W_ADDR]], align 64
+// CHECK: [[TMP0:%.*]] = load <8 x i64>, <8 x i64>* [[__W_ADDR]], align 64
+// CHECK: store <8 x i64> [[TMP0]], <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP1:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP2:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE_I:%.*]] = shufflevector <8 x i64> [[TMP1]], <8 x i64> [[TMP2]], <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP3:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE1_I:%.*]] = shufflevector <8 x i64> [[TMP3]], <8 x i64> [[TMP4]], <8 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: store <8 x i64> [[SHUFFLE_I]], <8 x i64>* [[__A_ADDR_I_I]], align 64
+// CHECK: store <8 x i64> [[SHUFFLE1_I]], <8 x i64>* [[__B_ADDR_I_I]], align 64
+// CHECK: [[TMP5:%.*]] = load <8 x i64>, <8 x i64>* [[__A_ADDR_I_I]], align 64
+// CHECK: [[TMP6:%.*]] = load <8 x i64>, <8 x i64>* [[__B_ADDR_I_I]], align 64
+// CHECK: store <8 x i64> zeroinitializer, <8 x i64>* [[_COMPOUNDLITERAL_I_I_I]], align 64
+// CHECK: [[TMP7:%.*]] = load <8 x i64>, <8 x i64>* [[_COMPOUNDLITERAL_I_I_I]], align 64
+// CHECK: [[TMP8:%.*]] = icmp ugt <8 x i64> [[TMP5]], [[TMP6]]
+// CHECK: [[TMP9:%.*]] = select <8 x i1> [[TMP8]], <8 x i64> [[TMP5]], <8 x i64> [[TMP6]]
+// CHECK: store <8 x i64> [[TMP9]], <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP10:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP11:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE2_I:%.*]] = shufflevector <8 x i64> [[TMP10]], <8 x i64> [[TMP11]], <8 x i32> <i32 0, i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP12:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP13:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE3_I:%.*]] = shufflevector <8 x i64> [[TMP12]], <8 x i64> [[TMP13]], <8 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: store <8 x i64> [[SHUFFLE2_I]], <8 x i64>* [[__A_ADDR_I12_I]], align 64
+// CHECK: store <8 x i64> [[SHUFFLE3_I]], <8 x i64>* [[__B_ADDR_I13_I]], align 64
+// CHECK: [[TMP14:%.*]] = load <8 x i64>, <8 x i64>* [[__A_ADDR_I12_I]], align 64
+// CHECK: [[TMP15:%.*]] = load <8 x i64>, <8 x i64>* [[__B_ADDR_I13_I]], align 64
+// CHECK: store <8 x i64> zeroinitializer, <8 x i64>* [[_COMPOUNDLITERAL_I_I11_I]], align 64
+// CHECK: [[TMP16:%.*]] = load <8 x i64>, <8 x i64>* [[_COMPOUNDLITERAL_I_I11_I]], align 64
+// CHECK: [[TMP17:%.*]] = icmp ugt <8 x i64> [[TMP14]], [[TMP15]]
+// CHECK: [[TMP18:%.*]] = select <8 x i1> [[TMP17]], <8 x i64> [[TMP14]], <8 x i64> [[TMP15]]
+// CHECK: store <8 x i64> [[TMP18]], <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP19:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP20:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE5_I:%.*]] = shufflevector <8 x i64> [[TMP19]], <8 x i64> [[TMP20]], <8 x i32> <i32 0, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP21:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP22:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE6_I:%.*]] = shufflevector <8 x i64> [[TMP21]], <8 x i64> [[TMP22]], <8 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: store <8 x i64> [[SHUFFLE5_I]], <8 x i64>* [[__A_ADDR_I9_I]], align 64
+// CHECK: store <8 x i64> [[SHUFFLE6_I]], <8 x i64>* [[__B_ADDR_I10_I]], align 64
+// CHECK: [[TMP23:%.*]] = load <8 x i64>, <8 x i64>* [[__A_ADDR_I9_I]], align 64
+// CHECK: [[TMP24:%.*]] = load <8 x i64>, <8 x i64>* [[__B_ADDR_I10_I]], align 64
+// CHECK: store <8 x i64> zeroinitializer, <8 x i64>* [[_COMPOUNDLITERAL_I_I8_I]], align 64
+// CHECK: [[TMP25:%.*]] = load <8 x i64>, <8 x i64>* [[_COMPOUNDLITERAL_I_I8_I]], align 64
+// CHECK: [[TMP26:%.*]] = icmp ugt <8 x i64> [[TMP23]], [[TMP24]]
+// CHECK: [[TMP27:%.*]] = select <8 x i1> [[TMP26]], <8 x i64> [[TMP23]], <8 x i64> [[TMP24]]
+// CHECK: store <8 x i64> [[TMP27]], <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP28:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[VECEXT_I:%.*]] = extractelement <8 x i64> [[TMP28]], i32 0
+// CHECK: ret i64 [[VECEXT_I]]
unsigned long long test_mm512_reduce_min_epu64(__m512i __W){
- // CHECK: %shuffle1.i = shufflevector <8 x i64> %__W, <8 x i64> undef, <8 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp = icmp ult <8 x i64> %shuffle1.i, %__W
- // CHECK: %tmp1 = select <8 x i1> %tmp, <8 x i64> %__W, <8 x i64> %shuffle1.i
- // CHECK: %shuffle3.i = shufflevector <8 x i64> %tmp1, <8 x i64> undef, <8 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp2 = icmp ugt <8 x i64> %tmp1, %shuffle3.i
- // CHECK: %tmp3 = select <8 x i1> %tmp2, <8 x i64> %tmp1, <8 x i64> %shuffle3.i
- // CHECK: %shuffle6.i = shufflevector <8 x i64> %tmp3, <8 x i64> undef, <8 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp4 = icmp ugt <8 x i64> %tmp3, %shuffle6.i
- // CHECK: %.elt.i = extractelement <8 x i1> %tmp4, i32 0
- // CHECK: %.elt20.i = extractelement <8 x i64> %tmp3, i32 0
- // CHECK: %shuffle6.elt.i = extractelement <8 x i64> %tmp3, i32 1
- // CHECK: %vecext.i = select i1 %.elt.i, i64 %.elt20.i, i64 %shuffle6.elt.i
- // CHECK: ret i64 %vecext.i
return _mm512_reduce_max_epu64(__W);
}
+// CHECK-LABEL: define double @test_mm512_reduce_min_pd(<8 x double> %__W) #0 {
+// CHECK: [[_COMPOUNDLITERAL_I_I11_I:%.*]] = alloca <8 x double>, align 64
+// CHECK: [[__A_ADDR_I12_I:%.*]] = alloca <8 x double>, align 64
+// CHECK: [[__B_ADDR_I13_I:%.*]] = alloca <8 x double>, align 64
+// CHECK: [[_COMPOUNDLITERAL_I_I8_I:%.*]] = alloca <8 x double>, align 64
+// CHECK: [[__A_ADDR_I9_I:%.*]] = alloca <8 x double>, align 64
+// CHECK: [[__B_ADDR_I10_I:%.*]] = alloca <8 x double>, align 64
+// CHECK: [[_COMPOUNDLITERAL_I_I_I:%.*]] = alloca <8 x double>, align 64
+// CHECK: [[__A_ADDR_I_I:%.*]] = alloca <8 x double>, align 64
+// CHECK: [[__B_ADDR_I_I:%.*]] = alloca <8 x double>, align 64
+// CHECK: [[__V_ADDR_I:%.*]] = alloca <8 x double>, align 64
+// CHECK: [[__W_ADDR:%.*]] = alloca <8 x double>, align 64
+// CHECK: store <8 x double> %__W, <8 x double>* [[__W_ADDR]], align 64
+// CHECK: [[TMP0:%.*]] = load <8 x double>, <8 x double>* [[__W_ADDR]], align 64
+// CHECK: store <8 x double> [[TMP0]], <8 x double>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP1:%.*]] = load <8 x double>, <8 x double>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP2:%.*]] = load <8 x double>, <8 x double>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE_I:%.*]] = shufflevector <8 x double> [[TMP1]], <8 x double> [[TMP2]], <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP3:%.*]] = load <8 x double>, <8 x double>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP4:%.*]] = load <8 x double>, <8 x double>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE1_I:%.*]] = shufflevector <8 x double> [[TMP3]], <8 x double> [[TMP4]], <8 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: store <8 x double> [[SHUFFLE_I]], <8 x double>* [[__A_ADDR_I_I]], align 64
+// CHECK: store <8 x double> [[SHUFFLE1_I]], <8 x double>* [[__B_ADDR_I_I]], align 64
+// CHECK: [[TMP5:%.*]] = load <8 x double>, <8 x double>* [[__A_ADDR_I_I]], align 64
+// CHECK: [[TMP6:%.*]] = load <8 x double>, <8 x double>* [[__B_ADDR_I_I]], align 64
+// CHECK: store <8 x double> zeroinitializer, <8 x double>* [[_COMPOUNDLITERAL_I_I_I]], align 64
+// CHECK: [[TMP7:%.*]] = load <8 x double>, <8 x double>* [[_COMPOUNDLITERAL_I_I_I]], align 64
+// CHECK: [[TMP8:%.*]] = call <8 x double> @llvm.x86.avx512.mask.min.pd.512(<8 x double> [[TMP5]], <8 x double> [[TMP6]], <8 x double> [[TMP7]], i8 -1, i32 4) #2
+// CHECK: store <8 x double> [[TMP8]], <8 x double>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP9:%.*]] = load <8 x double>, <8 x double>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP10:%.*]] = load <8 x double>, <8 x double>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE2_I:%.*]] = shufflevector <8 x double> [[TMP9]], <8 x double> [[TMP10]], <8 x i32> <i32 0, i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP11:%.*]] = load <8 x double>, <8 x double>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP12:%.*]] = load <8 x double>, <8 x double>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE3_I:%.*]] = shufflevector <8 x double> [[TMP11]], <8 x double> [[TMP12]], <8 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: store <8 x double> [[SHUFFLE2_I]], <8 x double>* [[__A_ADDR_I12_I]], align 64
+// CHECK: store <8 x double> [[SHUFFLE3_I]], <8 x double>* [[__B_ADDR_I13_I]], align 64
+// CHECK: [[TMP13:%.*]] = load <8 x double>, <8 x double>* [[__A_ADDR_I12_I]], align 64
+// CHECK: [[TMP14:%.*]] = load <8 x double>, <8 x double>* [[__B_ADDR_I13_I]], align 64
+// CHECK: store <8 x double> zeroinitializer, <8 x double>* [[_COMPOUNDLITERAL_I_I11_I]], align 64
+// CHECK: [[TMP15:%.*]] = load <8 x double>, <8 x double>* [[_COMPOUNDLITERAL_I_I11_I]], align 64
+// CHECK: [[TMP16:%.*]] = call <8 x double> @llvm.x86.avx512.mask.min.pd.512(<8 x double> [[TMP13]], <8 x double> [[TMP14]], <8 x double> [[TMP15]], i8 -1, i32 4) #2
+// CHECK: store <8 x double> [[TMP16]], <8 x double>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP17:%.*]] = load <8 x double>, <8 x double>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP18:%.*]] = load <8 x double>, <8 x double>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE5_I:%.*]] = shufflevector <8 x double> [[TMP17]], <8 x double> [[TMP18]], <8 x i32> <i32 0, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP19:%.*]] = load <8 x double>, <8 x double>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP20:%.*]] = load <8 x double>, <8 x double>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE6_I:%.*]] = shufflevector <8 x double> [[TMP19]], <8 x double> [[TMP20]], <8 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: store <8 x double> [[SHUFFLE5_I]], <8 x double>* [[__A_ADDR_I9_I]], align 64
+// CHECK: store <8 x double> [[SHUFFLE6_I]], <8 x double>* [[__B_ADDR_I10_I]], align 64
+// CHECK: [[TMP21:%.*]] = load <8 x double>, <8 x double>* [[__A_ADDR_I9_I]], align 64
+// CHECK: [[TMP22:%.*]] = load <8 x double>, <8 x double>* [[__B_ADDR_I10_I]], align 64
+// CHECK: store <8 x double> zeroinitializer, <8 x double>* [[_COMPOUNDLITERAL_I_I8_I]], align 64
+// CHECK: [[TMP23:%.*]] = load <8 x double>, <8 x double>* [[_COMPOUNDLITERAL_I_I8_I]], align 64
+// CHECK: [[TMP24:%.*]] = call <8 x double> @llvm.x86.avx512.mask.min.pd.512(<8 x double> [[TMP21]], <8 x double> [[TMP22]], <8 x double> [[TMP23]], i8 -1, i32 4) #2
+// CHECK: store <8 x double> [[TMP24]], <8 x double>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP25:%.*]] = load <8 x double>, <8 x double>* [[__V_ADDR_I]], align 64
+// CHECK: [[VECEXT_I:%.*]] = extractelement <8 x double> [[TMP25]], i32 0
+// CHECK: ret double [[VECEXT_I]]
double test_mm512_reduce_min_pd(__m512d __W){
- // CHECK: %shuffle1.i = shufflevector <8 x double> %__W, <8 x double> undef, <8 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp = tail call <8 x double> @llvm.x86.avx512.mask.min.pd.512(<8 x double> %__W, <8 x double> %shuffle1.i, <8 x double> zeroinitializer, i8 -1, i32 4) #3
- // CHECK: %shuffle3.i = shufflevector <8 x double> %tmp, <8 x double> undef, <8 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp1 = tail call <8 x double> @llvm.x86.avx512.mask.min.pd.512(<8 x double> %tmp, <8 x double> %shuffle3.i, <8 x double> zeroinitializer, i8 -1, i32 4) #3
- // CHECK: %shuffle6.i = shufflevector <8 x double> %tmp1, <8 x double> undef, <8 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp2 = tail call <8 x double> @llvm.x86.avx512.mask.min.pd.512(<8 x double> %tmp1, <8 x double> %shuffle6.i, <8 x double> zeroinitializer, i8 -1, i32 4) #3
- // CHECK: %vecext.i = extractelement <8 x double> %tmp2, i32 0
- // CHECK: ret double %vecext.i
return _mm512_reduce_min_pd(__W);
}
+// CHECK-LABEL: define i64 @test_mm512_mask_reduce_max_epi64(i8 zeroext %__M, <8 x i64> %__W) #0 {
+// CHECK: [[_COMPOUNDLITERAL_I_I12_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__A_ADDR_I13_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__B_ADDR_I14_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[_COMPOUNDLITERAL_I_I9_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__A_ADDR_I10_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__B_ADDR_I11_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[_COMPOUNDLITERAL_I_I_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__A_ADDR_I_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__B_ADDR_I_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__D_ADDR_I_I:%.*]] = alloca i64, align 8
+// CHECK: [[_COMPOUNDLITERAL_I_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__M_ADDR_I:%.*]] = alloca i8, align 1
+// CHECK: [[__V_ADDR_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__M_ADDR:%.*]] = alloca i8, align 1
+// CHECK: [[__W_ADDR:%.*]] = alloca <8 x i64>, align 64
+// CHECK: store i8 %__M, i8* [[__M_ADDR]], align 1
+// CHECK: store <8 x i64> %__W, <8 x i64>* [[__W_ADDR]], align 64
+// CHECK: [[TMP0:%.*]] = load i8, i8* [[__M_ADDR]], align 1
+// CHECK: [[TMP1:%.*]] = load <8 x i64>, <8 x i64>* [[__W_ADDR]], align 64
+// CHECK: store i8 [[TMP0]], i8* [[__M_ADDR_I]], align 1
+// CHECK: store <8 x i64> [[TMP1]], <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP2:%.*]] = load i8, i8* [[__M_ADDR_I]], align 1
+// CHECK: [[TMP3:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: store i64 -9223372036854775808, i64* [[__D_ADDR_I_I]], align 8
+// CHECK: [[TMP4:%.*]] = load i64, i64* [[__D_ADDR_I_I]], align 8
+// CHECK: [[VECINIT_I_I:%.*]] = insertelement <8 x i64> undef, i64 [[TMP4]], i32 0
+// CHECK: [[TMP5:%.*]] = load i64, i64* [[__D_ADDR_I_I]], align 8
+// CHECK: [[VECINIT1_I_I:%.*]] = insertelement <8 x i64> [[VECINIT_I_I]], i64 [[TMP5]], i32 1
+// CHECK: [[TMP6:%.*]] = load i64, i64* [[__D_ADDR_I_I]], align 8
+// CHECK: [[VECINIT2_I_I:%.*]] = insertelement <8 x i64> [[VECINIT1_I_I]], i64 [[TMP6]], i32 2
+// CHECK: [[TMP7:%.*]] = load i64, i64* [[__D_ADDR_I_I]], align 8
+// CHECK: [[VECINIT3_I_I:%.*]] = insertelement <8 x i64> [[VECINIT2_I_I]], i64 [[TMP7]], i32 3
+// CHECK: [[TMP8:%.*]] = load i64, i64* [[__D_ADDR_I_I]], align 8
+// CHECK: [[VECINIT4_I_I:%.*]] = insertelement <8 x i64> [[VECINIT3_I_I]], i64 [[TMP8]], i32 4
+// CHECK: [[TMP9:%.*]] = load i64, i64* [[__D_ADDR_I_I]], align 8
+// CHECK: [[VECINIT5_I_I:%.*]] = insertelement <8 x i64> [[VECINIT4_I_I]], i64 [[TMP9]], i32 5
+// CHECK: [[TMP10:%.*]] = load i64, i64* [[__D_ADDR_I_I]], align 8
+// CHECK: [[VECINIT6_I_I:%.*]] = insertelement <8 x i64> [[VECINIT5_I_I]], i64 [[TMP10]], i32 6
+// CHECK: [[TMP11:%.*]] = load i64, i64* [[__D_ADDR_I_I]], align 8
+// CHECK: [[VECINIT7_I_I:%.*]] = insertelement <8 x i64> [[VECINIT6_I_I]], i64 [[TMP11]], i32 7
+// CHECK: store <8 x i64> [[VECINIT7_I_I]], <8 x i64>* [[_COMPOUNDLITERAL_I_I]], align 64
+// CHECK: [[TMP12:%.*]] = load <8 x i64>, <8 x i64>* [[_COMPOUNDLITERAL_I_I]], align 64
+// CHECK: [[TMP13:%.*]] = bitcast i8 [[TMP2]] to <8 x i1>
+// CHECK: [[TMP14:%.*]] = select <8 x i1> [[TMP13]], <8 x i64> [[TMP3]], <8 x i64> [[TMP12]]
+// CHECK: store <8 x i64> [[TMP14]], <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP15:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP16:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE_I:%.*]] = shufflevector <8 x i64> [[TMP15]], <8 x i64> [[TMP16]], <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP17:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP18:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE1_I:%.*]] = shufflevector <8 x i64> [[TMP17]], <8 x i64> [[TMP18]], <8 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: store <8 x i64> [[SHUFFLE_I]], <8 x i64>* [[__A_ADDR_I13_I]], align 64
+// CHECK: store <8 x i64> [[SHUFFLE1_I]], <8 x i64>* [[__B_ADDR_I14_I]], align 64
+// CHECK: [[TMP19:%.*]] = load <8 x i64>, <8 x i64>* [[__A_ADDR_I13_I]], align 64
+// CHECK: [[TMP20:%.*]] = load <8 x i64>, <8 x i64>* [[__B_ADDR_I14_I]], align 64
+// CHECK: store <8 x i64> zeroinitializer, <8 x i64>* [[_COMPOUNDLITERAL_I_I12_I]], align 64
+// CHECK: [[TMP21:%.*]] = load <8 x i64>, <8 x i64>* [[_COMPOUNDLITERAL_I_I12_I]], align 64
+// CHECK: [[TMP22:%.*]] = icmp sgt <8 x i64> [[TMP19]], [[TMP20]]
+// CHECK: [[TMP23:%.*]] = select <8 x i1> [[TMP22]], <8 x i64> [[TMP19]], <8 x i64> [[TMP20]]
+// CHECK: store <8 x i64> [[TMP23]], <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP24:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP25:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE3_I:%.*]] = shufflevector <8 x i64> [[TMP24]], <8 x i64> [[TMP25]], <8 x i32> <i32 0, i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP26:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP27:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE4_I:%.*]] = shufflevector <8 x i64> [[TMP26]], <8 x i64> [[TMP27]], <8 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: store <8 x i64> [[SHUFFLE3_I]], <8 x i64>* [[__A_ADDR_I10_I]], align 64
+// CHECK: store <8 x i64> [[SHUFFLE4_I]], <8 x i64>* [[__B_ADDR_I11_I]], align 64
+// CHECK: [[TMP28:%.*]] = load <8 x i64>, <8 x i64>* [[__A_ADDR_I10_I]], align 64
+// CHECK: [[TMP29:%.*]] = load <8 x i64>, <8 x i64>* [[__B_ADDR_I11_I]], align 64
+// CHECK: store <8 x i64> zeroinitializer, <8 x i64>* [[_COMPOUNDLITERAL_I_I9_I]], align 64
+// CHECK: [[TMP30:%.*]] = load <8 x i64>, <8 x i64>* [[_COMPOUNDLITERAL_I_I9_I]], align 64
+// CHECK: [[TMP31:%.*]] = icmp sgt <8 x i64> [[TMP28]], [[TMP29]]
+// CHECK: [[TMP32:%.*]] = select <8 x i1> [[TMP31]], <8 x i64> [[TMP28]], <8 x i64> [[TMP29]]
+// CHECK: store <8 x i64> [[TMP32]], <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP33:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP34:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE6_I:%.*]] = shufflevector <8 x i64> [[TMP33]], <8 x i64> [[TMP34]], <8 x i32> <i32 0, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP35:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP36:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE7_I:%.*]] = shufflevector <8 x i64> [[TMP35]], <8 x i64> [[TMP36]], <8 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: store <8 x i64> [[SHUFFLE6_I]], <8 x i64>* [[__A_ADDR_I_I]], align 64
+// CHECK: store <8 x i64> [[SHUFFLE7_I]], <8 x i64>* [[__B_ADDR_I_I]], align 64
+// CHECK: [[TMP37:%.*]] = load <8 x i64>, <8 x i64>* [[__A_ADDR_I_I]], align 64
+// CHECK: [[TMP38:%.*]] = load <8 x i64>, <8 x i64>* [[__B_ADDR_I_I]], align 64
+// CHECK: store <8 x i64> zeroinitializer, <8 x i64>* [[_COMPOUNDLITERAL_I_I_I]], align 64
+// CHECK: [[TMP39:%.*]] = load <8 x i64>, <8 x i64>* [[_COMPOUNDLITERAL_I_I_I]], align 64
+// CHECK: [[TMP40:%.*]] = icmp sgt <8 x i64> [[TMP37]], [[TMP38]]
+// CHECK: [[TMP41:%.*]] = select <8 x i1> [[TMP40]], <8 x i64> [[TMP37]], <8 x i64> [[TMP38]]
+// CHECK: store <8 x i64> [[TMP41]], <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP42:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[VECEXT_I:%.*]] = extractelement <8 x i64> [[TMP42]], i32 0
+// CHECK: ret i64 [[VECEXT_I]]
long long test_mm512_mask_reduce_max_epi64(__mmask8 __M, __m512i __W){
- // CHECK: %tmp = bitcast i8 %__M to <8 x i1>
- // CHECK: %tmp1 = select <8 x i1> %tmp, <8 x i64> %__W, <8 x i64> <i64 -9223372036854775808, i64 -9223372036854775808, i64 -9223372036854775808, i64 -9223372036854775808, i64 -9223372036854775808, i64 -9223372036854775808, i64 -9223372036854775808, i64 -9223372036854775808>
- // CHECK: %shuffle1.i = shufflevector <8 x i64> %tmp1, <8 x i64> undef, <8 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp2 = icmp sgt <8 x i64> %tmp1, %shuffle1.i
- // CHECK: %tmp3 = select <8 x i1> %tmp2, <8 x i64> %tmp1, <8 x i64> %shuffle1.i
- // CHECK: %shuffle4.i = shufflevector <8 x i64> %tmp3, <8 x i64> undef, <8 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp4 = icmp sgt <8 x i64> %tmp3, %shuffle4.i
- // CHECK: %tmp5 = select <8 x i1> %tmp4, <8 x i64> %tmp3, <8 x i64> %shuffle4.i
- // CHECK: %shuffle7.i = shufflevector <8 x i64> %tmp5, <8 x i64> undef, <8 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp6 = icmp sgt <8 x i64> %tmp5, %shuffle7.i
- // CHECK: %.elt.i = extractelement <8 x i1> %tmp6, i32 0
- // CHECK: %.elt22.i = extractelement <8 x i64> %tmp5, i32 0
- // CHECK: %shuffle7.elt.i = extractelement <8 x i64> %tmp5, i32 1
- // CHECK: %vecext.i = select i1 %.elt.i, i64 %.elt22.i, i64 %shuffle7.elt.i
- // CHECK: ret i64 %vecext.i
return _mm512_mask_reduce_max_epi64(__M, __W);
}
+// CHECK-LABEL: define i64 @test_mm512_mask_reduce_max_epu64(i8 zeroext %__M, <8 x i64> %__W) #0 {
+// CHECK: [[_COMPOUNDLITERAL_I_I12_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__A_ADDR_I13_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__B_ADDR_I14_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[_COMPOUNDLITERAL_I_I9_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__A_ADDR_I10_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__B_ADDR_I11_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[_COMPOUNDLITERAL_I_I_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__A_ADDR_I_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__B_ADDR_I_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__D_ADDR_I_I:%.*]] = alloca i64, align 8
+// CHECK: [[_COMPOUNDLITERAL_I_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__M_ADDR_I:%.*]] = alloca i8, align 1
+// CHECK: [[__V_ADDR_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__M_ADDR:%.*]] = alloca i8, align 1
+// CHECK: [[__W_ADDR:%.*]] = alloca <8 x i64>, align 64
+// CHECK: store i8 %__M, i8* [[__M_ADDR]], align 1
+// CHECK: store <8 x i64> %__W, <8 x i64>* [[__W_ADDR]], align 64
+// CHECK: [[TMP0:%.*]] = load i8, i8* [[__M_ADDR]], align 1
+// CHECK: [[TMP1:%.*]] = load <8 x i64>, <8 x i64>* [[__W_ADDR]], align 64
+// CHECK: store i8 [[TMP0]], i8* [[__M_ADDR_I]], align 1
+// CHECK: store <8 x i64> [[TMP1]], <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP2:%.*]] = load i8, i8* [[__M_ADDR_I]], align 1
+// CHECK: [[TMP3:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: store i64 0, i64* [[__D_ADDR_I_I]], align 8
+// CHECK: [[TMP4:%.*]] = load i64, i64* [[__D_ADDR_I_I]], align 8
+// CHECK: [[VECINIT_I_I:%.*]] = insertelement <8 x i64> undef, i64 [[TMP4]], i32 0
+// CHECK: [[TMP5:%.*]] = load i64, i64* [[__D_ADDR_I_I]], align 8
+// CHECK: [[VECINIT1_I_I:%.*]] = insertelement <8 x i64> [[VECINIT_I_I]], i64 [[TMP5]], i32 1
+// CHECK: [[TMP6:%.*]] = load i64, i64* [[__D_ADDR_I_I]], align 8
+// CHECK: [[VECINIT2_I_I:%.*]] = insertelement <8 x i64> [[VECINIT1_I_I]], i64 [[TMP6]], i32 2
+// CHECK: [[TMP7:%.*]] = load i64, i64* [[__D_ADDR_I_I]], align 8
+// CHECK: [[VECINIT3_I_I:%.*]] = insertelement <8 x i64> [[VECINIT2_I_I]], i64 [[TMP7]], i32 3
+// CHECK: [[TMP8:%.*]] = load i64, i64* [[__D_ADDR_I_I]], align 8
+// CHECK: [[VECINIT4_I_I:%.*]] = insertelement <8 x i64> [[VECINIT3_I_I]], i64 [[TMP8]], i32 4
+// CHECK: [[TMP9:%.*]] = load i64, i64* [[__D_ADDR_I_I]], align 8
+// CHECK: [[VECINIT5_I_I:%.*]] = insertelement <8 x i64> [[VECINIT4_I_I]], i64 [[TMP9]], i32 5
+// CHECK: [[TMP10:%.*]] = load i64, i64* [[__D_ADDR_I_I]], align 8
+// CHECK: [[VECINIT6_I_I:%.*]] = insertelement <8 x i64> [[VECINIT5_I_I]], i64 [[TMP10]], i32 6
+// CHECK: [[TMP11:%.*]] = load i64, i64* [[__D_ADDR_I_I]], align 8
+// CHECK: [[VECINIT7_I_I:%.*]] = insertelement <8 x i64> [[VECINIT6_I_I]], i64 [[TMP11]], i32 7
+// CHECK: store <8 x i64> [[VECINIT7_I_I]], <8 x i64>* [[_COMPOUNDLITERAL_I_I]], align 64
+// CHECK: [[TMP12:%.*]] = load <8 x i64>, <8 x i64>* [[_COMPOUNDLITERAL_I_I]], align 64
+// CHECK: [[TMP13:%.*]] = bitcast i8 [[TMP2]] to <8 x i1>
+// CHECK: [[TMP14:%.*]] = select <8 x i1> [[TMP13]], <8 x i64> [[TMP3]], <8 x i64> [[TMP12]]
+// CHECK: store <8 x i64> [[TMP14]], <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP15:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP16:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE_I:%.*]] = shufflevector <8 x i64> [[TMP15]], <8 x i64> [[TMP16]], <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP17:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP18:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE1_I:%.*]] = shufflevector <8 x i64> [[TMP17]], <8 x i64> [[TMP18]], <8 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: store <8 x i64> [[SHUFFLE_I]], <8 x i64>* [[__A_ADDR_I13_I]], align 64
+// CHECK: store <8 x i64> [[SHUFFLE1_I]], <8 x i64>* [[__B_ADDR_I14_I]], align 64
+// CHECK: [[TMP19:%.*]] = load <8 x i64>, <8 x i64>* [[__A_ADDR_I13_I]], align 64
+// CHECK: [[TMP20:%.*]] = load <8 x i64>, <8 x i64>* [[__B_ADDR_I14_I]], align 64
+// CHECK: store <8 x i64> zeroinitializer, <8 x i64>* [[_COMPOUNDLITERAL_I_I12_I]], align 64
+// CHECK: [[TMP21:%.*]] = load <8 x i64>, <8 x i64>* [[_COMPOUNDLITERAL_I_I12_I]], align 64
+// CHECK: [[TMP22:%.*]] = icmp ugt <8 x i64> [[TMP19]], [[TMP20]]
+// CHECK: [[TMP23:%.*]] = select <8 x i1> [[TMP22]], <8 x i64> [[TMP19]], <8 x i64> [[TMP20]]
+// CHECK: store <8 x i64> [[TMP23]], <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP24:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP25:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE3_I:%.*]] = shufflevector <8 x i64> [[TMP24]], <8 x i64> [[TMP25]], <8 x i32> <i32 0, i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP26:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP27:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE4_I:%.*]] = shufflevector <8 x i64> [[TMP26]], <8 x i64> [[TMP27]], <8 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: store <8 x i64> [[SHUFFLE3_I]], <8 x i64>* [[__A_ADDR_I10_I]], align 64
+// CHECK: store <8 x i64> [[SHUFFLE4_I]], <8 x i64>* [[__B_ADDR_I11_I]], align 64
+// CHECK: [[TMP28:%.*]] = load <8 x i64>, <8 x i64>* [[__A_ADDR_I10_I]], align 64
+// CHECK: [[TMP29:%.*]] = load <8 x i64>, <8 x i64>* [[__B_ADDR_I11_I]], align 64
+// CHECK: store <8 x i64> zeroinitializer, <8 x i64>* [[_COMPOUNDLITERAL_I_I9_I]], align 64
+// CHECK: [[TMP30:%.*]] = load <8 x i64>, <8 x i64>* [[_COMPOUNDLITERAL_I_I9_I]], align 64
+// CHECK: [[TMP31:%.*]] = icmp ugt <8 x i64> [[TMP28]], [[TMP29]]
+// CHECK: [[TMP32:%.*]] = select <8 x i1> [[TMP31]], <8 x i64> [[TMP28]], <8 x i64> [[TMP29]]
+// CHECK: store <8 x i64> [[TMP32]], <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP33:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP34:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE6_I:%.*]] = shufflevector <8 x i64> [[TMP33]], <8 x i64> [[TMP34]], <8 x i32> <i32 0, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP35:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP36:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE7_I:%.*]] = shufflevector <8 x i64> [[TMP35]], <8 x i64> [[TMP36]], <8 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: store <8 x i64> [[SHUFFLE6_I]], <8 x i64>* [[__A_ADDR_I_I]], align 64
+// CHECK: store <8 x i64> [[SHUFFLE7_I]], <8 x i64>* [[__B_ADDR_I_I]], align 64
+// CHECK: [[TMP37:%.*]] = load <8 x i64>, <8 x i64>* [[__A_ADDR_I_I]], align 64
+// CHECK: [[TMP38:%.*]] = load <8 x i64>, <8 x i64>* [[__B_ADDR_I_I]], align 64
+// CHECK: store <8 x i64> zeroinitializer, <8 x i64>* [[_COMPOUNDLITERAL_I_I_I]], align 64
+// CHECK: [[TMP39:%.*]] = load <8 x i64>, <8 x i64>* [[_COMPOUNDLITERAL_I_I_I]], align 64
+// CHECK: [[TMP40:%.*]] = icmp ugt <8 x i64> [[TMP37]], [[TMP38]]
+// CHECK: [[TMP41:%.*]] = select <8 x i1> [[TMP40]], <8 x i64> [[TMP37]], <8 x i64> [[TMP38]]
+// CHECK: store <8 x i64> [[TMP41]], <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP42:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[VECEXT_I:%.*]] = extractelement <8 x i64> [[TMP42]], i32 0
+// CHECK: ret i64 [[VECEXT_I]]
unsigned long test_mm512_mask_reduce_max_epu64(__mmask8 __M, __m512i __W){
- // CHECK: %tmp = bitcast i8 %__M to <8 x i1>
- // CHECK: %tmp1 = select <8 x i1> %tmp, <8 x i64> %__W, <8 x i64> zeroinitializer
- // CHECK: %shuffle1.i = shufflevector <8 x i64> %tmp1, <8 x i64> undef, <8 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp2 = icmp ugt <8 x i64> %tmp1, %shuffle1.i
- // CHECK: %tmp3 = select <8 x i1> %tmp2, <8 x i64> %tmp1, <8 x i64> %shuffle1.i
- // CHECK: %shuffle4.i = shufflevector <8 x i64> %tmp3, <8 x i64> undef, <8 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp4 = icmp ugt <8 x i64> %tmp3, %shuffle4.i
- // CHECK: %tmp5 = select <8 x i1> %tmp4, <8 x i64> %tmp3, <8 x i64> %shuffle4.i
- // CHECK: %shuffle7.i = shufflevector <8 x i64> %tmp5, <8 x i64> undef, <8 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp6 = icmp ugt <8 x i64> %tmp5, %shuffle7.i
- // CHECK: %.elt.i = extractelement <8 x i1> %tmp6, i32 0
- // CHECK: %.elt22.i = extractelement <8 x i64> %tmp5, i32 0
- // CHECK: %shuffle7.elt.i = extractelement <8 x i64> %tmp5, i32 1
- // CHECK: %vecext.i = select i1 %.elt.i, i64 %.elt22.i, i64 %shuffle7.elt.i
- // CHECK: ret i64 %vecext.i
return _mm512_mask_reduce_max_epu64(__M, __W);
}
+// CHECK-LABEL: define i64 @test_mm512_mask_reduce_max_pd(i8 zeroext %__M, <8 x double> %__W) #0 {
+// CHECK: [[_COMPOUNDLITERAL_I_I12_I:%.*]] = alloca <8 x double>, align 64
+// CHECK: [[__A_ADDR_I13_I:%.*]] = alloca <8 x double>, align 64
+// CHECK: [[__B_ADDR_I14_I:%.*]] = alloca <8 x double>, align 64
+// CHECK: [[_COMPOUNDLITERAL_I_I9_I:%.*]] = alloca <8 x double>, align 64
+// CHECK: [[__A_ADDR_I10_I:%.*]] = alloca <8 x double>, align 64
+// CHECK: [[__B_ADDR_I11_I:%.*]] = alloca <8 x double>, align 64
+// CHECK: [[_COMPOUNDLITERAL_I_I_I:%.*]] = alloca <8 x double>, align 64
+// CHECK: [[__A_ADDR_I_I:%.*]] = alloca <8 x double>, align 64
+// CHECK: [[__B_ADDR_I_I:%.*]] = alloca <8 x double>, align 64
+// CHECK: [[__W_ADDR_I_I:%.*]] = alloca double, align 8
+// CHECK: [[_COMPOUNDLITERAL_I_I:%.*]] = alloca <8 x double>, align 64
+// CHECK: [[__M_ADDR_I:%.*]] = alloca i8, align 1
+// CHECK: [[__V_ADDR_I:%.*]] = alloca <8 x double>, align 64
+// CHECK: [[__M_ADDR:%.*]] = alloca i8, align 1
+// CHECK: [[__W_ADDR:%.*]] = alloca <8 x double>, align 64
+// CHECK: store i8 %__M, i8* [[__M_ADDR]], align 1
+// CHECK: store <8 x double> %__W, <8 x double>* [[__W_ADDR]], align 64
+// CHECK: [[TMP0:%.*]] = load i8, i8* [[__M_ADDR]], align 1
+// CHECK: [[TMP1:%.*]] = load <8 x double>, <8 x double>* [[__W_ADDR]], align 64
+// CHECK: store i8 [[TMP0]], i8* [[__M_ADDR_I]], align 1
+// CHECK: store <8 x double> [[TMP1]], <8 x double>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP2:%.*]] = load i8, i8* [[__M_ADDR_I]], align 1
+// CHECK: [[TMP3:%.*]] = load <8 x double>, <8 x double>* [[__V_ADDR_I]], align 64
+// CHECK: store double 0x7FF0000000000000, double* [[__W_ADDR_I_I]], align 8
+// CHECK: [[TMP4:%.*]] = load double, double* [[__W_ADDR_I_I]], align 8
+// CHECK: [[VECINIT_I_I:%.*]] = insertelement <8 x double> undef, double [[TMP4]], i32 0
+// CHECK: [[TMP5:%.*]] = load double, double* [[__W_ADDR_I_I]], align 8
+// CHECK: [[VECINIT1_I_I:%.*]] = insertelement <8 x double> [[VECINIT_I_I]], double [[TMP5]], i32 1
+// CHECK: [[TMP6:%.*]] = load double, double* [[__W_ADDR_I_I]], align 8
+// CHECK: [[VECINIT2_I_I:%.*]] = insertelement <8 x double> [[VECINIT1_I_I]], double [[TMP6]], i32 2
+// CHECK: [[TMP7:%.*]] = load double, double* [[__W_ADDR_I_I]], align 8
+// CHECK: [[VECINIT3_I_I:%.*]] = insertelement <8 x double> [[VECINIT2_I_I]], double [[TMP7]], i32 3
+// CHECK: [[TMP8:%.*]] = load double, double* [[__W_ADDR_I_I]], align 8
+// CHECK: [[VECINIT4_I_I:%.*]] = insertelement <8 x double> [[VECINIT3_I_I]], double [[TMP8]], i32 4
+// CHECK: [[TMP9:%.*]] = load double, double* [[__W_ADDR_I_I]], align 8
+// CHECK: [[VECINIT5_I_I:%.*]] = insertelement <8 x double> [[VECINIT4_I_I]], double [[TMP9]], i32 5
+// CHECK: [[TMP10:%.*]] = load double, double* [[__W_ADDR_I_I]], align 8
+// CHECK: [[VECINIT6_I_I:%.*]] = insertelement <8 x double> [[VECINIT5_I_I]], double [[TMP10]], i32 6
+// CHECK: [[TMP11:%.*]] = load double, double* [[__W_ADDR_I_I]], align 8
+// CHECK: [[VECINIT7_I_I:%.*]] = insertelement <8 x double> [[VECINIT6_I_I]], double [[TMP11]], i32 7
+// CHECK: store <8 x double> [[VECINIT7_I_I]], <8 x double>* [[_COMPOUNDLITERAL_I_I]], align 64
+// CHECK: [[TMP12:%.*]] = load <8 x double>, <8 x double>* [[_COMPOUNDLITERAL_I_I]], align 64
+// CHECK: [[SUB_I:%.*]] = fsub <8 x double> <double -0.000000e+00, double -0.000000e+00, double -0.000000e+00, double -0.000000e+00, double -0.000000e+00, double -0.000000e+00, double -0.000000e+00, double -0.000000e+00>, [[TMP12]]
+// CHECK: [[TMP13:%.*]] = bitcast i8 [[TMP2]] to <8 x i1>
+// CHECK: [[TMP14:%.*]] = select <8 x i1> [[TMP13]], <8 x double> [[TMP3]], <8 x double> [[SUB_I]]
+// CHECK: store <8 x double> [[TMP14]], <8 x double>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP15:%.*]] = load <8 x double>, <8 x double>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP16:%.*]] = load <8 x double>, <8 x double>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE_I:%.*]] = shufflevector <8 x double> [[TMP15]], <8 x double> [[TMP16]], <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP17:%.*]] = load <8 x double>, <8 x double>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP18:%.*]] = load <8 x double>, <8 x double>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE1_I:%.*]] = shufflevector <8 x double> [[TMP17]], <8 x double> [[TMP18]], <8 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: store <8 x double> [[SHUFFLE_I]], <8 x double>* [[__A_ADDR_I13_I]], align 64
+// CHECK: store <8 x double> [[SHUFFLE1_I]], <8 x double>* [[__B_ADDR_I14_I]], align 64
+// CHECK: [[TMP19:%.*]] = load <8 x double>, <8 x double>* [[__A_ADDR_I13_I]], align 64
+// CHECK: [[TMP20:%.*]] = load <8 x double>, <8 x double>* [[__B_ADDR_I14_I]], align 64
+// CHECK: store <8 x double> zeroinitializer, <8 x double>* [[_COMPOUNDLITERAL_I_I12_I]], align 64
+// CHECK: [[TMP21:%.*]] = load <8 x double>, <8 x double>* [[_COMPOUNDLITERAL_I_I12_I]], align 64
+// CHECK: [[TMP22:%.*]] = call <8 x double> @llvm.x86.avx512.mask.max.pd.512(<8 x double> [[TMP19]], <8 x double> [[TMP20]], <8 x double> [[TMP21]], i8 -1, i32 4) #2
+// CHECK: store <8 x double> [[TMP22]], <8 x double>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP23:%.*]] = load <8 x double>, <8 x double>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP24:%.*]] = load <8 x double>, <8 x double>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE3_I:%.*]] = shufflevector <8 x double> [[TMP23]], <8 x double> [[TMP24]], <8 x i32> <i32 0, i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP25:%.*]] = load <8 x double>, <8 x double>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP26:%.*]] = load <8 x double>, <8 x double>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE4_I:%.*]] = shufflevector <8 x double> [[TMP25]], <8 x double> [[TMP26]], <8 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: store <8 x double> [[SHUFFLE3_I]], <8 x double>* [[__A_ADDR_I10_I]], align 64
+// CHECK: store <8 x double> [[SHUFFLE4_I]], <8 x double>* [[__B_ADDR_I11_I]], align 64
+// CHECK: [[TMP27:%.*]] = load <8 x double>, <8 x double>* [[__A_ADDR_I10_I]], align 64
+// CHECK: [[TMP28:%.*]] = load <8 x double>, <8 x double>* [[__B_ADDR_I11_I]], align 64
+// CHECK: store <8 x double> zeroinitializer, <8 x double>* [[_COMPOUNDLITERAL_I_I9_I]], align 64
+// CHECK: [[TMP29:%.*]] = load <8 x double>, <8 x double>* [[_COMPOUNDLITERAL_I_I9_I]], align 64
+// CHECK: [[TMP30:%.*]] = call <8 x double> @llvm.x86.avx512.mask.max.pd.512(<8 x double> [[TMP27]], <8 x double> [[TMP28]], <8 x double> [[TMP29]], i8 -1, i32 4) #2
+// CHECK: store <8 x double> [[TMP30]], <8 x double>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP31:%.*]] = load <8 x double>, <8 x double>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP32:%.*]] = load <8 x double>, <8 x double>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE6_I:%.*]] = shufflevector <8 x double> [[TMP31]], <8 x double> [[TMP32]], <8 x i32> <i32 0, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP33:%.*]] = load <8 x double>, <8 x double>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP34:%.*]] = load <8 x double>, <8 x double>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE7_I:%.*]] = shufflevector <8 x double> [[TMP33]], <8 x double> [[TMP34]], <8 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: store <8 x double> [[SHUFFLE6_I]], <8 x double>* [[__A_ADDR_I_I]], align 64
+// CHECK: store <8 x double> [[SHUFFLE7_I]], <8 x double>* [[__B_ADDR_I_I]], align 64
+// CHECK: [[TMP35:%.*]] = load <8 x double>, <8 x double>* [[__A_ADDR_I_I]], align 64
+// CHECK: [[TMP36:%.*]] = load <8 x double>, <8 x double>* [[__B_ADDR_I_I]], align 64
+// CHECK: store <8 x double> zeroinitializer, <8 x double>* [[_COMPOUNDLITERAL_I_I_I]], align 64
+// CHECK: [[TMP37:%.*]] = load <8 x double>, <8 x double>* [[_COMPOUNDLITERAL_I_I_I]], align 64
+// CHECK: [[TMP38:%.*]] = call <8 x double> @llvm.x86.avx512.mask.max.pd.512(<8 x double> [[TMP35]], <8 x double> [[TMP36]], <8 x double> [[TMP37]], i8 -1, i32 4) #2
+// CHECK: store <8 x double> [[TMP38]], <8 x double>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP39:%.*]] = load <8 x double>, <8 x double>* [[__V_ADDR_I]], align 64
+// CHECK: [[VECEXT_I:%.*]] = extractelement <8 x double> [[TMP39]], i32 0
+// CHECK: [[CONV:%.*]] = fptosi double [[VECEXT_I]] to i64
+// CHECK: ret i64 [[CONV]]
long long test_mm512_mask_reduce_max_pd(__mmask8 __M, __m512d __W){
- // CHECK: %tmp = bitcast i8 %__M to <8 x i1>
- // CHECK: %tmp1 = select <8 x i1> %tmp, <8 x double> %__W, <8 x double> <double 0xFFF0000000000000, double 0xFFF0000000000000, double 0xFFF0000000000000, double 0xFFF0000000000000, double 0xFFF0000000000000, double 0xFFF0000000000000, double 0xFFF0000000000000, double 0xFFF0000000000000>
- // CHECK: %shuffle1.i = shufflevector <8 x double> %tmp1, <8 x double> undef, <8 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp2 = tail call <8 x double> @llvm.x86.avx512.mask.max.pd.512(<8 x double> %tmp1, <8 x double> %shuffle1.i, <8 x double> zeroinitializer, i8 -1, i32 4) #3
- // CHECK: %shuffle4.i = shufflevector <8 x double> %tmp2, <8 x double> undef, <8 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp3 = tail call <8 x double> @llvm.x86.avx512.mask.max.pd.512(<8 x double> %tmp2, <8 x double> %shuffle4.i, <8 x double> zeroinitializer, i8 -1, i32 4) #3
- // CHECK: %shuffle7.i = shufflevector <8 x double> %tmp3, <8 x double> undef, <8 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp4 = tail call <8 x double> @llvm.x86.avx512.mask.max.pd.512(<8 x double> %tmp3, <8 x double> %shuffle7.i, <8 x double> zeroinitializer, i8 -1, i32 4) #3
- // CHECK: %vecext.i = extractelement <8 x double> %tmp4, i32 0
- // CHECK: %conv = fptosi double %vecext.i to i64
- // CHECK: ret i64 %conv
return _mm512_mask_reduce_max_pd(__M, __W);
}
+// CHECK-LABEL: define i64 @test_mm512_mask_reduce_min_epi64(i8 zeroext %__M, <8 x i64> %__W) #0 {
+// CHECK: [[_COMPOUNDLITERAL_I_I12_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__A_ADDR_I13_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__B_ADDR_I14_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[_COMPOUNDLITERAL_I_I9_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__A_ADDR_I10_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__B_ADDR_I11_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[_COMPOUNDLITERAL_I_I_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__A_ADDR_I_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__B_ADDR_I_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__D_ADDR_I_I:%.*]] = alloca i64, align 8
+// CHECK: [[_COMPOUNDLITERAL_I_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__M_ADDR_I:%.*]] = alloca i8, align 1
+// CHECK: [[__V_ADDR_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__M_ADDR:%.*]] = alloca i8, align 1
+// CHECK: [[__W_ADDR:%.*]] = alloca <8 x i64>, align 64
+// CHECK: store i8 %__M, i8* [[__M_ADDR]], align 1
+// CHECK: store <8 x i64> %__W, <8 x i64>* [[__W_ADDR]], align 64
+// CHECK: [[TMP0:%.*]] = load i8, i8* [[__M_ADDR]], align 1
+// CHECK: [[TMP1:%.*]] = load <8 x i64>, <8 x i64>* [[__W_ADDR]], align 64
+// CHECK: store i8 [[TMP0]], i8* [[__M_ADDR_I]], align 1
+// CHECK: store <8 x i64> [[TMP1]], <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP2:%.*]] = load i8, i8* [[__M_ADDR_I]], align 1
+// CHECK: [[TMP3:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: store i64 9223372036854775807, i64* [[__D_ADDR_I_I]], align 8
+// CHECK: [[TMP4:%.*]] = load i64, i64* [[__D_ADDR_I_I]], align 8
+// CHECK: [[VECINIT_I_I:%.*]] = insertelement <8 x i64> undef, i64 [[TMP4]], i32 0
+// CHECK: [[TMP5:%.*]] = load i64, i64* [[__D_ADDR_I_I]], align 8
+// CHECK: [[VECINIT1_I_I:%.*]] = insertelement <8 x i64> [[VECINIT_I_I]], i64 [[TMP5]], i32 1
+// CHECK: [[TMP6:%.*]] = load i64, i64* [[__D_ADDR_I_I]], align 8
+// CHECK: [[VECINIT2_I_I:%.*]] = insertelement <8 x i64> [[VECINIT1_I_I]], i64 [[TMP6]], i32 2
+// CHECK: [[TMP7:%.*]] = load i64, i64* [[__D_ADDR_I_I]], align 8
+// CHECK: [[VECINIT3_I_I:%.*]] = insertelement <8 x i64> [[VECINIT2_I_I]], i64 [[TMP7]], i32 3
+// CHECK: [[TMP8:%.*]] = load i64, i64* [[__D_ADDR_I_I]], align 8
+// CHECK: [[VECINIT4_I_I:%.*]] = insertelement <8 x i64> [[VECINIT3_I_I]], i64 [[TMP8]], i32 4
+// CHECK: [[TMP9:%.*]] = load i64, i64* [[__D_ADDR_I_I]], align 8
+// CHECK: [[VECINIT5_I_I:%.*]] = insertelement <8 x i64> [[VECINIT4_I_I]], i64 [[TMP9]], i32 5
+// CHECK: [[TMP10:%.*]] = load i64, i64* [[__D_ADDR_I_I]], align 8
+// CHECK: [[VECINIT6_I_I:%.*]] = insertelement <8 x i64> [[VECINIT5_I_I]], i64 [[TMP10]], i32 6
+// CHECK: [[TMP11:%.*]] = load i64, i64* [[__D_ADDR_I_I]], align 8
+// CHECK: [[VECINIT7_I_I:%.*]] = insertelement <8 x i64> [[VECINIT6_I_I]], i64 [[TMP11]], i32 7
+// CHECK: store <8 x i64> [[VECINIT7_I_I]], <8 x i64>* [[_COMPOUNDLITERAL_I_I]], align 64
+// CHECK: [[TMP12:%.*]] = load <8 x i64>, <8 x i64>* [[_COMPOUNDLITERAL_I_I]], align 64
+// CHECK: [[TMP13:%.*]] = bitcast i8 [[TMP2]] to <8 x i1>
+// CHECK: [[TMP14:%.*]] = select <8 x i1> [[TMP13]], <8 x i64> [[TMP3]], <8 x i64> [[TMP12]]
+// CHECK: store <8 x i64> [[TMP14]], <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP15:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP16:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE_I:%.*]] = shufflevector <8 x i64> [[TMP15]], <8 x i64> [[TMP16]], <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP17:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP18:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE1_I:%.*]] = shufflevector <8 x i64> [[TMP17]], <8 x i64> [[TMP18]], <8 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: store <8 x i64> [[SHUFFLE_I]], <8 x i64>* [[__A_ADDR_I13_I]], align 64
+// CHECK: store <8 x i64> [[SHUFFLE1_I]], <8 x i64>* [[__B_ADDR_I14_I]], align 64
+// CHECK: [[TMP19:%.*]] = load <8 x i64>, <8 x i64>* [[__A_ADDR_I13_I]], align 64
+// CHECK: [[TMP20:%.*]] = load <8 x i64>, <8 x i64>* [[__B_ADDR_I14_I]], align 64
+// CHECK: store <8 x i64> zeroinitializer, <8 x i64>* [[_COMPOUNDLITERAL_I_I12_I]], align 64
+// CHECK: [[TMP21:%.*]] = load <8 x i64>, <8 x i64>* [[_COMPOUNDLITERAL_I_I12_I]], align 64
+// CHECK: [[TMP22:%.*]] = icmp slt <8 x i64> [[TMP19]], [[TMP20]]
+// CHECK: [[TMP23:%.*]] = select <8 x i1> [[TMP22]], <8 x i64> [[TMP19]], <8 x i64> [[TMP20]]
+// CHECK: store <8 x i64> [[TMP23]], <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP24:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP25:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE3_I:%.*]] = shufflevector <8 x i64> [[TMP24]], <8 x i64> [[TMP25]], <8 x i32> <i32 0, i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP26:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP27:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE4_I:%.*]] = shufflevector <8 x i64> [[TMP26]], <8 x i64> [[TMP27]], <8 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: store <8 x i64> [[SHUFFLE3_I]], <8 x i64>* [[__A_ADDR_I10_I]], align 64
+// CHECK: store <8 x i64> [[SHUFFLE4_I]], <8 x i64>* [[__B_ADDR_I11_I]], align 64
+// CHECK: [[TMP28:%.*]] = load <8 x i64>, <8 x i64>* [[__A_ADDR_I10_I]], align 64
+// CHECK: [[TMP29:%.*]] = load <8 x i64>, <8 x i64>* [[__B_ADDR_I11_I]], align 64
+// CHECK: store <8 x i64> zeroinitializer, <8 x i64>* [[_COMPOUNDLITERAL_I_I9_I]], align 64
+// CHECK: [[TMP30:%.*]] = load <8 x i64>, <8 x i64>* [[_COMPOUNDLITERAL_I_I9_I]], align 64
+// CHECK: [[TMP31:%.*]] = icmp slt <8 x i64> [[TMP28]], [[TMP29]]
+// CHECK: [[TMP32:%.*]] = select <8 x i1> [[TMP31]], <8 x i64> [[TMP28]], <8 x i64> [[TMP29]]
+// CHECK: store <8 x i64> [[TMP32]], <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP33:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP34:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE6_I:%.*]] = shufflevector <8 x i64> [[TMP33]], <8 x i64> [[TMP34]], <8 x i32> <i32 0, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP35:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP36:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE7_I:%.*]] = shufflevector <8 x i64> [[TMP35]], <8 x i64> [[TMP36]], <8 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: store <8 x i64> [[SHUFFLE6_I]], <8 x i64>* [[__A_ADDR_I_I]], align 64
+// CHECK: store <8 x i64> [[SHUFFLE7_I]], <8 x i64>* [[__B_ADDR_I_I]], align 64
+// CHECK: [[TMP37:%.*]] = load <8 x i64>, <8 x i64>* [[__A_ADDR_I_I]], align 64
+// CHECK: [[TMP38:%.*]] = load <8 x i64>, <8 x i64>* [[__B_ADDR_I_I]], align 64
+// CHECK: store <8 x i64> zeroinitializer, <8 x i64>* [[_COMPOUNDLITERAL_I_I_I]], align 64
+// CHECK: [[TMP39:%.*]] = load <8 x i64>, <8 x i64>* [[_COMPOUNDLITERAL_I_I_I]], align 64
+// CHECK: [[TMP40:%.*]] = icmp slt <8 x i64> [[TMP37]], [[TMP38]]
+// CHECK: [[TMP41:%.*]] = select <8 x i1> [[TMP40]], <8 x i64> [[TMP37]], <8 x i64> [[TMP38]]
+// CHECK: store <8 x i64> [[TMP41]], <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP42:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[VECEXT_I:%.*]] = extractelement <8 x i64> [[TMP42]], i32 0
+// CHECK: ret i64 [[VECEXT_I]]
long long test_mm512_mask_reduce_min_epi64(__mmask8 __M, __m512i __W){
- // CHECK: %tmp = bitcast i8 %__M to <8 x i1>
- // CHECK: %tmp1 = select <8 x i1> %tmp, <8 x i64> %__W, <8 x i64> <i64 9223372036854775807, i64 9223372036854775807, i64 9223372036854775807, i64 9223372036854775807, i64 9223372036854775807, i64 9223372036854775807, i64 9223372036854775807, i64 9223372036854775807>
- // CHECK: %shuffle1.i = shufflevector <8 x i64> %tmp1, <8 x i64> undef, <8 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp2 = icmp slt <8 x i64> %tmp1, %shuffle1.i
- // CHECK: %tmp3 = select <8 x i1> %tmp2, <8 x i64> %tmp1, <8 x i64> %shuffle1.i
- // CHECK: %shuffle4.i = shufflevector <8 x i64> %tmp3, <8 x i64> undef, <8 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp4 = icmp slt <8 x i64> %tmp3, %shuffle4.i
- // CHECK: %tmp5 = select <8 x i1> %tmp4, <8 x i64> %tmp3, <8 x i64> %shuffle4.i
- // CHECK: %shuffle7.i = shufflevector <8 x i64> %tmp5, <8 x i64> undef, <8 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp6 = icmp slt <8 x i64> %tmp5, %shuffle7.i
- // CHECK: %.elt.i = extractelement <8 x i1> %tmp6, i32 0
- // CHECK: %.elt22.i = extractelement <8 x i64> %tmp5, i32 0
- // CHECK: %shuffle7.elt.i = extractelement <8 x i64> %tmp5, i32 1
- // CHECK: %vecext.i = select i1 %.elt.i, i64 %.elt22.i, i64 %shuffle7.elt.i
- // CHECK: ret i64 %vecext.i
return _mm512_mask_reduce_min_epi64(__M, __W);
}
+// CHECK-LABEL: define i64 @test_mm512_mask_reduce_min_epu64(i8 zeroext %__M, <8 x i64> %__W) #0 {
+// CHECK: [[_COMPOUNDLITERAL_I_I12_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__A_ADDR_I13_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__B_ADDR_I14_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[_COMPOUNDLITERAL_I_I9_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__A_ADDR_I10_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__B_ADDR_I11_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[_COMPOUNDLITERAL_I_I_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__A_ADDR_I_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__B_ADDR_I_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__D_ADDR_I_I:%.*]] = alloca i64, align 8
+// CHECK: [[_COMPOUNDLITERAL_I_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__M_ADDR_I:%.*]] = alloca i8, align 1
+// CHECK: [[__V_ADDR_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__M_ADDR:%.*]] = alloca i8, align 1
+// CHECK: [[__W_ADDR:%.*]] = alloca <8 x i64>, align 64
+// CHECK: store i8 %__M, i8* [[__M_ADDR]], align 1
+// CHECK: store <8 x i64> %__W, <8 x i64>* [[__W_ADDR]], align 64
+// CHECK: [[TMP0:%.*]] = load i8, i8* [[__M_ADDR]], align 1
+// CHECK: [[TMP1:%.*]] = load <8 x i64>, <8 x i64>* [[__W_ADDR]], align 64
+// CHECK: store i8 [[TMP0]], i8* [[__M_ADDR_I]], align 1
+// CHECK: store <8 x i64> [[TMP1]], <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP2:%.*]] = load i8, i8* [[__M_ADDR_I]], align 1
+// CHECK: [[TMP3:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: store i64 0, i64* [[__D_ADDR_I_I]], align 8
+// CHECK: [[TMP4:%.*]] = load i64, i64* [[__D_ADDR_I_I]], align 8
+// CHECK: [[VECINIT_I_I:%.*]] = insertelement <8 x i64> undef, i64 [[TMP4]], i32 0
+// CHECK: [[TMP5:%.*]] = load i64, i64* [[__D_ADDR_I_I]], align 8
+// CHECK: [[VECINIT1_I_I:%.*]] = insertelement <8 x i64> [[VECINIT_I_I]], i64 [[TMP5]], i32 1
+// CHECK: [[TMP6:%.*]] = load i64, i64* [[__D_ADDR_I_I]], align 8
+// CHECK: [[VECINIT2_I_I:%.*]] = insertelement <8 x i64> [[VECINIT1_I_I]], i64 [[TMP6]], i32 2
+// CHECK: [[TMP7:%.*]] = load i64, i64* [[__D_ADDR_I_I]], align 8
+// CHECK: [[VECINIT3_I_I:%.*]] = insertelement <8 x i64> [[VECINIT2_I_I]], i64 [[TMP7]], i32 3
+// CHECK: [[TMP8:%.*]] = load i64, i64* [[__D_ADDR_I_I]], align 8
+// CHECK: [[VECINIT4_I_I:%.*]] = insertelement <8 x i64> [[VECINIT3_I_I]], i64 [[TMP8]], i32 4
+// CHECK: [[TMP9:%.*]] = load i64, i64* [[__D_ADDR_I_I]], align 8
+// CHECK: [[VECINIT5_I_I:%.*]] = insertelement <8 x i64> [[VECINIT4_I_I]], i64 [[TMP9]], i32 5
+// CHECK: [[TMP10:%.*]] = load i64, i64* [[__D_ADDR_I_I]], align 8
+// CHECK: [[VECINIT6_I_I:%.*]] = insertelement <8 x i64> [[VECINIT5_I_I]], i64 [[TMP10]], i32 6
+// CHECK: [[TMP11:%.*]] = load i64, i64* [[__D_ADDR_I_I]], align 8
+// CHECK: [[VECINIT7_I_I:%.*]] = insertelement <8 x i64> [[VECINIT6_I_I]], i64 [[TMP11]], i32 7
+// CHECK: store <8 x i64> [[VECINIT7_I_I]], <8 x i64>* [[_COMPOUNDLITERAL_I_I]], align 64
+// CHECK: [[TMP12:%.*]] = load <8 x i64>, <8 x i64>* [[_COMPOUNDLITERAL_I_I]], align 64
+// CHECK: [[TMP13:%.*]] = bitcast i8 [[TMP2]] to <8 x i1>
+// CHECK: [[TMP14:%.*]] = select <8 x i1> [[TMP13]], <8 x i64> [[TMP3]], <8 x i64> [[TMP12]]
+// CHECK: store <8 x i64> [[TMP14]], <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP15:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP16:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE_I:%.*]] = shufflevector <8 x i64> [[TMP15]], <8 x i64> [[TMP16]], <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP17:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP18:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE1_I:%.*]] = shufflevector <8 x i64> [[TMP17]], <8 x i64> [[TMP18]], <8 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: store <8 x i64> [[SHUFFLE_I]], <8 x i64>* [[__A_ADDR_I13_I]], align 64
+// CHECK: store <8 x i64> [[SHUFFLE1_I]], <8 x i64>* [[__B_ADDR_I14_I]], align 64
+// CHECK: [[TMP19:%.*]] = load <8 x i64>, <8 x i64>* [[__A_ADDR_I13_I]], align 64
+// CHECK: [[TMP20:%.*]] = load <8 x i64>, <8 x i64>* [[__B_ADDR_I14_I]], align 64
+// CHECK: store <8 x i64> zeroinitializer, <8 x i64>* [[_COMPOUNDLITERAL_I_I12_I]], align 64
+// CHECK: [[TMP21:%.*]] = load <8 x i64>, <8 x i64>* [[_COMPOUNDLITERAL_I_I12_I]], align 64
+// CHECK: [[TMP22:%.*]] = icmp ugt <8 x i64> [[TMP19]], [[TMP20]]
+// CHECK: [[TMP23:%.*]] = select <8 x i1> [[TMP22]], <8 x i64> [[TMP19]], <8 x i64> [[TMP20]]
+// CHECK: store <8 x i64> [[TMP23]], <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP24:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP25:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE3_I:%.*]] = shufflevector <8 x i64> [[TMP24]], <8 x i64> [[TMP25]], <8 x i32> <i32 0, i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP26:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP27:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE4_I:%.*]] = shufflevector <8 x i64> [[TMP26]], <8 x i64> [[TMP27]], <8 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: store <8 x i64> [[SHUFFLE3_I]], <8 x i64>* [[__A_ADDR_I10_I]], align 64
+// CHECK: store <8 x i64> [[SHUFFLE4_I]], <8 x i64>* [[__B_ADDR_I11_I]], align 64
+// CHECK: [[TMP28:%.*]] = load <8 x i64>, <8 x i64>* [[__A_ADDR_I10_I]], align 64
+// CHECK: [[TMP29:%.*]] = load <8 x i64>, <8 x i64>* [[__B_ADDR_I11_I]], align 64
+// CHECK: store <8 x i64> zeroinitializer, <8 x i64>* [[_COMPOUNDLITERAL_I_I9_I]], align 64
+// CHECK: [[TMP30:%.*]] = load <8 x i64>, <8 x i64>* [[_COMPOUNDLITERAL_I_I9_I]], align 64
+// CHECK: [[TMP31:%.*]] = icmp ugt <8 x i64> [[TMP28]], [[TMP29]]
+// CHECK: [[TMP32:%.*]] = select <8 x i1> [[TMP31]], <8 x i64> [[TMP28]], <8 x i64> [[TMP29]]
+// CHECK: store <8 x i64> [[TMP32]], <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP33:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP34:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE6_I:%.*]] = shufflevector <8 x i64> [[TMP33]], <8 x i64> [[TMP34]], <8 x i32> <i32 0, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP35:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP36:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE7_I:%.*]] = shufflevector <8 x i64> [[TMP35]], <8 x i64> [[TMP36]], <8 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: store <8 x i64> [[SHUFFLE6_I]], <8 x i64>* [[__A_ADDR_I_I]], align 64
+// CHECK: store <8 x i64> [[SHUFFLE7_I]], <8 x i64>* [[__B_ADDR_I_I]], align 64
+// CHECK: [[TMP37:%.*]] = load <8 x i64>, <8 x i64>* [[__A_ADDR_I_I]], align 64
+// CHECK: [[TMP38:%.*]] = load <8 x i64>, <8 x i64>* [[__B_ADDR_I_I]], align 64
+// CHECK: store <8 x i64> zeroinitializer, <8 x i64>* [[_COMPOUNDLITERAL_I_I_I]], align 64
+// CHECK: [[TMP39:%.*]] = load <8 x i64>, <8 x i64>* [[_COMPOUNDLITERAL_I_I_I]], align 64
+// CHECK: [[TMP40:%.*]] = icmp ugt <8 x i64> [[TMP37]], [[TMP38]]
+// CHECK: [[TMP41:%.*]] = select <8 x i1> [[TMP40]], <8 x i64> [[TMP37]], <8 x i64> [[TMP38]]
+// CHECK: store <8 x i64> [[TMP41]], <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP42:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[VECEXT_I:%.*]] = extractelement <8 x i64> [[TMP42]], i32 0
+// CHECK: ret i64 [[VECEXT_I]]
long long test_mm512_mask_reduce_min_epu64(__mmask8 __M, __m512i __W){
- // CHECK: %tmp = bitcast i8 %__M to <8 x i1>
- // CHECK: %tmp1 = select <8 x i1> %tmp, <8 x i64> %__W, <8 x i64> zeroinitializer
- // CHECK: %shuffle1.i = shufflevector <8 x i64> %tmp1, <8 x i64> undef, <8 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp2 = icmp ugt <8 x i64> %tmp1, %shuffle1.i
- // CHECK: %tmp3 = select <8 x i1> %tmp2, <8 x i64> %tmp1, <8 x i64> %shuffle1.i
- // CHECK: %shuffle4.i = shufflevector <8 x i64> %tmp3, <8 x i64> undef, <8 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp4 = icmp ugt <8 x i64> %tmp3, %shuffle4.i
- // CHECK: %tmp5 = select <8 x i1> %tmp4, <8 x i64> %tmp3, <8 x i64> %shuffle4.i
- // CHECK: %shuffle7.i = shufflevector <8 x i64> %tmp5, <8 x i64> undef, <8 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp6 = icmp ugt <8 x i64> %tmp5, %shuffle7.i
- // CHECK: %.elt.i = extractelement <8 x i1> %tmp6, i32 0
- // CHECK: %.elt22.i = extractelement <8 x i64> %tmp5, i32 0
- // CHECK: %shuffle7.elt.i = extractelement <8 x i64> %tmp5, i32 1
- // CHECK: %vecext.i = select i1 %.elt.i, i64 %.elt22.i, i64 %shuffle7.elt.i
- // CHECK: ret i64 %vecext.i
return _mm512_mask_reduce_max_epu64(__M, __W);
}
+// CHECK-LABEL: define double @test_mm512_mask_reduce_min_pd(i8 zeroext %__M, <8 x double> %__W) #0 {
+// CHECK: [[_COMPOUNDLITERAL_I_I12_I:%.*]] = alloca <8 x double>, align 64
+// CHECK: [[__A_ADDR_I13_I:%.*]] = alloca <8 x double>, align 64
+// CHECK: [[__B_ADDR_I14_I:%.*]] = alloca <8 x double>, align 64
+// CHECK: [[_COMPOUNDLITERAL_I_I9_I:%.*]] = alloca <8 x double>, align 64
+// CHECK: [[__A_ADDR_I10_I:%.*]] = alloca <8 x double>, align 64
+// CHECK: [[__B_ADDR_I11_I:%.*]] = alloca <8 x double>, align 64
+// CHECK: [[_COMPOUNDLITERAL_I_I_I:%.*]] = alloca <8 x double>, align 64
+// CHECK: [[__A_ADDR_I_I:%.*]] = alloca <8 x double>, align 64
+// CHECK: [[__B_ADDR_I_I:%.*]] = alloca <8 x double>, align 64
+// CHECK: [[__W_ADDR_I_I:%.*]] = alloca double, align 8
+// CHECK: [[_COMPOUNDLITERAL_I_I:%.*]] = alloca <8 x double>, align 64
+// CHECK: [[__M_ADDR_I:%.*]] = alloca i8, align 1
+// CHECK: [[__V_ADDR_I:%.*]] = alloca <8 x double>, align 64
+// CHECK: [[__M_ADDR:%.*]] = alloca i8, align 1
+// CHECK: [[__W_ADDR:%.*]] = alloca <8 x double>, align 64
+// CHECK: store i8 %__M, i8* [[__M_ADDR]], align 1
+// CHECK: store <8 x double> %__W, <8 x double>* [[__W_ADDR]], align 64
+// CHECK: [[TMP0:%.*]] = load i8, i8* [[__M_ADDR]], align 1
+// CHECK: [[TMP1:%.*]] = load <8 x double>, <8 x double>* [[__W_ADDR]], align 64
+// CHECK: store i8 [[TMP0]], i8* [[__M_ADDR_I]], align 1
+// CHECK: store <8 x double> [[TMP1]], <8 x double>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP2:%.*]] = load i8, i8* [[__M_ADDR_I]], align 1
+// CHECK: [[TMP3:%.*]] = load <8 x double>, <8 x double>* [[__V_ADDR_I]], align 64
+// CHECK: store double 0x7FF0000000000000, double* [[__W_ADDR_I_I]], align 8
+// CHECK: [[TMP4:%.*]] = load double, double* [[__W_ADDR_I_I]], align 8
+// CHECK: [[VECINIT_I_I:%.*]] = insertelement <8 x double> undef, double [[TMP4]], i32 0
+// CHECK: [[TMP5:%.*]] = load double, double* [[__W_ADDR_I_I]], align 8
+// CHECK: [[VECINIT1_I_I:%.*]] = insertelement <8 x double> [[VECINIT_I_I]], double [[TMP5]], i32 1
+// CHECK: [[TMP6:%.*]] = load double, double* [[__W_ADDR_I_I]], align 8
+// CHECK: [[VECINIT2_I_I:%.*]] = insertelement <8 x double> [[VECINIT1_I_I]], double [[TMP6]], i32 2
+// CHECK: [[TMP7:%.*]] = load double, double* [[__W_ADDR_I_I]], align 8
+// CHECK: [[VECINIT3_I_I:%.*]] = insertelement <8 x double> [[VECINIT2_I_I]], double [[TMP7]], i32 3
+// CHECK: [[TMP8:%.*]] = load double, double* [[__W_ADDR_I_I]], align 8
+// CHECK: [[VECINIT4_I_I:%.*]] = insertelement <8 x double> [[VECINIT3_I_I]], double [[TMP8]], i32 4
+// CHECK: [[TMP9:%.*]] = load double, double* [[__W_ADDR_I_I]], align 8
+// CHECK: [[VECINIT5_I_I:%.*]] = insertelement <8 x double> [[VECINIT4_I_I]], double [[TMP9]], i32 5
+// CHECK: [[TMP10:%.*]] = load double, double* [[__W_ADDR_I_I]], align 8
+// CHECK: [[VECINIT6_I_I:%.*]] = insertelement <8 x double> [[VECINIT5_I_I]], double [[TMP10]], i32 6
+// CHECK: [[TMP11:%.*]] = load double, double* [[__W_ADDR_I_I]], align 8
+// CHECK: [[VECINIT7_I_I:%.*]] = insertelement <8 x double> [[VECINIT6_I_I]], double [[TMP11]], i32 7
+// CHECK: store <8 x double> [[VECINIT7_I_I]], <8 x double>* [[_COMPOUNDLITERAL_I_I]], align 64
+// CHECK: [[TMP12:%.*]] = load <8 x double>, <8 x double>* [[_COMPOUNDLITERAL_I_I]], align 64
+// CHECK: [[TMP13:%.*]] = bitcast i8 [[TMP2]] to <8 x i1>
+// CHECK: [[TMP14:%.*]] = select <8 x i1> [[TMP13]], <8 x double> [[TMP3]], <8 x double> [[TMP12]]
+// CHECK: store <8 x double> [[TMP14]], <8 x double>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP15:%.*]] = load <8 x double>, <8 x double>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP16:%.*]] = load <8 x double>, <8 x double>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE_I:%.*]] = shufflevector <8 x double> [[TMP15]], <8 x double> [[TMP16]], <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP17:%.*]] = load <8 x double>, <8 x double>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP18:%.*]] = load <8 x double>, <8 x double>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE1_I:%.*]] = shufflevector <8 x double> [[TMP17]], <8 x double> [[TMP18]], <8 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: store <8 x double> [[SHUFFLE_I]], <8 x double>* [[__A_ADDR_I13_I]], align 64
+// CHECK: store <8 x double> [[SHUFFLE1_I]], <8 x double>* [[__B_ADDR_I14_I]], align 64
+// CHECK: [[TMP19:%.*]] = load <8 x double>, <8 x double>* [[__A_ADDR_I13_I]], align 64
+// CHECK: [[TMP20:%.*]] = load <8 x double>, <8 x double>* [[__B_ADDR_I14_I]], align 64
+// CHECK: store <8 x double> zeroinitializer, <8 x double>* [[_COMPOUNDLITERAL_I_I12_I]], align 64
+// CHECK: [[TMP21:%.*]] = load <8 x double>, <8 x double>* [[_COMPOUNDLITERAL_I_I12_I]], align 64
+// CHECK: [[TMP22:%.*]] = call <8 x double> @llvm.x86.avx512.mask.min.pd.512(<8 x double> [[TMP19]], <8 x double> [[TMP20]], <8 x double> [[TMP21]], i8 -1, i32 4) #2
+// CHECK: store <8 x double> [[TMP22]], <8 x double>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP23:%.*]] = load <8 x double>, <8 x double>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP24:%.*]] = load <8 x double>, <8 x double>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE3_I:%.*]] = shufflevector <8 x double> [[TMP23]], <8 x double> [[TMP24]], <8 x i32> <i32 0, i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP25:%.*]] = load <8 x double>, <8 x double>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP26:%.*]] = load <8 x double>, <8 x double>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE4_I:%.*]] = shufflevector <8 x double> [[TMP25]], <8 x double> [[TMP26]], <8 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: store <8 x double> [[SHUFFLE3_I]], <8 x double>* [[__A_ADDR_I10_I]], align 64
+// CHECK: store <8 x double> [[SHUFFLE4_I]], <8 x double>* [[__B_ADDR_I11_I]], align 64
+// CHECK: [[TMP27:%.*]] = load <8 x double>, <8 x double>* [[__A_ADDR_I10_I]], align 64
+// CHECK: [[TMP28:%.*]] = load <8 x double>, <8 x double>* [[__B_ADDR_I11_I]], align 64
+// CHECK: store <8 x double> zeroinitializer, <8 x double>* [[_COMPOUNDLITERAL_I_I9_I]], align 64
+// CHECK: [[TMP29:%.*]] = load <8 x double>, <8 x double>* [[_COMPOUNDLITERAL_I_I9_I]], align 64
+// CHECK: [[TMP30:%.*]] = call <8 x double> @llvm.x86.avx512.mask.min.pd.512(<8 x double> [[TMP27]], <8 x double> [[TMP28]], <8 x double> [[TMP29]], i8 -1, i32 4) #2
+// CHECK: store <8 x double> [[TMP30]], <8 x double>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP31:%.*]] = load <8 x double>, <8 x double>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP32:%.*]] = load <8 x double>, <8 x double>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE6_I:%.*]] = shufflevector <8 x double> [[TMP31]], <8 x double> [[TMP32]], <8 x i32> <i32 0, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP33:%.*]] = load <8 x double>, <8 x double>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP34:%.*]] = load <8 x double>, <8 x double>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE7_I:%.*]] = shufflevector <8 x double> [[TMP33]], <8 x double> [[TMP34]], <8 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: store <8 x double> [[SHUFFLE6_I]], <8 x double>* [[__A_ADDR_I_I]], align 64
+// CHECK: store <8 x double> [[SHUFFLE7_I]], <8 x double>* [[__B_ADDR_I_I]], align 64
+// CHECK: [[TMP35:%.*]] = load <8 x double>, <8 x double>* [[__A_ADDR_I_I]], align 64
+// CHECK: [[TMP36:%.*]] = load <8 x double>, <8 x double>* [[__B_ADDR_I_I]], align 64
+// CHECK: store <8 x double> zeroinitializer, <8 x double>* [[_COMPOUNDLITERAL_I_I_I]], align 64
+// CHECK: [[TMP37:%.*]] = load <8 x double>, <8 x double>* [[_COMPOUNDLITERAL_I_I_I]], align 64
+// CHECK: [[TMP38:%.*]] = call <8 x double> @llvm.x86.avx512.mask.min.pd.512(<8 x double> [[TMP35]], <8 x double> [[TMP36]], <8 x double> [[TMP37]], i8 -1, i32 4) #2
+// CHECK: store <8 x double> [[TMP38]], <8 x double>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP39:%.*]] = load <8 x double>, <8 x double>* [[__V_ADDR_I]], align 64
+// CHECK: [[VECEXT_I:%.*]] = extractelement <8 x double> [[TMP39]], i32 0
+// CHECK: ret double [[VECEXT_I]]
double test_mm512_mask_reduce_min_pd(__mmask8 __M, __m512d __W){
- // CHECK: %tmp = bitcast i8 %__M to <8 x i1>
- // CHECK: %tmp1 = select <8 x i1> %tmp, <8 x double> %__W, <8 x double> <double 0x7FF0000000000000, double 0x7FF0000000000000, double 0x7FF0000000000000, double 0x7FF0000000000000, double 0x7FF0000000000000, double 0x7FF0000000000000, double 0x7FF0000000000000, double 0x7FF0000000000000>
- // CHECK: %shuffle1.i = shufflevector <8 x double> %tmp1, <8 x double> undef, <8 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp2 = tail call <8 x double> @llvm.x86.avx512.mask.min.pd.512(<8 x double> %tmp1, <8 x double> %shuffle1.i, <8 x double> zeroinitializer, i8 -1, i32 4) #3
- // CHECK: %shuffle4.i = shufflevector <8 x double> %tmp2, <8 x double> undef, <8 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp3 = tail call <8 x double> @llvm.x86.avx512.mask.min.pd.512(<8 x double> %tmp2, <8 x double> %shuffle4.i, <8 x double> zeroinitializer, i8 -1, i32 4) #3
- // CHECK: %shuffle7.i = shufflevector <8 x double> %tmp3, <8 x double> undef, <8 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp4 = tail call <8 x double> @llvm.x86.avx512.mask.min.pd.512(<8 x double> %tmp3, <8 x double> %shuffle7.i, <8 x double> zeroinitializer, i8 -1, i32 4) #3
- // CHECK: %vecext.i = extractelement <8 x double> %tmp4, i32 0
- // CHECK: ret double %vecext.i
return _mm512_mask_reduce_min_pd(__M, __W);
}
+// CHECK-LABEL: define i32 @test_mm512_reduce_max_epi32(<8 x i64> %__W) #0 {
+// CHECK: [[_COMPOUNDLITERAL_I_I17_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__A_ADDR_I18_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__B_ADDR_I19_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[_COMPOUNDLITERAL_I_I14_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__A_ADDR_I15_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__B_ADDR_I16_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[_COMPOUNDLITERAL_I_I11_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__A_ADDR_I12_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__B_ADDR_I13_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[_COMPOUNDLITERAL_I_I_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__A_ADDR_I_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__B_ADDR_I_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[A_ADDR_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__W_ADDR:%.*]] = alloca <8 x i64>, align 64
+// CHECK: store <8 x i64> %__W, <8 x i64>* [[__W_ADDR]], align 64
+// CHECK: [[TMP0:%.*]] = load <8 x i64>, <8 x i64>* [[__W_ADDR]], align 64
+// CHECK: store <8 x i64> [[TMP0]], <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP1:%.*]] = load <8 x i64>, <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP2:%.*]] = bitcast <8 x i64> [[TMP1]] to <16 x i32>
+// CHECK: [[TMP3:%.*]] = load <8 x i64>, <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP4:%.*]] = bitcast <8 x i64> [[TMP3]] to <16 x i32>
+// CHECK: [[SHUFFLE_I:%.*]] = shufflevector <16 x i32> [[TMP2]], <16 x i32> [[TMP4]], <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP5:%.*]] = bitcast <16 x i32> [[SHUFFLE_I]] to <8 x i64>
+// CHECK: [[TMP6:%.*]] = load <8 x i64>, <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP7:%.*]] = bitcast <8 x i64> [[TMP6]] to <16 x i32>
+// CHECK: [[TMP8:%.*]] = load <8 x i64>, <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP9:%.*]] = bitcast <8 x i64> [[TMP8]] to <16 x i32>
+// CHECK: [[SHUFFLE1_I:%.*]] = shufflevector <16 x i32> [[TMP7]], <16 x i32> [[TMP9]], <16 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP10:%.*]] = bitcast <16 x i32> [[SHUFFLE1_I]] to <8 x i64>
+// CHECK: store <8 x i64> [[TMP5]], <8 x i64>* [[__A_ADDR_I_I]], align 64
+// CHECK: store <8 x i64> [[TMP10]], <8 x i64>* [[__B_ADDR_I_I]], align 64
+// CHECK: [[TMP11:%.*]] = load <8 x i64>, <8 x i64>* [[__A_ADDR_I_I]], align 64
+// CHECK: [[TMP12:%.*]] = bitcast <8 x i64> [[TMP11]] to <16 x i32>
+// CHECK: [[TMP13:%.*]] = load <8 x i64>, <8 x i64>* [[__B_ADDR_I_I]], align 64
+// CHECK: [[TMP14:%.*]] = bitcast <8 x i64> [[TMP13]] to <16 x i32>
+// CHECK: store <8 x i64> zeroinitializer, <8 x i64>* [[_COMPOUNDLITERAL_I_I_I]], align 64
+// CHECK: [[TMP15:%.*]] = load <8 x i64>, <8 x i64>* [[_COMPOUNDLITERAL_I_I_I]], align 64
+// CHECK: [[TMP16:%.*]] = bitcast <8 x i64> [[TMP15]] to <16 x i32>
+// CHECK: [[TMP17:%.*]] = icmp sgt <16 x i32> [[TMP12]], [[TMP14]]
+// CHECK: [[TMP18:%.*]] = select <16 x i1> [[TMP17]], <16 x i32> [[TMP12]], <16 x i32> [[TMP14]]
+// CHECK: [[TMP19:%.*]] = bitcast <16 x i32> [[TMP18]] to <8 x i64>
+// CHECK: store <8 x i64> [[TMP19]], <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP20:%.*]] = load <8 x i64>, <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP21:%.*]] = bitcast <8 x i64> [[TMP20]] to <16 x i32>
+// CHECK: [[TMP22:%.*]] = load <8 x i64>, <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP23:%.*]] = bitcast <8 x i64> [[TMP22]] to <16 x i32>
+// CHECK: [[SHUFFLE2_I:%.*]] = shufflevector <16 x i32> [[TMP21]], <16 x i32> [[TMP23]], <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP24:%.*]] = bitcast <16 x i32> [[SHUFFLE2_I]] to <8 x i64>
+// CHECK: [[TMP25:%.*]] = load <8 x i64>, <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP26:%.*]] = bitcast <8 x i64> [[TMP25]] to <16 x i32>
+// CHECK: [[TMP27:%.*]] = load <8 x i64>, <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP28:%.*]] = bitcast <8 x i64> [[TMP27]] to <16 x i32>
+// CHECK: [[SHUFFLE3_I:%.*]] = shufflevector <16 x i32> [[TMP26]], <16 x i32> [[TMP28]], <16 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP29:%.*]] = bitcast <16 x i32> [[SHUFFLE3_I]] to <8 x i64>
+// CHECK: store <8 x i64> [[TMP24]], <8 x i64>* [[__A_ADDR_I18_I]], align 64
+// CHECK: store <8 x i64> [[TMP29]], <8 x i64>* [[__B_ADDR_I19_I]], align 64
+// CHECK: [[TMP30:%.*]] = load <8 x i64>, <8 x i64>* [[__A_ADDR_I18_I]], align 64
+// CHECK: [[TMP31:%.*]] = bitcast <8 x i64> [[TMP30]] to <16 x i32>
+// CHECK: [[TMP32:%.*]] = load <8 x i64>, <8 x i64>* [[__B_ADDR_I19_I]], align 64
+// CHECK: [[TMP33:%.*]] = bitcast <8 x i64> [[TMP32]] to <16 x i32>
+// CHECK: store <8 x i64> zeroinitializer, <8 x i64>* [[_COMPOUNDLITERAL_I_I17_I]], align 64
+// CHECK: [[TMP34:%.*]] = load <8 x i64>, <8 x i64>* [[_COMPOUNDLITERAL_I_I17_I]], align 64
+// CHECK: [[TMP35:%.*]] = bitcast <8 x i64> [[TMP34]] to <16 x i32>
+// CHECK: [[TMP36:%.*]] = icmp sgt <16 x i32> [[TMP31]], [[TMP33]]
+// CHECK: [[TMP37:%.*]] = select <16 x i1> [[TMP36]], <16 x i32> [[TMP31]], <16 x i32> [[TMP33]]
+// CHECK: [[TMP38:%.*]] = bitcast <16 x i32> [[TMP37]] to <8 x i64>
+// CHECK: store <8 x i64> [[TMP38]], <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP39:%.*]] = load <8 x i64>, <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP40:%.*]] = bitcast <8 x i64> [[TMP39]] to <16 x i32>
+// CHECK: [[TMP41:%.*]] = load <8 x i64>, <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP42:%.*]] = bitcast <8 x i64> [[TMP41]] to <16 x i32>
+// CHECK: [[SHUFFLE5_I:%.*]] = shufflevector <16 x i32> [[TMP40]], <16 x i32> [[TMP42]], <16 x i32> <i32 0, i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP43:%.*]] = bitcast <16 x i32> [[SHUFFLE5_I]] to <8 x i64>
+// CHECK: [[TMP44:%.*]] = load <8 x i64>, <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP45:%.*]] = bitcast <8 x i64> [[TMP44]] to <16 x i32>
+// CHECK: [[TMP46:%.*]] = load <8 x i64>, <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP47:%.*]] = bitcast <8 x i64> [[TMP46]] to <16 x i32>
+// CHECK: [[SHUFFLE6_I:%.*]] = shufflevector <16 x i32> [[TMP45]], <16 x i32> [[TMP47]], <16 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP48:%.*]] = bitcast <16 x i32> [[SHUFFLE6_I]] to <8 x i64>
+// CHECK: store <8 x i64> [[TMP43]], <8 x i64>* [[__A_ADDR_I15_I]], align 64
+// CHECK: store <8 x i64> [[TMP48]], <8 x i64>* [[__B_ADDR_I16_I]], align 64
+// CHECK: [[TMP49:%.*]] = load <8 x i64>, <8 x i64>* [[__A_ADDR_I15_I]], align 64
+// CHECK: [[TMP50:%.*]] = bitcast <8 x i64> [[TMP49]] to <16 x i32>
+// CHECK: [[TMP51:%.*]] = load <8 x i64>, <8 x i64>* [[__B_ADDR_I16_I]], align 64
+// CHECK: [[TMP52:%.*]] = bitcast <8 x i64> [[TMP51]] to <16 x i32>
+// CHECK: store <8 x i64> zeroinitializer, <8 x i64>* [[_COMPOUNDLITERAL_I_I14_I]], align 64
+// CHECK: [[TMP53:%.*]] = load <8 x i64>, <8 x i64>* [[_COMPOUNDLITERAL_I_I14_I]], align 64
+// CHECK: [[TMP54:%.*]] = bitcast <8 x i64> [[TMP53]] to <16 x i32>
+// CHECK: [[TMP55:%.*]] = icmp sgt <16 x i32> [[TMP50]], [[TMP52]]
+// CHECK: [[TMP56:%.*]] = select <16 x i1> [[TMP55]], <16 x i32> [[TMP50]], <16 x i32> [[TMP52]]
+// CHECK: [[TMP57:%.*]] = bitcast <16 x i32> [[TMP56]] to <8 x i64>
+// CHECK: store <8 x i64> [[TMP57]], <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP58:%.*]] = load <8 x i64>, <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP59:%.*]] = bitcast <8 x i64> [[TMP58]] to <16 x i32>
+// CHECK: [[TMP60:%.*]] = load <8 x i64>, <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP61:%.*]] = bitcast <8 x i64> [[TMP60]] to <16 x i32>
+// CHECK: [[SHUFFLE8_I:%.*]] = shufflevector <16 x i32> [[TMP59]], <16 x i32> [[TMP61]], <16 x i32> <i32 0, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP62:%.*]] = bitcast <16 x i32> [[SHUFFLE8_I]] to <8 x i64>
+// CHECK: [[TMP63:%.*]] = load <8 x i64>, <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP64:%.*]] = bitcast <8 x i64> [[TMP63]] to <16 x i32>
+// CHECK: [[TMP65:%.*]] = load <8 x i64>, <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP66:%.*]] = bitcast <8 x i64> [[TMP65]] to <16 x i32>
+// CHECK: [[SHUFFLE9_I:%.*]] = shufflevector <16 x i32> [[TMP64]], <16 x i32> [[TMP66]], <16 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP67:%.*]] = bitcast <16 x i32> [[SHUFFLE9_I]] to <8 x i64>
+// CHECK: store <8 x i64> [[TMP62]], <8 x i64>* [[__A_ADDR_I12_I]], align 64
+// CHECK: store <8 x i64> [[TMP67]], <8 x i64>* [[__B_ADDR_I13_I]], align 64
+// CHECK: [[TMP68:%.*]] = load <8 x i64>, <8 x i64>* [[__A_ADDR_I12_I]], align 64
+// CHECK: [[TMP69:%.*]] = bitcast <8 x i64> [[TMP68]] to <16 x i32>
+// CHECK: [[TMP70:%.*]] = load <8 x i64>, <8 x i64>* [[__B_ADDR_I13_I]], align 64
+// CHECK: [[TMP71:%.*]] = bitcast <8 x i64> [[TMP70]] to <16 x i32>
+// CHECK: store <8 x i64> zeroinitializer, <8 x i64>* [[_COMPOUNDLITERAL_I_I11_I]], align 64
+// CHECK: [[TMP72:%.*]] = load <8 x i64>, <8 x i64>* [[_COMPOUNDLITERAL_I_I11_I]], align 64
+// CHECK: [[TMP73:%.*]] = bitcast <8 x i64> [[TMP72]] to <16 x i32>
+// CHECK: [[TMP74:%.*]] = icmp sgt <16 x i32> [[TMP69]], [[TMP71]]
+// CHECK: [[TMP75:%.*]] = select <16 x i1> [[TMP74]], <16 x i32> [[TMP69]], <16 x i32> [[TMP71]]
+// CHECK: [[TMP76:%.*]] = bitcast <16 x i32> [[TMP75]] to <8 x i64>
+// CHECK: store <8 x i64> [[TMP76]], <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP77:%.*]] = load <8 x i64>, <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[VECEXT_I:%.*]] = extractelement <8 x i64> [[TMP77]], i32 0
+// CHECK: [[CONV_I:%.*]] = trunc i64 [[VECEXT_I]] to i32
+// CHECK: ret i32 [[CONV_I]]
int test_mm512_reduce_max_epi32(__m512i __W){
- // CHECK: %tmp = bitcast <8 x i64> %__W to <16 x i32>
- // CHECK: %shuffle1.i = shufflevector <16 x i32> %tmp, <16 x i32> undef, <16 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp1 = icmp slt <16 x i32> %shuffle1.i, %tmp
- // CHECK: %tmp2 = select <16 x i1> %tmp1, <16 x i32> %tmp, <16 x i32> %shuffle1.i
- // CHECK: %shuffle3.i = shufflevector <16 x i32> %tmp2, <16 x i32> undef, <16 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp3 = icmp sgt <16 x i32> %tmp2, %shuffle3.i
- // CHECK: %tmp4 = select <16 x i1> %tmp3, <16 x i32> %tmp2, <16 x i32> %shuffle3.i
- // CHECK: %shuffle6.i = shufflevector <16 x i32> %tmp4, <16 x i32> undef, <16 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp5 = icmp sgt <16 x i32> %tmp4, %shuffle6.i
- // CHECK: %tmp6 = select <16 x i1> %tmp5, <16 x i32> %tmp4, <16 x i32> %shuffle6.i
- // CHECK: %shuffle9.i = shufflevector <16 x i32> %tmp6, <16 x i32> undef, <16 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp7 = icmp sgt <16 x i32> %tmp6, %shuffle9.i
- // CHECK: %tmp8 = select <16 x i1> %tmp7, <16 x i32> %tmp6, <16 x i32> %shuffle9.i
- // CHECK: %tmp9 = bitcast <16 x i32> %tmp8 to <8 x i64>
- // CHECK: %vecext.i = extractelement <8 x i64> %tmp9, i32 0
- // CHECK: %conv.i = trunc i64 %vecext.i to i32
- // CHECK: ret i32 %conv.i
return _mm512_reduce_max_epi32(__W);
}
+// CHECK-LABEL: define i32 @test_mm512_reduce_max_epu32(<8 x i64> %__W) #0 {
+// CHECK: [[_COMPOUNDLITERAL_I_I17_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__A_ADDR_I18_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__B_ADDR_I19_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[_COMPOUNDLITERAL_I_I14_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__A_ADDR_I15_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__B_ADDR_I16_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[_COMPOUNDLITERAL_I_I11_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__A_ADDR_I12_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__B_ADDR_I13_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[_COMPOUNDLITERAL_I_I_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__A_ADDR_I_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__B_ADDR_I_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[A_ADDR_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__W_ADDR:%.*]] = alloca <8 x i64>, align 64
+// CHECK: store <8 x i64> %__W, <8 x i64>* [[__W_ADDR]], align 64
+// CHECK: [[TMP0:%.*]] = load <8 x i64>, <8 x i64>* [[__W_ADDR]], align 64
+// CHECK: store <8 x i64> [[TMP0]], <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP1:%.*]] = load <8 x i64>, <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP2:%.*]] = bitcast <8 x i64> [[TMP1]] to <16 x i32>
+// CHECK: [[TMP3:%.*]] = load <8 x i64>, <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP4:%.*]] = bitcast <8 x i64> [[TMP3]] to <16 x i32>
+// CHECK: [[SHUFFLE_I:%.*]] = shufflevector <16 x i32> [[TMP2]], <16 x i32> [[TMP4]], <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP5:%.*]] = bitcast <16 x i32> [[SHUFFLE_I]] to <8 x i64>
+// CHECK: [[TMP6:%.*]] = load <8 x i64>, <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP7:%.*]] = bitcast <8 x i64> [[TMP6]] to <16 x i32>
+// CHECK: [[TMP8:%.*]] = load <8 x i64>, <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP9:%.*]] = bitcast <8 x i64> [[TMP8]] to <16 x i32>
+// CHECK: [[SHUFFLE1_I:%.*]] = shufflevector <16 x i32> [[TMP7]], <16 x i32> [[TMP9]], <16 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP10:%.*]] = bitcast <16 x i32> [[SHUFFLE1_I]] to <8 x i64>
+// CHECK: store <8 x i64> [[TMP5]], <8 x i64>* [[__A_ADDR_I_I]], align 64
+// CHECK: store <8 x i64> [[TMP10]], <8 x i64>* [[__B_ADDR_I_I]], align 64
+// CHECK: [[TMP11:%.*]] = load <8 x i64>, <8 x i64>* [[__A_ADDR_I_I]], align 64
+// CHECK: [[TMP12:%.*]] = bitcast <8 x i64> [[TMP11]] to <16 x i32>
+// CHECK: [[TMP13:%.*]] = load <8 x i64>, <8 x i64>* [[__B_ADDR_I_I]], align 64
+// CHECK: [[TMP14:%.*]] = bitcast <8 x i64> [[TMP13]] to <16 x i32>
+// CHECK: store <8 x i64> zeroinitializer, <8 x i64>* [[_COMPOUNDLITERAL_I_I_I]], align 64
+// CHECK: [[TMP15:%.*]] = load <8 x i64>, <8 x i64>* [[_COMPOUNDLITERAL_I_I_I]], align 64
+// CHECK: [[TMP16:%.*]] = bitcast <8 x i64> [[TMP15]] to <16 x i32>
+// CHECK: [[TMP17:%.*]] = icmp ugt <16 x i32> [[TMP12]], [[TMP14]]
+// CHECK: [[TMP18:%.*]] = select <16 x i1> [[TMP17]], <16 x i32> [[TMP12]], <16 x i32> [[TMP14]]
+// CHECK: [[TMP19:%.*]] = bitcast <16 x i32> [[TMP18]] to <8 x i64>
+// CHECK: store <8 x i64> [[TMP19]], <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP20:%.*]] = load <8 x i64>, <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP21:%.*]] = bitcast <8 x i64> [[TMP20]] to <16 x i32>
+// CHECK: [[TMP22:%.*]] = load <8 x i64>, <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP23:%.*]] = bitcast <8 x i64> [[TMP22]] to <16 x i32>
+// CHECK: [[SHUFFLE2_I:%.*]] = shufflevector <16 x i32> [[TMP21]], <16 x i32> [[TMP23]], <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP24:%.*]] = bitcast <16 x i32> [[SHUFFLE2_I]] to <8 x i64>
+// CHECK: [[TMP25:%.*]] = load <8 x i64>, <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP26:%.*]] = bitcast <8 x i64> [[TMP25]] to <16 x i32>
+// CHECK: [[TMP27:%.*]] = load <8 x i64>, <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP28:%.*]] = bitcast <8 x i64> [[TMP27]] to <16 x i32>
+// CHECK: [[SHUFFLE3_I:%.*]] = shufflevector <16 x i32> [[TMP26]], <16 x i32> [[TMP28]], <16 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP29:%.*]] = bitcast <16 x i32> [[SHUFFLE3_I]] to <8 x i64>
+// CHECK: store <8 x i64> [[TMP24]], <8 x i64>* [[__A_ADDR_I18_I]], align 64
+// CHECK: store <8 x i64> [[TMP29]], <8 x i64>* [[__B_ADDR_I19_I]], align 64
+// CHECK: [[TMP30:%.*]] = load <8 x i64>, <8 x i64>* [[__A_ADDR_I18_I]], align 64
+// CHECK: [[TMP31:%.*]] = bitcast <8 x i64> [[TMP30]] to <16 x i32>
+// CHECK: [[TMP32:%.*]] = load <8 x i64>, <8 x i64>* [[__B_ADDR_I19_I]], align 64
+// CHECK: [[TMP33:%.*]] = bitcast <8 x i64> [[TMP32]] to <16 x i32>
+// CHECK: store <8 x i64> zeroinitializer, <8 x i64>* [[_COMPOUNDLITERAL_I_I17_I]], align 64
+// CHECK: [[TMP34:%.*]] = load <8 x i64>, <8 x i64>* [[_COMPOUNDLITERAL_I_I17_I]], align 64
+// CHECK: [[TMP35:%.*]] = bitcast <8 x i64> [[TMP34]] to <16 x i32>
+// CHECK: [[TMP36:%.*]] = icmp ugt <16 x i32> [[TMP31]], [[TMP33]]
+// CHECK: [[TMP37:%.*]] = select <16 x i1> [[TMP36]], <16 x i32> [[TMP31]], <16 x i32> [[TMP33]]
+// CHECK: [[TMP38:%.*]] = bitcast <16 x i32> [[TMP37]] to <8 x i64>
+// CHECK: store <8 x i64> [[TMP38]], <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP39:%.*]] = load <8 x i64>, <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP40:%.*]] = bitcast <8 x i64> [[TMP39]] to <16 x i32>
+// CHECK: [[TMP41:%.*]] = load <8 x i64>, <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP42:%.*]] = bitcast <8 x i64> [[TMP41]] to <16 x i32>
+// CHECK: [[SHUFFLE5_I:%.*]] = shufflevector <16 x i32> [[TMP40]], <16 x i32> [[TMP42]], <16 x i32> <i32 0, i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP43:%.*]] = bitcast <16 x i32> [[SHUFFLE5_I]] to <8 x i64>
+// CHECK: [[TMP44:%.*]] = load <8 x i64>, <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP45:%.*]] = bitcast <8 x i64> [[TMP44]] to <16 x i32>
+// CHECK: [[TMP46:%.*]] = load <8 x i64>, <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP47:%.*]] = bitcast <8 x i64> [[TMP46]] to <16 x i32>
+// CHECK: [[SHUFFLE6_I:%.*]] = shufflevector <16 x i32> [[TMP45]], <16 x i32> [[TMP47]], <16 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP48:%.*]] = bitcast <16 x i32> [[SHUFFLE6_I]] to <8 x i64>
+// CHECK: store <8 x i64> [[TMP43]], <8 x i64>* [[__A_ADDR_I15_I]], align 64
+// CHECK: store <8 x i64> [[TMP48]], <8 x i64>* [[__B_ADDR_I16_I]], align 64
+// CHECK: [[TMP49:%.*]] = load <8 x i64>, <8 x i64>* [[__A_ADDR_I15_I]], align 64
+// CHECK: [[TMP50:%.*]] = bitcast <8 x i64> [[TMP49]] to <16 x i32>
+// CHECK: [[TMP51:%.*]] = load <8 x i64>, <8 x i64>* [[__B_ADDR_I16_I]], align 64
+// CHECK: [[TMP52:%.*]] = bitcast <8 x i64> [[TMP51]] to <16 x i32>
+// CHECK: store <8 x i64> zeroinitializer, <8 x i64>* [[_COMPOUNDLITERAL_I_I14_I]], align 64
+// CHECK: [[TMP53:%.*]] = load <8 x i64>, <8 x i64>* [[_COMPOUNDLITERAL_I_I14_I]], align 64
+// CHECK: [[TMP54:%.*]] = bitcast <8 x i64> [[TMP53]] to <16 x i32>
+// CHECK: [[TMP55:%.*]] = icmp ugt <16 x i32> [[TMP50]], [[TMP52]]
+// CHECK: [[TMP56:%.*]] = select <16 x i1> [[TMP55]], <16 x i32> [[TMP50]], <16 x i32> [[TMP52]]
+// CHECK: [[TMP57:%.*]] = bitcast <16 x i32> [[TMP56]] to <8 x i64>
+// CHECK: store <8 x i64> [[TMP57]], <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP58:%.*]] = load <8 x i64>, <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP59:%.*]] = bitcast <8 x i64> [[TMP58]] to <16 x i32>
+// CHECK: [[TMP60:%.*]] = load <8 x i64>, <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP61:%.*]] = bitcast <8 x i64> [[TMP60]] to <16 x i32>
+// CHECK: [[SHUFFLE8_I:%.*]] = shufflevector <16 x i32> [[TMP59]], <16 x i32> [[TMP61]], <16 x i32> <i32 0, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP62:%.*]] = bitcast <16 x i32> [[SHUFFLE8_I]] to <8 x i64>
+// CHECK: [[TMP63:%.*]] = load <8 x i64>, <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP64:%.*]] = bitcast <8 x i64> [[TMP63]] to <16 x i32>
+// CHECK: [[TMP65:%.*]] = load <8 x i64>, <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP66:%.*]] = bitcast <8 x i64> [[TMP65]] to <16 x i32>
+// CHECK: [[SHUFFLE9_I:%.*]] = shufflevector <16 x i32> [[TMP64]], <16 x i32> [[TMP66]], <16 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP67:%.*]] = bitcast <16 x i32> [[SHUFFLE9_I]] to <8 x i64>
+// CHECK: store <8 x i64> [[TMP62]], <8 x i64>* [[__A_ADDR_I12_I]], align 64
+// CHECK: store <8 x i64> [[TMP67]], <8 x i64>* [[__B_ADDR_I13_I]], align 64
+// CHECK: [[TMP68:%.*]] = load <8 x i64>, <8 x i64>* [[__A_ADDR_I12_I]], align 64
+// CHECK: [[TMP69:%.*]] = bitcast <8 x i64> [[TMP68]] to <16 x i32>
+// CHECK: [[TMP70:%.*]] = load <8 x i64>, <8 x i64>* [[__B_ADDR_I13_I]], align 64
+// CHECK: [[TMP71:%.*]] = bitcast <8 x i64> [[TMP70]] to <16 x i32>
+// CHECK: store <8 x i64> zeroinitializer, <8 x i64>* [[_COMPOUNDLITERAL_I_I11_I]], align 64
+// CHECK: [[TMP72:%.*]] = load <8 x i64>, <8 x i64>* [[_COMPOUNDLITERAL_I_I11_I]], align 64
+// CHECK: [[TMP73:%.*]] = bitcast <8 x i64> [[TMP72]] to <16 x i32>
+// CHECK: [[TMP74:%.*]] = icmp ugt <16 x i32> [[TMP69]], [[TMP71]]
+// CHECK: [[TMP75:%.*]] = select <16 x i1> [[TMP74]], <16 x i32> [[TMP69]], <16 x i32> [[TMP71]]
+// CHECK: [[TMP76:%.*]] = bitcast <16 x i32> [[TMP75]] to <8 x i64>
+// CHECK: store <8 x i64> [[TMP76]], <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP77:%.*]] = load <8 x i64>, <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[VECEXT_I:%.*]] = extractelement <8 x i64> [[TMP77]], i32 0
+// CHECK: [[CONV_I:%.*]] = trunc i64 [[VECEXT_I]] to i32
+// CHECK: ret i32 [[CONV_I]]
unsigned int test_mm512_reduce_max_epu32(__m512i __W){
- // CHECK: %tmp = bitcast <8 x i64> %__W to <16 x i32>
- // CHECK: %shuffle1.i = shufflevector <16 x i32> %tmp, <16 x i32> undef, <16 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp1 = icmp ult <16 x i32> %shuffle1.i, %tmp
- // CHECK: %tmp2 = select <16 x i1> %tmp1, <16 x i32> %tmp, <16 x i32> %shuffle1.i
- // CHECK: %shuffle3.i = shufflevector <16 x i32> %tmp2, <16 x i32> undef, <16 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp3 = icmp ugt <16 x i32> %tmp2, %shuffle3.i
- // CHECK: %tmp4 = select <16 x i1> %tmp3, <16 x i32> %tmp2, <16 x i32> %shuffle3.i
- // CHECK: %shuffle6.i = shufflevector <16 x i32> %tmp4, <16 x i32> undef, <16 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp5 = icmp ugt <16 x i32> %tmp4, %shuffle6.i
- // CHECK: %tmp6 = select <16 x i1> %tmp5, <16 x i32> %tmp4, <16 x i32> %shuffle6.i
- // CHECK: %shuffle9.i = shufflevector <16 x i32> %tmp6, <16 x i32> undef, <16 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp7 = icmp ugt <16 x i32> %tmp6, %shuffle9.i
- // CHECK: %tmp8 = select <16 x i1> %tmp7, <16 x i32> %tmp6, <16 x i32> %shuffle9.i
- // CHECK: %tmp9 = bitcast <16 x i32> %tmp8 to <8 x i64>
- // CHECK: %vecext.i = extractelement <8 x i64> %tmp9, i32 0
- // CHECK: %conv.i = trunc i64 %vecext.i to i32
- // CHECK: ret i32 %conv.i
return _mm512_reduce_max_epu32(__W);
}
+// CHECK-LABEL: define float @test_mm512_reduce_max_ps(<16 x float> %__W) #0 {
+// CHECK: [[_COMPOUNDLITERAL_I_I17_I:%.*]] = alloca <16 x float>, align 64
+// CHECK: [[__A_ADDR_I18_I:%.*]] = alloca <16 x float>, align 64
+// CHECK: [[__B_ADDR_I19_I:%.*]] = alloca <16 x float>, align 64
+// CHECK: [[_COMPOUNDLITERAL_I_I14_I:%.*]] = alloca <16 x float>, align 64
+// CHECK: [[__A_ADDR_I15_I:%.*]] = alloca <16 x float>, align 64
+// CHECK: [[__B_ADDR_I16_I:%.*]] = alloca <16 x float>, align 64
+// CHECK: [[_COMPOUNDLITERAL_I_I11_I:%.*]] = alloca <16 x float>, align 64
+// CHECK: [[__A_ADDR_I12_I:%.*]] = alloca <16 x float>, align 64
+// CHECK: [[__B_ADDR_I13_I:%.*]] = alloca <16 x float>, align 64
+// CHECK: [[_COMPOUNDLITERAL_I_I_I:%.*]] = alloca <16 x float>, align 64
+// CHECK: [[__A_ADDR_I_I:%.*]] = alloca <16 x float>, align 64
+// CHECK: [[__B_ADDR_I_I:%.*]] = alloca <16 x float>, align 64
+// CHECK: [[A_ADDR_I:%.*]] = alloca <16 x float>, align 64
+// CHECK: [[__W_ADDR:%.*]] = alloca <16 x float>, align 64
+// CHECK: store <16 x float> %__W, <16 x float>* [[__W_ADDR]], align 64
+// CHECK: [[TMP0:%.*]] = load <16 x float>, <16 x float>* [[__W_ADDR]], align 64
+// CHECK: store <16 x float> [[TMP0]], <16 x float>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP1:%.*]] = load <16 x float>, <16 x float>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP2:%.*]] = load <16 x float>, <16 x float>* [[A_ADDR_I]], align 64
+// CHECK: [[SHUFFLE_I:%.*]] = shufflevector <16 x float> [[TMP1]], <16 x float> [[TMP2]], <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP3:%.*]] = load <16 x float>, <16 x float>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP4:%.*]] = load <16 x float>, <16 x float>* [[A_ADDR_I]], align 64
+// CHECK: [[SHUFFLE1_I:%.*]] = shufflevector <16 x float> [[TMP3]], <16 x float> [[TMP4]], <16 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: store <16 x float> [[SHUFFLE_I]], <16 x float>* [[__A_ADDR_I_I]], align 64
+// CHECK: store <16 x float> [[SHUFFLE1_I]], <16 x float>* [[__B_ADDR_I_I]], align 64
+// CHECK: [[TMP5:%.*]] = load <16 x float>, <16 x float>* [[__A_ADDR_I_I]], align 64
+// CHECK: [[TMP6:%.*]] = load <16 x float>, <16 x float>* [[__B_ADDR_I_I]], align 64
+// CHECK: store <16 x float> zeroinitializer, <16 x float>* [[_COMPOUNDLITERAL_I_I_I]], align 64
+// CHECK: [[TMP7:%.*]] = load <16 x float>, <16 x float>* [[_COMPOUNDLITERAL_I_I_I]], align 64
+// CHECK: [[TMP8:%.*]] = call <16 x float> @llvm.x86.avx512.mask.max.ps.512(<16 x float> [[TMP5]], <16 x float> [[TMP6]], <16 x float> [[TMP7]], i16 -1, i32 4) #2
+// CHECK: store <16 x float> [[TMP8]], <16 x float>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP9:%.*]] = load <16 x float>, <16 x float>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP10:%.*]] = load <16 x float>, <16 x float>* [[A_ADDR_I]], align 64
+// CHECK: [[SHUFFLE2_I:%.*]] = shufflevector <16 x float> [[TMP9]], <16 x float> [[TMP10]], <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP11:%.*]] = load <16 x float>, <16 x float>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP12:%.*]] = load <16 x float>, <16 x float>* [[A_ADDR_I]], align 64
+// CHECK: [[SHUFFLE3_I:%.*]] = shufflevector <16 x float> [[TMP11]], <16 x float> [[TMP12]], <16 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: store <16 x float> [[SHUFFLE2_I]], <16 x float>* [[__A_ADDR_I18_I]], align 64
+// CHECK: store <16 x float> [[SHUFFLE3_I]], <16 x float>* [[__B_ADDR_I19_I]], align 64
+// CHECK: [[TMP13:%.*]] = load <16 x float>, <16 x float>* [[__A_ADDR_I18_I]], align 64
+// CHECK: [[TMP14:%.*]] = load <16 x float>, <16 x float>* [[__B_ADDR_I19_I]], align 64
+// CHECK: store <16 x float> zeroinitializer, <16 x float>* [[_COMPOUNDLITERAL_I_I17_I]], align 64
+// CHECK: [[TMP15:%.*]] = load <16 x float>, <16 x float>* [[_COMPOUNDLITERAL_I_I17_I]], align 64
+// CHECK: [[TMP16:%.*]] = call <16 x float> @llvm.x86.avx512.mask.max.ps.512(<16 x float> [[TMP13]], <16 x float> [[TMP14]], <16 x float> [[TMP15]], i16 -1, i32 4) #2
+// CHECK: store <16 x float> [[TMP16]], <16 x float>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP17:%.*]] = load <16 x float>, <16 x float>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP18:%.*]] = load <16 x float>, <16 x float>* [[A_ADDR_I]], align 64
+// CHECK: [[SHUFFLE5_I:%.*]] = shufflevector <16 x float> [[TMP17]], <16 x float> [[TMP18]], <16 x i32> <i32 0, i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP19:%.*]] = load <16 x float>, <16 x float>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP20:%.*]] = load <16 x float>, <16 x float>* [[A_ADDR_I]], align 64
+// CHECK: [[SHUFFLE6_I:%.*]] = shufflevector <16 x float> [[TMP19]], <16 x float> [[TMP20]], <16 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: store <16 x float> [[SHUFFLE5_I]], <16 x float>* [[__A_ADDR_I15_I]], align 64
+// CHECK: store <16 x float> [[SHUFFLE6_I]], <16 x float>* [[__B_ADDR_I16_I]], align 64
+// CHECK: [[TMP21:%.*]] = load <16 x float>, <16 x float>* [[__A_ADDR_I15_I]], align 64
+// CHECK: [[TMP22:%.*]] = load <16 x float>, <16 x float>* [[__B_ADDR_I16_I]], align 64
+// CHECK: store <16 x float> zeroinitializer, <16 x float>* [[_COMPOUNDLITERAL_I_I14_I]], align 64
+// CHECK: [[TMP23:%.*]] = load <16 x float>, <16 x float>* [[_COMPOUNDLITERAL_I_I14_I]], align 64
+// CHECK: [[TMP24:%.*]] = call <16 x float> @llvm.x86.avx512.mask.max.ps.512(<16 x float> [[TMP21]], <16 x float> [[TMP22]], <16 x float> [[TMP23]], i16 -1, i32 4) #2
+// CHECK: store <16 x float> [[TMP24]], <16 x float>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP25:%.*]] = load <16 x float>, <16 x float>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP26:%.*]] = load <16 x float>, <16 x float>* [[A_ADDR_I]], align 64
+// CHECK: [[SHUFFLE8_I:%.*]] = shufflevector <16 x float> [[TMP25]], <16 x float> [[TMP26]], <16 x i32> <i32 0, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP27:%.*]] = load <16 x float>, <16 x float>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP28:%.*]] = load <16 x float>, <16 x float>* [[A_ADDR_I]], align 64
+// CHECK: [[SHUFFLE9_I:%.*]] = shufflevector <16 x float> [[TMP27]], <16 x float> [[TMP28]], <16 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: store <16 x float> [[SHUFFLE8_I]], <16 x float>* [[__A_ADDR_I12_I]], align 64
+// CHECK: store <16 x float> [[SHUFFLE9_I]], <16 x float>* [[__B_ADDR_I13_I]], align 64
+// CHECK: [[TMP29:%.*]] = load <16 x float>, <16 x float>* [[__A_ADDR_I12_I]], align 64
+// CHECK: [[TMP30:%.*]] = load <16 x float>, <16 x float>* [[__B_ADDR_I13_I]], align 64
+// CHECK: store <16 x float> zeroinitializer, <16 x float>* [[_COMPOUNDLITERAL_I_I11_I]], align 64
+// CHECK: [[TMP31:%.*]] = load <16 x float>, <16 x float>* [[_COMPOUNDLITERAL_I_I11_I]], align 64
+// CHECK: [[TMP32:%.*]] = call <16 x float> @llvm.x86.avx512.mask.max.ps.512(<16 x float> [[TMP29]], <16 x float> [[TMP30]], <16 x float> [[TMP31]], i16 -1, i32 4) #2
+// CHECK: store <16 x float> [[TMP32]], <16 x float>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP33:%.*]] = load <16 x float>, <16 x float>* [[A_ADDR_I]], align 64
+// CHECK: [[VECEXT_I:%.*]] = extractelement <16 x float> [[TMP33]], i32 0
+// CHECK: ret float [[VECEXT_I]]
float test_mm512_reduce_max_ps(__m512 __W){
- // CHECK: %shuffle1.i = shufflevector <16 x float> %__W, <16 x float> undef, <16 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp = tail call <16 x float> @llvm.x86.avx512.mask.max.ps.512(<16 x float> %__W, <16 x float> %shuffle1.i, <16 x float> zeroinitializer, i16 -1, i32 4) #3
- // CHECK: %shuffle3.i = shufflevector <16 x float> %tmp, <16 x float> undef, <16 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp1 = tail call <16 x float> @llvm.x86.avx512.mask.max.ps.512(<16 x float> %tmp, <16 x float> %shuffle3.i, <16 x float> zeroinitializer, i16 -1, i32 4) #3
- // CHECK: %shuffle6.i = shufflevector <16 x float> %tmp1, <16 x float> undef, <16 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp2 = tail call <16 x float> @llvm.x86.avx512.mask.max.ps.512(<16 x float> %tmp1, <16 x float> %shuffle6.i, <16 x float> zeroinitializer, i16 -1, i32 4) #3
- // CHECK: %shuffle9.i = shufflevector <16 x float> %tmp2, <16 x float> undef, <16 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp3 = tail call <16 x float> @llvm.x86.avx512.mask.max.ps.512(<16 x float> %tmp2, <16 x float> %shuffle9.i, <16 x float> zeroinitializer, i16 -1, i32 4) #3
- // CHECK: %vecext.i = extractelement <16 x float> %tmp3, i32 0
- // CHECK: ret float %vecext.i
return _mm512_reduce_max_ps(__W);
}
+// CHECK-LABEL: define i32 @test_mm512_reduce_min_epi32(<8 x i64> %__W) #0 {
+// CHECK: [[_COMPOUNDLITERAL_I_I17_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__A_ADDR_I18_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__B_ADDR_I19_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[_COMPOUNDLITERAL_I_I14_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__A_ADDR_I15_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__B_ADDR_I16_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[_COMPOUNDLITERAL_I_I11_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__A_ADDR_I12_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__B_ADDR_I13_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[_COMPOUNDLITERAL_I_I_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__A_ADDR_I_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__B_ADDR_I_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[A_ADDR_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__W_ADDR:%.*]] = alloca <8 x i64>, align 64
+// CHECK: store <8 x i64> %__W, <8 x i64>* [[__W_ADDR]], align 64
+// CHECK: [[TMP0:%.*]] = load <8 x i64>, <8 x i64>* [[__W_ADDR]], align 64
+// CHECK: store <8 x i64> [[TMP0]], <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP1:%.*]] = load <8 x i64>, <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP2:%.*]] = bitcast <8 x i64> [[TMP1]] to <16 x i32>
+// CHECK: [[TMP3:%.*]] = load <8 x i64>, <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP4:%.*]] = bitcast <8 x i64> [[TMP3]] to <16 x i32>
+// CHECK: [[SHUFFLE_I:%.*]] = shufflevector <16 x i32> [[TMP2]], <16 x i32> [[TMP4]], <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP5:%.*]] = bitcast <16 x i32> [[SHUFFLE_I]] to <8 x i64>
+// CHECK: [[TMP6:%.*]] = load <8 x i64>, <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP7:%.*]] = bitcast <8 x i64> [[TMP6]] to <16 x i32>
+// CHECK: [[TMP8:%.*]] = load <8 x i64>, <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP9:%.*]] = bitcast <8 x i64> [[TMP8]] to <16 x i32>
+// CHECK: [[SHUFFLE1_I:%.*]] = shufflevector <16 x i32> [[TMP7]], <16 x i32> [[TMP9]], <16 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP10:%.*]] = bitcast <16 x i32> [[SHUFFLE1_I]] to <8 x i64>
+// CHECK: store <8 x i64> [[TMP5]], <8 x i64>* [[__A_ADDR_I_I]], align 64
+// CHECK: store <8 x i64> [[TMP10]], <8 x i64>* [[__B_ADDR_I_I]], align 64
+// CHECK: [[TMP11:%.*]] = load <8 x i64>, <8 x i64>* [[__A_ADDR_I_I]], align 64
+// CHECK: [[TMP12:%.*]] = bitcast <8 x i64> [[TMP11]] to <16 x i32>
+// CHECK: [[TMP13:%.*]] = load <8 x i64>, <8 x i64>* [[__B_ADDR_I_I]], align 64
+// CHECK: [[TMP14:%.*]] = bitcast <8 x i64> [[TMP13]] to <16 x i32>
+// CHECK: store <8 x i64> zeroinitializer, <8 x i64>* [[_COMPOUNDLITERAL_I_I_I]], align 64
+// CHECK: [[TMP15:%.*]] = load <8 x i64>, <8 x i64>* [[_COMPOUNDLITERAL_I_I_I]], align 64
+// CHECK: [[TMP16:%.*]] = bitcast <8 x i64> [[TMP15]] to <16 x i32>
+// CHECK: [[TMP17:%.*]] = icmp slt <16 x i32> [[TMP12]], [[TMP14]]
+// CHECK: [[TMP18:%.*]] = select <16 x i1> [[TMP17]], <16 x i32> [[TMP12]], <16 x i32> [[TMP14]]
+// CHECK: [[TMP19:%.*]] = bitcast <16 x i32> [[TMP18]] to <8 x i64>
+// CHECK: store <8 x i64> [[TMP19]], <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP20:%.*]] = load <8 x i64>, <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP21:%.*]] = bitcast <8 x i64> [[TMP20]] to <16 x i32>
+// CHECK: [[TMP22:%.*]] = load <8 x i64>, <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP23:%.*]] = bitcast <8 x i64> [[TMP22]] to <16 x i32>
+// CHECK: [[SHUFFLE2_I:%.*]] = shufflevector <16 x i32> [[TMP21]], <16 x i32> [[TMP23]], <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP24:%.*]] = bitcast <16 x i32> [[SHUFFLE2_I]] to <8 x i64>
+// CHECK: [[TMP25:%.*]] = load <8 x i64>, <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP26:%.*]] = bitcast <8 x i64> [[TMP25]] to <16 x i32>
+// CHECK: [[TMP27:%.*]] = load <8 x i64>, <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP28:%.*]] = bitcast <8 x i64> [[TMP27]] to <16 x i32>
+// CHECK: [[SHUFFLE3_I:%.*]] = shufflevector <16 x i32> [[TMP26]], <16 x i32> [[TMP28]], <16 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP29:%.*]] = bitcast <16 x i32> [[SHUFFLE3_I]] to <8 x i64>
+// CHECK: store <8 x i64> [[TMP24]], <8 x i64>* [[__A_ADDR_I18_I]], align 64
+// CHECK: store <8 x i64> [[TMP29]], <8 x i64>* [[__B_ADDR_I19_I]], align 64
+// CHECK: [[TMP30:%.*]] = load <8 x i64>, <8 x i64>* [[__A_ADDR_I18_I]], align 64
+// CHECK: [[TMP31:%.*]] = bitcast <8 x i64> [[TMP30]] to <16 x i32>
+// CHECK: [[TMP32:%.*]] = load <8 x i64>, <8 x i64>* [[__B_ADDR_I19_I]], align 64
+// CHECK: [[TMP33:%.*]] = bitcast <8 x i64> [[TMP32]] to <16 x i32>
+// CHECK: store <8 x i64> zeroinitializer, <8 x i64>* [[_COMPOUNDLITERAL_I_I17_I]], align 64
+// CHECK: [[TMP34:%.*]] = load <8 x i64>, <8 x i64>* [[_COMPOUNDLITERAL_I_I17_I]], align 64
+// CHECK: [[TMP35:%.*]] = bitcast <8 x i64> [[TMP34]] to <16 x i32>
+// CHECK: [[TMP36:%.*]] = icmp slt <16 x i32> [[TMP31]], [[TMP33]]
+// CHECK: [[TMP37:%.*]] = select <16 x i1> [[TMP36]], <16 x i32> [[TMP31]], <16 x i32> [[TMP33]]
+// CHECK: [[TMP38:%.*]] = bitcast <16 x i32> [[TMP37]] to <8 x i64>
+// CHECK: store <8 x i64> [[TMP38]], <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP39:%.*]] = load <8 x i64>, <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP40:%.*]] = bitcast <8 x i64> [[TMP39]] to <16 x i32>
+// CHECK: [[TMP41:%.*]] = load <8 x i64>, <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP42:%.*]] = bitcast <8 x i64> [[TMP41]] to <16 x i32>
+// CHECK: [[SHUFFLE5_I:%.*]] = shufflevector <16 x i32> [[TMP40]], <16 x i32> [[TMP42]], <16 x i32> <i32 0, i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP43:%.*]] = bitcast <16 x i32> [[SHUFFLE5_I]] to <8 x i64>
+// CHECK: [[TMP44:%.*]] = load <8 x i64>, <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP45:%.*]] = bitcast <8 x i64> [[TMP44]] to <16 x i32>
+// CHECK: [[TMP46:%.*]] = load <8 x i64>, <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP47:%.*]] = bitcast <8 x i64> [[TMP46]] to <16 x i32>
+// CHECK: [[SHUFFLE6_I:%.*]] = shufflevector <16 x i32> [[TMP45]], <16 x i32> [[TMP47]], <16 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP48:%.*]] = bitcast <16 x i32> [[SHUFFLE6_I]] to <8 x i64>
+// CHECK: store <8 x i64> [[TMP43]], <8 x i64>* [[__A_ADDR_I15_I]], align 64
+// CHECK: store <8 x i64> [[TMP48]], <8 x i64>* [[__B_ADDR_I16_I]], align 64
+// CHECK: [[TMP49:%.*]] = load <8 x i64>, <8 x i64>* [[__A_ADDR_I15_I]], align 64
+// CHECK: [[TMP50:%.*]] = bitcast <8 x i64> [[TMP49]] to <16 x i32>
+// CHECK: [[TMP51:%.*]] = load <8 x i64>, <8 x i64>* [[__B_ADDR_I16_I]], align 64
+// CHECK: [[TMP52:%.*]] = bitcast <8 x i64> [[TMP51]] to <16 x i32>
+// CHECK: store <8 x i64> zeroinitializer, <8 x i64>* [[_COMPOUNDLITERAL_I_I14_I]], align 64
+// CHECK: [[TMP53:%.*]] = load <8 x i64>, <8 x i64>* [[_COMPOUNDLITERAL_I_I14_I]], align 64
+// CHECK: [[TMP54:%.*]] = bitcast <8 x i64> [[TMP53]] to <16 x i32>
+// CHECK: [[TMP55:%.*]] = icmp slt <16 x i32> [[TMP50]], [[TMP52]]
+// CHECK: [[TMP56:%.*]] = select <16 x i1> [[TMP55]], <16 x i32> [[TMP50]], <16 x i32> [[TMP52]]
+// CHECK: [[TMP57:%.*]] = bitcast <16 x i32> [[TMP56]] to <8 x i64>
+// CHECK: store <8 x i64> [[TMP57]], <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP58:%.*]] = load <8 x i64>, <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP59:%.*]] = bitcast <8 x i64> [[TMP58]] to <16 x i32>
+// CHECK: [[TMP60:%.*]] = load <8 x i64>, <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP61:%.*]] = bitcast <8 x i64> [[TMP60]] to <16 x i32>
+// CHECK: [[SHUFFLE8_I:%.*]] = shufflevector <16 x i32> [[TMP59]], <16 x i32> [[TMP61]], <16 x i32> <i32 0, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP62:%.*]] = bitcast <16 x i32> [[SHUFFLE8_I]] to <8 x i64>
+// CHECK: [[TMP63:%.*]] = load <8 x i64>, <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP64:%.*]] = bitcast <8 x i64> [[TMP63]] to <16 x i32>
+// CHECK: [[TMP65:%.*]] = load <8 x i64>, <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP66:%.*]] = bitcast <8 x i64> [[TMP65]] to <16 x i32>
+// CHECK: [[SHUFFLE9_I:%.*]] = shufflevector <16 x i32> [[TMP64]], <16 x i32> [[TMP66]], <16 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP67:%.*]] = bitcast <16 x i32> [[SHUFFLE9_I]] to <8 x i64>
+// CHECK: store <8 x i64> [[TMP62]], <8 x i64>* [[__A_ADDR_I12_I]], align 64
+// CHECK: store <8 x i64> [[TMP67]], <8 x i64>* [[__B_ADDR_I13_I]], align 64
+// CHECK: [[TMP68:%.*]] = load <8 x i64>, <8 x i64>* [[__A_ADDR_I12_I]], align 64
+// CHECK: [[TMP69:%.*]] = bitcast <8 x i64> [[TMP68]] to <16 x i32>
+// CHECK: [[TMP70:%.*]] = load <8 x i64>, <8 x i64>* [[__B_ADDR_I13_I]], align 64
+// CHECK: [[TMP71:%.*]] = bitcast <8 x i64> [[TMP70]] to <16 x i32>
+// CHECK: store <8 x i64> zeroinitializer, <8 x i64>* [[_COMPOUNDLITERAL_I_I11_I]], align 64
+// CHECK: [[TMP72:%.*]] = load <8 x i64>, <8 x i64>* [[_COMPOUNDLITERAL_I_I11_I]], align 64
+// CHECK: [[TMP73:%.*]] = bitcast <8 x i64> [[TMP72]] to <16 x i32>
+// CHECK: [[TMP74:%.*]] = icmp slt <16 x i32> [[TMP69]], [[TMP71]]
+// CHECK: [[TMP75:%.*]] = select <16 x i1> [[TMP74]], <16 x i32> [[TMP69]], <16 x i32> [[TMP71]]
+// CHECK: [[TMP76:%.*]] = bitcast <16 x i32> [[TMP75]] to <8 x i64>
+// CHECK: store <8 x i64> [[TMP76]], <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP77:%.*]] = load <8 x i64>, <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[VECEXT_I:%.*]] = extractelement <8 x i64> [[TMP77]], i32 0
+// CHECK: [[CONV_I:%.*]] = trunc i64 [[VECEXT_I]] to i32
+// CHECK: ret i32 [[CONV_I]]
int test_mm512_reduce_min_epi32(__m512i __W){
- // CHECK: %tmp = bitcast <8 x i64> %__W to <16 x i32>
- // CHECK: %shuffle1.i = shufflevector <16 x i32> %tmp, <16 x i32> undef, <16 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp1 = icmp sgt <16 x i32> %shuffle1.i, %tmp
- // CHECK: %tmp2 = select <16 x i1> %tmp1, <16 x i32> %tmp, <16 x i32> %shuffle1.i
- // CHECK: %shuffle3.i = shufflevector <16 x i32> %tmp2, <16 x i32> undef, <16 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp3 = icmp slt <16 x i32> %tmp2, %shuffle3.i
- // CHECK: %tmp4 = select <16 x i1> %tmp3, <16 x i32> %tmp2, <16 x i32> %shuffle3.i
- // CHECK: %shuffle6.i = shufflevector <16 x i32> %tmp4, <16 x i32> undef, <16 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp5 = icmp slt <16 x i32> %tmp4, %shuffle6.i
- // CHECK: %tmp6 = select <16 x i1> %tmp5, <16 x i32> %tmp4, <16 x i32> %shuffle6.i
- // CHECK: %shuffle9.i = shufflevector <16 x i32> %tmp6, <16 x i32> undef, <16 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp7 = icmp slt <16 x i32> %tmp6, %shuffle9.i
- // CHECK: %tmp8 = select <16 x i1> %tmp7, <16 x i32> %tmp6, <16 x i32> %shuffle9.i
- // CHECK: %tmp9 = bitcast <16 x i32> %tmp8 to <8 x i64>
- // CHECK: %vecext.i = extractelement <8 x i64> %tmp9, i32 0
- // CHECK: %conv.i = trunc i64 %vecext.i to i32
- // CHECK: ret i32 %conv.i
return _mm512_reduce_min_epi32(__W);
}
+// CHECK-LABEL: define i32 @test_mm512_reduce_min_epu32(<8 x i64> %__W) #0 {
+// CHECK: [[_COMPOUNDLITERAL_I_I17_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__A_ADDR_I18_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__B_ADDR_I19_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[_COMPOUNDLITERAL_I_I14_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__A_ADDR_I15_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__B_ADDR_I16_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[_COMPOUNDLITERAL_I_I11_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__A_ADDR_I12_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__B_ADDR_I13_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[_COMPOUNDLITERAL_I_I_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__A_ADDR_I_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__B_ADDR_I_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[A_ADDR_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__W_ADDR:%.*]] = alloca <8 x i64>, align 64
+// CHECK: store <8 x i64> %__W, <8 x i64>* [[__W_ADDR]], align 64
+// CHECK: [[TMP0:%.*]] = load <8 x i64>, <8 x i64>* [[__W_ADDR]], align 64
+// CHECK: store <8 x i64> [[TMP0]], <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP1:%.*]] = load <8 x i64>, <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP2:%.*]] = bitcast <8 x i64> [[TMP1]] to <16 x i32>
+// CHECK: [[TMP3:%.*]] = load <8 x i64>, <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP4:%.*]] = bitcast <8 x i64> [[TMP3]] to <16 x i32>
+// CHECK: [[SHUFFLE_I:%.*]] = shufflevector <16 x i32> [[TMP2]], <16 x i32> [[TMP4]], <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP5:%.*]] = bitcast <16 x i32> [[SHUFFLE_I]] to <8 x i64>
+// CHECK: [[TMP6:%.*]] = load <8 x i64>, <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP7:%.*]] = bitcast <8 x i64> [[TMP6]] to <16 x i32>
+// CHECK: [[TMP8:%.*]] = load <8 x i64>, <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP9:%.*]] = bitcast <8 x i64> [[TMP8]] to <16 x i32>
+// CHECK: [[SHUFFLE1_I:%.*]] = shufflevector <16 x i32> [[TMP7]], <16 x i32> [[TMP9]], <16 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP10:%.*]] = bitcast <16 x i32> [[SHUFFLE1_I]] to <8 x i64>
+// CHECK: store <8 x i64> [[TMP5]], <8 x i64>* [[__A_ADDR_I_I]], align 64
+// CHECK: store <8 x i64> [[TMP10]], <8 x i64>* [[__B_ADDR_I_I]], align 64
+// CHECK: [[TMP11:%.*]] = load <8 x i64>, <8 x i64>* [[__A_ADDR_I_I]], align 64
+// CHECK: [[TMP12:%.*]] = bitcast <8 x i64> [[TMP11]] to <16 x i32>
+// CHECK: [[TMP13:%.*]] = load <8 x i64>, <8 x i64>* [[__B_ADDR_I_I]], align 64
+// CHECK: [[TMP14:%.*]] = bitcast <8 x i64> [[TMP13]] to <16 x i32>
+// CHECK: store <8 x i64> zeroinitializer, <8 x i64>* [[_COMPOUNDLITERAL_I_I_I]], align 64
+// CHECK: [[TMP15:%.*]] = load <8 x i64>, <8 x i64>* [[_COMPOUNDLITERAL_I_I_I]], align 64
+// CHECK: [[TMP16:%.*]] = bitcast <8 x i64> [[TMP15]] to <16 x i32>
+// CHECK: [[TMP17:%.*]] = icmp ult <16 x i32> [[TMP12]], [[TMP14]]
+// CHECK: [[TMP18:%.*]] = select <16 x i1> [[TMP17]], <16 x i32> [[TMP12]], <16 x i32> [[TMP14]]
+// CHECK: [[TMP19:%.*]] = bitcast <16 x i32> [[TMP18]] to <8 x i64>
+// CHECK: store <8 x i64> [[TMP19]], <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP20:%.*]] = load <8 x i64>, <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP21:%.*]] = bitcast <8 x i64> [[TMP20]] to <16 x i32>
+// CHECK: [[TMP22:%.*]] = load <8 x i64>, <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP23:%.*]] = bitcast <8 x i64> [[TMP22]] to <16 x i32>
+// CHECK: [[SHUFFLE2_I:%.*]] = shufflevector <16 x i32> [[TMP21]], <16 x i32> [[TMP23]], <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP24:%.*]] = bitcast <16 x i32> [[SHUFFLE2_I]] to <8 x i64>
+// CHECK: [[TMP25:%.*]] = load <8 x i64>, <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP26:%.*]] = bitcast <8 x i64> [[TMP25]] to <16 x i32>
+// CHECK: [[TMP27:%.*]] = load <8 x i64>, <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP28:%.*]] = bitcast <8 x i64> [[TMP27]] to <16 x i32>
+// CHECK: [[SHUFFLE3_I:%.*]] = shufflevector <16 x i32> [[TMP26]], <16 x i32> [[TMP28]], <16 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP29:%.*]] = bitcast <16 x i32> [[SHUFFLE3_I]] to <8 x i64>
+// CHECK: store <8 x i64> [[TMP24]], <8 x i64>* [[__A_ADDR_I18_I]], align 64
+// CHECK: store <8 x i64> [[TMP29]], <8 x i64>* [[__B_ADDR_I19_I]], align 64
+// CHECK: [[TMP30:%.*]] = load <8 x i64>, <8 x i64>* [[__A_ADDR_I18_I]], align 64
+// CHECK: [[TMP31:%.*]] = bitcast <8 x i64> [[TMP30]] to <16 x i32>
+// CHECK: [[TMP32:%.*]] = load <8 x i64>, <8 x i64>* [[__B_ADDR_I19_I]], align 64
+// CHECK: [[TMP33:%.*]] = bitcast <8 x i64> [[TMP32]] to <16 x i32>
+// CHECK: store <8 x i64> zeroinitializer, <8 x i64>* [[_COMPOUNDLITERAL_I_I17_I]], align 64
+// CHECK: [[TMP34:%.*]] = load <8 x i64>, <8 x i64>* [[_COMPOUNDLITERAL_I_I17_I]], align 64
+// CHECK: [[TMP35:%.*]] = bitcast <8 x i64> [[TMP34]] to <16 x i32>
+// CHECK: [[TMP36:%.*]] = icmp ult <16 x i32> [[TMP31]], [[TMP33]]
+// CHECK: [[TMP37:%.*]] = select <16 x i1> [[TMP36]], <16 x i32> [[TMP31]], <16 x i32> [[TMP33]]
+// CHECK: [[TMP38:%.*]] = bitcast <16 x i32> [[TMP37]] to <8 x i64>
+// CHECK: store <8 x i64> [[TMP38]], <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP39:%.*]] = load <8 x i64>, <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP40:%.*]] = bitcast <8 x i64> [[TMP39]] to <16 x i32>
+// CHECK: [[TMP41:%.*]] = load <8 x i64>, <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP42:%.*]] = bitcast <8 x i64> [[TMP41]] to <16 x i32>
+// CHECK: [[SHUFFLE5_I:%.*]] = shufflevector <16 x i32> [[TMP40]], <16 x i32> [[TMP42]], <16 x i32> <i32 0, i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP43:%.*]] = bitcast <16 x i32> [[SHUFFLE5_I]] to <8 x i64>
+// CHECK: [[TMP44:%.*]] = load <8 x i64>, <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP45:%.*]] = bitcast <8 x i64> [[TMP44]] to <16 x i32>
+// CHECK: [[TMP46:%.*]] = load <8 x i64>, <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP47:%.*]] = bitcast <8 x i64> [[TMP46]] to <16 x i32>
+// CHECK: [[SHUFFLE6_I:%.*]] = shufflevector <16 x i32> [[TMP45]], <16 x i32> [[TMP47]], <16 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP48:%.*]] = bitcast <16 x i32> [[SHUFFLE6_I]] to <8 x i64>
+// CHECK: store <8 x i64> [[TMP43]], <8 x i64>* [[__A_ADDR_I15_I]], align 64
+// CHECK: store <8 x i64> [[TMP48]], <8 x i64>* [[__B_ADDR_I16_I]], align 64
+// CHECK: [[TMP49:%.*]] = load <8 x i64>, <8 x i64>* [[__A_ADDR_I15_I]], align 64
+// CHECK: [[TMP50:%.*]] = bitcast <8 x i64> [[TMP49]] to <16 x i32>
+// CHECK: [[TMP51:%.*]] = load <8 x i64>, <8 x i64>* [[__B_ADDR_I16_I]], align 64
+// CHECK: [[TMP52:%.*]] = bitcast <8 x i64> [[TMP51]] to <16 x i32>
+// CHECK: store <8 x i64> zeroinitializer, <8 x i64>* [[_COMPOUNDLITERAL_I_I14_I]], align 64
+// CHECK: [[TMP53:%.*]] = load <8 x i64>, <8 x i64>* [[_COMPOUNDLITERAL_I_I14_I]], align 64
+// CHECK: [[TMP54:%.*]] = bitcast <8 x i64> [[TMP53]] to <16 x i32>
+// CHECK: [[TMP55:%.*]] = icmp ult <16 x i32> [[TMP50]], [[TMP52]]
+// CHECK: [[TMP56:%.*]] = select <16 x i1> [[TMP55]], <16 x i32> [[TMP50]], <16 x i32> [[TMP52]]
+// CHECK: [[TMP57:%.*]] = bitcast <16 x i32> [[TMP56]] to <8 x i64>
+// CHECK: store <8 x i64> [[TMP57]], <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP58:%.*]] = load <8 x i64>, <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP59:%.*]] = bitcast <8 x i64> [[TMP58]] to <16 x i32>
+// CHECK: [[TMP60:%.*]] = load <8 x i64>, <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP61:%.*]] = bitcast <8 x i64> [[TMP60]] to <16 x i32>
+// CHECK: [[SHUFFLE8_I:%.*]] = shufflevector <16 x i32> [[TMP59]], <16 x i32> [[TMP61]], <16 x i32> <i32 0, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP62:%.*]] = bitcast <16 x i32> [[SHUFFLE8_I]] to <8 x i64>
+// CHECK: [[TMP63:%.*]] = load <8 x i64>, <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP64:%.*]] = bitcast <8 x i64> [[TMP63]] to <16 x i32>
+// CHECK: [[TMP65:%.*]] = load <8 x i64>, <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP66:%.*]] = bitcast <8 x i64> [[TMP65]] to <16 x i32>
+// CHECK: [[SHUFFLE9_I:%.*]] = shufflevector <16 x i32> [[TMP64]], <16 x i32> [[TMP66]], <16 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP67:%.*]] = bitcast <16 x i32> [[SHUFFLE9_I]] to <8 x i64>
+// CHECK: store <8 x i64> [[TMP62]], <8 x i64>* [[__A_ADDR_I12_I]], align 64
+// CHECK: store <8 x i64> [[TMP67]], <8 x i64>* [[__B_ADDR_I13_I]], align 64
+// CHECK: [[TMP68:%.*]] = load <8 x i64>, <8 x i64>* [[__A_ADDR_I12_I]], align 64
+// CHECK: [[TMP69:%.*]] = bitcast <8 x i64> [[TMP68]] to <16 x i32>
+// CHECK: [[TMP70:%.*]] = load <8 x i64>, <8 x i64>* [[__B_ADDR_I13_I]], align 64
+// CHECK: [[TMP71:%.*]] = bitcast <8 x i64> [[TMP70]] to <16 x i32>
+// CHECK: store <8 x i64> zeroinitializer, <8 x i64>* [[_COMPOUNDLITERAL_I_I11_I]], align 64
+// CHECK: [[TMP72:%.*]] = load <8 x i64>, <8 x i64>* [[_COMPOUNDLITERAL_I_I11_I]], align 64
+// CHECK: [[TMP73:%.*]] = bitcast <8 x i64> [[TMP72]] to <16 x i32>
+// CHECK: [[TMP74:%.*]] = icmp ult <16 x i32> [[TMP69]], [[TMP71]]
+// CHECK: [[TMP75:%.*]] = select <16 x i1> [[TMP74]], <16 x i32> [[TMP69]], <16 x i32> [[TMP71]]
+// CHECK: [[TMP76:%.*]] = bitcast <16 x i32> [[TMP75]] to <8 x i64>
+// CHECK: store <8 x i64> [[TMP76]], <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP77:%.*]] = load <8 x i64>, <8 x i64>* [[A_ADDR_I]], align 64
+// CHECK: [[VECEXT_I:%.*]] = extractelement <8 x i64> [[TMP77]], i32 0
+// CHECK: [[CONV_I:%.*]] = trunc i64 [[VECEXT_I]] to i32
+// CHECK: ret i32 [[CONV_I]]
unsigned int test_mm512_reduce_min_epu32(__m512i __W){
- // CHECK: %tmp = bitcast <8 x i64> %__W to <16 x i32>
- // CHECK: %shuffle1.i = shufflevector <16 x i32> %tmp, <16 x i32> undef, <16 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp1 = icmp ugt <16 x i32> %shuffle1.i, %tmp
- // CHECK: %tmp2 = select <16 x i1> %tmp1, <16 x i32> %tmp, <16 x i32> %shuffle1.i
- // CHECK: %shuffle3.i = shufflevector <16 x i32> %tmp2, <16 x i32> undef, <16 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp3 = icmp ult <16 x i32> %tmp2, %shuffle3.i
- // CHECK: %tmp4 = select <16 x i1> %tmp3, <16 x i32> %tmp2, <16 x i32> %shuffle3.i
- // CHECK: %shuffle6.i = shufflevector <16 x i32> %tmp4, <16 x i32> undef, <16 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp5 = icmp ult <16 x i32> %tmp4, %shuffle6.i
- // CHECK: %tmp6 = select <16 x i1> %tmp5, <16 x i32> %tmp4, <16 x i32> %shuffle6.i
- // CHECK: %shuffle9.i = shufflevector <16 x i32> %tmp6, <16 x i32> undef, <16 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp7 = icmp ult <16 x i32> %tmp6, %shuffle9.i
- // CHECK: %tmp8 = select <16 x i1> %tmp7, <16 x i32> %tmp6, <16 x i32> %shuffle9.i
- // CHECK: %tmp9 = bitcast <16 x i32> %tmp8 to <8 x i64>
- // CHECK: %vecext.i = extractelement <8 x i64> %tmp9, i32 0
- // CHECK: %conv.i = trunc i64 %vecext.i to i32
- // CHECK: ret i32 %conv.i
return _mm512_reduce_min_epu32(__W);
}
+// CHECK-LABEL: define float @test_mm512_reduce_min_ps(<16 x float> %__W) #0 {
+// CHECK: [[_COMPOUNDLITERAL_I_I17_I:%.*]] = alloca <16 x float>, align 64
+// CHECK: [[__A_ADDR_I18_I:%.*]] = alloca <16 x float>, align 64
+// CHECK: [[__B_ADDR_I19_I:%.*]] = alloca <16 x float>, align 64
+// CHECK: [[_COMPOUNDLITERAL_I_I14_I:%.*]] = alloca <16 x float>, align 64
+// CHECK: [[__A_ADDR_I15_I:%.*]] = alloca <16 x float>, align 64
+// CHECK: [[__B_ADDR_I16_I:%.*]] = alloca <16 x float>, align 64
+// CHECK: [[_COMPOUNDLITERAL_I_I11_I:%.*]] = alloca <16 x float>, align 64
+// CHECK: [[__A_ADDR_I12_I:%.*]] = alloca <16 x float>, align 64
+// CHECK: [[__B_ADDR_I13_I:%.*]] = alloca <16 x float>, align 64
+// CHECK: [[_COMPOUNDLITERAL_I_I_I:%.*]] = alloca <16 x float>, align 64
+// CHECK: [[__A_ADDR_I_I:%.*]] = alloca <16 x float>, align 64
+// CHECK: [[__B_ADDR_I_I:%.*]] = alloca <16 x float>, align 64
+// CHECK: [[A_ADDR_I:%.*]] = alloca <16 x float>, align 64
+// CHECK: [[__W_ADDR:%.*]] = alloca <16 x float>, align 64
+// CHECK: store <16 x float> %__W, <16 x float>* [[__W_ADDR]], align 64
+// CHECK: [[TMP0:%.*]] = load <16 x float>, <16 x float>* [[__W_ADDR]], align 64
+// CHECK: store <16 x float> [[TMP0]], <16 x float>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP1:%.*]] = load <16 x float>, <16 x float>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP2:%.*]] = load <16 x float>, <16 x float>* [[A_ADDR_I]], align 64
+// CHECK: [[SHUFFLE_I:%.*]] = shufflevector <16 x float> [[TMP1]], <16 x float> [[TMP2]], <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP3:%.*]] = load <16 x float>, <16 x float>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP4:%.*]] = load <16 x float>, <16 x float>* [[A_ADDR_I]], align 64
+// CHECK: [[SHUFFLE1_I:%.*]] = shufflevector <16 x float> [[TMP3]], <16 x float> [[TMP4]], <16 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: store <16 x float> [[SHUFFLE_I]], <16 x float>* [[__A_ADDR_I_I]], align 64
+// CHECK: store <16 x float> [[SHUFFLE1_I]], <16 x float>* [[__B_ADDR_I_I]], align 64
+// CHECK: [[TMP5:%.*]] = load <16 x float>, <16 x float>* [[__A_ADDR_I_I]], align 64
+// CHECK: [[TMP6:%.*]] = load <16 x float>, <16 x float>* [[__B_ADDR_I_I]], align 64
+// CHECK: store <16 x float> zeroinitializer, <16 x float>* [[_COMPOUNDLITERAL_I_I_I]], align 64
+// CHECK: [[TMP7:%.*]] = load <16 x float>, <16 x float>* [[_COMPOUNDLITERAL_I_I_I]], align 64
+// CHECK: [[TMP8:%.*]] = call <16 x float> @llvm.x86.avx512.mask.min.ps.512(<16 x float> [[TMP5]], <16 x float> [[TMP6]], <16 x float> [[TMP7]], i16 -1, i32 4) #2
+// CHECK: store <16 x float> [[TMP8]], <16 x float>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP9:%.*]] = load <16 x float>, <16 x float>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP10:%.*]] = load <16 x float>, <16 x float>* [[A_ADDR_I]], align 64
+// CHECK: [[SHUFFLE2_I:%.*]] = shufflevector <16 x float> [[TMP9]], <16 x float> [[TMP10]], <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP11:%.*]] = load <16 x float>, <16 x float>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP12:%.*]] = load <16 x float>, <16 x float>* [[A_ADDR_I]], align 64
+// CHECK: [[SHUFFLE3_I:%.*]] = shufflevector <16 x float> [[TMP11]], <16 x float> [[TMP12]], <16 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: store <16 x float> [[SHUFFLE2_I]], <16 x float>* [[__A_ADDR_I18_I]], align 64
+// CHECK: store <16 x float> [[SHUFFLE3_I]], <16 x float>* [[__B_ADDR_I19_I]], align 64
+// CHECK: [[TMP13:%.*]] = load <16 x float>, <16 x float>* [[__A_ADDR_I18_I]], align 64
+// CHECK: [[TMP14:%.*]] = load <16 x float>, <16 x float>* [[__B_ADDR_I19_I]], align 64
+// CHECK: store <16 x float> zeroinitializer, <16 x float>* [[_COMPOUNDLITERAL_I_I17_I]], align 64
+// CHECK: [[TMP15:%.*]] = load <16 x float>, <16 x float>* [[_COMPOUNDLITERAL_I_I17_I]], align 64
+// CHECK: [[TMP16:%.*]] = call <16 x float> @llvm.x86.avx512.mask.min.ps.512(<16 x float> [[TMP13]], <16 x float> [[TMP14]], <16 x float> [[TMP15]], i16 -1, i32 4) #2
+// CHECK: store <16 x float> [[TMP16]], <16 x float>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP17:%.*]] = load <16 x float>, <16 x float>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP18:%.*]] = load <16 x float>, <16 x float>* [[A_ADDR_I]], align 64
+// CHECK: [[SHUFFLE5_I:%.*]] = shufflevector <16 x float> [[TMP17]], <16 x float> [[TMP18]], <16 x i32> <i32 0, i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP19:%.*]] = load <16 x float>, <16 x float>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP20:%.*]] = load <16 x float>, <16 x float>* [[A_ADDR_I]], align 64
+// CHECK: [[SHUFFLE6_I:%.*]] = shufflevector <16 x float> [[TMP19]], <16 x float> [[TMP20]], <16 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: store <16 x float> [[SHUFFLE5_I]], <16 x float>* [[__A_ADDR_I15_I]], align 64
+// CHECK: store <16 x float> [[SHUFFLE6_I]], <16 x float>* [[__B_ADDR_I16_I]], align 64
+// CHECK: [[TMP21:%.*]] = load <16 x float>, <16 x float>* [[__A_ADDR_I15_I]], align 64
+// CHECK: [[TMP22:%.*]] = load <16 x float>, <16 x float>* [[__B_ADDR_I16_I]], align 64
+// CHECK: store <16 x float> zeroinitializer, <16 x float>* [[_COMPOUNDLITERAL_I_I14_I]], align 64
+// CHECK: [[TMP23:%.*]] = load <16 x float>, <16 x float>* [[_COMPOUNDLITERAL_I_I14_I]], align 64
+// CHECK: [[TMP24:%.*]] = call <16 x float> @llvm.x86.avx512.mask.min.ps.512(<16 x float> [[TMP21]], <16 x float> [[TMP22]], <16 x float> [[TMP23]], i16 -1, i32 4) #2
+// CHECK: store <16 x float> [[TMP24]], <16 x float>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP25:%.*]] = load <16 x float>, <16 x float>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP26:%.*]] = load <16 x float>, <16 x float>* [[A_ADDR_I]], align 64
+// CHECK: [[SHUFFLE8_I:%.*]] = shufflevector <16 x float> [[TMP25]], <16 x float> [[TMP26]], <16 x i32> <i32 0, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP27:%.*]] = load <16 x float>, <16 x float>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP28:%.*]] = load <16 x float>, <16 x float>* [[A_ADDR_I]], align 64
+// CHECK: [[SHUFFLE9_I:%.*]] = shufflevector <16 x float> [[TMP27]], <16 x float> [[TMP28]], <16 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: store <16 x float> [[SHUFFLE8_I]], <16 x float>* [[__A_ADDR_I12_I]], align 64
+// CHECK: store <16 x float> [[SHUFFLE9_I]], <16 x float>* [[__B_ADDR_I13_I]], align 64
+// CHECK: [[TMP29:%.*]] = load <16 x float>, <16 x float>* [[__A_ADDR_I12_I]], align 64
+// CHECK: [[TMP30:%.*]] = load <16 x float>, <16 x float>* [[__B_ADDR_I13_I]], align 64
+// CHECK: store <16 x float> zeroinitializer, <16 x float>* [[_COMPOUNDLITERAL_I_I11_I]], align 64
+// CHECK: [[TMP31:%.*]] = load <16 x float>, <16 x float>* [[_COMPOUNDLITERAL_I_I11_I]], align 64
+// CHECK: [[TMP32:%.*]] = call <16 x float> @llvm.x86.avx512.mask.min.ps.512(<16 x float> [[TMP29]], <16 x float> [[TMP30]], <16 x float> [[TMP31]], i16 -1, i32 4) #2
+// CHECK: store <16 x float> [[TMP32]], <16 x float>* [[A_ADDR_I]], align 64
+// CHECK: [[TMP33:%.*]] = load <16 x float>, <16 x float>* [[A_ADDR_I]], align 64
+// CHECK: [[VECEXT_I:%.*]] = extractelement <16 x float> [[TMP33]], i32 0
+// CHECK: ret float [[VECEXT_I]]
float test_mm512_reduce_min_ps(__m512 __W){
- // CHECK: %shuffle1.i = shufflevector <16 x float> %__W, <16 x float> undef, <16 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp = tail call <16 x float> @llvm.x86.avx512.mask.min.ps.512(<16 x float> %__W, <16 x float> %shuffle1.i, <16 x float> zeroinitializer, i16 -1, i32 4) #3
- // CHECK: %shuffle3.i = shufflevector <16 x float> %tmp, <16 x float> undef, <16 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp1 = tail call <16 x float> @llvm.x86.avx512.mask.min.ps.512(<16 x float> %tmp, <16 x float> %shuffle3.i, <16 x float> zeroinitializer, i16 -1, i32 4) #3
- // CHECK: %shuffle6.i = shufflevector <16 x float> %tmp1, <16 x float> undef, <16 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp2 = tail call <16 x float> @llvm.x86.avx512.mask.min.ps.512(<16 x float> %tmp1, <16 x float> %shuffle6.i, <16 x float> zeroinitializer, i16 -1, i32 4) #3
- // CHECK: %shuffle9.i = shufflevector <16 x float> %tmp2, <16 x float> undef, <16 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp3 = tail call <16 x float> @llvm.x86.avx512.mask.min.ps.512(<16 x float> %tmp2, <16 x float> %shuffle9.i, <16 x float> zeroinitializer, i16 -1, i32 4) #3
- // CHECK: %vecext.i = extractelement <16 x float> %tmp3, i32 0
- // CHECK: ret float %vecext.i
return _mm512_reduce_min_ps(__W);
}
+// CHECK-LABEL: define i32 @test_mm512_mask_reduce_max_epi32(i16 zeroext %__M, <8 x i64> %__W) #0 {
+// CHECK: [[_COMPOUNDLITERAL_I_I18_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__A_ADDR_I19_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__B_ADDR_I20_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[_COMPOUNDLITERAL_I_I15_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__A_ADDR_I16_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__B_ADDR_I17_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[_COMPOUNDLITERAL_I_I12_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__A_ADDR_I13_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__B_ADDR_I14_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[_COMPOUNDLITERAL_I_I_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__A_ADDR_I_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__B_ADDR_I_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__S_ADDR_I_I:%.*]] = alloca i32, align 4
+// CHECK: [[_COMPOUNDLITERAL_I_I:%.*]] = alloca <16 x i32>, align 64
+// CHECK: [[__M_ADDR_I:%.*]] = alloca i16, align 2
+// CHECK: [[__V_ADDR_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__M_ADDR:%.*]] = alloca i16, align 2
+// CHECK: [[__W_ADDR:%.*]] = alloca <8 x i64>, align 64
+// CHECK: store i16 %__M, i16* [[__M_ADDR]], align 2
+// CHECK: store <8 x i64> %__W, <8 x i64>* [[__W_ADDR]], align 64
+// CHECK: [[TMP0:%.*]] = load i16, i16* [[__M_ADDR]], align 2
+// CHECK: [[TMP1:%.*]] = load <8 x i64>, <8 x i64>* [[__W_ADDR]], align 64
+// CHECK: store i16 [[TMP0]], i16* [[__M_ADDR_I]], align 2
+// CHECK: store <8 x i64> [[TMP1]], <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP2:%.*]] = load i16, i16* [[__M_ADDR_I]], align 2
+// CHECK: [[TMP3:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP4:%.*]] = bitcast <8 x i64> [[TMP3]] to <16 x i32>
+// CHECK: store i32 -2147483648, i32* [[__S_ADDR_I_I]], align 4
+// CHECK: [[TMP5:%.*]] = load i32, i32* [[__S_ADDR_I_I]], align 4
+// CHECK: [[VECINIT_I_I:%.*]] = insertelement <16 x i32> undef, i32 [[TMP5]], i32 0
+// CHECK: [[TMP6:%.*]] = load i32, i32* [[__S_ADDR_I_I]], align 4
+// CHECK: [[VECINIT1_I_I:%.*]] = insertelement <16 x i32> [[VECINIT_I_I]], i32 [[TMP6]], i32 1
+// CHECK: [[TMP7:%.*]] = load i32, i32* [[__S_ADDR_I_I]], align 4
+// CHECK: [[VECINIT2_I_I:%.*]] = insertelement <16 x i32> [[VECINIT1_I_I]], i32 [[TMP7]], i32 2
+// CHECK: [[TMP8:%.*]] = load i32, i32* [[__S_ADDR_I_I]], align 4
+// CHECK: [[VECINIT3_I_I:%.*]] = insertelement <16 x i32> [[VECINIT2_I_I]], i32 [[TMP8]], i32 3
+// CHECK: [[TMP9:%.*]] = load i32, i32* [[__S_ADDR_I_I]], align 4
+// CHECK: [[VECINIT4_I_I:%.*]] = insertelement <16 x i32> [[VECINIT3_I_I]], i32 [[TMP9]], i32 4
+// CHECK: [[TMP10:%.*]] = load i32, i32* [[__S_ADDR_I_I]], align 4
+// CHECK: [[VECINIT5_I_I:%.*]] = insertelement <16 x i32> [[VECINIT4_I_I]], i32 [[TMP10]], i32 5
+// CHECK: [[TMP11:%.*]] = load i32, i32* [[__S_ADDR_I_I]], align 4
+// CHECK: [[VECINIT6_I_I:%.*]] = insertelement <16 x i32> [[VECINIT5_I_I]], i32 [[TMP11]], i32 6
+// CHECK: [[TMP12:%.*]] = load i32, i32* [[__S_ADDR_I_I]], align 4
+// CHECK: [[VECINIT7_I_I:%.*]] = insertelement <16 x i32> [[VECINIT6_I_I]], i32 [[TMP12]], i32 7
+// CHECK: [[TMP13:%.*]] = load i32, i32* [[__S_ADDR_I_I]], align 4
+// CHECK: [[VECINIT8_I_I:%.*]] = insertelement <16 x i32> [[VECINIT7_I_I]], i32 [[TMP13]], i32 8
+// CHECK: [[TMP14:%.*]] = load i32, i32* [[__S_ADDR_I_I]], align 4
+// CHECK: [[VECINIT9_I_I:%.*]] = insertelement <16 x i32> [[VECINIT8_I_I]], i32 [[TMP14]], i32 9
+// CHECK: [[TMP15:%.*]] = load i32, i32* [[__S_ADDR_I_I]], align 4
+// CHECK: [[VECINIT10_I_I:%.*]] = insertelement <16 x i32> [[VECINIT9_I_I]], i32 [[TMP15]], i32 10
+// CHECK: [[TMP16:%.*]] = load i32, i32* [[__S_ADDR_I_I]], align 4
+// CHECK: [[VECINIT11_I_I:%.*]] = insertelement <16 x i32> [[VECINIT10_I_I]], i32 [[TMP16]], i32 11
+// CHECK: [[TMP17:%.*]] = load i32, i32* [[__S_ADDR_I_I]], align 4
+// CHECK: [[VECINIT12_I_I:%.*]] = insertelement <16 x i32> [[VECINIT11_I_I]], i32 [[TMP17]], i32 12
+// CHECK: [[TMP18:%.*]] = load i32, i32* [[__S_ADDR_I_I]], align 4
+// CHECK: [[VECINIT13_I_I:%.*]] = insertelement <16 x i32> [[VECINIT12_I_I]], i32 [[TMP18]], i32 13
+// CHECK: [[TMP19:%.*]] = load i32, i32* [[__S_ADDR_I_I]], align 4
+// CHECK: [[VECINIT14_I_I:%.*]] = insertelement <16 x i32> [[VECINIT13_I_I]], i32 [[TMP19]], i32 14
+// CHECK: [[TMP20:%.*]] = load i32, i32* [[__S_ADDR_I_I]], align 4
+// CHECK: [[VECINIT15_I_I:%.*]] = insertelement <16 x i32> [[VECINIT14_I_I]], i32 [[TMP20]], i32 15
+// CHECK: store <16 x i32> [[VECINIT15_I_I]], <16 x i32>* [[_COMPOUNDLITERAL_I_I]], align 64
+// CHECK: [[TMP21:%.*]] = load <16 x i32>, <16 x i32>* [[_COMPOUNDLITERAL_I_I]], align 64
+// CHECK: [[TMP22:%.*]] = bitcast <16 x i32> [[TMP21]] to <8 x i64>
+// CHECK: [[TMP23:%.*]] = bitcast i16 [[TMP2]] to <16 x i1>
+// CHECK: [[TMP24:%.*]] = select <16 x i1> [[TMP23]], <16 x i32> [[TMP4]], <16 x i32> [[TMP21]]
+// CHECK: [[TMP25:%.*]] = bitcast <16 x i32> [[TMP24]] to <8 x i64>
+// CHECK: store <8 x i64> [[TMP25]], <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP26:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP27:%.*]] = bitcast <8 x i64> [[TMP26]] to <16 x i32>
+// CHECK: [[TMP28:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP29:%.*]] = bitcast <8 x i64> [[TMP28]] to <16 x i32>
+// CHECK: [[SHUFFLE_I:%.*]] = shufflevector <16 x i32> [[TMP27]], <16 x i32> [[TMP29]], <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP30:%.*]] = bitcast <16 x i32> [[SHUFFLE_I]] to <8 x i64>
+// CHECK: [[TMP31:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP32:%.*]] = bitcast <8 x i64> [[TMP31]] to <16 x i32>
+// CHECK: [[TMP33:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP34:%.*]] = bitcast <8 x i64> [[TMP33]] to <16 x i32>
+// CHECK: [[SHUFFLE1_I:%.*]] = shufflevector <16 x i32> [[TMP32]], <16 x i32> [[TMP34]], <16 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP35:%.*]] = bitcast <16 x i32> [[SHUFFLE1_I]] to <8 x i64>
+// CHECK: store <8 x i64> [[TMP30]], <8 x i64>* [[__A_ADDR_I19_I]], align 64
+// CHECK: store <8 x i64> [[TMP35]], <8 x i64>* [[__B_ADDR_I20_I]], align 64
+// CHECK: [[TMP36:%.*]] = load <8 x i64>, <8 x i64>* [[__A_ADDR_I19_I]], align 64
+// CHECK: [[TMP37:%.*]] = bitcast <8 x i64> [[TMP36]] to <16 x i32>
+// CHECK: [[TMP38:%.*]] = load <8 x i64>, <8 x i64>* [[__B_ADDR_I20_I]], align 64
+// CHECK: [[TMP39:%.*]] = bitcast <8 x i64> [[TMP38]] to <16 x i32>
+// CHECK: store <8 x i64> zeroinitializer, <8 x i64>* [[_COMPOUNDLITERAL_I_I18_I]], align 64
+// CHECK: [[TMP40:%.*]] = load <8 x i64>, <8 x i64>* [[_COMPOUNDLITERAL_I_I18_I]], align 64
+// CHECK: [[TMP41:%.*]] = bitcast <8 x i64> [[TMP40]] to <16 x i32>
+// CHECK: [[TMP42:%.*]] = icmp sgt <16 x i32> [[TMP37]], [[TMP39]]
+// CHECK: [[TMP43:%.*]] = select <16 x i1> [[TMP42]], <16 x i32> [[TMP37]], <16 x i32> [[TMP39]]
+// CHECK: [[TMP44:%.*]] = bitcast <16 x i32> [[TMP43]] to <8 x i64>
+// CHECK: store <8 x i64> [[TMP44]], <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP45:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP46:%.*]] = bitcast <8 x i64> [[TMP45]] to <16 x i32>
+// CHECK: [[TMP47:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP48:%.*]] = bitcast <8 x i64> [[TMP47]] to <16 x i32>
+// CHECK: [[SHUFFLE3_I:%.*]] = shufflevector <16 x i32> [[TMP46]], <16 x i32> [[TMP48]], <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP49:%.*]] = bitcast <16 x i32> [[SHUFFLE3_I]] to <8 x i64>
+// CHECK: [[TMP50:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP51:%.*]] = bitcast <8 x i64> [[TMP50]] to <16 x i32>
+// CHECK: [[TMP52:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP53:%.*]] = bitcast <8 x i64> [[TMP52]] to <16 x i32>
+// CHECK: [[SHUFFLE4_I:%.*]] = shufflevector <16 x i32> [[TMP51]], <16 x i32> [[TMP53]], <16 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP54:%.*]] = bitcast <16 x i32> [[SHUFFLE4_I]] to <8 x i64>
+// CHECK: store <8 x i64> [[TMP49]], <8 x i64>* [[__A_ADDR_I16_I]], align 64
+// CHECK: store <8 x i64> [[TMP54]], <8 x i64>* [[__B_ADDR_I17_I]], align 64
+// CHECK: [[TMP55:%.*]] = load <8 x i64>, <8 x i64>* [[__A_ADDR_I16_I]], align 64
+// CHECK: [[TMP56:%.*]] = bitcast <8 x i64> [[TMP55]] to <16 x i32>
+// CHECK: [[TMP57:%.*]] = load <8 x i64>, <8 x i64>* [[__B_ADDR_I17_I]], align 64
+// CHECK: [[TMP58:%.*]] = bitcast <8 x i64> [[TMP57]] to <16 x i32>
+// CHECK: store <8 x i64> zeroinitializer, <8 x i64>* [[_COMPOUNDLITERAL_I_I15_I]], align 64
+// CHECK: [[TMP59:%.*]] = load <8 x i64>, <8 x i64>* [[_COMPOUNDLITERAL_I_I15_I]], align 64
+// CHECK: [[TMP60:%.*]] = bitcast <8 x i64> [[TMP59]] to <16 x i32>
+// CHECK: [[TMP61:%.*]] = icmp sgt <16 x i32> [[TMP56]], [[TMP58]]
+// CHECK: [[TMP62:%.*]] = select <16 x i1> [[TMP61]], <16 x i32> [[TMP56]], <16 x i32> [[TMP58]]
+// CHECK: [[TMP63:%.*]] = bitcast <16 x i32> [[TMP62]] to <8 x i64>
+// CHECK: store <8 x i64> [[TMP63]], <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP64:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP65:%.*]] = bitcast <8 x i64> [[TMP64]] to <16 x i32>
+// CHECK: [[TMP66:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP67:%.*]] = bitcast <8 x i64> [[TMP66]] to <16 x i32>
+// CHECK: [[SHUFFLE6_I:%.*]] = shufflevector <16 x i32> [[TMP65]], <16 x i32> [[TMP67]], <16 x i32> <i32 0, i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP68:%.*]] = bitcast <16 x i32> [[SHUFFLE6_I]] to <8 x i64>
+// CHECK: [[TMP69:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP70:%.*]] = bitcast <8 x i64> [[TMP69]] to <16 x i32>
+// CHECK: [[TMP71:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP72:%.*]] = bitcast <8 x i64> [[TMP71]] to <16 x i32>
+// CHECK: [[SHUFFLE7_I:%.*]] = shufflevector <16 x i32> [[TMP70]], <16 x i32> [[TMP72]], <16 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP73:%.*]] = bitcast <16 x i32> [[SHUFFLE7_I]] to <8 x i64>
+// CHECK: store <8 x i64> [[TMP68]], <8 x i64>* [[__A_ADDR_I13_I]], align 64
+// CHECK: store <8 x i64> [[TMP73]], <8 x i64>* [[__B_ADDR_I14_I]], align 64
+// CHECK: [[TMP74:%.*]] = load <8 x i64>, <8 x i64>* [[__A_ADDR_I13_I]], align 64
+// CHECK: [[TMP75:%.*]] = bitcast <8 x i64> [[TMP74]] to <16 x i32>
+// CHECK: [[TMP76:%.*]] = load <8 x i64>, <8 x i64>* [[__B_ADDR_I14_I]], align 64
+// CHECK: [[TMP77:%.*]] = bitcast <8 x i64> [[TMP76]] to <16 x i32>
+// CHECK: store <8 x i64> zeroinitializer, <8 x i64>* [[_COMPOUNDLITERAL_I_I12_I]], align 64
+// CHECK: [[TMP78:%.*]] = load <8 x i64>, <8 x i64>* [[_COMPOUNDLITERAL_I_I12_I]], align 64
+// CHECK: [[TMP79:%.*]] = bitcast <8 x i64> [[TMP78]] to <16 x i32>
+// CHECK: [[TMP80:%.*]] = icmp sgt <16 x i32> [[TMP75]], [[TMP77]]
+// CHECK: [[TMP81:%.*]] = select <16 x i1> [[TMP80]], <16 x i32> [[TMP75]], <16 x i32> [[TMP77]]
+// CHECK: [[TMP82:%.*]] = bitcast <16 x i32> [[TMP81]] to <8 x i64>
+// CHECK: store <8 x i64> [[TMP82]], <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP83:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP84:%.*]] = bitcast <8 x i64> [[TMP83]] to <16 x i32>
+// CHECK: [[TMP85:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP86:%.*]] = bitcast <8 x i64> [[TMP85]] to <16 x i32>
+// CHECK: [[SHUFFLE9_I:%.*]] = shufflevector <16 x i32> [[TMP84]], <16 x i32> [[TMP86]], <16 x i32> <i32 0, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP87:%.*]] = bitcast <16 x i32> [[SHUFFLE9_I]] to <8 x i64>
+// CHECK: [[TMP88:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP89:%.*]] = bitcast <8 x i64> [[TMP88]] to <16 x i32>
+// CHECK: [[TMP90:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP91:%.*]] = bitcast <8 x i64> [[TMP90]] to <16 x i32>
+// CHECK: [[SHUFFLE10_I:%.*]] = shufflevector <16 x i32> [[TMP89]], <16 x i32> [[TMP91]], <16 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP92:%.*]] = bitcast <16 x i32> [[SHUFFLE10_I]] to <8 x i64>
+// CHECK: store <8 x i64> [[TMP87]], <8 x i64>* [[__A_ADDR_I_I]], align 64
+// CHECK: store <8 x i64> [[TMP92]], <8 x i64>* [[__B_ADDR_I_I]], align 64
+// CHECK: [[TMP93:%.*]] = load <8 x i64>, <8 x i64>* [[__A_ADDR_I_I]], align 64
+// CHECK: [[TMP94:%.*]] = bitcast <8 x i64> [[TMP93]] to <16 x i32>
+// CHECK: [[TMP95:%.*]] = load <8 x i64>, <8 x i64>* [[__B_ADDR_I_I]], align 64
+// CHECK: [[TMP96:%.*]] = bitcast <8 x i64> [[TMP95]] to <16 x i32>
+// CHECK: store <8 x i64> zeroinitializer, <8 x i64>* [[_COMPOUNDLITERAL_I_I_I]], align 64
+// CHECK: [[TMP97:%.*]] = load <8 x i64>, <8 x i64>* [[_COMPOUNDLITERAL_I_I_I]], align 64
+// CHECK: [[TMP98:%.*]] = bitcast <8 x i64> [[TMP97]] to <16 x i32>
+// CHECK: [[TMP99:%.*]] = icmp sgt <16 x i32> [[TMP94]], [[TMP96]]
+// CHECK: [[TMP100:%.*]] = select <16 x i1> [[TMP99]], <16 x i32> [[TMP94]], <16 x i32> [[TMP96]]
+// CHECK: [[TMP101:%.*]] = bitcast <16 x i32> [[TMP100]] to <8 x i64>
+// CHECK: store <8 x i64> [[TMP101]], <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP102:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[VECEXT_I:%.*]] = extractelement <8 x i64> [[TMP102]], i32 0
+// CHECK: [[CONV_I:%.*]] = trunc i64 [[VECEXT_I]] to i32
+// CHECK: ret i32 [[CONV_I]]
int test_mm512_mask_reduce_max_epi32(__mmask16 __M, __m512i __W){
- // CHECK: %tmp = bitcast <8 x i64> %__W to <16 x i32>
- // CHECK: %tmp1 = bitcast i16 %__M to <16 x i1>
- // CHECK: %tmp2 = select <16 x i1> %tmp1, <16 x i32> %tmp, <16 x i32> <i32 -2147483648, i32 -2147483648, i32 -2147483648, i32 -2147483648, i32 -2147483648, i32 -2147483648, i32 -2147483648, i32 -2147483648, i32 -2147483648, i32 -2147483648, i32 -2147483648, i32 -2147483648, i32 -2147483648, i32 -2147483648, i32 -2147483648, i32 -2147483648>
- // CHECK: %shuffle1.i = shufflevector <16 x i32> %tmp2, <16 x i32> undef, <16 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp3 = icmp sgt <16 x i32> %tmp2, %shuffle1.i
- // CHECK: %tmp4 = select <16 x i1> %tmp3, <16 x i32> %tmp2, <16 x i32> %shuffle1.i
- // CHECK: %shuffle4.i = shufflevector <16 x i32> %tmp4, <16 x i32> undef, <16 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp5 = icmp sgt <16 x i32> %tmp4, %shuffle4.i
- // CHECK: %tmp6 = select <16 x i1> %tmp5, <16 x i32> %tmp4, <16 x i32> %shuffle4.i
- // CHECK: %shuffle7.i = shufflevector <16 x i32> %tmp6, <16 x i32> undef, <16 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp7 = icmp sgt <16 x i32> %tmp6, %shuffle7.i
- // CHECK: %tmp8 = select <16 x i1> %tmp7, <16 x i32> %tmp6, <16 x i32> %shuffle7.i
- // CHECK: %shuffle10.i = shufflevector <16 x i32> %tmp8, <16 x i32> undef, <16 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp9 = icmp sgt <16 x i32> %tmp8, %shuffle10.i
- // CHECK: %tmp10 = select <16 x i1> %tmp9, <16 x i32> %tmp8, <16 x i32> %shuffle10.i
- // CHECK: %tmp11 = bitcast <16 x i32> %tmp10 to <8 x i64>
- // CHECK: %vecext.i = extractelement <8 x i64> %tmp11, i32 0
- // CHECK: %conv.i = trunc i64 %vecext.i to i32
- // CHECK: ret i32 %conv.i
return _mm512_mask_reduce_max_epi32(__M, __W);
}
+// CHECK-LABEL: define i32 @test_mm512_mask_reduce_max_epu32(i16 zeroext %__M, <8 x i64> %__W) #0 {
+// CHECK: [[_COMPOUNDLITERAL_I_I18_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__A_ADDR_I19_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__B_ADDR_I20_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[_COMPOUNDLITERAL_I_I15_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__A_ADDR_I16_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__B_ADDR_I17_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[_COMPOUNDLITERAL_I_I12_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__A_ADDR_I13_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__B_ADDR_I14_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[_COMPOUNDLITERAL_I_I_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__A_ADDR_I_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__B_ADDR_I_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__S_ADDR_I_I:%.*]] = alloca i32, align 4
+// CHECK: [[_COMPOUNDLITERAL_I_I:%.*]] = alloca <16 x i32>, align 64
+// CHECK: [[__M_ADDR_I:%.*]] = alloca i16, align 2
+// CHECK: [[__V_ADDR_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__M_ADDR:%.*]] = alloca i16, align 2
+// CHECK: [[__W_ADDR:%.*]] = alloca <8 x i64>, align 64
+// CHECK: store i16 %__M, i16* [[__M_ADDR]], align 2
+// CHECK: store <8 x i64> %__W, <8 x i64>* [[__W_ADDR]], align 64
+// CHECK: [[TMP0:%.*]] = load i16, i16* [[__M_ADDR]], align 2
+// CHECK: [[TMP1:%.*]] = load <8 x i64>, <8 x i64>* [[__W_ADDR]], align 64
+// CHECK: store i16 [[TMP0]], i16* [[__M_ADDR_I]], align 2
+// CHECK: store <8 x i64> [[TMP1]], <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP2:%.*]] = load i16, i16* [[__M_ADDR_I]], align 2
+// CHECK: [[TMP3:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP4:%.*]] = bitcast <8 x i64> [[TMP3]] to <16 x i32>
+// CHECK: store i32 0, i32* [[__S_ADDR_I_I]], align 4
+// CHECK: [[TMP5:%.*]] = load i32, i32* [[__S_ADDR_I_I]], align 4
+// CHECK: [[VECINIT_I_I:%.*]] = insertelement <16 x i32> undef, i32 [[TMP5]], i32 0
+// CHECK: [[TMP6:%.*]] = load i32, i32* [[__S_ADDR_I_I]], align 4
+// CHECK: [[VECINIT1_I_I:%.*]] = insertelement <16 x i32> [[VECINIT_I_I]], i32 [[TMP6]], i32 1
+// CHECK: [[TMP7:%.*]] = load i32, i32* [[__S_ADDR_I_I]], align 4
+// CHECK: [[VECINIT2_I_I:%.*]] = insertelement <16 x i32> [[VECINIT1_I_I]], i32 [[TMP7]], i32 2
+// CHECK: [[TMP8:%.*]] = load i32, i32* [[__S_ADDR_I_I]], align 4
+// CHECK: [[VECINIT3_I_I:%.*]] = insertelement <16 x i32> [[VECINIT2_I_I]], i32 [[TMP8]], i32 3
+// CHECK: [[TMP9:%.*]] = load i32, i32* [[__S_ADDR_I_I]], align 4
+// CHECK: [[VECINIT4_I_I:%.*]] = insertelement <16 x i32> [[VECINIT3_I_I]], i32 [[TMP9]], i32 4
+// CHECK: [[TMP10:%.*]] = load i32, i32* [[__S_ADDR_I_I]], align 4
+// CHECK: [[VECINIT5_I_I:%.*]] = insertelement <16 x i32> [[VECINIT4_I_I]], i32 [[TMP10]], i32 5
+// CHECK: [[TMP11:%.*]] = load i32, i32* [[__S_ADDR_I_I]], align 4
+// CHECK: [[VECINIT6_I_I:%.*]] = insertelement <16 x i32> [[VECINIT5_I_I]], i32 [[TMP11]], i32 6
+// CHECK: [[TMP12:%.*]] = load i32, i32* [[__S_ADDR_I_I]], align 4
+// CHECK: [[VECINIT7_I_I:%.*]] = insertelement <16 x i32> [[VECINIT6_I_I]], i32 [[TMP12]], i32 7
+// CHECK: [[TMP13:%.*]] = load i32, i32* [[__S_ADDR_I_I]], align 4
+// CHECK: [[VECINIT8_I_I:%.*]] = insertelement <16 x i32> [[VECINIT7_I_I]], i32 [[TMP13]], i32 8
+// CHECK: [[TMP14:%.*]] = load i32, i32* [[__S_ADDR_I_I]], align 4
+// CHECK: [[VECINIT9_I_I:%.*]] = insertelement <16 x i32> [[VECINIT8_I_I]], i32 [[TMP14]], i32 9
+// CHECK: [[TMP15:%.*]] = load i32, i32* [[__S_ADDR_I_I]], align 4
+// CHECK: [[VECINIT10_I_I:%.*]] = insertelement <16 x i32> [[VECINIT9_I_I]], i32 [[TMP15]], i32 10
+// CHECK: [[TMP16:%.*]] = load i32, i32* [[__S_ADDR_I_I]], align 4
+// CHECK: [[VECINIT11_I_I:%.*]] = insertelement <16 x i32> [[VECINIT10_I_I]], i32 [[TMP16]], i32 11
+// CHECK: [[TMP17:%.*]] = load i32, i32* [[__S_ADDR_I_I]], align 4
+// CHECK: [[VECINIT12_I_I:%.*]] = insertelement <16 x i32> [[VECINIT11_I_I]], i32 [[TMP17]], i32 12
+// CHECK: [[TMP18:%.*]] = load i32, i32* [[__S_ADDR_I_I]], align 4
+// CHECK: [[VECINIT13_I_I:%.*]] = insertelement <16 x i32> [[VECINIT12_I_I]], i32 [[TMP18]], i32 13
+// CHECK: [[TMP19:%.*]] = load i32, i32* [[__S_ADDR_I_I]], align 4
+// CHECK: [[VECINIT14_I_I:%.*]] = insertelement <16 x i32> [[VECINIT13_I_I]], i32 [[TMP19]], i32 14
+// CHECK: [[TMP20:%.*]] = load i32, i32* [[__S_ADDR_I_I]], align 4
+// CHECK: [[VECINIT15_I_I:%.*]] = insertelement <16 x i32> [[VECINIT14_I_I]], i32 [[TMP20]], i32 15
+// CHECK: store <16 x i32> [[VECINIT15_I_I]], <16 x i32>* [[_COMPOUNDLITERAL_I_I]], align 64
+// CHECK: [[TMP21:%.*]] = load <16 x i32>, <16 x i32>* [[_COMPOUNDLITERAL_I_I]], align 64
+// CHECK: [[TMP22:%.*]] = bitcast <16 x i32> [[TMP21]] to <8 x i64>
+// CHECK: [[TMP23:%.*]] = bitcast i16 [[TMP2]] to <16 x i1>
+// CHECK: [[TMP24:%.*]] = select <16 x i1> [[TMP23]], <16 x i32> [[TMP4]], <16 x i32> [[TMP21]]
+// CHECK: [[TMP25:%.*]] = bitcast <16 x i32> [[TMP24]] to <8 x i64>
+// CHECK: store <8 x i64> [[TMP25]], <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP26:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP27:%.*]] = bitcast <8 x i64> [[TMP26]] to <16 x i32>
+// CHECK: [[TMP28:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP29:%.*]] = bitcast <8 x i64> [[TMP28]] to <16 x i32>
+// CHECK: [[SHUFFLE_I:%.*]] = shufflevector <16 x i32> [[TMP27]], <16 x i32> [[TMP29]], <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP30:%.*]] = bitcast <16 x i32> [[SHUFFLE_I]] to <8 x i64>
+// CHECK: [[TMP31:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP32:%.*]] = bitcast <8 x i64> [[TMP31]] to <16 x i32>
+// CHECK: [[TMP33:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP34:%.*]] = bitcast <8 x i64> [[TMP33]] to <16 x i32>
+// CHECK: [[SHUFFLE1_I:%.*]] = shufflevector <16 x i32> [[TMP32]], <16 x i32> [[TMP34]], <16 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP35:%.*]] = bitcast <16 x i32> [[SHUFFLE1_I]] to <8 x i64>
+// CHECK: store <8 x i64> [[TMP30]], <8 x i64>* [[__A_ADDR_I19_I]], align 64
+// CHECK: store <8 x i64> [[TMP35]], <8 x i64>* [[__B_ADDR_I20_I]], align 64
+// CHECK: [[TMP36:%.*]] = load <8 x i64>, <8 x i64>* [[__A_ADDR_I19_I]], align 64
+// CHECK: [[TMP37:%.*]] = bitcast <8 x i64> [[TMP36]] to <16 x i32>
+// CHECK: [[TMP38:%.*]] = load <8 x i64>, <8 x i64>* [[__B_ADDR_I20_I]], align 64
+// CHECK: [[TMP39:%.*]] = bitcast <8 x i64> [[TMP38]] to <16 x i32>
+// CHECK: store <8 x i64> zeroinitializer, <8 x i64>* [[_COMPOUNDLITERAL_I_I18_I]], align 64
+// CHECK: [[TMP40:%.*]] = load <8 x i64>, <8 x i64>* [[_COMPOUNDLITERAL_I_I18_I]], align 64
+// CHECK: [[TMP41:%.*]] = bitcast <8 x i64> [[TMP40]] to <16 x i32>
+// CHECK: [[TMP42:%.*]] = icmp ugt <16 x i32> [[TMP37]], [[TMP39]]
+// CHECK: [[TMP43:%.*]] = select <16 x i1> [[TMP42]], <16 x i32> [[TMP37]], <16 x i32> [[TMP39]]
+// CHECK: [[TMP44:%.*]] = bitcast <16 x i32> [[TMP43]] to <8 x i64>
+// CHECK: store <8 x i64> [[TMP44]], <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP45:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP46:%.*]] = bitcast <8 x i64> [[TMP45]] to <16 x i32>
+// CHECK: [[TMP47:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP48:%.*]] = bitcast <8 x i64> [[TMP47]] to <16 x i32>
+// CHECK: [[SHUFFLE3_I:%.*]] = shufflevector <16 x i32> [[TMP46]], <16 x i32> [[TMP48]], <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP49:%.*]] = bitcast <16 x i32> [[SHUFFLE3_I]] to <8 x i64>
+// CHECK: [[TMP50:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP51:%.*]] = bitcast <8 x i64> [[TMP50]] to <16 x i32>
+// CHECK: [[TMP52:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP53:%.*]] = bitcast <8 x i64> [[TMP52]] to <16 x i32>
+// CHECK: [[SHUFFLE4_I:%.*]] = shufflevector <16 x i32> [[TMP51]], <16 x i32> [[TMP53]], <16 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP54:%.*]] = bitcast <16 x i32> [[SHUFFLE4_I]] to <8 x i64>
+// CHECK: store <8 x i64> [[TMP49]], <8 x i64>* [[__A_ADDR_I16_I]], align 64
+// CHECK: store <8 x i64> [[TMP54]], <8 x i64>* [[__B_ADDR_I17_I]], align 64
+// CHECK: [[TMP55:%.*]] = load <8 x i64>, <8 x i64>* [[__A_ADDR_I16_I]], align 64
+// CHECK: [[TMP56:%.*]] = bitcast <8 x i64> [[TMP55]] to <16 x i32>
+// CHECK: [[TMP57:%.*]] = load <8 x i64>, <8 x i64>* [[__B_ADDR_I17_I]], align 64
+// CHECK: [[TMP58:%.*]] = bitcast <8 x i64> [[TMP57]] to <16 x i32>
+// CHECK: store <8 x i64> zeroinitializer, <8 x i64>* [[_COMPOUNDLITERAL_I_I15_I]], align 64
+// CHECK: [[TMP59:%.*]] = load <8 x i64>, <8 x i64>* [[_COMPOUNDLITERAL_I_I15_I]], align 64
+// CHECK: [[TMP60:%.*]] = bitcast <8 x i64> [[TMP59]] to <16 x i32>
+// CHECK: [[TMP61:%.*]] = icmp ugt <16 x i32> [[TMP56]], [[TMP58]]
+// CHECK: [[TMP62:%.*]] = select <16 x i1> [[TMP61]], <16 x i32> [[TMP56]], <16 x i32> [[TMP58]]
+// CHECK: [[TMP63:%.*]] = bitcast <16 x i32> [[TMP62]] to <8 x i64>
+// CHECK: store <8 x i64> [[TMP63]], <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP64:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP65:%.*]] = bitcast <8 x i64> [[TMP64]] to <16 x i32>
+// CHECK: [[TMP66:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP67:%.*]] = bitcast <8 x i64> [[TMP66]] to <16 x i32>
+// CHECK: [[SHUFFLE6_I:%.*]] = shufflevector <16 x i32> [[TMP65]], <16 x i32> [[TMP67]], <16 x i32> <i32 0, i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP68:%.*]] = bitcast <16 x i32> [[SHUFFLE6_I]] to <8 x i64>
+// CHECK: [[TMP69:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP70:%.*]] = bitcast <8 x i64> [[TMP69]] to <16 x i32>
+// CHECK: [[TMP71:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP72:%.*]] = bitcast <8 x i64> [[TMP71]] to <16 x i32>
+// CHECK: [[SHUFFLE7_I:%.*]] = shufflevector <16 x i32> [[TMP70]], <16 x i32> [[TMP72]], <16 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP73:%.*]] = bitcast <16 x i32> [[SHUFFLE7_I]] to <8 x i64>
+// CHECK: store <8 x i64> [[TMP68]], <8 x i64>* [[__A_ADDR_I13_I]], align 64
+// CHECK: store <8 x i64> [[TMP73]], <8 x i64>* [[__B_ADDR_I14_I]], align 64
+// CHECK: [[TMP74:%.*]] = load <8 x i64>, <8 x i64>* [[__A_ADDR_I13_I]], align 64
+// CHECK: [[TMP75:%.*]] = bitcast <8 x i64> [[TMP74]] to <16 x i32>
+// CHECK: [[TMP76:%.*]] = load <8 x i64>, <8 x i64>* [[__B_ADDR_I14_I]], align 64
+// CHECK: [[TMP77:%.*]] = bitcast <8 x i64> [[TMP76]] to <16 x i32>
+// CHECK: store <8 x i64> zeroinitializer, <8 x i64>* [[_COMPOUNDLITERAL_I_I12_I]], align 64
+// CHECK: [[TMP78:%.*]] = load <8 x i64>, <8 x i64>* [[_COMPOUNDLITERAL_I_I12_I]], align 64
+// CHECK: [[TMP79:%.*]] = bitcast <8 x i64> [[TMP78]] to <16 x i32>
+// CHECK: [[TMP80:%.*]] = icmp ugt <16 x i32> [[TMP75]], [[TMP77]]
+// CHECK: [[TMP81:%.*]] = select <16 x i1> [[TMP80]], <16 x i32> [[TMP75]], <16 x i32> [[TMP77]]
+// CHECK: [[TMP82:%.*]] = bitcast <16 x i32> [[TMP81]] to <8 x i64>
+// CHECK: store <8 x i64> [[TMP82]], <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP83:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP84:%.*]] = bitcast <8 x i64> [[TMP83]] to <16 x i32>
+// CHECK: [[TMP85:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP86:%.*]] = bitcast <8 x i64> [[TMP85]] to <16 x i32>
+// CHECK: [[SHUFFLE9_I:%.*]] = shufflevector <16 x i32> [[TMP84]], <16 x i32> [[TMP86]], <16 x i32> <i32 0, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP87:%.*]] = bitcast <16 x i32> [[SHUFFLE9_I]] to <8 x i64>
+// CHECK: [[TMP88:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP89:%.*]] = bitcast <8 x i64> [[TMP88]] to <16 x i32>
+// CHECK: [[TMP90:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP91:%.*]] = bitcast <8 x i64> [[TMP90]] to <16 x i32>
+// CHECK: [[SHUFFLE10_I:%.*]] = shufflevector <16 x i32> [[TMP89]], <16 x i32> [[TMP91]], <16 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP92:%.*]] = bitcast <16 x i32> [[SHUFFLE10_I]] to <8 x i64>
+// CHECK: store <8 x i64> [[TMP87]], <8 x i64>* [[__A_ADDR_I_I]], align 64
+// CHECK: store <8 x i64> [[TMP92]], <8 x i64>* [[__B_ADDR_I_I]], align 64
+// CHECK: [[TMP93:%.*]] = load <8 x i64>, <8 x i64>* [[__A_ADDR_I_I]], align 64
+// CHECK: [[TMP94:%.*]] = bitcast <8 x i64> [[TMP93]] to <16 x i32>
+// CHECK: [[TMP95:%.*]] = load <8 x i64>, <8 x i64>* [[__B_ADDR_I_I]], align 64
+// CHECK: [[TMP96:%.*]] = bitcast <8 x i64> [[TMP95]] to <16 x i32>
+// CHECK: store <8 x i64> zeroinitializer, <8 x i64>* [[_COMPOUNDLITERAL_I_I_I]], align 64
+// CHECK: [[TMP97:%.*]] = load <8 x i64>, <8 x i64>* [[_COMPOUNDLITERAL_I_I_I]], align 64
+// CHECK: [[TMP98:%.*]] = bitcast <8 x i64> [[TMP97]] to <16 x i32>
+// CHECK: [[TMP99:%.*]] = icmp ugt <16 x i32> [[TMP94]], [[TMP96]]
+// CHECK: [[TMP100:%.*]] = select <16 x i1> [[TMP99]], <16 x i32> [[TMP94]], <16 x i32> [[TMP96]]
+// CHECK: [[TMP101:%.*]] = bitcast <16 x i32> [[TMP100]] to <8 x i64>
+// CHECK: store <8 x i64> [[TMP101]], <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP102:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[VECEXT_I:%.*]] = extractelement <8 x i64> [[TMP102]], i32 0
+// CHECK: [[CONV_I:%.*]] = trunc i64 [[VECEXT_I]] to i32
+// CHECK: ret i32 [[CONV_I]]
unsigned int test_mm512_mask_reduce_max_epu32(__mmask16 __M, __m512i __W){
- // CHECK: %tmp = bitcast <8 x i64> %__W to <16 x i32>
- // CHECK: %tmp1 = bitcast i16 %__M to <16 x i1>
- // CHECK: %tmp2 = select <16 x i1> %tmp1, <16 x i32> %tmp, <16 x i32> zeroinitializer
- // CHECK: %shuffle1.i = shufflevector <16 x i32> %tmp2, <16 x i32> undef, <16 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp3 = icmp ugt <16 x i32> %tmp2, %shuffle1.i
- // CHECK: %tmp4 = select <16 x i1> %tmp3, <16 x i32> %tmp2, <16 x i32> %shuffle1.i
- // CHECK: %shuffle4.i = shufflevector <16 x i32> %tmp4, <16 x i32> undef, <16 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp5 = icmp ugt <16 x i32> %tmp4, %shuffle4.i
- // CHECK: %tmp6 = select <16 x i1> %tmp5, <16 x i32> %tmp4, <16 x i32> %shuffle4.i
- // CHECK: %shuffle7.i = shufflevector <16 x i32> %tmp6, <16 x i32> undef, <16 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp7 = icmp ugt <16 x i32> %tmp6, %shuffle7.i
- // CHECK: %tmp8 = select <16 x i1> %tmp7, <16 x i32> %tmp6, <16 x i32> %shuffle7.i
- // CHECK: %shuffle10.i = shufflevector <16 x i32> %tmp8, <16 x i32> undef, <16 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp9 = icmp ugt <16 x i32> %tmp8, %shuffle10.i
- // CHECK: %tmp10 = select <16 x i1> %tmp9, <16 x i32> %tmp8, <16 x i32> %shuffle10.i
- // CHECK: %tmp11 = bitcast <16 x i32> %tmp10 to <8 x i64>
- // CHECK: %vecext.i = extractelement <8 x i64> %tmp11, i32 0
- // CHECK: %conv.i = trunc i64 %vecext.i to i32
- // CHECK: ret i32 %conv.i
return _mm512_mask_reduce_max_epu32(__M, __W);
}
+// CHECK-LABEL: define float @test_mm512_mask_reduce_max_ps(i16 zeroext %__M, <16 x float> %__W) #0 {
+// CHECK: [[_COMPOUNDLITERAL_I_I18_I:%.*]] = alloca <16 x float>, align 64
+// CHECK: [[__A_ADDR_I19_I:%.*]] = alloca <16 x float>, align 64
+// CHECK: [[__B_ADDR_I20_I:%.*]] = alloca <16 x float>, align 64
+// CHECK: [[_COMPOUNDLITERAL_I_I15_I:%.*]] = alloca <16 x float>, align 64
+// CHECK: [[__A_ADDR_I16_I:%.*]] = alloca <16 x float>, align 64
+// CHECK: [[__B_ADDR_I17_I:%.*]] = alloca <16 x float>, align 64
+// CHECK: [[_COMPOUNDLITERAL_I_I12_I:%.*]] = alloca <16 x float>, align 64
+// CHECK: [[__A_ADDR_I13_I:%.*]] = alloca <16 x float>, align 64
+// CHECK: [[__B_ADDR_I14_I:%.*]] = alloca <16 x float>, align 64
+// CHECK: [[_COMPOUNDLITERAL_I_I_I:%.*]] = alloca <16 x float>, align 64
+// CHECK: [[__A_ADDR_I_I:%.*]] = alloca <16 x float>, align 64
+// CHECK: [[__B_ADDR_I_I:%.*]] = alloca <16 x float>, align 64
+// CHECK: [[__W_ADDR_I_I:%.*]] = alloca float, align 4
+// CHECK: [[_COMPOUNDLITERAL_I_I:%.*]] = alloca <16 x float>, align 64
+// CHECK: [[__M_ADDR_I:%.*]] = alloca i16, align 2
+// CHECK: [[__V_ADDR_I:%.*]] = alloca <16 x float>, align 64
+// CHECK: [[__M_ADDR:%.*]] = alloca i16, align 2
+// CHECK: [[__W_ADDR:%.*]] = alloca <16 x float>, align 64
+// CHECK: store i16 %__M, i16* [[__M_ADDR]], align 2
+// CHECK: store <16 x float> %__W, <16 x float>* [[__W_ADDR]], align 64
+// CHECK: [[TMP0:%.*]] = load i16, i16* [[__M_ADDR]], align 2
+// CHECK: [[TMP1:%.*]] = load <16 x float>, <16 x float>* [[__W_ADDR]], align 64
+// CHECK: store i16 [[TMP0]], i16* [[__M_ADDR_I]], align 2
+// CHECK: store <16 x float> [[TMP1]], <16 x float>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP2:%.*]] = load i16, i16* [[__M_ADDR_I]], align 2
+// CHECK: [[TMP3:%.*]] = load <16 x float>, <16 x float>* [[__V_ADDR_I]], align 64
+// CHECK: store float 0x7FF0000000000000, float* [[__W_ADDR_I_I]], align 4
+// CHECK: [[TMP4:%.*]] = load float, float* [[__W_ADDR_I_I]], align 4
+// CHECK: [[VECINIT_I_I:%.*]] = insertelement <16 x float> undef, float [[TMP4]], i32 0
+// CHECK: [[TMP5:%.*]] = load float, float* [[__W_ADDR_I_I]], align 4
+// CHECK: [[VECINIT1_I_I:%.*]] = insertelement <16 x float> [[VECINIT_I_I]], float [[TMP5]], i32 1
+// CHECK: [[TMP6:%.*]] = load float, float* [[__W_ADDR_I_I]], align 4
+// CHECK: [[VECINIT2_I_I:%.*]] = insertelement <16 x float> [[VECINIT1_I_I]], float [[TMP6]], i32 2
+// CHECK: [[TMP7:%.*]] = load float, float* [[__W_ADDR_I_I]], align 4
+// CHECK: [[VECINIT3_I_I:%.*]] = insertelement <16 x float> [[VECINIT2_I_I]], float [[TMP7]], i32 3
+// CHECK: [[TMP8:%.*]] = load float, float* [[__W_ADDR_I_I]], align 4
+// CHECK: [[VECINIT4_I_I:%.*]] = insertelement <16 x float> [[VECINIT3_I_I]], float [[TMP8]], i32 4
+// CHECK: [[TMP9:%.*]] = load float, float* [[__W_ADDR_I_I]], align 4
+// CHECK: [[VECINIT5_I_I:%.*]] = insertelement <16 x float> [[VECINIT4_I_I]], float [[TMP9]], i32 5
+// CHECK: [[TMP10:%.*]] = load float, float* [[__W_ADDR_I_I]], align 4
+// CHECK: [[VECINIT6_I_I:%.*]] = insertelement <16 x float> [[VECINIT5_I_I]], float [[TMP10]], i32 6
+// CHECK: [[TMP11:%.*]] = load float, float* [[__W_ADDR_I_I]], align 4
+// CHECK: [[VECINIT7_I_I:%.*]] = insertelement <16 x float> [[VECINIT6_I_I]], float [[TMP11]], i32 7
+// CHECK: [[TMP12:%.*]] = load float, float* [[__W_ADDR_I_I]], align 4
+// CHECK: [[VECINIT8_I_I:%.*]] = insertelement <16 x float> [[VECINIT7_I_I]], float [[TMP12]], i32 8
+// CHECK: [[TMP13:%.*]] = load float, float* [[__W_ADDR_I_I]], align 4
+// CHECK: [[VECINIT9_I_I:%.*]] = insertelement <16 x float> [[VECINIT8_I_I]], float [[TMP13]], i32 9
+// CHECK: [[TMP14:%.*]] = load float, float* [[__W_ADDR_I_I]], align 4
+// CHECK: [[VECINIT10_I_I:%.*]] = insertelement <16 x float> [[VECINIT9_I_I]], float [[TMP14]], i32 10
+// CHECK: [[TMP15:%.*]] = load float, float* [[__W_ADDR_I_I]], align 4
+// CHECK: [[VECINIT11_I_I:%.*]] = insertelement <16 x float> [[VECINIT10_I_I]], float [[TMP15]], i32 11
+// CHECK: [[TMP16:%.*]] = load float, float* [[__W_ADDR_I_I]], align 4
+// CHECK: [[VECINIT12_I_I:%.*]] = insertelement <16 x float> [[VECINIT11_I_I]], float [[TMP16]], i32 12
+// CHECK: [[TMP17:%.*]] = load float, float* [[__W_ADDR_I_I]], align 4
+// CHECK: [[VECINIT13_I_I:%.*]] = insertelement <16 x float> [[VECINIT12_I_I]], float [[TMP17]], i32 13
+// CHECK: [[TMP18:%.*]] = load float, float* [[__W_ADDR_I_I]], align 4
+// CHECK: [[VECINIT14_I_I:%.*]] = insertelement <16 x float> [[VECINIT13_I_I]], float [[TMP18]], i32 14
+// CHECK: [[TMP19:%.*]] = load float, float* [[__W_ADDR_I_I]], align 4
+// CHECK: [[VECINIT15_I_I:%.*]] = insertelement <16 x float> [[VECINIT14_I_I]], float [[TMP19]], i32 15
+// CHECK: store <16 x float> [[VECINIT15_I_I]], <16 x float>* [[_COMPOUNDLITERAL_I_I]], align 64
+// CHECK: [[TMP20:%.*]] = load <16 x float>, <16 x float>* [[_COMPOUNDLITERAL_I_I]], align 64
+// CHECK: [[SUB_I:%.*]] = fsub <16 x float> <float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00>, [[TMP20]]
+// CHECK: [[TMP21:%.*]] = bitcast i16 [[TMP2]] to <16 x i1>
+// CHECK: [[TMP22:%.*]] = select <16 x i1> [[TMP21]], <16 x float> [[TMP3]], <16 x float> [[SUB_I]]
+// CHECK: store <16 x float> [[TMP22]], <16 x float>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP23:%.*]] = load <16 x float>, <16 x float>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP24:%.*]] = load <16 x float>, <16 x float>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE_I:%.*]] = shufflevector <16 x float> [[TMP23]], <16 x float> [[TMP24]], <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP25:%.*]] = load <16 x float>, <16 x float>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP26:%.*]] = load <16 x float>, <16 x float>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE1_I:%.*]] = shufflevector <16 x float> [[TMP25]], <16 x float> [[TMP26]], <16 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: store <16 x float> [[SHUFFLE_I]], <16 x float>* [[__A_ADDR_I19_I]], align 64
+// CHECK: store <16 x float> [[SHUFFLE1_I]], <16 x float>* [[__B_ADDR_I20_I]], align 64
+// CHECK: [[TMP27:%.*]] = load <16 x float>, <16 x float>* [[__A_ADDR_I19_I]], align 64
+// CHECK: [[TMP28:%.*]] = load <16 x float>, <16 x float>* [[__B_ADDR_I20_I]], align 64
+// CHECK: store <16 x float> zeroinitializer, <16 x float>* [[_COMPOUNDLITERAL_I_I18_I]], align 64
+// CHECK: [[TMP29:%.*]] = load <16 x float>, <16 x float>* [[_COMPOUNDLITERAL_I_I18_I]], align 64
+// CHECK: [[TMP30:%.*]] = call <16 x float> @llvm.x86.avx512.mask.max.ps.512(<16 x float> [[TMP27]], <16 x float> [[TMP28]], <16 x float> [[TMP29]], i16 -1, i32 4) #2
+// CHECK: store <16 x float> [[TMP30]], <16 x float>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP31:%.*]] = load <16 x float>, <16 x float>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP32:%.*]] = load <16 x float>, <16 x float>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE3_I:%.*]] = shufflevector <16 x float> [[TMP31]], <16 x float> [[TMP32]], <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP33:%.*]] = load <16 x float>, <16 x float>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP34:%.*]] = load <16 x float>, <16 x float>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE4_I:%.*]] = shufflevector <16 x float> [[TMP33]], <16 x float> [[TMP34]], <16 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: store <16 x float> [[SHUFFLE3_I]], <16 x float>* [[__A_ADDR_I16_I]], align 64
+// CHECK: store <16 x float> [[SHUFFLE4_I]], <16 x float>* [[__B_ADDR_I17_I]], align 64
+// CHECK: [[TMP35:%.*]] = load <16 x float>, <16 x float>* [[__A_ADDR_I16_I]], align 64
+// CHECK: [[TMP36:%.*]] = load <16 x float>, <16 x float>* [[__B_ADDR_I17_I]], align 64
+// CHECK: store <16 x float> zeroinitializer, <16 x float>* [[_COMPOUNDLITERAL_I_I15_I]], align 64
+// CHECK: [[TMP37:%.*]] = load <16 x float>, <16 x float>* [[_COMPOUNDLITERAL_I_I15_I]], align 64
+// CHECK: [[TMP38:%.*]] = call <16 x float> @llvm.x86.avx512.mask.max.ps.512(<16 x float> [[TMP35]], <16 x float> [[TMP36]], <16 x float> [[TMP37]], i16 -1, i32 4) #2
+// CHECK: store <16 x float> [[TMP38]], <16 x float>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP39:%.*]] = load <16 x float>, <16 x float>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP40:%.*]] = load <16 x float>, <16 x float>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE6_I:%.*]] = shufflevector <16 x float> [[TMP39]], <16 x float> [[TMP40]], <16 x i32> <i32 0, i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP41:%.*]] = load <16 x float>, <16 x float>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP42:%.*]] = load <16 x float>, <16 x float>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE7_I:%.*]] = shufflevector <16 x float> [[TMP41]], <16 x float> [[TMP42]], <16 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: store <16 x float> [[SHUFFLE6_I]], <16 x float>* [[__A_ADDR_I13_I]], align 64
+// CHECK: store <16 x float> [[SHUFFLE7_I]], <16 x float>* [[__B_ADDR_I14_I]], align 64
+// CHECK: [[TMP43:%.*]] = load <16 x float>, <16 x float>* [[__A_ADDR_I13_I]], align 64
+// CHECK: [[TMP44:%.*]] = load <16 x float>, <16 x float>* [[__B_ADDR_I14_I]], align 64
+// CHECK: store <16 x float> zeroinitializer, <16 x float>* [[_COMPOUNDLITERAL_I_I12_I]], align 64
+// CHECK: [[TMP45:%.*]] = load <16 x float>, <16 x float>* [[_COMPOUNDLITERAL_I_I12_I]], align 64
+// CHECK: [[TMP46:%.*]] = call <16 x float> @llvm.x86.avx512.mask.max.ps.512(<16 x float> [[TMP43]], <16 x float> [[TMP44]], <16 x float> [[TMP45]], i16 -1, i32 4) #2
+// CHECK: store <16 x float> [[TMP46]], <16 x float>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP47:%.*]] = load <16 x float>, <16 x float>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP48:%.*]] = load <16 x float>, <16 x float>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE9_I:%.*]] = shufflevector <16 x float> [[TMP47]], <16 x float> [[TMP48]], <16 x i32> <i32 0, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP49:%.*]] = load <16 x float>, <16 x float>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP50:%.*]] = load <16 x float>, <16 x float>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE10_I:%.*]] = shufflevector <16 x float> [[TMP49]], <16 x float> [[TMP50]], <16 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: store <16 x float> [[SHUFFLE9_I]], <16 x float>* [[__A_ADDR_I_I]], align 64
+// CHECK: store <16 x float> [[SHUFFLE10_I]], <16 x float>* [[__B_ADDR_I_I]], align 64
+// CHECK: [[TMP51:%.*]] = load <16 x float>, <16 x float>* [[__A_ADDR_I_I]], align 64
+// CHECK: [[TMP52:%.*]] = load <16 x float>, <16 x float>* [[__B_ADDR_I_I]], align 64
+// CHECK: store <16 x float> zeroinitializer, <16 x float>* [[_COMPOUNDLITERAL_I_I_I]], align 64
+// CHECK: [[TMP53:%.*]] = load <16 x float>, <16 x float>* [[_COMPOUNDLITERAL_I_I_I]], align 64
+// CHECK: [[TMP54:%.*]] = call <16 x float> @llvm.x86.avx512.mask.max.ps.512(<16 x float> [[TMP51]], <16 x float> [[TMP52]], <16 x float> [[TMP53]], i16 -1, i32 4) #2
+// CHECK: store <16 x float> [[TMP54]], <16 x float>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP55:%.*]] = load <16 x float>, <16 x float>* [[__V_ADDR_I]], align 64
+// CHECK: [[VECEXT_I:%.*]] = extractelement <16 x float> [[TMP55]], i32 0
+// CHECK: ret float [[VECEXT_I]]
float test_mm512_mask_reduce_max_ps(__mmask16 __M, __m512 __W){
- // CHECK: %tmp = bitcast i16 %__M to <16 x i1>
- // CHECK: %tmp1 = select <16 x i1> %tmp, <16 x float> %__W, <16 x float> <float 0xFFF0000000000000, float 0xFFF0000000000000, float 0xFFF0000000000000, float 0xFFF0000000000000, float 0xFFF0000000000000, float 0xFFF0000000000000, float 0xFFF0000000000000, float 0xFFF0000000000000, float 0xFFF0000000000000, float 0xFFF0000000000000, float 0xFFF0000000000000, float 0xFFF0000000000000, float 0xFFF0000000000000, float 0xFFF0000000000000, float 0xFFF0000000000000, float 0xFFF0000000000000>
- // CHECK: %shuffle1.i = shufflevector <16 x float> %tmp1, <16 x float> undef, <16 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp2 = tail call <16 x float> @llvm.x86.avx512.mask.max.ps.512(<16 x float> %tmp1, <16 x float> %shuffle1.i, <16 x float> zeroinitializer, i16 -1, i32 4) #3
- // CHECK: %shuffle4.i = shufflevector <16 x float> %tmp2, <16 x float> undef, <16 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp3 = tail call <16 x float> @llvm.x86.avx512.mask.max.ps.512(<16 x float> %tmp2, <16 x float> %shuffle4.i, <16 x float> zeroinitializer, i16 -1, i32 4) #3
- // CHECK: %shuffle7.i = shufflevector <16 x float> %tmp3, <16 x float> undef, <16 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp4 = tail call <16 x float> @llvm.x86.avx512.mask.max.ps.512(<16 x float> %tmp3, <16 x float> %shuffle7.i, <16 x float> zeroinitializer, i16 -1, i32 4) #3
- // CHECK: %shuffle10.i = shufflevector <16 x float> %tmp4, <16 x float> undef, <16 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp5 = tail call <16 x float> @llvm.x86.avx512.mask.max.ps.512(<16 x float> %tmp4, <16 x float> %shuffle10.i, <16 x float> zeroinitializer, i16 -1, i32 4) #3
- // CHECK: %vecext.i = extractelement <16 x float> %tmp5, i32 0
- // CHECK: ret float %vecext.i
return _mm512_mask_reduce_max_ps(__M, __W);
}
+// CHECK-LABEL: define i32 @test_mm512_mask_reduce_min_epi32(i16 zeroext %__M, <8 x i64> %__W) #0 {
+// CHECK: [[_COMPOUNDLITERAL_I_I18_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__A_ADDR_I19_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__B_ADDR_I20_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[_COMPOUNDLITERAL_I_I15_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__A_ADDR_I16_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__B_ADDR_I17_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[_COMPOUNDLITERAL_I_I12_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__A_ADDR_I13_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__B_ADDR_I14_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[_COMPOUNDLITERAL_I_I_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__A_ADDR_I_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__B_ADDR_I_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__S_ADDR_I_I:%.*]] = alloca i32, align 4
+// CHECK: [[_COMPOUNDLITERAL_I_I:%.*]] = alloca <16 x i32>, align 64
+// CHECK: [[__M_ADDR_I:%.*]] = alloca i16, align 2
+// CHECK: [[__V_ADDR_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__M_ADDR:%.*]] = alloca i16, align 2
+// CHECK: [[__W_ADDR:%.*]] = alloca <8 x i64>, align 64
+// CHECK: store i16 %__M, i16* [[__M_ADDR]], align 2
+// CHECK: store <8 x i64> %__W, <8 x i64>* [[__W_ADDR]], align 64
+// CHECK: [[TMP0:%.*]] = load i16, i16* [[__M_ADDR]], align 2
+// CHECK: [[TMP1:%.*]] = load <8 x i64>, <8 x i64>* [[__W_ADDR]], align 64
+// CHECK: store i16 [[TMP0]], i16* [[__M_ADDR_I]], align 2
+// CHECK: store <8 x i64> [[TMP1]], <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP2:%.*]] = load i16, i16* [[__M_ADDR_I]], align 2
+// CHECK: [[TMP3:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP4:%.*]] = bitcast <8 x i64> [[TMP3]] to <16 x i32>
+// CHECK: store i32 2147483647, i32* [[__S_ADDR_I_I]], align 4
+// CHECK: [[TMP5:%.*]] = load i32, i32* [[__S_ADDR_I_I]], align 4
+// CHECK: [[VECINIT_I_I:%.*]] = insertelement <16 x i32> undef, i32 [[TMP5]], i32 0
+// CHECK: [[TMP6:%.*]] = load i32, i32* [[__S_ADDR_I_I]], align 4
+// CHECK: [[VECINIT1_I_I:%.*]] = insertelement <16 x i32> [[VECINIT_I_I]], i32 [[TMP6]], i32 1
+// CHECK: [[TMP7:%.*]] = load i32, i32* [[__S_ADDR_I_I]], align 4
+// CHECK: [[VECINIT2_I_I:%.*]] = insertelement <16 x i32> [[VECINIT1_I_I]], i32 [[TMP7]], i32 2
+// CHECK: [[TMP8:%.*]] = load i32, i32* [[__S_ADDR_I_I]], align 4
+// CHECK: [[VECINIT3_I_I:%.*]] = insertelement <16 x i32> [[VECINIT2_I_I]], i32 [[TMP8]], i32 3
+// CHECK: [[TMP9:%.*]] = load i32, i32* [[__S_ADDR_I_I]], align 4
+// CHECK: [[VECINIT4_I_I:%.*]] = insertelement <16 x i32> [[VECINIT3_I_I]], i32 [[TMP9]], i32 4
+// CHECK: [[TMP10:%.*]] = load i32, i32* [[__S_ADDR_I_I]], align 4
+// CHECK: [[VECINIT5_I_I:%.*]] = insertelement <16 x i32> [[VECINIT4_I_I]], i32 [[TMP10]], i32 5
+// CHECK: [[TMP11:%.*]] = load i32, i32* [[__S_ADDR_I_I]], align 4
+// CHECK: [[VECINIT6_I_I:%.*]] = insertelement <16 x i32> [[VECINIT5_I_I]], i32 [[TMP11]], i32 6
+// CHECK: [[TMP12:%.*]] = load i32, i32* [[__S_ADDR_I_I]], align 4
+// CHECK: [[VECINIT7_I_I:%.*]] = insertelement <16 x i32> [[VECINIT6_I_I]], i32 [[TMP12]], i32 7
+// CHECK: [[TMP13:%.*]] = load i32, i32* [[__S_ADDR_I_I]], align 4
+// CHECK: [[VECINIT8_I_I:%.*]] = insertelement <16 x i32> [[VECINIT7_I_I]], i32 [[TMP13]], i32 8
+// CHECK: [[TMP14:%.*]] = load i32, i32* [[__S_ADDR_I_I]], align 4
+// CHECK: [[VECINIT9_I_I:%.*]] = insertelement <16 x i32> [[VECINIT8_I_I]], i32 [[TMP14]], i32 9
+// CHECK: [[TMP15:%.*]] = load i32, i32* [[__S_ADDR_I_I]], align 4
+// CHECK: [[VECINIT10_I_I:%.*]] = insertelement <16 x i32> [[VECINIT9_I_I]], i32 [[TMP15]], i32 10
+// CHECK: [[TMP16:%.*]] = load i32, i32* [[__S_ADDR_I_I]], align 4
+// CHECK: [[VECINIT11_I_I:%.*]] = insertelement <16 x i32> [[VECINIT10_I_I]], i32 [[TMP16]], i32 11
+// CHECK: [[TMP17:%.*]] = load i32, i32* [[__S_ADDR_I_I]], align 4
+// CHECK: [[VECINIT12_I_I:%.*]] = insertelement <16 x i32> [[VECINIT11_I_I]], i32 [[TMP17]], i32 12
+// CHECK: [[TMP18:%.*]] = load i32, i32* [[__S_ADDR_I_I]], align 4
+// CHECK: [[VECINIT13_I_I:%.*]] = insertelement <16 x i32> [[VECINIT12_I_I]], i32 [[TMP18]], i32 13
+// CHECK: [[TMP19:%.*]] = load i32, i32* [[__S_ADDR_I_I]], align 4
+// CHECK: [[VECINIT14_I_I:%.*]] = insertelement <16 x i32> [[VECINIT13_I_I]], i32 [[TMP19]], i32 14
+// CHECK: [[TMP20:%.*]] = load i32, i32* [[__S_ADDR_I_I]], align 4
+// CHECK: [[VECINIT15_I_I:%.*]] = insertelement <16 x i32> [[VECINIT14_I_I]], i32 [[TMP20]], i32 15
+// CHECK: store <16 x i32> [[VECINIT15_I_I]], <16 x i32>* [[_COMPOUNDLITERAL_I_I]], align 64
+// CHECK: [[TMP21:%.*]] = load <16 x i32>, <16 x i32>* [[_COMPOUNDLITERAL_I_I]], align 64
+// CHECK: [[TMP22:%.*]] = bitcast <16 x i32> [[TMP21]] to <8 x i64>
+// CHECK: [[TMP23:%.*]] = bitcast i16 [[TMP2]] to <16 x i1>
+// CHECK: [[TMP24:%.*]] = select <16 x i1> [[TMP23]], <16 x i32> [[TMP4]], <16 x i32> [[TMP21]]
+// CHECK: [[TMP25:%.*]] = bitcast <16 x i32> [[TMP24]] to <8 x i64>
+// CHECK: store <8 x i64> [[TMP25]], <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP26:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP27:%.*]] = bitcast <8 x i64> [[TMP26]] to <16 x i32>
+// CHECK: [[TMP28:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP29:%.*]] = bitcast <8 x i64> [[TMP28]] to <16 x i32>
+// CHECK: [[SHUFFLE_I:%.*]] = shufflevector <16 x i32> [[TMP27]], <16 x i32> [[TMP29]], <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP30:%.*]] = bitcast <16 x i32> [[SHUFFLE_I]] to <8 x i64>
+// CHECK: [[TMP31:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP32:%.*]] = bitcast <8 x i64> [[TMP31]] to <16 x i32>
+// CHECK: [[TMP33:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP34:%.*]] = bitcast <8 x i64> [[TMP33]] to <16 x i32>
+// CHECK: [[SHUFFLE1_I:%.*]] = shufflevector <16 x i32> [[TMP32]], <16 x i32> [[TMP34]], <16 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP35:%.*]] = bitcast <16 x i32> [[SHUFFLE1_I]] to <8 x i64>
+// CHECK: store <8 x i64> [[TMP30]], <8 x i64>* [[__A_ADDR_I19_I]], align 64
+// CHECK: store <8 x i64> [[TMP35]], <8 x i64>* [[__B_ADDR_I20_I]], align 64
+// CHECK: [[TMP36:%.*]] = load <8 x i64>, <8 x i64>* [[__A_ADDR_I19_I]], align 64
+// CHECK: [[TMP37:%.*]] = bitcast <8 x i64> [[TMP36]] to <16 x i32>
+// CHECK: [[TMP38:%.*]] = load <8 x i64>, <8 x i64>* [[__B_ADDR_I20_I]], align 64
+// CHECK: [[TMP39:%.*]] = bitcast <8 x i64> [[TMP38]] to <16 x i32>
+// CHECK: store <8 x i64> zeroinitializer, <8 x i64>* [[_COMPOUNDLITERAL_I_I18_I]], align 64
+// CHECK: [[TMP40:%.*]] = load <8 x i64>, <8 x i64>* [[_COMPOUNDLITERAL_I_I18_I]], align 64
+// CHECK: [[TMP41:%.*]] = bitcast <8 x i64> [[TMP40]] to <16 x i32>
+// CHECK: [[TMP42:%.*]] = icmp slt <16 x i32> [[TMP37]], [[TMP39]]
+// CHECK: [[TMP43:%.*]] = select <16 x i1> [[TMP42]], <16 x i32> [[TMP37]], <16 x i32> [[TMP39]]
+// CHECK: [[TMP44:%.*]] = bitcast <16 x i32> [[TMP43]] to <8 x i64>
+// CHECK: store <8 x i64> [[TMP44]], <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP45:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP46:%.*]] = bitcast <8 x i64> [[TMP45]] to <16 x i32>
+// CHECK: [[TMP47:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP48:%.*]] = bitcast <8 x i64> [[TMP47]] to <16 x i32>
+// CHECK: [[SHUFFLE3_I:%.*]] = shufflevector <16 x i32> [[TMP46]], <16 x i32> [[TMP48]], <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP49:%.*]] = bitcast <16 x i32> [[SHUFFLE3_I]] to <8 x i64>
+// CHECK: [[TMP50:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP51:%.*]] = bitcast <8 x i64> [[TMP50]] to <16 x i32>
+// CHECK: [[TMP52:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP53:%.*]] = bitcast <8 x i64> [[TMP52]] to <16 x i32>
+// CHECK: [[SHUFFLE4_I:%.*]] = shufflevector <16 x i32> [[TMP51]], <16 x i32> [[TMP53]], <16 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP54:%.*]] = bitcast <16 x i32> [[SHUFFLE4_I]] to <8 x i64>
+// CHECK: store <8 x i64> [[TMP49]], <8 x i64>* [[__A_ADDR_I16_I]], align 64
+// CHECK: store <8 x i64> [[TMP54]], <8 x i64>* [[__B_ADDR_I17_I]], align 64
+// CHECK: [[TMP55:%.*]] = load <8 x i64>, <8 x i64>* [[__A_ADDR_I16_I]], align 64
+// CHECK: [[TMP56:%.*]] = bitcast <8 x i64> [[TMP55]] to <16 x i32>
+// CHECK: [[TMP57:%.*]] = load <8 x i64>, <8 x i64>* [[__B_ADDR_I17_I]], align 64
+// CHECK: [[TMP58:%.*]] = bitcast <8 x i64> [[TMP57]] to <16 x i32>
+// CHECK: store <8 x i64> zeroinitializer, <8 x i64>* [[_COMPOUNDLITERAL_I_I15_I]], align 64
+// CHECK: [[TMP59:%.*]] = load <8 x i64>, <8 x i64>* [[_COMPOUNDLITERAL_I_I15_I]], align 64
+// CHECK: [[TMP60:%.*]] = bitcast <8 x i64> [[TMP59]] to <16 x i32>
+// CHECK: [[TMP61:%.*]] = icmp slt <16 x i32> [[TMP56]], [[TMP58]]
+// CHECK: [[TMP62:%.*]] = select <16 x i1> [[TMP61]], <16 x i32> [[TMP56]], <16 x i32> [[TMP58]]
+// CHECK: [[TMP63:%.*]] = bitcast <16 x i32> [[TMP62]] to <8 x i64>
+// CHECK: store <8 x i64> [[TMP63]], <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP64:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP65:%.*]] = bitcast <8 x i64> [[TMP64]] to <16 x i32>
+// CHECK: [[TMP66:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP67:%.*]] = bitcast <8 x i64> [[TMP66]] to <16 x i32>
+// CHECK: [[SHUFFLE6_I:%.*]] = shufflevector <16 x i32> [[TMP65]], <16 x i32> [[TMP67]], <16 x i32> <i32 0, i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP68:%.*]] = bitcast <16 x i32> [[SHUFFLE6_I]] to <8 x i64>
+// CHECK: [[TMP69:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP70:%.*]] = bitcast <8 x i64> [[TMP69]] to <16 x i32>
+// CHECK: [[TMP71:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP72:%.*]] = bitcast <8 x i64> [[TMP71]] to <16 x i32>
+// CHECK: [[SHUFFLE7_I:%.*]] = shufflevector <16 x i32> [[TMP70]], <16 x i32> [[TMP72]], <16 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP73:%.*]] = bitcast <16 x i32> [[SHUFFLE7_I]] to <8 x i64>
+// CHECK: store <8 x i64> [[TMP68]], <8 x i64>* [[__A_ADDR_I13_I]], align 64
+// CHECK: store <8 x i64> [[TMP73]], <8 x i64>* [[__B_ADDR_I14_I]], align 64
+// CHECK: [[TMP74:%.*]] = load <8 x i64>, <8 x i64>* [[__A_ADDR_I13_I]], align 64
+// CHECK: [[TMP75:%.*]] = bitcast <8 x i64> [[TMP74]] to <16 x i32>
+// CHECK: [[TMP76:%.*]] = load <8 x i64>, <8 x i64>* [[__B_ADDR_I14_I]], align 64
+// CHECK: [[TMP77:%.*]] = bitcast <8 x i64> [[TMP76]] to <16 x i32>
+// CHECK: store <8 x i64> zeroinitializer, <8 x i64>* [[_COMPOUNDLITERAL_I_I12_I]], align 64
+// CHECK: [[TMP78:%.*]] = load <8 x i64>, <8 x i64>* [[_COMPOUNDLITERAL_I_I12_I]], align 64
+// CHECK: [[TMP79:%.*]] = bitcast <8 x i64> [[TMP78]] to <16 x i32>
+// CHECK: [[TMP80:%.*]] = icmp slt <16 x i32> [[TMP75]], [[TMP77]]
+// CHECK: [[TMP81:%.*]] = select <16 x i1> [[TMP80]], <16 x i32> [[TMP75]], <16 x i32> [[TMP77]]
+// CHECK: [[TMP82:%.*]] = bitcast <16 x i32> [[TMP81]] to <8 x i64>
+// CHECK: store <8 x i64> [[TMP82]], <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP83:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP84:%.*]] = bitcast <8 x i64> [[TMP83]] to <16 x i32>
+// CHECK: [[TMP85:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP86:%.*]] = bitcast <8 x i64> [[TMP85]] to <16 x i32>
+// CHECK: [[SHUFFLE9_I:%.*]] = shufflevector <16 x i32> [[TMP84]], <16 x i32> [[TMP86]], <16 x i32> <i32 0, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP87:%.*]] = bitcast <16 x i32> [[SHUFFLE9_I]] to <8 x i64>
+// CHECK: [[TMP88:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP89:%.*]] = bitcast <8 x i64> [[TMP88]] to <16 x i32>
+// CHECK: [[TMP90:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP91:%.*]] = bitcast <8 x i64> [[TMP90]] to <16 x i32>
+// CHECK: [[SHUFFLE10_I:%.*]] = shufflevector <16 x i32> [[TMP89]], <16 x i32> [[TMP91]], <16 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP92:%.*]] = bitcast <16 x i32> [[SHUFFLE10_I]] to <8 x i64>
+// CHECK: store <8 x i64> [[TMP87]], <8 x i64>* [[__A_ADDR_I_I]], align 64
+// CHECK: store <8 x i64> [[TMP92]], <8 x i64>* [[__B_ADDR_I_I]], align 64
+// CHECK: [[TMP93:%.*]] = load <8 x i64>, <8 x i64>* [[__A_ADDR_I_I]], align 64
+// CHECK: [[TMP94:%.*]] = bitcast <8 x i64> [[TMP93]] to <16 x i32>
+// CHECK: [[TMP95:%.*]] = load <8 x i64>, <8 x i64>* [[__B_ADDR_I_I]], align 64
+// CHECK: [[TMP96:%.*]] = bitcast <8 x i64> [[TMP95]] to <16 x i32>
+// CHECK: store <8 x i64> zeroinitializer, <8 x i64>* [[_COMPOUNDLITERAL_I_I_I]], align 64
+// CHECK: [[TMP97:%.*]] = load <8 x i64>, <8 x i64>* [[_COMPOUNDLITERAL_I_I_I]], align 64
+// CHECK: [[TMP98:%.*]] = bitcast <8 x i64> [[TMP97]] to <16 x i32>
+// CHECK: [[TMP99:%.*]] = icmp slt <16 x i32> [[TMP94]], [[TMP96]]
+// CHECK: [[TMP100:%.*]] = select <16 x i1> [[TMP99]], <16 x i32> [[TMP94]], <16 x i32> [[TMP96]]
+// CHECK: [[TMP101:%.*]] = bitcast <16 x i32> [[TMP100]] to <8 x i64>
+// CHECK: store <8 x i64> [[TMP101]], <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP102:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[VECEXT_I:%.*]] = extractelement <8 x i64> [[TMP102]], i32 0
+// CHECK: [[CONV_I:%.*]] = trunc i64 [[VECEXT_I]] to i32
+// CHECK: ret i32 [[CONV_I]]
int test_mm512_mask_reduce_min_epi32(__mmask16 __M, __m512i __W){
- // CHECK: %tmp = bitcast <8 x i64> %__W to <16 x i32>
- // CHECK: %tmp1 = bitcast i16 %__M to <16 x i1>
- // CHECK: %tmp2 = select <16 x i1> %tmp1, <16 x i32> %tmp, <16 x i32> <i32 2147483647, i32 2147483647, i32 2147483647, i32 2147483647, i32 2147483647, i32 2147483647, i32 2147483647, i32 2147483647, i32 2147483647, i32 2147483647, i32 2147483647, i32 2147483647, i32 2147483647, i32 2147483647, i32 2147483647, i32 2147483647>
- // CHECK: %shuffle1.i = shufflevector <16 x i32> %tmp2, <16 x i32> undef, <16 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp3 = icmp slt <16 x i32> %tmp2, %shuffle1.i
- // CHECK: %tmp4 = select <16 x i1> %tmp3, <16 x i32> %tmp2, <16 x i32> %shuffle1.i
- // CHECK: %shuffle4.i = shufflevector <16 x i32> %tmp4, <16 x i32> undef, <16 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp5 = icmp slt <16 x i32> %tmp4, %shuffle4.i
- // CHECK: %tmp6 = select <16 x i1> %tmp5, <16 x i32> %tmp4, <16 x i32> %shuffle4.i
- // CHECK: %shuffle7.i = shufflevector <16 x i32> %tmp6, <16 x i32> undef, <16 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp7 = icmp slt <16 x i32> %tmp6, %shuffle7.i
- // CHECK: %tmp8 = select <16 x i1> %tmp7, <16 x i32> %tmp6, <16 x i32> %shuffle7.i
- // CHECK: %shuffle10.i = shufflevector <16 x i32> %tmp8, <16 x i32> undef, <16 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp9 = icmp slt <16 x i32> %tmp8, %shuffle10.i
- // CHECK: %tmp10 = select <16 x i1> %tmp9, <16 x i32> %tmp8, <16 x i32> %shuffle10.i
- // CHECK: %tmp11 = bitcast <16 x i32> %tmp10 to <8 x i64>
- // CHECK: %vecext.i = extractelement <8 x i64> %tmp11, i32 0
- // CHECK: %conv.i = trunc i64 %vecext.i to i32
- // CHECK: ret i32 %conv.i
return _mm512_mask_reduce_min_epi32(__M, __W);
}
+// CHECK-LABEL: define i32 @test_mm512_mask_reduce_min_epu32(i16 zeroext %__M, <8 x i64> %__W) #0 {
+// CHECK: [[_COMPOUNDLITERAL_I_I18_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__A_ADDR_I19_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__B_ADDR_I20_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[_COMPOUNDLITERAL_I_I15_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__A_ADDR_I16_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__B_ADDR_I17_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[_COMPOUNDLITERAL_I_I12_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__A_ADDR_I13_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__B_ADDR_I14_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[_COMPOUNDLITERAL_I_I_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__A_ADDR_I_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__B_ADDR_I_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__S_ADDR_I_I:%.*]] = alloca i32, align 4
+// CHECK: [[_COMPOUNDLITERAL_I_I:%.*]] = alloca <16 x i32>, align 64
+// CHECK: [[__M_ADDR_I:%.*]] = alloca i16, align 2
+// CHECK: [[__V_ADDR_I:%.*]] = alloca <8 x i64>, align 64
+// CHECK: [[__M_ADDR:%.*]] = alloca i16, align 2
+// CHECK: [[__W_ADDR:%.*]] = alloca <8 x i64>, align 64
+// CHECK: store i16 %__M, i16* [[__M_ADDR]], align 2
+// CHECK: store <8 x i64> %__W, <8 x i64>* [[__W_ADDR]], align 64
+// CHECK: [[TMP0:%.*]] = load i16, i16* [[__M_ADDR]], align 2
+// CHECK: [[TMP1:%.*]] = load <8 x i64>, <8 x i64>* [[__W_ADDR]], align 64
+// CHECK: store i16 [[TMP0]], i16* [[__M_ADDR_I]], align 2
+// CHECK: store <8 x i64> [[TMP1]], <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP2:%.*]] = load i16, i16* [[__M_ADDR_I]], align 2
+// CHECK: [[TMP3:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP4:%.*]] = bitcast <8 x i64> [[TMP3]] to <16 x i32>
+// CHECK: store i32 -1, i32* [[__S_ADDR_I_I]], align 4
+// CHECK: [[TMP5:%.*]] = load i32, i32* [[__S_ADDR_I_I]], align 4
+// CHECK: [[VECINIT_I_I:%.*]] = insertelement <16 x i32> undef, i32 [[TMP5]], i32 0
+// CHECK: [[TMP6:%.*]] = load i32, i32* [[__S_ADDR_I_I]], align 4
+// CHECK: [[VECINIT1_I_I:%.*]] = insertelement <16 x i32> [[VECINIT_I_I]], i32 [[TMP6]], i32 1
+// CHECK: [[TMP7:%.*]] = load i32, i32* [[__S_ADDR_I_I]], align 4
+// CHECK: [[VECINIT2_I_I:%.*]] = insertelement <16 x i32> [[VECINIT1_I_I]], i32 [[TMP7]], i32 2
+// CHECK: [[TMP8:%.*]] = load i32, i32* [[__S_ADDR_I_I]], align 4
+// CHECK: [[VECINIT3_I_I:%.*]] = insertelement <16 x i32> [[VECINIT2_I_I]], i32 [[TMP8]], i32 3
+// CHECK: [[TMP9:%.*]] = load i32, i32* [[__S_ADDR_I_I]], align 4
+// CHECK: [[VECINIT4_I_I:%.*]] = insertelement <16 x i32> [[VECINIT3_I_I]], i32 [[TMP9]], i32 4
+// CHECK: [[TMP10:%.*]] = load i32, i32* [[__S_ADDR_I_I]], align 4
+// CHECK: [[VECINIT5_I_I:%.*]] = insertelement <16 x i32> [[VECINIT4_I_I]], i32 [[TMP10]], i32 5
+// CHECK: [[TMP11:%.*]] = load i32, i32* [[__S_ADDR_I_I]], align 4
+// CHECK: [[VECINIT6_I_I:%.*]] = insertelement <16 x i32> [[VECINIT5_I_I]], i32 [[TMP11]], i32 6
+// CHECK: [[TMP12:%.*]] = load i32, i32* [[__S_ADDR_I_I]], align 4
+// CHECK: [[VECINIT7_I_I:%.*]] = insertelement <16 x i32> [[VECINIT6_I_I]], i32 [[TMP12]], i32 7
+// CHECK: [[TMP13:%.*]] = load i32, i32* [[__S_ADDR_I_I]], align 4
+// CHECK: [[VECINIT8_I_I:%.*]] = insertelement <16 x i32> [[VECINIT7_I_I]], i32 [[TMP13]], i32 8
+// CHECK: [[TMP14:%.*]] = load i32, i32* [[__S_ADDR_I_I]], align 4
+// CHECK: [[VECINIT9_I_I:%.*]] = insertelement <16 x i32> [[VECINIT8_I_I]], i32 [[TMP14]], i32 9
+// CHECK: [[TMP15:%.*]] = load i32, i32* [[__S_ADDR_I_I]], align 4
+// CHECK: [[VECINIT10_I_I:%.*]] = insertelement <16 x i32> [[VECINIT9_I_I]], i32 [[TMP15]], i32 10
+// CHECK: [[TMP16:%.*]] = load i32, i32* [[__S_ADDR_I_I]], align 4
+// CHECK: [[VECINIT11_I_I:%.*]] = insertelement <16 x i32> [[VECINIT10_I_I]], i32 [[TMP16]], i32 11
+// CHECK: [[TMP17:%.*]] = load i32, i32* [[__S_ADDR_I_I]], align 4
+// CHECK: [[VECINIT12_I_I:%.*]] = insertelement <16 x i32> [[VECINIT11_I_I]], i32 [[TMP17]], i32 12
+// CHECK: [[TMP18:%.*]] = load i32, i32* [[__S_ADDR_I_I]], align 4
+// CHECK: [[VECINIT13_I_I:%.*]] = insertelement <16 x i32> [[VECINIT12_I_I]], i32 [[TMP18]], i32 13
+// CHECK: [[TMP19:%.*]] = load i32, i32* [[__S_ADDR_I_I]], align 4
+// CHECK: [[VECINIT14_I_I:%.*]] = insertelement <16 x i32> [[VECINIT13_I_I]], i32 [[TMP19]], i32 14
+// CHECK: [[TMP20:%.*]] = load i32, i32* [[__S_ADDR_I_I]], align 4
+// CHECK: [[VECINIT15_I_I:%.*]] = insertelement <16 x i32> [[VECINIT14_I_I]], i32 [[TMP20]], i32 15
+// CHECK: store <16 x i32> [[VECINIT15_I_I]], <16 x i32>* [[_COMPOUNDLITERAL_I_I]], align 64
+// CHECK: [[TMP21:%.*]] = load <16 x i32>, <16 x i32>* [[_COMPOUNDLITERAL_I_I]], align 64
+// CHECK: [[TMP22:%.*]] = bitcast <16 x i32> [[TMP21]] to <8 x i64>
+// CHECK: [[TMP23:%.*]] = bitcast i16 [[TMP2]] to <16 x i1>
+// CHECK: [[TMP24:%.*]] = select <16 x i1> [[TMP23]], <16 x i32> [[TMP4]], <16 x i32> [[TMP21]]
+// CHECK: [[TMP25:%.*]] = bitcast <16 x i32> [[TMP24]] to <8 x i64>
+// CHECK: store <8 x i64> [[TMP25]], <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP26:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP27:%.*]] = bitcast <8 x i64> [[TMP26]] to <16 x i32>
+// CHECK: [[TMP28:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP29:%.*]] = bitcast <8 x i64> [[TMP28]] to <16 x i32>
+// CHECK: [[SHUFFLE_I:%.*]] = shufflevector <16 x i32> [[TMP27]], <16 x i32> [[TMP29]], <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP30:%.*]] = bitcast <16 x i32> [[SHUFFLE_I]] to <8 x i64>
+// CHECK: [[TMP31:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP32:%.*]] = bitcast <8 x i64> [[TMP31]] to <16 x i32>
+// CHECK: [[TMP33:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP34:%.*]] = bitcast <8 x i64> [[TMP33]] to <16 x i32>
+// CHECK: [[SHUFFLE1_I:%.*]] = shufflevector <16 x i32> [[TMP32]], <16 x i32> [[TMP34]], <16 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP35:%.*]] = bitcast <16 x i32> [[SHUFFLE1_I]] to <8 x i64>
+// CHECK: store <8 x i64> [[TMP30]], <8 x i64>* [[__A_ADDR_I19_I]], align 64
+// CHECK: store <8 x i64> [[TMP35]], <8 x i64>* [[__B_ADDR_I20_I]], align 64
+// CHECK: [[TMP36:%.*]] = load <8 x i64>, <8 x i64>* [[__A_ADDR_I19_I]], align 64
+// CHECK: [[TMP37:%.*]] = bitcast <8 x i64> [[TMP36]] to <16 x i32>
+// CHECK: [[TMP38:%.*]] = load <8 x i64>, <8 x i64>* [[__B_ADDR_I20_I]], align 64
+// CHECK: [[TMP39:%.*]] = bitcast <8 x i64> [[TMP38]] to <16 x i32>
+// CHECK: store <8 x i64> zeroinitializer, <8 x i64>* [[_COMPOUNDLITERAL_I_I18_I]], align 64
+// CHECK: [[TMP40:%.*]] = load <8 x i64>, <8 x i64>* [[_COMPOUNDLITERAL_I_I18_I]], align 64
+// CHECK: [[TMP41:%.*]] = bitcast <8 x i64> [[TMP40]] to <16 x i32>
+// CHECK: [[TMP42:%.*]] = icmp ult <16 x i32> [[TMP37]], [[TMP39]]
+// CHECK: [[TMP43:%.*]] = select <16 x i1> [[TMP42]], <16 x i32> [[TMP37]], <16 x i32> [[TMP39]]
+// CHECK: [[TMP44:%.*]] = bitcast <16 x i32> [[TMP43]] to <8 x i64>
+// CHECK: store <8 x i64> [[TMP44]], <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP45:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP46:%.*]] = bitcast <8 x i64> [[TMP45]] to <16 x i32>
+// CHECK: [[TMP47:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP48:%.*]] = bitcast <8 x i64> [[TMP47]] to <16 x i32>
+// CHECK: [[SHUFFLE3_I:%.*]] = shufflevector <16 x i32> [[TMP46]], <16 x i32> [[TMP48]], <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP49:%.*]] = bitcast <16 x i32> [[SHUFFLE3_I]] to <8 x i64>
+// CHECK: [[TMP50:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP51:%.*]] = bitcast <8 x i64> [[TMP50]] to <16 x i32>
+// CHECK: [[TMP52:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP53:%.*]] = bitcast <8 x i64> [[TMP52]] to <16 x i32>
+// CHECK: [[SHUFFLE4_I:%.*]] = shufflevector <16 x i32> [[TMP51]], <16 x i32> [[TMP53]], <16 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP54:%.*]] = bitcast <16 x i32> [[SHUFFLE4_I]] to <8 x i64>
+// CHECK: store <8 x i64> [[TMP49]], <8 x i64>* [[__A_ADDR_I16_I]], align 64
+// CHECK: store <8 x i64> [[TMP54]], <8 x i64>* [[__B_ADDR_I17_I]], align 64
+// CHECK: [[TMP55:%.*]] = load <8 x i64>, <8 x i64>* [[__A_ADDR_I16_I]], align 64
+// CHECK: [[TMP56:%.*]] = bitcast <8 x i64> [[TMP55]] to <16 x i32>
+// CHECK: [[TMP57:%.*]] = load <8 x i64>, <8 x i64>* [[__B_ADDR_I17_I]], align 64
+// CHECK: [[TMP58:%.*]] = bitcast <8 x i64> [[TMP57]] to <16 x i32>
+// CHECK: store <8 x i64> zeroinitializer, <8 x i64>* [[_COMPOUNDLITERAL_I_I15_I]], align 64
+// CHECK: [[TMP59:%.*]] = load <8 x i64>, <8 x i64>* [[_COMPOUNDLITERAL_I_I15_I]], align 64
+// CHECK: [[TMP60:%.*]] = bitcast <8 x i64> [[TMP59]] to <16 x i32>
+// CHECK: [[TMP61:%.*]] = icmp ult <16 x i32> [[TMP56]], [[TMP58]]
+// CHECK: [[TMP62:%.*]] = select <16 x i1> [[TMP61]], <16 x i32> [[TMP56]], <16 x i32> [[TMP58]]
+// CHECK: [[TMP63:%.*]] = bitcast <16 x i32> [[TMP62]] to <8 x i64>
+// CHECK: store <8 x i64> [[TMP63]], <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP64:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP65:%.*]] = bitcast <8 x i64> [[TMP64]] to <16 x i32>
+// CHECK: [[TMP66:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP67:%.*]] = bitcast <8 x i64> [[TMP66]] to <16 x i32>
+// CHECK: [[SHUFFLE6_I:%.*]] = shufflevector <16 x i32> [[TMP65]], <16 x i32> [[TMP67]], <16 x i32> <i32 0, i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP68:%.*]] = bitcast <16 x i32> [[SHUFFLE6_I]] to <8 x i64>
+// CHECK: [[TMP69:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP70:%.*]] = bitcast <8 x i64> [[TMP69]] to <16 x i32>
+// CHECK: [[TMP71:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP72:%.*]] = bitcast <8 x i64> [[TMP71]] to <16 x i32>
+// CHECK: [[SHUFFLE7_I:%.*]] = shufflevector <16 x i32> [[TMP70]], <16 x i32> [[TMP72]], <16 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP73:%.*]] = bitcast <16 x i32> [[SHUFFLE7_I]] to <8 x i64>
+// CHECK: store <8 x i64> [[TMP68]], <8 x i64>* [[__A_ADDR_I13_I]], align 64
+// CHECK: store <8 x i64> [[TMP73]], <8 x i64>* [[__B_ADDR_I14_I]], align 64
+// CHECK: [[TMP74:%.*]] = load <8 x i64>, <8 x i64>* [[__A_ADDR_I13_I]], align 64
+// CHECK: [[TMP75:%.*]] = bitcast <8 x i64> [[TMP74]] to <16 x i32>
+// CHECK: [[TMP76:%.*]] = load <8 x i64>, <8 x i64>* [[__B_ADDR_I14_I]], align 64
+// CHECK: [[TMP77:%.*]] = bitcast <8 x i64> [[TMP76]] to <16 x i32>
+// CHECK: store <8 x i64> zeroinitializer, <8 x i64>* [[_COMPOUNDLITERAL_I_I12_I]], align 64
+// CHECK: [[TMP78:%.*]] = load <8 x i64>, <8 x i64>* [[_COMPOUNDLITERAL_I_I12_I]], align 64
+// CHECK: [[TMP79:%.*]] = bitcast <8 x i64> [[TMP78]] to <16 x i32>
+// CHECK: [[TMP80:%.*]] = icmp ult <16 x i32> [[TMP75]], [[TMP77]]
+// CHECK: [[TMP81:%.*]] = select <16 x i1> [[TMP80]], <16 x i32> [[TMP75]], <16 x i32> [[TMP77]]
+// CHECK: [[TMP82:%.*]] = bitcast <16 x i32> [[TMP81]] to <8 x i64>
+// CHECK: store <8 x i64> [[TMP82]], <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP83:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP84:%.*]] = bitcast <8 x i64> [[TMP83]] to <16 x i32>
+// CHECK: [[TMP85:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP86:%.*]] = bitcast <8 x i64> [[TMP85]] to <16 x i32>
+// CHECK: [[SHUFFLE9_I:%.*]] = shufflevector <16 x i32> [[TMP84]], <16 x i32> [[TMP86]], <16 x i32> <i32 0, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP87:%.*]] = bitcast <16 x i32> [[SHUFFLE9_I]] to <8 x i64>
+// CHECK: [[TMP88:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP89:%.*]] = bitcast <8 x i64> [[TMP88]] to <16 x i32>
+// CHECK: [[TMP90:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP91:%.*]] = bitcast <8 x i64> [[TMP90]] to <16 x i32>
+// CHECK: [[SHUFFLE10_I:%.*]] = shufflevector <16 x i32> [[TMP89]], <16 x i32> [[TMP91]], <16 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP92:%.*]] = bitcast <16 x i32> [[SHUFFLE10_I]] to <8 x i64>
+// CHECK: store <8 x i64> [[TMP87]], <8 x i64>* [[__A_ADDR_I_I]], align 64
+// CHECK: store <8 x i64> [[TMP92]], <8 x i64>* [[__B_ADDR_I_I]], align 64
+// CHECK: [[TMP93:%.*]] = load <8 x i64>, <8 x i64>* [[__A_ADDR_I_I]], align 64
+// CHECK: [[TMP94:%.*]] = bitcast <8 x i64> [[TMP93]] to <16 x i32>
+// CHECK: [[TMP95:%.*]] = load <8 x i64>, <8 x i64>* [[__B_ADDR_I_I]], align 64
+// CHECK: [[TMP96:%.*]] = bitcast <8 x i64> [[TMP95]] to <16 x i32>
+// CHECK: store <8 x i64> zeroinitializer, <8 x i64>* [[_COMPOUNDLITERAL_I_I_I]], align 64
+// CHECK: [[TMP97:%.*]] = load <8 x i64>, <8 x i64>* [[_COMPOUNDLITERAL_I_I_I]], align 64
+// CHECK: [[TMP98:%.*]] = bitcast <8 x i64> [[TMP97]] to <16 x i32>
+// CHECK: [[TMP99:%.*]] = icmp ult <16 x i32> [[TMP94]], [[TMP96]]
+// CHECK: [[TMP100:%.*]] = select <16 x i1> [[TMP99]], <16 x i32> [[TMP94]], <16 x i32> [[TMP96]]
+// CHECK: [[TMP101:%.*]] = bitcast <16 x i32> [[TMP100]] to <8 x i64>
+// CHECK: store <8 x i64> [[TMP101]], <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP102:%.*]] = load <8 x i64>, <8 x i64>* [[__V_ADDR_I]], align 64
+// CHECK: [[VECEXT_I:%.*]] = extractelement <8 x i64> [[TMP102]], i32 0
+// CHECK: [[CONV_I:%.*]] = trunc i64 [[VECEXT_I]] to i32
+// CHECK: ret i32 [[CONV_I]]
unsigned int test_mm512_mask_reduce_min_epu32(__mmask16 __M, __m512i __W){
- // CHECK: %tmp = bitcast <8 x i64> %__W to <16 x i32>
- // CHECK: %tmp1 = bitcast i16 %__M to <16 x i1>
- // CHECK: %tmp2 = select <16 x i1> %tmp1, <16 x i32> %tmp, <16 x i32> <i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1>
- // CHECK: %shuffle1.i = shufflevector <16 x i32> %tmp2, <16 x i32> undef, <16 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp3 = icmp ult <16 x i32> %tmp2, %shuffle1.i
- // CHECK: %tmp4 = select <16 x i1> %tmp3, <16 x i32> %tmp2, <16 x i32> %shuffle1.i
- // CHECK: %shuffle4.i = shufflevector <16 x i32> %tmp4, <16 x i32> undef, <16 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp5 = icmp ult <16 x i32> %tmp4, %shuffle4.i
- // CHECK: %tmp6 = select <16 x i1> %tmp5, <16 x i32> %tmp4, <16 x i32> %shuffle4.i
- // CHECK: %shuffle7.i = shufflevector <16 x i32> %tmp6, <16 x i32> undef, <16 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp7 = icmp ult <16 x i32> %tmp6, %shuffle7.i
- // CHECK: %tmp8 = select <16 x i1> %tmp7, <16 x i32> %tmp6, <16 x i32> %shuffle7.i
- // CHECK: %shuffle10.i = shufflevector <16 x i32> %tmp8, <16 x i32> undef, <16 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp9 = icmp ult <16 x i32> %tmp8, %shuffle10.i
- // CHECK: %tmp10 = select <16 x i1> %tmp9, <16 x i32> %tmp8, <16 x i32> %shuffle10.i
- // CHECK: %tmp11 = bitcast <16 x i32> %tmp10 to <8 x i64>
- // CHECK: %vecext.i = extractelement <8 x i64> %tmp11, i32 0
- // CHECK: %conv.i = trunc i64 %vecext.i to i32
- // CHECK: ret i32 %conv.i
return _mm512_mask_reduce_min_epu32(__M, __W);
}
+// CHECK-LABEL: define float @test_mm512_mask_reduce_min_ps(i16 zeroext %__M, <16 x float> %__W) #0 {
+// CHECK: [[_COMPOUNDLITERAL_I_I18_I:%.*]] = alloca <16 x float>, align 64
+// CHECK: [[__A_ADDR_I19_I:%.*]] = alloca <16 x float>, align 64
+// CHECK: [[__B_ADDR_I20_I:%.*]] = alloca <16 x float>, align 64
+// CHECK: [[_COMPOUNDLITERAL_I_I15_I:%.*]] = alloca <16 x float>, align 64
+// CHECK: [[__A_ADDR_I16_I:%.*]] = alloca <16 x float>, align 64
+// CHECK: [[__B_ADDR_I17_I:%.*]] = alloca <16 x float>, align 64
+// CHECK: [[_COMPOUNDLITERAL_I_I12_I:%.*]] = alloca <16 x float>, align 64
+// CHECK: [[__A_ADDR_I13_I:%.*]] = alloca <16 x float>, align 64
+// CHECK: [[__B_ADDR_I14_I:%.*]] = alloca <16 x float>, align 64
+// CHECK: [[_COMPOUNDLITERAL_I_I_I:%.*]] = alloca <16 x float>, align 64
+// CHECK: [[__A_ADDR_I_I:%.*]] = alloca <16 x float>, align 64
+// CHECK: [[__B_ADDR_I_I:%.*]] = alloca <16 x float>, align 64
+// CHECK: [[__W_ADDR_I_I:%.*]] = alloca float, align 4
+// CHECK: [[_COMPOUNDLITERAL_I_I:%.*]] = alloca <16 x float>, align 64
+// CHECK: [[__M_ADDR_I:%.*]] = alloca i16, align 2
+// CHECK: [[__V_ADDR_I:%.*]] = alloca <16 x float>, align 64
+// CHECK: [[__M_ADDR:%.*]] = alloca i16, align 2
+// CHECK: [[__W_ADDR:%.*]] = alloca <16 x float>, align 64
+// CHECK: store i16 %__M, i16* [[__M_ADDR]], align 2
+// CHECK: store <16 x float> %__W, <16 x float>* [[__W_ADDR]], align 64
+// CHECK: [[TMP0:%.*]] = load i16, i16* [[__M_ADDR]], align 2
+// CHECK: [[TMP1:%.*]] = load <16 x float>, <16 x float>* [[__W_ADDR]], align 64
+// CHECK: store i16 [[TMP0]], i16* [[__M_ADDR_I]], align 2
+// CHECK: store <16 x float> [[TMP1]], <16 x float>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP2:%.*]] = load i16, i16* [[__M_ADDR_I]], align 2
+// CHECK: [[TMP3:%.*]] = load <16 x float>, <16 x float>* [[__V_ADDR_I]], align 64
+// CHECK: store float 0x7FF0000000000000, float* [[__W_ADDR_I_I]], align 4
+// CHECK: [[TMP4:%.*]] = load float, float* [[__W_ADDR_I_I]], align 4
+// CHECK: [[VECINIT_I_I:%.*]] = insertelement <16 x float> undef, float [[TMP4]], i32 0
+// CHECK: [[TMP5:%.*]] = load float, float* [[__W_ADDR_I_I]], align 4
+// CHECK: [[VECINIT1_I_I:%.*]] = insertelement <16 x float> [[VECINIT_I_I]], float [[TMP5]], i32 1
+// CHECK: [[TMP6:%.*]] = load float, float* [[__W_ADDR_I_I]], align 4
+// CHECK: [[VECINIT2_I_I:%.*]] = insertelement <16 x float> [[VECINIT1_I_I]], float [[TMP6]], i32 2
+// CHECK: [[TMP7:%.*]] = load float, float* [[__W_ADDR_I_I]], align 4
+// CHECK: [[VECINIT3_I_I:%.*]] = insertelement <16 x float> [[VECINIT2_I_I]], float [[TMP7]], i32 3
+// CHECK: [[TMP8:%.*]] = load float, float* [[__W_ADDR_I_I]], align 4
+// CHECK: [[VECINIT4_I_I:%.*]] = insertelement <16 x float> [[VECINIT3_I_I]], float [[TMP8]], i32 4
+// CHECK: [[TMP9:%.*]] = load float, float* [[__W_ADDR_I_I]], align 4
+// CHECK: [[VECINIT5_I_I:%.*]] = insertelement <16 x float> [[VECINIT4_I_I]], float [[TMP9]], i32 5
+// CHECK: [[TMP10:%.*]] = load float, float* [[__W_ADDR_I_I]], align 4
+// CHECK: [[VECINIT6_I_I:%.*]] = insertelement <16 x float> [[VECINIT5_I_I]], float [[TMP10]], i32 6
+// CHECK: [[TMP11:%.*]] = load float, float* [[__W_ADDR_I_I]], align 4
+// CHECK: [[VECINIT7_I_I:%.*]] = insertelement <16 x float> [[VECINIT6_I_I]], float [[TMP11]], i32 7
+// CHECK: [[TMP12:%.*]] = load float, float* [[__W_ADDR_I_I]], align 4
+// CHECK: [[VECINIT8_I_I:%.*]] = insertelement <16 x float> [[VECINIT7_I_I]], float [[TMP12]], i32 8
+// CHECK: [[TMP13:%.*]] = load float, float* [[__W_ADDR_I_I]], align 4
+// CHECK: [[VECINIT9_I_I:%.*]] = insertelement <16 x float> [[VECINIT8_I_I]], float [[TMP13]], i32 9
+// CHECK: [[TMP14:%.*]] = load float, float* [[__W_ADDR_I_I]], align 4
+// CHECK: [[VECINIT10_I_I:%.*]] = insertelement <16 x float> [[VECINIT9_I_I]], float [[TMP14]], i32 10
+// CHECK: [[TMP15:%.*]] = load float, float* [[__W_ADDR_I_I]], align 4
+// CHECK: [[VECINIT11_I_I:%.*]] = insertelement <16 x float> [[VECINIT10_I_I]], float [[TMP15]], i32 11
+// CHECK: [[TMP16:%.*]] = load float, float* [[__W_ADDR_I_I]], align 4
+// CHECK: [[VECINIT12_I_I:%.*]] = insertelement <16 x float> [[VECINIT11_I_I]], float [[TMP16]], i32 12
+// CHECK: [[TMP17:%.*]] = load float, float* [[__W_ADDR_I_I]], align 4
+// CHECK: [[VECINIT13_I_I:%.*]] = insertelement <16 x float> [[VECINIT12_I_I]], float [[TMP17]], i32 13
+// CHECK: [[TMP18:%.*]] = load float, float* [[__W_ADDR_I_I]], align 4
+// CHECK: [[VECINIT14_I_I:%.*]] = insertelement <16 x float> [[VECINIT13_I_I]], float [[TMP18]], i32 14
+// CHECK: [[TMP19:%.*]] = load float, float* [[__W_ADDR_I_I]], align 4
+// CHECK: [[VECINIT15_I_I:%.*]] = insertelement <16 x float> [[VECINIT14_I_I]], float [[TMP19]], i32 15
+// CHECK: store <16 x float> [[VECINIT15_I_I]], <16 x float>* [[_COMPOUNDLITERAL_I_I]], align 64
+// CHECK: [[TMP20:%.*]] = load <16 x float>, <16 x float>* [[_COMPOUNDLITERAL_I_I]], align 64
+// CHECK: [[TMP21:%.*]] = bitcast i16 [[TMP2]] to <16 x i1>
+// CHECK: [[TMP22:%.*]] = select <16 x i1> [[TMP21]], <16 x float> [[TMP3]], <16 x float> [[TMP20]]
+// CHECK: store <16 x float> [[TMP22]], <16 x float>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP23:%.*]] = load <16 x float>, <16 x float>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP24:%.*]] = load <16 x float>, <16 x float>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE_I:%.*]] = shufflevector <16 x float> [[TMP23]], <16 x float> [[TMP24]], <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP25:%.*]] = load <16 x float>, <16 x float>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP26:%.*]] = load <16 x float>, <16 x float>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE1_I:%.*]] = shufflevector <16 x float> [[TMP25]], <16 x float> [[TMP26]], <16 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: store <16 x float> [[SHUFFLE_I]], <16 x float>* [[__A_ADDR_I19_I]], align 64
+// CHECK: store <16 x float> [[SHUFFLE1_I]], <16 x float>* [[__B_ADDR_I20_I]], align 64
+// CHECK: [[TMP27:%.*]] = load <16 x float>, <16 x float>* [[__A_ADDR_I19_I]], align 64
+// CHECK: [[TMP28:%.*]] = load <16 x float>, <16 x float>* [[__B_ADDR_I20_I]], align 64
+// CHECK: store <16 x float> zeroinitializer, <16 x float>* [[_COMPOUNDLITERAL_I_I18_I]], align 64
+// CHECK: [[TMP29:%.*]] = load <16 x float>, <16 x float>* [[_COMPOUNDLITERAL_I_I18_I]], align 64
+// CHECK: [[TMP30:%.*]] = call <16 x float> @llvm.x86.avx512.mask.min.ps.512(<16 x float> [[TMP27]], <16 x float> [[TMP28]], <16 x float> [[TMP29]], i16 -1, i32 4) #2
+// CHECK: store <16 x float> [[TMP30]], <16 x float>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP31:%.*]] = load <16 x float>, <16 x float>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP32:%.*]] = load <16 x float>, <16 x float>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE3_I:%.*]] = shufflevector <16 x float> [[TMP31]], <16 x float> [[TMP32]], <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP33:%.*]] = load <16 x float>, <16 x float>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP34:%.*]] = load <16 x float>, <16 x float>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE4_I:%.*]] = shufflevector <16 x float> [[TMP33]], <16 x float> [[TMP34]], <16 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: store <16 x float> [[SHUFFLE3_I]], <16 x float>* [[__A_ADDR_I16_I]], align 64
+// CHECK: store <16 x float> [[SHUFFLE4_I]], <16 x float>* [[__B_ADDR_I17_I]], align 64
+// CHECK: [[TMP35:%.*]] = load <16 x float>, <16 x float>* [[__A_ADDR_I16_I]], align 64
+// CHECK: [[TMP36:%.*]] = load <16 x float>, <16 x float>* [[__B_ADDR_I17_I]], align 64
+// CHECK: store <16 x float> zeroinitializer, <16 x float>* [[_COMPOUNDLITERAL_I_I15_I]], align 64
+// CHECK: [[TMP37:%.*]] = load <16 x float>, <16 x float>* [[_COMPOUNDLITERAL_I_I15_I]], align 64
+// CHECK: [[TMP38:%.*]] = call <16 x float> @llvm.x86.avx512.mask.min.ps.512(<16 x float> [[TMP35]], <16 x float> [[TMP36]], <16 x float> [[TMP37]], i16 -1, i32 4) #2
+// CHECK: store <16 x float> [[TMP38]], <16 x float>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP39:%.*]] = load <16 x float>, <16 x float>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP40:%.*]] = load <16 x float>, <16 x float>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE6_I:%.*]] = shufflevector <16 x float> [[TMP39]], <16 x float> [[TMP40]], <16 x i32> <i32 0, i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP41:%.*]] = load <16 x float>, <16 x float>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP42:%.*]] = load <16 x float>, <16 x float>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE7_I:%.*]] = shufflevector <16 x float> [[TMP41]], <16 x float> [[TMP42]], <16 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: store <16 x float> [[SHUFFLE6_I]], <16 x float>* [[__A_ADDR_I13_I]], align 64
+// CHECK: store <16 x float> [[SHUFFLE7_I]], <16 x float>* [[__B_ADDR_I14_I]], align 64
+// CHECK: [[TMP43:%.*]] = load <16 x float>, <16 x float>* [[__A_ADDR_I13_I]], align 64
+// CHECK: [[TMP44:%.*]] = load <16 x float>, <16 x float>* [[__B_ADDR_I14_I]], align 64
+// CHECK: store <16 x float> zeroinitializer, <16 x float>* [[_COMPOUNDLITERAL_I_I12_I]], align 64
+// CHECK: [[TMP45:%.*]] = load <16 x float>, <16 x float>* [[_COMPOUNDLITERAL_I_I12_I]], align 64
+// CHECK: [[TMP46:%.*]] = call <16 x float> @llvm.x86.avx512.mask.min.ps.512(<16 x float> [[TMP43]], <16 x float> [[TMP44]], <16 x float> [[TMP45]], i16 -1, i32 4) #2
+// CHECK: store <16 x float> [[TMP46]], <16 x float>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP47:%.*]] = load <16 x float>, <16 x float>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP48:%.*]] = load <16 x float>, <16 x float>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE9_I:%.*]] = shufflevector <16 x float> [[TMP47]], <16 x float> [[TMP48]], <16 x i32> <i32 0, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: [[TMP49:%.*]] = load <16 x float>, <16 x float>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP50:%.*]] = load <16 x float>, <16 x float>* [[__V_ADDR_I]], align 64
+// CHECK: [[SHUFFLE10_I:%.*]] = shufflevector <16 x float> [[TMP49]], <16 x float> [[TMP50]], <16 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+// CHECK: store <16 x float> [[SHUFFLE9_I]], <16 x float>* [[__A_ADDR_I_I]], align 64
+// CHECK: store <16 x float> [[SHUFFLE10_I]], <16 x float>* [[__B_ADDR_I_I]], align 64
+// CHECK: [[TMP51:%.*]] = load <16 x float>, <16 x float>* [[__A_ADDR_I_I]], align 64
+// CHECK: [[TMP52:%.*]] = load <16 x float>, <16 x float>* [[__B_ADDR_I_I]], align 64
+// CHECK: store <16 x float> zeroinitializer, <16 x float>* [[_COMPOUNDLITERAL_I_I_I]], align 64
+// CHECK: [[TMP53:%.*]] = load <16 x float>, <16 x float>* [[_COMPOUNDLITERAL_I_I_I]], align 64
+// CHECK: [[TMP54:%.*]] = call <16 x float> @llvm.x86.avx512.mask.min.ps.512(<16 x float> [[TMP51]], <16 x float> [[TMP52]], <16 x float> [[TMP53]], i16 -1, i32 4) #2
+// CHECK: store <16 x float> [[TMP54]], <16 x float>* [[__V_ADDR_I]], align 64
+// CHECK: [[TMP55:%.*]] = load <16 x float>, <16 x float>* [[__V_ADDR_I]], align 64
+// CHECK: [[VECEXT_I:%.*]] = extractelement <16 x float> [[TMP55]], i32 0
+// CHECK: ret float [[VECEXT_I]]
float test_mm512_mask_reduce_min_ps(__mmask16 __M, __m512 __W){
- // CHECK: %tmp = bitcast i16 %__M to <16 x i1>
- // CHECK: %tmp1 = select <16 x i1> %tmp, <16 x float> %__W, <16 x float> <float 0x7FF0000000000000, float 0x7FF0000000000000, float 0x7FF0000000000000, float 0x7FF0000000000000, float 0x7FF0000000000000, float 0x7FF0000000000000, float 0x7FF0000000000000, float 0x7FF0000000000000, float 0x7FF0000000000000, float 0x7FF0000000000000, float 0x7FF0000000000000, float 0x7FF0000000000000, float 0x7FF0000000000000, float 0x7FF0000000000000, float 0x7FF0000000000000, float 0x7FF0000000000000>
- // CHECK: %shuffle1.i = shufflevector <16 x float> %tmp1, <16 x float> undef, <16 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp2 = tail call <16 x float> @llvm.x86.avx512.mask.min.ps.512(<16 x float> %tmp1, <16 x float> %shuffle1.i, <16 x float> zeroinitializer, i16 -1, i32 4) #3
- // CHECK: %shuffle4.i = shufflevector <16 x float> %tmp2, <16 x float> undef, <16 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp3 = tail call <16 x float> @llvm.x86.avx512.mask.min.ps.512(<16 x float> %tmp2, <16 x float> %shuffle4.i, <16 x float> zeroinitializer, i16 -1, i32 4) #3
- // CHECK: %shuffle7.i = shufflevector <16 x float> %tmp3, <16 x float> undef, <16 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp4 = tail call <16 x float> @llvm.x86.avx512.mask.min.ps.512(<16 x float> %tmp3, <16 x float> %shuffle7.i, <16 x float> zeroinitializer, i16 -1, i32 4) #3
- // CHECK: %shuffle10.i = shufflevector <16 x float> %tmp4, <16 x float> undef, <16 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // CHECK: %tmp5 = tail call <16 x float> @llvm.x86.avx512.mask.min.ps.512(<16 x float> %tmp4, <16 x float> %shuffle10.i, <16 x float> zeroinitializer, i16 -1, i32 4) #3
- // CHECK: %vecext.i = extractelement <16 x float> %tmp5, i32 0
- // CHECK: ret float %vecext.i
return _mm512_mask_reduce_min_ps(__M, __W);
}
diff --git a/test/CodeGen/avx512bw-builtins.c b/test/CodeGen/avx512bw-builtins.c
index 60d2423e9c34..3160a6667c00 100644
--- a/test/CodeGen/avx512bw-builtins.c
+++ b/test/CodeGen/avx512bw-builtins.c
@@ -480,32 +480,48 @@ __m512i test_mm512_mask_blend_epi16(__mmask32 __U, __m512i __A, __m512i __W) {
}
__m512i test_mm512_abs_epi8(__m512i __A) {
// CHECK-LABEL: @test_mm512_abs_epi8
- // CHECK: @llvm.x86.avx512.mask.pabs.b.512
+ // CHECK: [[SUB:%.*]] = sub <64 x i8> zeroinitializer, [[A:%.*]]
+ // CHECK: [[CMP:%.*]] = icmp sgt <64 x i8> [[A]], zeroinitializer
+ // CHECK: select <64 x i1> [[CMP]], <64 x i8> [[A]], <64 x i8> [[SUB]]
return _mm512_abs_epi8(__A);
}
__m512i test_mm512_mask_abs_epi8(__m512i __W, __mmask64 __U, __m512i __A) {
// CHECK-LABEL: @test_mm512_mask_abs_epi8
- // CHECK: @llvm.x86.avx512.mask.pabs.b.512
+ // CHECK: [[SUB:%.*]] = sub <64 x i8> zeroinitializer, [[A:%.*]]
+ // CHECK: [[CMP:%.*]] = icmp sgt <64 x i8> [[A]], zeroinitializer
+ // CHECK: [[SEL:%.*]] = select <64 x i1> [[CMP]], <64 x i8> [[A]], <64 x i8> [[SUB]]
+ // CHECK: select <64 x i1> %{{.*}}, <64 x i8> [[SEL]], <64 x i8> %{{.*}}
return _mm512_mask_abs_epi8(__W,__U,__A);
}
__m512i test_mm512_maskz_abs_epi8(__mmask64 __U, __m512i __A) {
// CHECK-LABEL: @test_mm512_maskz_abs_epi8
- // CHECK: @llvm.x86.avx512.mask.pabs.b.512
+ // CHECK: [[SUB:%.*]] = sub <64 x i8> zeroinitializer, [[A:%.*]]
+ // CHECK: [[CMP:%.*]] = icmp sgt <64 x i8> [[A]], zeroinitializer
+ // CHECK: [[SEL:%.*]] = select <64 x i1> [[CMP]], <64 x i8> [[A]], <64 x i8> [[SUB]]
+ // CHECK: select <64 x i1> %{{.*}}, <64 x i8> [[SEL]], <64 x i8> %{{.*}}
return _mm512_maskz_abs_epi8(__U,__A);
}
__m512i test_mm512_abs_epi16(__m512i __A) {
// CHECK-LABEL: @test_mm512_abs_epi16
- // CHECK: @llvm.x86.avx512.mask.pabs.w.512
+ // CHECK: [[SUB:%.*]] = sub <32 x i16> zeroinitializer, [[A:%.*]]
+ // CHECK: [[CMP:%.*]] = icmp sgt <32 x i16> [[A]], zeroinitializer
+ // CHECK: select <32 x i1> [[CMP]], <32 x i16> [[A]], <32 x i16> [[SUB]]
return _mm512_abs_epi16(__A);
}
__m512i test_mm512_mask_abs_epi16(__m512i __W, __mmask32 __U, __m512i __A) {
// CHECK-LABEL: @test_mm512_mask_abs_epi16
- // CHECK: @llvm.x86.avx512.mask.pabs.w.512
+ // CHECK: [[SUB:%.*]] = sub <32 x i16> zeroinitializer, [[A:%.*]]
+ // CHECK: [[CMP:%.*]] = icmp sgt <32 x i16> [[A]], zeroinitializer
+ // CHECK: [[SEL:%.*]] = select <32 x i1> [[CMP]], <32 x i16> [[A]], <32 x i16> [[SUB]]
+ // CHECK: select <32 x i1> %{{.*}}, <32 x i16> [[SEL]], <32 x i16> %{{.*}}
return _mm512_mask_abs_epi16(__W,__U,__A);
}
__m512i test_mm512_maskz_abs_epi16(__mmask32 __U, __m512i __A) {
// CHECK-LABEL: @test_mm512_maskz_abs_epi16
- // CHECK: @llvm.x86.avx512.mask.pabs.w.512
+ // CHECK: [[SUB:%.*]] = sub <32 x i16> zeroinitializer, [[A:%.*]]
+ // CHECK: [[CMP:%.*]] = icmp sgt <32 x i16> [[A]], zeroinitializer
+ // CHECK: [[SEL:%.*]] = select <32 x i1> [[CMP]], <32 x i16> [[A]], <32 x i16> [[SUB]]
+ // CHECK: select <32 x i1> %{{.*}}, <32 x i16> [[SEL]], <32 x i16> %{{.*}}
return _mm512_maskz_abs_epi16(__U,__A);
}
__m512i test_mm512_packs_epi32(__m512i __A, __m512i __B) {
@@ -638,32 +654,74 @@ __m512i test_mm512_maskz_adds_epu16(__mmask32 __U, __m512i __A, __m512i __B) {
}
__m512i test_mm512_avg_epu8(__m512i __A, __m512i __B) {
// CHECK-LABEL: @test_mm512_avg_epu8
- // CHECK: @llvm.x86.avx512.mask.pavg.b.512
+ // CHECK-NOT: @llvm.x86.avx512.mask.pavg.b.512
+ // CHECK: zext <64 x i8> %{{.*}} to <64 x i16>
+ // CHECK: zext <64 x i8> %{{.*}} to <64 x i16>
+ // CHECK: add <64 x i16> %{{.*}}, %{{.*}}
+ // CHECK: add <64 x i16> %{{.*}}, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
+ // CHECK: lshr <64 x i16> %{{.*}}, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
+ // CHECK: trunc <64 x i16> %{{.*}} to <64 x i8>
return _mm512_avg_epu8(__A,__B);
}
__m512i test_mm512_mask_avg_epu8(__m512i __W, __mmask64 __U, __m512i __A, __m512i __B) {
// CHECK-LABEL: @test_mm512_mask_avg_epu8
- // CHECK: @llvm.x86.avx512.mask.pavg.b.512
+ // CHECK-NOT: @llvm.x86.avx512.mask.pavg.b.512
+ // CHECK: zext <64 x i8> %{{.*}} to <64 x i16>
+ // CHECK: zext <64 x i8> %{{.*}} to <64 x i16>
+ // CHECK: add <64 x i16> %{{.*}}, %{{.*}}
+ // CHECK: add <64 x i16> %{{.*}}, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
+ // CHECK: lshr <64 x i16> %{{.*}}, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
+ // CHECK: trunc <64 x i16> %{{.*}} to <64 x i8>
+ // CHECK: select <64 x i1> %{{.*}}, <64 x i8> %{{.*}}, <64 x i8> %{{.*}}
return _mm512_mask_avg_epu8(__W,__U,__A,__B);
}
__m512i test_mm512_maskz_avg_epu8(__mmask64 __U, __m512i __A, __m512i __B) {
// CHECK-LABEL: @test_mm512_maskz_avg_epu8
- // CHECK: @llvm.x86.avx512.mask.pavg.b.512
+ // CHECK-NOT: @llvm.x86.avx512.mask.pavg.b.512
+ // CHECK: zext <64 x i8> %{{.*}} to <64 x i16>
+ // CHECK: zext <64 x i8> %{{.*}} to <64 x i16>
+ // CHECK: add <64 x i16> %{{.*}}, %{{.*}}
+ // CHECK: add <64 x i16> %{{.*}}, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
+ // CHECK: lshr <64 x i16> %{{.*}}, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
+ // CHECK: trunc <64 x i16> %{{.*}} to <64 x i8>
+ // CHECK: store <64 x i8> zeroinitializer
+ // CHECK: select <64 x i1> %{{.*}}, <64 x i8> %{{.*}}, <64 x i8> %{{.*}}
return _mm512_maskz_avg_epu8(__U,__A,__B);
}
__m512i test_mm512_avg_epu16(__m512i __A, __m512i __B) {
// CHECK-LABEL: @test_mm512_avg_epu16
- // CHECK: @llvm.x86.avx512.mask.pavg.w.512
+ // CHECK-NOT: @llvm.x86.avx512.mask.pavg.w.512
+ // CHECK: zext <32 x i16> %{{.*}} to <32 x i32>
+ // CHECK: zext <32 x i16> %{{.*}} to <32 x i32>
+ // CHECK: add <32 x i32> %{{.*}}, %{{.*}}
+ // CHECK: add <32 x i32> %{{.*}}, <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1>
+ // CHECK: lshr <32 x i32> %{{.*}}, <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1>
+ // CHECK: trunc <32 x i32> %{{.*}} to <32 x i16>
return _mm512_avg_epu16(__A,__B);
}
__m512i test_mm512_mask_avg_epu16(__m512i __W, __mmask32 __U, __m512i __A, __m512i __B) {
// CHECK-LABEL: @test_mm512_mask_avg_epu16
- // CHECK: @llvm.x86.avx512.mask.pavg.w.512
+ // CHECK-NOT: @llvm.x86.avx512.mask.pavg.w.512
+ // CHECK: zext <32 x i16> %{{.*}} to <32 x i32>
+ // CHECK: zext <32 x i16> %{{.*}} to <32 x i32>
+ // CHECK: add <32 x i32> %{{.*}}, %{{.*}}
+ // CHECK: add <32 x i32> %{{.*}}, <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1>
+ // CHECK: lshr <32 x i32> %{{.*}}, <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1>
+ // CHECK: trunc <32 x i32> %{{.*}} to <32 x i16>
+ // CHECK: select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}}
return _mm512_mask_avg_epu16(__W,__U,__A,__B);
}
__m512i test_mm512_maskz_avg_epu16(__mmask32 __U, __m512i __A, __m512i __B) {
// CHECK-LABEL: @test_mm512_maskz_avg_epu16
- // CHECK: @llvm.x86.avx512.mask.pavg.w.512
+ // CHECK-NOT: @llvm.x86.avx512.mask.pavg.w.512
+ // CHECK: zext <32 x i16> %{{.*}} to <32 x i32>
+ // CHECK: zext <32 x i16> %{{.*}} to <32 x i32>
+ // CHECK: add <32 x i32> %{{.*}}, %{{.*}}
+ // CHECK: add <32 x i32> %{{.*}}, <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1>
+ // CHECK: lshr <32 x i32> %{{.*}}, <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1>
+ // CHECK: trunc <32 x i32> %{{.*}} to <32 x i16>
+ // CHECK: store <32 x i16> zeroinitializer
+ // CHECK: select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}}
return _mm512_maskz_avg_epu16(__U,__A,__B);
}
__m512i test_mm512_max_epi8(__m512i __A, __m512i __B) {
@@ -1432,26 +1490,162 @@ __m512i test_mm512_maskz_mov_epi8(__mmask64 __U, __m512i __A) {
__m512i test_mm512_mask_set1_epi8(__m512i __O, __mmask64 __M, char __A) {
// CHECK-LABEL: @test_mm512_mask_set1_epi8
- // CHECK: @llvm.x86.avx512.mask.pbroadcast.b.gpr.512
+ // CHECK: insertelement <64 x i8> undef, i8 %{{.*}}, i32 0
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 1
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 2
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 3
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 4
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 5
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 6
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 7
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 8
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 9
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 10
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 11
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 12
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 13
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 14
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 15
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 16
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 17
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 18
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 19
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 20
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 21
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 22
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 23
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 24
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 25
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 26
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 27
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 28
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 29
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 30
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 31
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 34
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 35
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 36
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 37
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 38
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 39
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 40
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 41
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 42
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 43
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 44
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 45
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 46
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 47
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 48
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 49
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 50
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 51
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 52
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 53
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 54
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 55
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 56
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 57
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 58
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 59
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 60
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 61
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 62
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 63
+ // CHECK: select <64 x i1> %{{.*}}, <64 x i8> %{{.*}}, <64 x i8> %{{.*}}
return _mm512_mask_set1_epi8(__O, __M, __A);
}
__m512i test_mm512_maskz_set1_epi8(__mmask64 __M, char __A) {
// CHECK-LABEL: @test_mm512_maskz_set1_epi8
- // CHECK: @llvm.x86.avx512.mask.pbroadcast.b.gpr.512
+ // CHECK: insertelement <64 x i8> undef, i8 %{{.*}}, i32 0
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 1
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 2
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 3
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 4
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 5
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 6
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 7
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 8
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 9
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 10
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 11
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 12
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 13
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 14
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 15
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 16
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 17
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 18
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 19
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 20
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 21
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 22
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 23
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 24
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 25
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 26
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 27
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 28
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 29
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 30
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 31
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 32
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 33
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 34
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 35
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 36
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 37
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 38
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 39
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 40
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 41
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 42
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 43
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 44
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 45
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 46
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 47
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 48
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 49
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 50
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 51
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 52
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 53
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 54
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 55
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 56
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 57
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 58
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 59
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 60
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 61
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 62
+ // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 63
+ // CHECK: select <64 x i1> %{{.*}}, <64 x i8> %{{.*}}, <64 x i8> %{{.*}}
return _mm512_maskz_set1_epi8(__M, __A);
}
-__mmask64 test_mm512_kunpackd(__mmask64 __A, __mmask64 __B) {
+__mmask64 test_mm512_kunpackd(__m512i __A, __m512i __B, __m512i __C, __m512i __D, __m512i __E, __m512i __F) {
// CHECK-LABEL: @test_mm512_kunpackd
- // CHECK: @llvm.x86.avx512.kunpck.dq
- return _mm512_kunpackd(__A, __B);
+ // CHECK: bitcast <64 x i1> %{{.*}} to i64
+ // CHECK: bitcast <64 x i1> %{{.*}} to i64
+ // CHECK: and i64 %{{.*}}, 4294967295
+ // CHECK: shl i64 %{{.*}}, 32
+ // CHECK: or i64 %{{.*}}, %{{.*}}
+ // CHECK: bitcast i64 %{{.*}} to <64 x i1>
+ return _mm512_mask_cmpneq_epu8_mask(_mm512_kunpackd(_mm512_cmpneq_epu8_mask(__B, __A),_mm512_cmpneq_epu8_mask(__C, __D)), __E, __F);
}
-__mmask32 test_mm512_kunpackw(__mmask32 __A, __mmask32 __B) {
+__mmask32 test_mm512_kunpackw(__m512i __A, __m512i __B, __m512i __C, __m512i __D, __m512i __E, __m512i __F) {
// CHECK-LABEL: @test_mm512_kunpackw
- // CHECK: @llvm.x86.avx512.kunpck.wd
- return _mm512_kunpackw(__A, __B);
+ // CHECK: bitcast <32 x i1> %{{.*}} to i32
+ // CHECK: bitcast <32 x i1> %{{.*}} to i32
+ // CHECK: and i32 %{{.*}}, 65535
+ // CHECK: shl i32 %{{.*}}, 16
+ // CHECK: or i32 %{{.*}}, %{{.*}}
+ // CHECK: bitcast i32 %{{.*}} to <32 x i1>
+ return _mm512_mask_cmpneq_epu16_mask(_mm512_kunpackw(_mm512_cmpneq_epu16_mask(__B, __A),_mm512_cmpneq_epu16_mask(__C, __D)), __E, __F);
}
__m512i test_mm512_mask_loadu_epi16(__m512i __W, __mmask32 __U, void const *__P) {
@@ -1484,7 +1678,8 @@ void test_mm512_mask_storeu_epi16(void *__P, __mmask32 __U, __m512i __A) {
}
__mmask64 test_mm512_test_epi8_mask(__m512i __A, __m512i __B) {
// CHECK-LABEL: @test_mm512_test_epi8_mask
- // CHECK: @llvm.x86.avx512.ptestm.b.512
+ // CHECK: and <16 x i32> %{{.*}}, %{{.*}}
+ // CHECK: icmp ne <64 x i8> %{{.*}}, %{{.*}}
return _mm512_test_epi8_mask(__A, __B);
}
@@ -1495,43 +1690,54 @@ void test_mm512_mask_storeu_epi8(void *__P, __mmask64 __U, __m512i __A) {
}
__mmask64 test_mm512_mask_test_epi8_mask(__mmask64 __U, __m512i __A, __m512i __B) {
// CHECK-LABEL: @test_mm512_mask_test_epi8_mask
- // CHECK: @llvm.x86.avx512.ptestm.b.512
+ // CHECK: and <16 x i32> %{{.*}}, %{{.*}}
+ // CHECK: icmp ne <64 x i8> %{{.*}}, %{{.*}}
+ // CHECK: and <64 x i1> %{{.*}}, %{{.*}}
return _mm512_mask_test_epi8_mask(__U, __A, __B);
}
__mmask32 test_mm512_test_epi16_mask(__m512i __A, __m512i __B) {
// CHECK-LABEL: @test_mm512_test_epi16_mask
- // CHECK: @llvm.x86.avx512.ptestm.w.
+ // CHECK: and <16 x i32> %{{.*}}, %{{.*}}
+ // CHECK: icmp ne <32 x i16> %{{.*}}, %{{.*}}
return _mm512_test_epi16_mask(__A, __B);
}
__mmask32 test_mm512_mask_test_epi16_mask(__mmask32 __U, __m512i __A, __m512i __B) {
// CHECK-LABEL: @test_mm512_mask_test_epi16_mask
- // CHECK: @llvm.x86.avx512.ptestm.w.
+ // CHECK: and <16 x i32> %{{.*}}, %{{.*}}
+ // CHECK: icmp ne <32 x i16> %{{.*}}, %{{.*}}
+ // CHECK: and <32 x i1> %{{.*}}, %{{.*}}
return _mm512_mask_test_epi16_mask(__U, __A, __B);
}
__mmask64 test_mm512_testn_epi8_mask(__m512i __A, __m512i __B) {
// CHECK-LABEL: @test_mm512_testn_epi8_mask
- // CHECK: @llvm.x86.avx512.ptestnm.b.
+ // CHECK: and <16 x i32> %{{.*}}, %{{.*}}
+ // CHECK: icmp eq <64 x i8> %{{.*}}, %{{.*}}
return _mm512_testn_epi8_mask(__A, __B);
}
__mmask64 test_mm512_mask_testn_epi8_mask(__mmask64 __U, __m512i __A, __m512i __B) {
// CHECK-LABEL: @test_mm512_mask_testn_epi8_mask
- // CHECK: @llvm.x86.avx512.ptestnm.b.
+ // CHECK: and <16 x i32> %{{.*}}, %{{.*}}
+ // CHECK: icmp eq <64 x i8> %{{.*}}, %{{.*}}
+ // CHECK: and <64 x i1> %{{.*}}, %{{.*}}
return _mm512_mask_testn_epi8_mask(__U, __A, __B);
}
__mmask32 test_mm512_testn_epi16_mask(__m512i __A, __m512i __B) {
// CHECK-LABEL: @test_mm512_testn_epi16_mask
- // CHECK: @llvm.x86.avx512.ptestnm.w.
+ // CHECK: and <16 x i32> %{{.*}}, %{{.*}}
+ // CHECK: icmp eq <32 x i16> %{{.*}}, %{{.*}}
return _mm512_testn_epi16_mask(__A, __B);
}
__mmask32 test_mm512_mask_testn_epi16_mask(__mmask32 __U, __m512i __A, __m512i __B) {
// CHECK-LABEL: @test_mm512_mask_testn_epi16_mask
- // CHECK: @llvm.x86.avx512.ptestnm.w.
+ // CHECK: and <16 x i32> %{{.*}}, %{{.*}}
+ // CHECK: icmp eq <32 x i16> %{{.*}}, %{{.*}}
+ // CHECK: and <32 x i1> %{{.*}}, %{{.*}}
return _mm512_mask_testn_epi16_mask(__U, __A, __B);
}
@@ -1597,13 +1803,77 @@ __m512i test_mm512_maskz_broadcastw_epi16(__mmask32 __M, __m128i __A) {
__m512i test_mm512_mask_set1_epi16(__m512i __O, __mmask32 __M, short __A) {
// CHECK-LABEL: @test_mm512_mask_set1_epi16
- // CHECK: @llvm.x86.avx512.mask.pbroadcast.w.gpr.512
+ // CHECK: insertelement <32 x i16> undef, i16 %{{.*}}, i32 0
+ // CHECK: insertelement <32 x i16> %{{.*}}, i16 %{{.*}}, i32 1
+ // CHECK: insertelement <32 x i16> %{{.*}}, i16 %{{.*}}, i32 2
+ // CHECK: insertelement <32 x i16> %{{.*}}, i16 %{{.*}}, i32 3
+ // CHECK: insertelement <32 x i16> %{{.*}}, i16 %{{.*}}, i32 4
+ // CHECK: insertelement <32 x i16> %{{.*}}, i16 %{{.*}}, i32 5
+ // CHECK: insertelement <32 x i16> %{{.*}}, i16 %{{.*}}, i32 6
+ // CHECK: insertelement <32 x i16> %{{.*}}, i16 %{{.*}}, i32 7
+ // CHECK: insertelement <32 x i16> %{{.*}}, i16 %{{.*}}, i32 8
+ // CHECK: insertelement <32 x i16> %{{.*}}, i16 %{{.*}}, i32 9
+ // CHECK: insertelement <32 x i16> %{{.*}}, i16 %{{.*}}, i32 10
+ // CHECK: insertelement <32 x i16> %{{.*}}, i16 %{{.*}}, i32 11
+ // CHECK: insertelement <32 x i16> %{{.*}}, i16 %{{.*}}, i32 12
+ // CHECK: insertelement <32 x i16> %{{.*}}, i16 %{{.*}}, i32 13
+ // CHECK: insertelement <32 x i16> %{{.*}}, i16 %{{.*}}, i32 14
+ // CHECK: insertelement <32 x i16> %{{.*}}, i16 %{{.*}}, i32 15
+ // CHECK: insertelement <32 x i16> %{{.*}}, i16 %{{.*}}, i32 16
+ // CHECK: insertelement <32 x i16> %{{.*}}, i16 %{{.*}}, i32 17
+ // CHECK: insertelement <32 x i16> %{{.*}}, i16 %{{.*}}, i32 18
+ // CHECK: insertelement <32 x i16> %{{.*}}, i16 %{{.*}}, i32 19
+ // CHECK: insertelement <32 x i16> %{{.*}}, i16 %{{.*}}, i32 20
+ // CHECK: insertelement <32 x i16> %{{.*}}, i16 %{{.*}}, i32 21
+ // CHECK: insertelement <32 x i16> %{{.*}}, i16 %{{.*}}, i32 22
+ // CHECK: insertelement <32 x i16> %{{.*}}, i16 %{{.*}}, i32 23
+ // CHECK: insertelement <32 x i16> %{{.*}}, i16 %{{.*}}, i32 24
+ // CHECK: insertelement <32 x i16> %{{.*}}, i16 %{{.*}}, i32 25
+ // CHECK: insertelement <32 x i16> %{{.*}}, i16 %{{.*}}, i32 26
+ // CHECK: insertelement <32 x i16> %{{.*}}, i16 %{{.*}}, i32 27
+ // CHECK: insertelement <32 x i16> %{{.*}}, i16 %{{.*}}, i32 28
+ // CHECK: insertelement <32 x i16> %{{.*}}, i16 %{{.*}}, i32 29
+ // CHECK: insertelement <32 x i16> %{{.*}}, i16 %{{.*}}, i32 30
+ // CHECK: insertelement <32 x i16> %{{.*}}, i16 %{{.*}}, i32 31
+ // CHECK: select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}}
return _mm512_mask_set1_epi16(__O, __M, __A);
}
__m512i test_mm512_maskz_set1_epi16(__mmask32 __M, short __A) {
// CHECK-LABEL: @test_mm512_maskz_set1_epi16
- // CHECK: @llvm.x86.avx512.mask.pbroadcast.w.gpr.512
+ // CHECK: insertelement <32 x i16> undef, i16 %{{.*}}, i32 0
+ // CHECK: insertelement <32 x i16> %{{.*}}, i16 %{{.*}}, i32 1
+ // CHECK: insertelement <32 x i16> %{{.*}}, i16 %{{.*}}, i32 2
+ // CHECK: insertelement <32 x i16> %{{.*}}, i16 %{{.*}}, i32 3
+ // CHECK: insertelement <32 x i16> %{{.*}}, i16 %{{.*}}, i32 4
+ // CHECK: insertelement <32 x i16> %{{.*}}, i16 %{{.*}}, i32 5
+ // CHECK: insertelement <32 x i16> %{{.*}}, i16 %{{.*}}, i32 6
+ // CHECK: insertelement <32 x i16> %{{.*}}, i16 %{{.*}}, i32 7
+ // CHECK: insertelement <32 x i16> %{{.*}}, i16 %{{.*}}, i32 8
+ // CHECK: insertelement <32 x i16> %{{.*}}, i16 %{{.*}}, i32 9
+ // CHECK: insertelement <32 x i16> %{{.*}}, i16 %{{.*}}, i32 10
+ // CHECK: insertelement <32 x i16> %{{.*}}, i16 %{{.*}}, i32 11
+ // CHECK: insertelement <32 x i16> %{{.*}}, i16 %{{.*}}, i32 12
+ // CHECK: insertelement <32 x i16> %{{.*}}, i16 %{{.*}}, i32 13
+ // CHECK: insertelement <32 x i16> %{{.*}}, i16 %{{.*}}, i32 14
+ // CHECK: insertelement <32 x i16> %{{.*}}, i16 %{{.*}}, i32 15
+ // CHECK: insertelement <32 x i16> %{{.*}}, i16 %{{.*}}, i32 16
+ // CHECK: insertelement <32 x i16> %{{.*}}, i16 %{{.*}}, i32 17
+ // CHECK: insertelement <32 x i16> %{{.*}}, i16 %{{.*}}, i32 18
+ // CHECK: insertelement <32 x i16> %{{.*}}, i16 %{{.*}}, i32 19
+ // CHECK: insertelement <32 x i16> %{{.*}}, i16 %{{.*}}, i32 20
+ // CHECK: insertelement <32 x i16> %{{.*}}, i16 %{{.*}}, i32 21
+ // CHECK: insertelement <32 x i16> %{{.*}}, i16 %{{.*}}, i32 22
+ // CHECK: insertelement <32 x i16> %{{.*}}, i16 %{{.*}}, i32 23
+ // CHECK: insertelement <32 x i16> %{{.*}}, i16 %{{.*}}, i32 24
+ // CHECK: insertelement <32 x i16> %{{.*}}, i16 %{{.*}}, i32 25
+ // CHECK: insertelement <32 x i16> %{{.*}}, i16 %{{.*}}, i32 26
+ // CHECK: insertelement <32 x i16> %{{.*}}, i16 %{{.*}}, i32 27
+ // CHECK: insertelement <32 x i16> %{{.*}}, i16 %{{.*}}, i32 28
+ // CHECK: insertelement <32 x i16> %{{.*}}, i16 %{{.*}}, i32 29
+ // CHECK: insertelement <32 x i16> %{{.*}}, i16 %{{.*}}, i32 30
+ // CHECK: insertelement <32 x i16> %{{.*}}, i16 %{{.*}}, i32 31
+ // CHECK: select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}}
return _mm512_maskz_set1_epi16(__M, __A);
}
__m512i test_mm512_permutexvar_epi16(__m512i __A, __m512i __B) {
diff --git a/test/CodeGen/avx512cdintrin.c b/test/CodeGen/avx512cdintrin.c
index a28601895be1..e01d277be9ff 100644
--- a/test/CodeGen/avx512cdintrin.c
+++ b/test/CodeGen/avx512cdintrin.c
@@ -68,14 +68,40 @@ __m512i test_mm512_maskz_lzcnt_epi64(__mmask8 __U, __m512i __A) {
return _mm512_maskz_lzcnt_epi64(__U,__A);
}
-__m512i test_mm512_broadcastmb_epi64(__mmask8 __A) {
+__m512i test_mm512_broadcastmb_epi64(__m512i a, __m512i b) {
// CHECK-LABEL: @test_mm512_broadcastmb_epi64
- // CHECK: @llvm.x86.avx512.broadcastmb.512
- return _mm512_broadcastmb_epi64(__A);
+ // CHECK: icmp eq <8 x i64> %{{.*}}, %{{.*}}
+ // CHECK: zext i8 %{{.*}} to i64
+ // CHECK: insertelement <8 x i64> undef, i64 %{{.*}}, i32 0
+ // CHECK: insertelement <8 x i64> %{{.*}}, i64 %{{.*}}, i32 1
+ // CHECK: insertelement <8 x i64> %{{.*}}, i64 %{{.*}}, i32 2
+ // CHECK: insertelement <8 x i64> %{{.*}}, i64 %{{.*}}, i32 3
+ // CHECK: insertelement <8 x i64> %{{.*}}, i64 %{{.*}}, i32 4
+ // CHECK: insertelement <8 x i64> %{{.*}}, i64 %{{.*}}, i32 5
+ // CHECK: insertelement <8 x i64> %{{.*}}, i64 %{{.*}}, i32 6
+ // CHECK: insertelement <8 x i64> %{{.*}}, i64 %{{.*}}, i32 7
+ return _mm512_broadcastmb_epi64(_mm512_cmpeq_epu64_mask ( a, b));
}
-__m512i test_mm512_broadcastmw_epi32(__mmask16 __A) {
+__m512i test_mm512_broadcastmw_epi32(__m512i a, __m512i b) {
// CHECK-LABEL: @test_mm512_broadcastmw_epi32
- // CHECK: @llvm.x86.avx512.broadcastmw.512
- return _mm512_broadcastmw_epi32(__A);
+ // CHECK: icmp eq <16 x i32> %{{.*}}, %{{.*}}
+ // CHECK: zext i16 %{{.*}} to i32
+ // CHECK: insertelement <16 x i32> undef, i32 %{{.*}}
+ // CHECK: insertelement <16 x i32> %{{.*}}, i32 %{{.*}}
+ // CHECK: insertelement <16 x i32> %{{.*}}, i32 %{{.*}}
+ // CHECK: insertelement <16 x i32> %{{.*}}, i32 %{{.*}}
+ // CHECK: insertelement <16 x i32> %{{.*}}, i32 %{{.*}}
+ // CHECK: insertelement <16 x i32> %{{.*}}, i32 %{{.*}}
+ // CHECK: insertelement <16 x i32> %{{.*}}, i32 %{{.*}}
+ // CHECK: insertelement <16 x i32> %{{.*}}, i32 %{{.*}}
+ // CHECK: insertelement <16 x i32> %{{.*}}, i32 %{{.*}}
+ // CHECK: insertelement <16 x i32> %{{.*}}, i32 %{{.*}}
+ // CHECK: insertelement <16 x i32> %{{.*}}, i32 %{{.*}}
+ // CHECK: insertelement <16 x i32> %{{.*}}, i32 %{{.*}}
+ // CHECK: insertelement <16 x i32> %{{.*}}, i32 %{{.*}}
+ // CHECK: insertelement <16 x i32> %{{.*}}, i32 %{{.*}}
+ // CHECK: insertelement <16 x i32> %{{.*}}, i32 %{{.*}}
+ // CHECK: insertelement <16 x i32> %{{.*}}, i32 %{{.*}}
+ return _mm512_broadcastmw_epi32(_mm512_cmpeq_epi32_mask ( a, b));
}
diff --git a/test/CodeGen/avx512dq-builtins.c b/test/CodeGen/avx512dq-builtins.c
index ca8566c5979a..1b21ca3c4302 100644
--- a/test/CodeGen/avx512dq-builtins.c
+++ b/test/CodeGen/avx512dq-builtins.c
@@ -949,19 +949,21 @@ __mmask8 test_mm512_movepi64_mask(__m512i __A) {
__m512 test_mm512_broadcast_f32x2(__m128 __A) {
// CHECK-LABEL: @test_mm512_broadcast_f32x2
- // CHECK: @llvm.x86.avx512.mask.broadcastf32x2
+ // CHECK: shufflevector <4 x float> %{{.*}}, <4 x float> zeroinitializer, <16 x i32> <i32 0, i32 1, i32 0, i32 1, i32 0, i32 1, i32 0, i32 1, i32 0, i32 1, i32 0, i32 1, i32 0, i32 1, i32 0, i32 1>
return _mm512_broadcast_f32x2(__A);
}
__m512 test_mm512_mask_broadcast_f32x2(__m512 __O, __mmask16 __M, __m128 __A) {
// CHECK-LABEL: @test_mm512_mask_broadcast_f32x2
- // CHECK: @llvm.x86.avx512.mask.broadcastf32x2
+ // CHECK: shufflevector <4 x float> %{{.*}}, <4 x float> zeroinitializer, <16 x i32> <i32 0, i32 1, i32 0, i32 1, i32 0, i32 1, i32 0, i32 1, i32 0, i32 1, i32 0, i32 1, i32 0, i32 1, i32 0, i32 1>
+ // CHECK: select <16 x i1> %{{.*}}, <16 x float> %{{.*}}, <16 x float> %{{.*}}
return _mm512_mask_broadcast_f32x2(__O, __M, __A);
}
__m512 test_mm512_maskz_broadcast_f32x2(__mmask16 __M, __m128 __A) {
// CHECK-LABEL: @test_mm512_maskz_broadcast_f32x2
- // CHECK: @llvm.x86.avx512.mask.broadcastf32x2
+ // CHECK: shufflevector <4 x float> %{{.*}}, <4 x float> zeroinitializer, <16 x i32> <i32 0, i32 1, i32 0, i32 1, i32 0, i32 1, i32 0, i32 1, i32 0, i32 1, i32 0, i32 1, i32 0, i32 1, i32 0, i32 1>
+ // CHECK: select <16 x i1> %{{.*}}, <16 x float> %{{.*}}, <16 x float> %{{.*}}
return _mm512_maskz_broadcast_f32x2(__M, __A);
}
@@ -1007,19 +1009,21 @@ __m512d test_mm512_maskz_broadcast_f64x2(__mmask8 __M, double const* __A) {
__m512i test_mm512_broadcast_i32x2(__m128i __A) {
// CHECK-LABEL: @test_mm512_broadcast_i32x2
- // CHECK: @llvm.x86.avx512.mask.broadcasti32x2
+ // CHECK: shufflevector <4 x i32> %{{.*}}, <4 x i32> zeroinitializer, <16 x i32> <i32 0, i32 1, i32 0, i32 1, i32 0, i32 1, i32 0, i32 1, i32 0, i32 1, i32 0, i32 1, i32 0, i32 1, i32 0, i32 1>
return _mm512_broadcast_i32x2(__A);
}
__m512i test_mm512_mask_broadcast_i32x2(__m512i __O, __mmask16 __M, __m128i __A) {
// CHECK-LABEL: @test_mm512_mask_broadcast_i32x2
- // CHECK: @llvm.x86.avx512.mask.broadcasti32x2
+ // CHECK: shufflevector <4 x i32> %{{.*}}, <4 x i32> zeroinitializer, <16 x i32> <i32 0, i32 1, i32 0, i32 1, i32 0, i32 1, i32 0, i32 1, i32 0, i32 1, i32 0, i32 1, i32 0, i32 1, i32 0, i32 1>
+ // CHECK: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}}
return _mm512_mask_broadcast_i32x2(__O, __M, __A);
}
__m512i test_mm512_maskz_broadcast_i32x2(__mmask16 __M, __m128i __A) {
// CHECK-LABEL: @test_mm512_maskz_broadcast_i32x2
- // CHECK: @llvm.x86.avx512.mask.broadcasti32x2
+ // CHECK: shufflevector <4 x i32> %{{.*}}, <4 x i32> zeroinitializer, <16 x i32> <i32 0, i32 1, i32 0, i32 1, i32 0, i32 1, i32 0, i32 1, i32 0, i32 1, i32 0, i32 1, i32 0, i32 1, i32 0, i32 1>
+ // CHECK: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}}
return _mm512_maskz_broadcast_i32x2(__M, __A);
}
diff --git a/test/CodeGen/avx512f-builtins.c b/test/CodeGen/avx512f-builtins.c
index 1ce09df7caf7..ce831d690ee7 100644
--- a/test/CodeGen/avx512f-builtins.c
+++ b/test/CodeGen/avx512f-builtins.c
@@ -1,9 +1,5 @@
// RUN: %clang_cc1 -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +avx512f -emit-llvm -o - -Wall -Werror | FileCheck %s
-// FIXME: It's wrong to check LLVM IR transformations from clang. This run should be removed and tests added to the appropriate LLVM pass.
-
-// RUN: %clang_cc1 -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +avx512f -O2 -emit-llvm -o - -Wall -Werror | FileCheck %s -check-prefix=O2
-
#include <immintrin.h>
__m512d test_mm512_sqrt_pd(__m512d a)
@@ -389,7 +385,9 @@ __m512d test_mm512_set1_pd(double d)
__mmask16 test_mm512_knot(__mmask16 a)
{
// CHECK-LABEL: @test_mm512_knot
- // CHECK: @llvm.x86.avx512.knot.w
+ // CHECK: [[IN:%.*]] = bitcast i16 %{{.*}} to <16 x i1>
+ // CHECK: [[NOT:%.*]] = xor <16 x i1> [[IN]], <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true>
+ // CHECK: bitcast <16 x i1> [[NOT]] to i16
return _mm512_knot(a);
}
@@ -3861,39 +3859,48 @@ __m512i test_mm512_maskz_permutex2var_epi64(__mmask8 __U, __m512i __A, __m512i _
}
__mmask16 test_mm512_testn_epi32_mask(__m512i __A, __m512i __B) {
// CHECK-LABEL: @test_mm512_testn_epi32_mask
- // CHECK: @llvm.x86.avx512.ptestnm.d.512
+ // CHECK: and <16 x i32> %{{.*}}, %{{.*}}
+ // CHECK: icmp eq <16 x i32> %{{.*}}, %{{.*}}
return _mm512_testn_epi32_mask(__A, __B);
}
__mmask16 test_mm512_mask_testn_epi32_mask(__mmask16 __U, __m512i __A, __m512i __B) {
// CHECK-LABEL: @test_mm512_mask_testn_epi32_mask
- // CHECK: @llvm.x86.avx512.ptestnm.d.512
+ // CHECK: and <16 x i32> %{{.*}}, %{{.*}}
+ // CHECK: icmp eq <16 x i32> %{{.*}}, %{{.*}}
+ // CHECK: and <16 x i1> %{{.*}}, %{{.*}}
return _mm512_mask_testn_epi32_mask(__U, __A, __B);
}
__mmask8 test_mm512_testn_epi64_mask(__m512i __A, __m512i __B) {
// CHECK-LABEL: @test_mm512_testn_epi64_mask
- // CHECK: @llvm.x86.avx512.ptestnm.q.512
+ // CHECK: and <16 x i32> %{{.*}}, %{{.*}}
+ // CHECK: icmp eq <8 x i64> %{{.*}}, %{{.*}}
return _mm512_testn_epi64_mask(__A, __B);
}
__mmask8 test_mm512_mask_testn_epi64_mask(__mmask8 __U, __m512i __A, __m512i __B) {
// CHECK-LABEL: @test_mm512_mask_testn_epi64_mask
- // CHECK: @llvm.x86.avx512.ptestnm.q.512
+ // CHECK: and <16 x i32> %{{.*}}, %{{.*}}
+ // CHECK: icmp eq <8 x i64> %{{.*}}, %{{.*}}
+ // CHECK: and <8 x i1> %{{.*}}, %{{.*}}
return _mm512_mask_testn_epi64_mask(__U, __A, __B);
}
__mmask16 test_mm512_mask_test_epi32_mask (__mmask16 __U, __m512i __A, __m512i __B)
{
// CHECK-LABEL: @test_mm512_mask_test_epi32_mask
- // CHECK: @llvm.x86.avx512.ptestm.d.512
+ // CHECK: and <16 x i32> %{{.*}}, %{{.*}}
+ // CHECK: icmp ne <16 x i32> %{{.*}}, %{{.*}}
return _mm512_mask_test_epi32_mask (__U,__A,__B);
}
__mmask8 test_mm512_mask_test_epi64_mask (__mmask8 __U, __m512i __A, __m512i __B)
{
// CHECK-LABEL: @test_mm512_mask_test_epi64_mask
- // CHECK: @llvm.x86.avx512.ptestm.q.512
+ // CHECK: and <16 x i32> %{{.*}}, %{{.*}}
+ // CHECK: icmp ne <8 x i64> %{{.*}}, %{{.*}}
+ // CHECK: and <8 x i1> %{{.*}}, %{{.*}}
return _mm512_mask_test_epi64_mask (__U,__A,__B);
}
@@ -4488,73 +4495,81 @@ __m512i test_mm512_maskz_ternarylogic_epi64(__mmask8 __U, __m512i __A, __m512i _
__m512 test_mm512_shuffle_f32x4(__m512 __A, __m512 __B) {
// CHECK-LABEL: @test_mm512_shuffle_f32x4
- // CHECK: @llvm.x86.avx512.mask.shuf.f32x4
+ // CHECK: shufflevector <16 x float> %{{.*}}, <16 x float> %{{.*}}, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 16, i32 17, i32 18, i32 19, i32 16, i32 17, i32 18, i32 19>
return _mm512_shuffle_f32x4(__A, __B, 4);
}
__m512 test_mm512_mask_shuffle_f32x4(__m512 __W, __mmask16 __U, __m512 __A, __m512 __B) {
// CHECK-LABEL: @test_mm512_mask_shuffle_f32x4
- // CHECK: @llvm.x86.avx512.mask.shuf.f32x4
+ // CHECK: shufflevector <16 x float> %{{.*}}, <16 x float> %{{.*}}, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 16, i32 17, i32 18, i32 19, i32 16, i32 17, i32 18, i32 19>
+ // CHECK: select <16 x i1> %{{.*}}, <16 x float> %{{.*}}, <16 x float> %{{.*}}
return _mm512_mask_shuffle_f32x4(__W, __U, __A, __B, 4);
}
__m512 test_mm512_maskz_shuffle_f32x4(__mmask16 __U, __m512 __A, __m512 __B) {
// CHECK-LABEL: @test_mm512_maskz_shuffle_f32x4
- // CHECK: @llvm.x86.avx512.mask.shuf.f32x4
+ // CHECK: shufflevector <16 x float> %{{.*}}, <16 x float> %{{.*}}, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 16, i32 17, i32 18, i32 19, i32 16, i32 17, i32 18, i32 19>
+ // CHECK: select <16 x i1> %{{.*}}, <16 x float> %{{.*}}, <16 x float> %{{.*}}
return _mm512_maskz_shuffle_f32x4(__U, __A, __B, 4);
}
__m512d test_mm512_shuffle_f64x2(__m512d __A, __m512d __B) {
// CHECK-LABEL: @test_mm512_shuffle_f64x2
- // CHECK: @llvm.x86.avx512.mask.shuf.f64x2
+ // CHECK: shufflevector <8 x double> %{{.*}}, <8 x double> %{{.*}}, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 8, i32 9, i32 8, i32 9>
return _mm512_shuffle_f64x2(__A, __B, 4);
}
__m512d test_mm512_mask_shuffle_f64x2(__m512d __W, __mmask8 __U, __m512d __A, __m512d __B) {
// CHECK-LABEL: @test_mm512_mask_shuffle_f64x2
- // CHECK: @llvm.x86.avx512.mask.shuf.f64x2
+ // CHECK: shufflevector <8 x double> %{{.*}}, <8 x double> %{{.*}}, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 8, i32 9, i32 8, i32 9>
+ // CHECK: select <8 x i1> %{{.*}}, <8 x double> %{{.*}}, <8 x double> %{{.*}}
return _mm512_mask_shuffle_f64x2(__W, __U, __A, __B, 4);
}
__m512d test_mm512_maskz_shuffle_f64x2(__mmask8 __U, __m512d __A, __m512d __B) {
// CHECK-LABEL: @test_mm512_maskz_shuffle_f64x2
- // CHECK: @llvm.x86.avx512.mask.shuf.f64x2
+ // CHECK: shufflevector <8 x double> %{{.*}}, <8 x double> %{{.*}}, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 8, i32 9, i32 8, i32 9>
+ // CHECK: select <8 x i1> %{{.*}}, <8 x double> %{{.*}}, <8 x double> %{{.*}}
return _mm512_maskz_shuffle_f64x2(__U, __A, __B, 4);
}
__m512i test_mm512_shuffle_i32x4(__m512i __A, __m512i __B) {
// CHECK-LABEL: @test_mm512_shuffle_i32x4
- // CHECK: @llvm.x86.avx512.mask.shuf.i32x4
+ // CHECK: shufflevector <8 x i64> %{{.*}}, <8 x i64> %{{.*}}, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 8, i32 9, i32 8, i32 9>
return _mm512_shuffle_i32x4(__A, __B, 4);
}
__m512i test_mm512_mask_shuffle_i32x4(__m512i __W, __mmask16 __U, __m512i __A, __m512i __B) {
// CHECK-LABEL: @test_mm512_mask_shuffle_i32x4
- // CHECK: @llvm.x86.avx512.mask.shuf.i32x4
+ // CHECK: shufflevector <8 x i64> %{{.*}}, <8 x i64> %{{.*}}, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 8, i32 9, i32 8, i32 9>
+ // CHECK: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}}
return _mm512_mask_shuffle_i32x4(__W, __U, __A, __B, 4);
}
__m512i test_mm512_maskz_shuffle_i32x4(__mmask16 __U, __m512i __A, __m512i __B) {
// CHECK-LABEL: @test_mm512_maskz_shuffle_i32x4
- // CHECK: @llvm.x86.avx512.mask.shuf.i32x4
+ // CHECK: shufflevector <8 x i64> %{{.*}}, <8 x i64> %{{.*}}, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 8, i32 9, i32 8, i32 9>
+ // CHECK: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}}
return _mm512_maskz_shuffle_i32x4(__U, __A, __B, 4);
}
__m512i test_mm512_shuffle_i64x2(__m512i __A, __m512i __B) {
// CHECK-LABEL: @test_mm512_shuffle_i64x2
- // CHECK: @llvm.x86.avx512.mask.shuf.i64x2
+ // CHECK: shufflevector <8 x i64> %{{.*}}, <8 x i64> %{{.*}}, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 8, i32 9, i32 8, i32 9>
return _mm512_shuffle_i64x2(__A, __B, 4);
}
__m512i test_mm512_mask_shuffle_i64x2(__m512i __W, __mmask8 __U, __m512i __A, __m512i __B) {
// CHECK-LABEL: @test_mm512_mask_shuffle_i64x2
- // CHECK: @llvm.x86.avx512.mask.shuf.i64x2
+ // CHECK: shufflevector <8 x i64> %{{.*}}, <8 x i64> %{{.*}}, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 8, i32 9, i32 8, i32 9>
+ // CHECK: select <8 x i1> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}}
return _mm512_mask_shuffle_i64x2(__W, __U, __A, __B, 4);
}
__m512i test_mm512_maskz_shuffle_i64x2(__mmask8 __U, __m512i __A, __m512i __B) {
// CHECK-LABEL: @test_mm512_maskz_shuffle_i64x2
- // CHECK: @llvm.x86.avx512.mask.shuf.i64x2
+ // CHECK: shufflevector <8 x i64> %{{.*}}, <8 x i64> %{{.*}}, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 8, i32 9, i32 8, i32 9>
+ // CHECK: select <8 x i1> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}}
return _mm512_maskz_shuffle_i64x2(__U, __A, __B, 4);
}
@@ -6198,22 +6213,38 @@ __m512i test_mm512_mask_permutexvar_epi32(__m512i __W, __mmask16 __M, __m512i __
return _mm512_mask_permutexvar_epi32(__W, __M, __X, __Y);
}
-__mmask16 test_mm512_kand(__mmask16 __A, __mmask16 __B) {
+__mmask16 test_mm512_kand(__m512i __A, __m512i __B, __m512i __C, __m512i __D, __m512i __E, __m512i __F) {
// CHECK-LABEL: @test_mm512_kand
- // CHECK: @llvm.x86.avx512.kand.w
- return _mm512_kand(__A, __B);
+ // CHECK: [[LHS:%.*]] = bitcast i16 %{{.*}} to <16 x i1>
+ // CHECK: [[RHS:%.*]] = bitcast i16 %{{.*}} to <16 x i1>
+ // CHECK: [[RES:%.*]] = and <16 x i1> [[LHS]], [[RHS]]
+ // CHECK: bitcast <16 x i1> [[RES]] to i16
+ return _mm512_mask_cmpneq_epu32_mask(_mm512_kand(_mm512_cmpneq_epu32_mask(__A, __B),
+ _mm512_cmpneq_epu32_mask(__C, __D)),
+ __E, __F);
}
-__mmask16 test_mm512_kandn(__mmask16 __A, __mmask16 __B) {
+__mmask16 test_mm512_kandn(__m512i __A, __m512i __B, __m512i __C, __m512i __D, __m512i __E, __m512i __F) {
// CHECK-LABEL: @test_mm512_kandn
- // CHECK: @llvm.x86.avx512.kandn.w
- return _mm512_kandn(__A, __B);
+ // CHECK: [[LHS:%.*]] = bitcast i16 %{{.*}} to <16 x i1>
+ // CHECK: [[RHS:%.*]] = bitcast i16 %{{.*}} to <16 x i1>
+ // CHECK: [[NOT:%.*]] = xor <16 x i1> [[LHS]], <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true>
+ // CHECK: [[RES:%.*]] = and <16 x i1> [[NOT]], [[RHS]]
+ // CHECK: bitcast <16 x i1> [[RES]] to i16
+ return _mm512_mask_cmpneq_epu32_mask(_mm512_kandn(_mm512_cmpneq_epu32_mask(__A, __B),
+ _mm512_cmpneq_epu32_mask(__C, __D)),
+ __E, __F);
}
-__mmask16 test_mm512_kor(__mmask16 __A, __mmask16 __B) {
+__mmask16 test_mm512_kor(__m512i __A, __m512i __B, __m512i __C, __m512i __D, __m512i __E, __m512i __F) {
// CHECK-LABEL: @test_mm512_kor
- // CHECK: @llvm.x86.avx512.kor.w
- return _mm512_kor(__A, __B);
+ // CHECK: [[LHS:%.*]] = bitcast i16 %{{.*}} to <16 x i1>
+ // CHECK: [[RHS:%.*]] = bitcast i16 %{{.*}} to <16 x i1>
+ // CHECK: [[RES:%.*]] = or <16 x i1> [[LHS]], [[RHS]]
+ // CHECK: bitcast <16 x i1> [[RES]] to i16
+ return _mm512_mask_cmpneq_epu32_mask(_mm512_kor(_mm512_cmpneq_epu32_mask(__A, __B),
+ _mm512_cmpneq_epu32_mask(__C, __D)),
+ __E, __F);
}
int test_mm512_kortestc(__mmask16 __A, __mmask16 __B) {
@@ -6228,22 +6259,40 @@ int test_mm512_kortestz(__mmask16 __A, __mmask16 __B) {
return _mm512_kortestz(__A, __B);
}
-__mmask16 test_mm512_kunpackb(__mmask16 __A, __mmask16 __B) {
+__mmask16 test_mm512_kunpackb(__m512i __A, __m512i __B, __m512i __C, __m512i __D, __m512i __E, __m512i __F) {
// CHECK-LABEL: @test_mm512_kunpackb
- // CHECK: @llvm.x86.avx512.kunpck.bw
- return _mm512_kunpackb(__A, __B);
-}
-
-__mmask16 test_mm512_kxnor(__mmask16 __A, __mmask16 __B) {
+ // CHECK: bitcast <16 x i1> %{{.*}} to i16
+ // CHECK: bitcast <16 x i1> %{{.*}} to i16
+ // CHECK: and i32 %{{.*}}, 255
+ // CHECK: shl i32 %{{.*}}, 8
+ // CHECK: or i32 %{{.*}}, %{{.*}}
+ // CHECK: bitcast i16 %{{.*}} to <16 x i1>
+ return _mm512_mask_cmpneq_epu32_mask(_mm512_kunpackb(_mm512_cmpneq_epu32_mask(__A, __B),
+ _mm512_cmpneq_epu32_mask(__C, __D)),
+ __E, __F);
+}
+
+__mmask16 test_mm512_kxnor(__m512i __A, __m512i __B, __m512i __C, __m512i __D, __m512i __E, __m512i __F) {
// CHECK-LABEL: @test_mm512_kxnor
- // CHECK: @llvm.x86.avx512.kxnor.w
- return _mm512_kxnor(__A, __B);
+ // CHECK: [[LHS:%.*]] = bitcast i16 %{{.*}} to <16 x i1>
+ // CHECK: [[RHS:%.*]] = bitcast i16 %{{.*}} to <16 x i1>
+ // CHECK: [[NOT:%.*]] = xor <16 x i1> [[LHS]], <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true>
+ // CHECK: [[RES:%.*]] = xor <16 x i1> [[NOT]], [[RHS]]
+ // CHECK: bitcast <16 x i1> [[RES]] to i16
+ return _mm512_mask_cmpneq_epu32_mask(_mm512_kxnor(_mm512_cmpneq_epu32_mask(__A, __B),
+ _mm512_cmpneq_epu32_mask(__C, __D)),
+ __E, __F);
}
-__mmask16 test_mm512_kxor(__mmask16 __A, __mmask16 __B) {
+__mmask16 test_mm512_kxor(__m512i __A, __m512i __B, __m512i __C, __m512i __D, __m512i __E, __m512i __F) {
// CHECK-LABEL: @test_mm512_kxor
- // CHECK: @llvm.x86.avx512.kxor.w
- return _mm512_kxor(__A, __B);
+ // CHECK: [[LHS:%.*]] = bitcast i16 %{{.*}} to <16 x i1>
+ // CHECK: [[RHS:%.*]] = bitcast i16 %{{.*}} to <16 x i1>
+ // CHECK: [[RES:%.*]] = xor <16 x i1> [[LHS]], [[RHS]]
+ // CHECK: bitcast <16 x i1> [[RES]] to i16
+ return _mm512_mask_cmpneq_epu32_mask(_mm512_kxor(_mm512_cmpneq_epu32_mask(__A, __B),
+ _mm512_cmpneq_epu32_mask(__C, __D)),
+ __E, __F);
}
void test_mm512_stream_si512(__m512i * __P, __m512i __A) {
@@ -6258,6 +6307,12 @@ __m512i test_mm512_stream_load_si512(void *__P) {
return _mm512_stream_load_si512(__P);
}
+__m512i test_mm512_stream_load_si512_const(void const *__P) {
+ // CHECK-LABEL: @test_mm512_stream_load_si512_const
+ // CHECK: load <8 x i64>, <8 x i64>* %{{.*}}, align 64, !nontemporal
+ return _mm512_stream_load_si512(__P);
+}
+
void test_mm512_stream_pd(double *__P, __m512d __A) {
// CHECK-LABEL: @test_mm512_stream_pd
// CHECK: store <8 x double> %{{.*}}, <8 x double>* %{{.*}}, align 64, !nontemporal
@@ -7722,11 +7777,51 @@ __m512i test_mm512_maskz_min_epu64 (__mmask8 __M, __m512i __A, __m512i __B)
__m512i test_mm512_mask_set1_epi32 (__m512i __O, __mmask16 __M, int __A)
{
- //CHECK-LABEL: @test_mm512_mask_set1_epi32
- //CHECK: @llvm.x86.avx512.mask.pbroadcast.d.gpr.512
+ // CHECK-LABEL: @test_mm512_mask_set1_epi32
+ // CHECK: insertelement <16 x i32> undef, i32 %{{.*}}, i32 0
+ // CHECK: insertelement <16 x i32> %{{.*}}, i32 %{{.*}}, i32 1
+ // CHECK: insertelement <16 x i32> %{{.*}}, i32 %{{.*}}, i32 2
+ // CHECK: insertelement <16 x i32> %{{.*}}, i32 %{{.*}}, i32 3
+ // CHECK: insertelement <16 x i32> %{{.*}}, i32 %{{.*}}, i32 4
+ // CHECK: insertelement <16 x i32> %{{.*}}, i32 %{{.*}}, i32 5
+ // CHECK: insertelement <16 x i32> %{{.*}}, i32 %{{.*}}, i32 6
+ // CHECK: insertelement <16 x i32> %{{.*}}, i32 %{{.*}}, i32 7
+ // CHECK: insertelement <16 x i32> %{{.*}}, i32 %{{.*}}, i32 8
+ // CHECK: insertelement <16 x i32> %{{.*}}, i32 %{{.*}}, i32 9
+ // CHECK: insertelement <16 x i32> %{{.*}}, i32 %{{.*}}, i32 10
+ // CHECK: insertelement <16 x i32> %{{.*}}, i32 %{{.*}}, i32 11
+ // CHECK: insertelement <16 x i32> %{{.*}}, i32 %{{.*}}, i32 12
+ // CHECK: insertelement <16 x i32> %{{.*}}, i32 %{{.*}}, i32 13
+ // CHECK: insertelement <16 x i32> %{{.*}}, i32 %{{.*}}, i32 14
+ // CHECK: insertelement <16 x i32> %{{.*}}, i32 %{{.*}}, i32 15
+ // CHECK: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}}
return _mm512_mask_set1_epi32 ( __O, __M, __A);
}
+__m512i test_mm512_maskz_set1_epi32(__mmask16 __M, int __A)
+{
+ // CHECK-LABEL: @test_mm512_maskz_set1_epi32
+ // CHECK: insertelement <16 x i32> undef, i32 %{{.*}}, i32 0
+ // CHECK: insertelement <16 x i32> %{{.*}}, i32 %{{.*}}, i32 1
+ // CHECK: insertelement <16 x i32> %{{.*}}, i32 %{{.*}}, i32 2
+ // CHECK: insertelement <16 x i32> %{{.*}}, i32 %{{.*}}, i32 3
+ // CHECK: insertelement <16 x i32> %{{.*}}, i32 %{{.*}}, i32 4
+ // CHECK: insertelement <16 x i32> %{{.*}}, i32 %{{.*}}, i32 5
+ // CHECK: insertelement <16 x i32> %{{.*}}, i32 %{{.*}}, i32 6
+ // CHECK: insertelement <16 x i32> %{{.*}}, i32 %{{.*}}, i32 7
+ // CHECK: insertelement <16 x i32> %{{.*}}, i32 %{{.*}}, i32 8
+ // CHECK: insertelement <16 x i32> %{{.*}}, i32 %{{.*}}, i32 9
+ // CHECK: insertelement <16 x i32> %{{.*}}, i32 %{{.*}}, i32 10
+ // CHECK: insertelement <16 x i32> %{{.*}}, i32 %{{.*}}, i32 11
+ // CHECK: insertelement <16 x i32> %{{.*}}, i32 %{{.*}}, i32 12
+ // CHECK: insertelement <16 x i32> %{{.*}}, i32 %{{.*}}, i32 13
+ // CHECK: insertelement <16 x i32> %{{.*}}, i32 %{{.*}}, i32 14
+ // CHECK: insertelement <16 x i32> %{{.*}}, i32 %{{.*}}, i32 15
+ // CHECK: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}}
+ return _mm512_maskz_set1_epi32(__M, __A);
+}
+
+
__m512i test_mm512_set_epi8(char e63, char e62, char e61, char e60, char e59,
char e58, char e57, char e56, char e55, char e54, char e53, char e52,
char e51, char e50, char e49, char e48, char e47, char e46, char e45,
@@ -7861,21 +7956,21 @@ __m512i test_mm512_set_epi32 (int __A, int __B, int __C, int __D,
{
//CHECK-LABEL: @test_mm512_set_epi32
//CHECK: insertelement{{.*}}i32 0
- //CHECK: insertelement{{.*}}i32 1
- //CHECK: insertelement{{.*}}i32 2
- //CHECK: insertelement{{.*}}i32 3
- //CHECK: insertelement{{.*}}i32 4
- //CHECK: insertelement{{.*}}i32 5
- //CHECK: insertelement{{.*}}i32 6
- //CHECK: insertelement{{.*}}i32 7
- //CHECK: insertelement{{.*}}i32 8
- //CHECK: insertelement{{.*}}i32 9
- //CHECK: insertelement{{.*}}i32 10
- //CHECK: insertelement{{.*}}i32 11
- //CHECK: insertelement{{.*}}i32 12
- //CHECK: insertelement{{.*}}i32 13
- //CHECK: insertelement{{.*}}i32 14
- //CHECK: insertelement{{.*}}i32 15
+ //CHECK: insertelement{{.*}}i32 1
+ //CHECK: insertelement{{.*}}i32 2
+ //CHECK: insertelement{{.*}}i32 3
+ //CHECK: insertelement{{.*}}i32 4
+ //CHECK: insertelement{{.*}}i32 5
+ //CHECK: insertelement{{.*}}i32 6
+ //CHECK: insertelement{{.*}}i32 7
+ //CHECK: insertelement{{.*}}i32 8
+ //CHECK: insertelement{{.*}}i32 9
+ //CHECK: insertelement{{.*}}i32 10
+ //CHECK: insertelement{{.*}}i32 11
+ //CHECK: insertelement{{.*}}i32 12
+ //CHECK: insertelement{{.*}}i32 13
+ //CHECK: insertelement{{.*}}i32 14
+ //CHECK: insertelement{{.*}}i32 15
return _mm512_set_epi32( __A, __B, __C, __D,__E, __F, __G, __H,
__I, __J, __K, __L,__M, __N, __O, __P);
}
@@ -7885,39 +7980,39 @@ __m512i test_mm512_setr_epi32 (int __A, int __B, int __C, int __D,
int __I, int __J, int __K, int __L,
int __M, int __N, int __O, int __P)
{
- //CHECK-LABEL: @test_mm512_setr_epi32
- //CHECK: load{{.*}}%__P.addr, align 4
- //CHECK: load{{.*}}%__O.addr, align 4
- //CHECK: load{{.*}}%__N.addr, align 4
- //CHECK: load{{.*}}%__M.addr, align 4
- //CHECK: load{{.*}}%__L.addr, align 4
- //CHECK: load{{.*}}%__K.addr, align 4
- //CHECK: load{{.*}}%__J.addr, align 4
- //CHECK: load{{.*}}%__I.addr, align 4
- //CHECK: load{{.*}}%__H.addr, align 4
- //CHECK: load{{.*}}%__G.addr, align 4
- //CHECK: load{{.*}}%__F.addr, align 4
- //CHECK: load{{.*}}%__E.addr, align 4
- //CHECK: load{{.*}}%__D.addr, align 4
- //CHECK: load{{.*}}%__C.addr, align 4
- //CHECK: load{{.*}}%__B.addr, align 4
- //CHECK: load{{.*}}%__A.addr, align 4
- //CHECK: insertelement{{.*}}i32 0
- //CHECK: insertelement{{.*}}i32 1
- //CHECK: insertelement{{.*}}i32 2
- //CHECK: insertelement{{.*}}i32 3
- //CHECK: insertelement{{.*}}i32 4
- //CHECK: insertelement{{.*}}i32 5
- //CHECK: insertelement{{.*}}i32 6
- //CHECK: insertelement{{.*}}i32 7
- //CHECK: insertelement{{.*}}i32 8
- //CHECK: insertelement{{.*}}i32 9
- //CHECK: insertelement{{.*}}i32 10
- //CHECK: insertelement{{.*}}i32 11
- //CHECK: insertelement{{.*}}i32 12
- //CHECK: insertelement{{.*}}i32 13
- //CHECK: insertelement{{.*}}i32 14
- //CHECK: insertelement{{.*}}i32 15
+ //CHECK-LABEL: @test_mm512_setr_epi32
+ //CHECK: load{{.*}}%__P.addr, align 4
+ //CHECK: load{{.*}}%__O.addr, align 4
+ //CHECK: load{{.*}}%__N.addr, align 4
+ //CHECK: load{{.*}}%__M.addr, align 4
+ //CHECK: load{{.*}}%__L.addr, align 4
+ //CHECK: load{{.*}}%__K.addr, align 4
+ //CHECK: load{{.*}}%__J.addr, align 4
+ //CHECK: load{{.*}}%__I.addr, align 4
+ //CHECK: load{{.*}}%__H.addr, align 4
+ //CHECK: load{{.*}}%__G.addr, align 4
+ //CHECK: load{{.*}}%__F.addr, align 4
+ //CHECK: load{{.*}}%__E.addr, align 4
+ //CHECK: load{{.*}}%__D.addr, align 4
+ //CHECK: load{{.*}}%__C.addr, align 4
+ //CHECK: load{{.*}}%__B.addr, align 4
+ //CHECK: load{{.*}}%__A.addr, align 4
+ //CHECK: insertelement{{.*}}i32 0
+ //CHECK: insertelement{{.*}}i32 1
+ //CHECK: insertelement{{.*}}i32 2
+ //CHECK: insertelement{{.*}}i32 3
+ //CHECK: insertelement{{.*}}i32 4
+ //CHECK: insertelement{{.*}}i32 5
+ //CHECK: insertelement{{.*}}i32 6
+ //CHECK: insertelement{{.*}}i32 7
+ //CHECK: insertelement{{.*}}i32 8
+ //CHECK: insertelement{{.*}}i32 9
+ //CHECK: insertelement{{.*}}i32 10
+ //CHECK: insertelement{{.*}}i32 11
+ //CHECK: insertelement{{.*}}i32 12
+ //CHECK: insertelement{{.*}}i32 13
+ //CHECK: insertelement{{.*}}i32 14
+ //CHECK: insertelement{{.*}}i32 15
return _mm512_setr_epi32( __A, __B, __C, __D,__E, __F, __G, __H,
__I, __J, __K, __L,__M, __N, __O, __P);
}
@@ -7925,19 +8020,36 @@ __m512i test_mm512_setr_epi32 (int __A, int __B, int __C, int __D,
#ifdef __x86_64__
__m512i test_mm512_mask_set1_epi64 (__m512i __O, __mmask8 __M, long long __A)
{
- //CHECK-LABEL: @test_mm512_mask_set1_epi64
- //CHECK: @llvm.x86.avx512.mask.pbroadcast.q.gpr.512
+ // CHECK-LABEL: @test_mm512_mask_set1_epi64
+ // CHECK: insertelement <8 x i64> undef, i64 %{{.*}}, i32 0
+ // CHECK: insertelement <8 x i64> %{{.*}}, i64 %{{.*}}, i32 1
+ // CHECK: insertelement <8 x i64> %{{.*}}, i64 %{{.*}}, i32 2
+ // CHECK: insertelement <8 x i64> %{{.*}}, i64 %{{.*}}, i32 3
+ // CHECK: insertelement <8 x i64> %{{.*}}, i64 %{{.*}}, i32 4
+ // CHECK: insertelement <8 x i64> %{{.*}}, i64 %{{.*}}, i32 5
+ // CHECK: insertelement <8 x i64> %{{.*}}, i64 %{{.*}}, i32 6
+ // CHECK: insertelement <8 x i64> %{{.*}}, i64 %{{.*}}, i32 7
+ // CHECK: select <8 x i1> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}}
return _mm512_mask_set1_epi64 (__O, __M, __A);
}
__m512i test_mm512_maskz_set1_epi64 (__mmask8 __M, long long __A)
{
- //CHECK-LABEL: @test_mm512_maskz_set1_epi64
- //CHECK: @llvm.x86.avx512.mask.pbroadcast.q.gpr.512
+ // CHECK-LABEL: @test_mm512_maskz_set1_epi64
+ // CHECK: insertelement <8 x i64> undef, i64 %{{.*}}, i32 0
+ // CHECK: insertelement <8 x i64> %{{.*}}, i64 %{{.*}}, i32 1
+ // CHECK: insertelement <8 x i64> %{{.*}}, i64 %{{.*}}, i32 2
+ // CHECK: insertelement <8 x i64> %{{.*}}, i64 %{{.*}}, i32 3
+ // CHECK: insertelement <8 x i64> %{{.*}}, i64 %{{.*}}, i32 4
+ // CHECK: insertelement <8 x i64> %{{.*}}, i64 %{{.*}}, i32 5
+ // CHECK: insertelement <8 x i64> %{{.*}}, i64 %{{.*}}, i32 6
+ // CHECK: insertelement <8 x i64> %{{.*}}, i64 %{{.*}}, i32 7
+ // CHECK: select <8 x i1> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}}
return _mm512_maskz_set1_epi64 (__M, __A);
}
#endif
+
__m512i test_mm512_set_epi64 (long long __A, long long __B, long long __C,
long long __D, long long __E, long long __F,
long long __G, long long __H)
@@ -8045,28 +8157,40 @@ __m512 test_mm512_set_ps (float __A, float __B, float __C, float __D,
__m512i test_mm512_mask_abs_epi64 (__m512i __W, __mmask8 __U, __m512i __A)
{
// CHECK-LABEL: @test_mm512_mask_abs_epi64
- // CHECK: @llvm.x86.avx512.mask.pabs.q.512
+ // CHECK: [[SUB:%.*]] = sub <8 x i64> zeroinitializer, [[A:%.*]]
+ // CHECK: [[CMP:%.*]] = icmp sgt <8 x i64> [[A]], zeroinitializer
+ // CHECK: [[SEL:%.*]] = select <8 x i1> [[CMP]], <8 x i64> [[A]], <8 x i64> [[SUB]]
+ // CHECK: select <8 x i1> %{{.*}}, <8 x i64> [[SEL]], <8 x i64> %{{.*}}
return _mm512_mask_abs_epi64 (__W,__U,__A);
}
__m512i test_mm512_maskz_abs_epi64 (__mmask8 __U, __m512i __A)
{
// CHECK-LABEL: @test_mm512_maskz_abs_epi64
- // CHECK: @llvm.x86.avx512.mask.pabs.q.512
+ // CHECK: [[SUB:%.*]] = sub <8 x i64> zeroinitializer, [[A:%.*]]
+ // CHECK: [[CMP:%.*]] = icmp sgt <8 x i64> [[A]], zeroinitializer
+ // CHECK: [[SEL:%.*]] = select <8 x i1> [[CMP]], <8 x i64> [[A]], <8 x i64> [[SUB]]
+ // CHECK: select <8 x i1> %{{.*}}, <8 x i64> [[SEL]], <8 x i64> %{{.*}}
return _mm512_maskz_abs_epi64 (__U,__A);
}
__m512i test_mm512_mask_abs_epi32 (__m512i __W, __mmask16 __U, __m512i __A)
{
// CHECK-LABEL: @test_mm512_mask_abs_epi32
- // CHECK: @llvm.x86.avx512.mask.pabs.d.512
+ // CHECK: [[SUB:%.*]] = sub <16 x i32> zeroinitializer, [[A:%.*]]
+ // CHECK: [[CMP:%.*]] = icmp sgt <16 x i32> [[A]], zeroinitializer
+ // CHECK: [[SEL:%.*]] = select <16 x i1> [[CMP]], <16 x i32> [[A]], <16 x i32> [[SUB]]
+ // CHECK: select <16 x i1> %{{.*}}, <16 x i32> [[SEL]], <16 x i32> %{{.*}}
return _mm512_mask_abs_epi32 (__W,__U,__A);
}
__m512i test_mm512_maskz_abs_epi32 (__mmask16 __U, __m512i __A)
{
// CHECK-LABEL: @test_mm512_maskz_abs_epi32
- // CHECK: @llvm.x86.avx512.mask.pabs.d.512
+ // CHECK: [[SUB:%.*]] = sub <16 x i32> zeroinitializer, [[A:%.*]]
+ // CHECK: [[CMP:%.*]] = icmp sgt <16 x i32> [[A]], zeroinitializer
+ // CHECK: [[SEL:%.*]] = select <16 x i1> [[CMP]], <16 x i32> [[A]], <16 x i32> [[SUB]]
+ // CHECK: select <16 x i1> %{{.*}}, <16 x i32> [[SEL]], <16 x i32> %{{.*}}
return _mm512_maskz_abs_epi32 (__U,__A);
}
@@ -8234,138 +8358,95 @@ __m512d test_mm512_setzero_pd()
__mmask16 test_mm512_int2mask(int __a)
{
- // O2-LABEL: test_mm512_int2mask
- // O2: trunc i32 %__a to i16
+ // CHECK-LABEL: test_mm512_int2mask
+ // CHECK: trunc i32 %{{.*}} to i16
return _mm512_int2mask(__a);
}
int test_mm512_mask2int(__mmask16 __a)
{
- // O2-LABEL: test_mm512_mask2int
- // O2: zext i16 %__a to i32
+ // CHECK-LABEL: test_mm512_mask2int
+ // CHECK: zext i16 %{{.*}} to i32
return _mm512_mask2int(__a);
}
__m128 test_mm_mask_move_ss (__m128 __W, __mmask8 __U, __m128 __A, __m128 __B)
{
- // O2-LABEL: @test_mm_mask_move_ss
- // O2: %[[M:.*]] = and i8 %__U, 1
- // O2: %[[M2:.*]] = icmp
- // O2: %[[ELM1:.*]] = extractelement <4 x float>
- // O2: %[[ELM2:.*]] = extractelement <4 x float>
- // O2: %[[SEL:.*]] = select i1 %[[M2]]
- // O2: %[[RES:.*]] = insertelement <4 x float> %__A, float %[[SEL]], i32 0
- // O2: ret <4 x float> %[[RES]]
+ // CHECK-LABEL: @test_mm_mask_move_ss
+ // CHECK: extractelement <4 x float> %{{.*}}, i32 0
+ // CHECK: extractelement <4 x float> %{{.*}}, i32 0
+ // CHECK: phi float [ %{{.*}}, %{{.*}} ], [ %{{.*}}, %{{.*}} ]
+ // CHECK: insertelement <4 x float> %{{.*}}, float %cond.i, i32 0
return _mm_mask_move_ss ( __W, __U, __A, __B);
}
__m128 test_mm_maskz_move_ss (__mmask8 __U, __m128 __A, __m128 __B)
{
- // O2-LABEL: @test_mm_maskz_move_ss
- // O2: %[[M:.*]] = and i8 %__U, 1
- // O2: %[[M2:.*]] = icmp
- // O2: %[[ELM1:.*]] = extractelement <4 x float> %__B, i32 0
- // O2: %[[SEL:.*]] = select i1 %[[M2]]
- // O2: %[[RES:.*]] = insertelement <4 x float> %__A, float %[[SEL]], i32 0
- // O2: ret <4 x float> %[[RES]]
+ // CHECK-LABEL: @test_mm_maskz_move_ss
+ // CHECK: extractelement <4 x float> %{{.*}}, i32 0
+ // CHECK: phi float [ %{{.*}}, %{{.*}} ], [ 0.000000e+00, %{{.*}} ]
+ // CHECK: insertelement <4 x float> %{{.*}}, float %{{.*}}, i32 0
return _mm_maskz_move_ss (__U, __A, __B);
}
__m128d test_mm_mask_move_sd (__m128d __W, __mmask8 __U, __m128d __A, __m128d __B)
{
- // O2-LABEL: @test_mm_mask_move_sd
- // O2: %[[M:.*]] = and i8 %__U, 1
- // O2: %[[M2:.*]] = icmp
- // O2: %[[ELM1:.*]] = extractelement <2 x double>
- // O2: %[[ELM2:.*]] = extractelement <2 x double>
- // O2: %[[SEL:.*]] = select i1 %[[M2]]
- // O2: %[[RES:.*]] = insertelement <2 x double> %__A, double %[[SEL]], i32 0
- // O2: ret <2 x double> %[[RES]]
+ // CHECK-LABEL: @test_mm_mask_move_sd
+ // CHECK: extractelement <2 x double> %{{.*}}, i32 0
+ // CHECK: extractelement <2 x double> %{{.*}}, i32 0
+ // CHECK: phi double [ %{{.*}}, %{{.*}} ], [ %{{.*}}, %{{.*}} ]
+ // CHECK: insertelement <2 x double> %{{.*}}, double %{{.*}}, i32 0
return _mm_mask_move_sd ( __W, __U, __A, __B);
}
__m128d test_mm_maskz_move_sd (__mmask8 __U, __m128d __A, __m128d __B)
{
- // O2-LABEL: @test_mm_maskz_move_sd
- // O2: %[[M:.*]] = and i8 %__U, 1
- // O2: %[[M2:.*]] = icmp
- // O2: %[[ELM1:.*]] = extractelement <2 x double> %__B, i32 0
- // O2: %[[SEL:.*]] = select i1 %[[M2]]
- // O2: %[[RES:.*]] = insertelement <2 x double> %__A, double %[[SEL]], i32 0
- // O2: ret <2 x double> %[[RES]]
+ // CHECK-LABEL: @test_mm_maskz_move_sd
+ // CHECK: extractelement <2 x double> %{{.*}}, i32 0
+ // CHECK: phi double [ %{{.*}}, %{{.*}} ], [ 0.000000e+00, %{{.*}} ]
+ // CHECK: insertelement <2 x double> %{{.*}}, double %{{.*}}, i32 0
return _mm_maskz_move_sd (__U, __A, __B);
}
void test_mm_mask_store_ss(float * __P, __mmask8 __U, __m128 __A)
{
- // O2-LABEL: @test_mm_mask_store_ss
- // O2: %[[CAST:.*]] = bitcast float* %__P to <16 x float>*
- // O2: %[[SHUFFLE:.*]] = shufflevector <4 x float> %__A, <4 x float> undef, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // O2: %[[MASK1:.*]] = and i8 %__U, 1
- // O2: %[[MASK2:.*]] = zext i8 %[[MASK1]] to i16
- // O2: %[[MASK3:.*]] = bitcast i16 %[[MASK2]] to <16 x i1>
- // O2: tail call void @llvm.masked.store.v16f32.p0v16f32(<16 x float> %[[SHUFFLE]], <16 x float>* %[[CAST]], i32 16, <16 x i1> %[[MASK3]])
+ // CHECK-LABEL: @test_mm_mask_store_ss
+ // CHECK: call void @llvm.masked.store.v16f32.p0v16f32(
_mm_mask_store_ss(__P, __U, __A);
}
void test_mm_mask_store_sd(double * __P, __mmask8 __U, __m128d __A)
{
- // O2-LABEL: @test_mm_mask_store_sd
- // O2: %[[CAST:.*]] = bitcast double* %__P to <8 x double>*
- // O2: %[[SHUFFLE:.*]] = shufflevector <2 x double> %__A, <2 x double> undef, <8 x i32> <i32 0, i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // O2: %[[MASK1:.*]] = and i8 %__U, 1
- // O2: %[[MASK2:.*]] = bitcast i8 %[[MASK1]] to <8 x i1>
- // O2: tail call void @llvm.masked.store.v8f64.p0v8f64(<8 x double> %[[SHUFFLE]], <8 x double>* %[[CAST]], i32 16, <8 x i1> %[[MASK2]])
+ // CHECK-LABEL: @test_mm_mask_store_sd
+ // CHECK: call void @llvm.masked.store.v8f64.p0v8f64(
_mm_mask_store_sd(__P, __U, __A);
}
__m128 test_mm_mask_load_ss(__m128 __A, __mmask8 __U, const float* __W)
{
- // O2-LABEL: @test_mm_mask_load_ss
- // O2: %[[SHUF:.*]] = shufflevector <4 x float> %__A, <4 x float> <float 0.000000e+00, float undef, float undef, float undef>, <4 x i32> <i32 0, i32 4, i32 4, i32 4>
- // O2: %[[PTR:.*]] = bitcast float* %__W to <16 x float>*
- // O2: %[[SHUF2:.*]] = shufflevector <4 x float> %[[SHUF]], <4 x float> undef, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // O2: %[[AND:.*]] = and i8 %__U, 1
- // O2: %[[MASK:.*]] = zext i8 %[[AND]] to i16
- // O2: %[[MASK2:.*]] = bitcast i16 %[[MASK]] to <16 x i1>
- // O2: %[[RES:.*]] = tail call <16 x float> @llvm.masked.load.v16f32.p0v16f32(<16 x float>* %[[PTR]], i32 16, <16 x i1> %[[MASK2]], <16 x float> %[[SHUF2]])
- // O2: shufflevector <16 x float> %[[RES]], <16 x float> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
+ // CHECK-LABEL: @test_mm_mask_load_ss
+ // CHECK: call <16 x float> @llvm.masked.load.v16f32.p0v16f32(
return _mm_mask_load_ss(__A, __U, __W);
}
__m128 test_mm_maskz_load_ss (__mmask8 __U, const float * __W)
{
- // O2-LABEL: @test_mm_maskz_load_ss
- // O2: %[[PTR:.*]] = bitcast float* %__W to <16 x float>*
- // O2: %[[AND:.*]] = and i8 %__U, 1
- // O2: %[[MASK:.*]] = zext i8 %[[AND]] to i16
- // O2: %[[MASK2:.*]] = bitcast i16 %[[MASK]] to <16 x i1>
- // O2: %[[RES:.*]] = tail call <16 x float> @llvm.masked.load.v16f32.p0v16f32(<16 x float>* %[[PTR]], i32 16, <16 x i1> %[[MASK2]], <16 x float> zeroinitializer)
- // O2: shufflevector <16 x float> %[[RES]], <16 x float> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
+ // CHECK-LABEL: @test_mm_maskz_load_ss
+ // CHECK: call <16 x float> @llvm.masked.load.v16f32.p0v16f32(
return _mm_maskz_load_ss (__U, __W);
}
__m128d test_mm_mask_load_sd (__m128d __A, __mmask8 __U, const double * __W)
{
- // O2-LABEL: @test_mm_mask_load_sd
- // O2: %[[SHUF:.*]] = insertelement <2 x double> %__A, double 0.000000e+00, i32 1
- // O2: %[[PTR:.*]] = bitcast double* %__W to <8 x double>*
- // O2: %[[SHUF2:.*]] = shufflevector <2 x double> %[[SHUF]], <2 x double> undef, <8 x i32> <i32 0, i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
- // O2: %[[AND:.*]] = and i8 %__U, 1
- // O2: %[[MASK:.*]] = bitcast i8 %[[AND]] to <8 x i1>
- // O2: %[[RES:.*]] = tail call <8 x double> @llvm.masked.load.v8f64.p0v8f64(<8 x double>* %[[PTR]], i32 16, <8 x i1> %[[MASK]], <8 x double> %[[SHUF2]])
- // O2: shufflevector <8 x double> %[[RES]], <8 x double> undef, <2 x i32> <i32 0, i32 1>
+ // CHECK-LABEL: @test_mm_mask_load_sd
+ // CHECK: call <8 x double> @llvm.masked.load.v8f64.p0v8f64(
return _mm_mask_load_sd (__A, __U, __W);
}
__m128d test_mm_maskz_load_sd (__mmask8 __U, const double * __W)
{
- // O2-LABEL: @test_mm_maskz_load_sd
- // O2: %[[PTR:.*]] = bitcast double* %__W to <8 x double>*
- // O2: %[[AND:.*]] = and i8 %__U, 1
- // O2: %[[MASK:.*]] = bitcast i8 %[[AND]] to <8 x i1>
- // O2: %[[RES:.*]] = tail call <8 x double> @llvm.masked.load.v8f64.p0v8f64(<8 x double>* %[[PTR]], i32 16, <8 x i1> %[[MASK]], <8 x double> zeroinitializer)
- // O2: shufflevector <8 x double> %[[RES]], <8 x double> undef, <2 x i32> <i32 0, i32 1>
+ // CHECK-LABEL: @test_mm_maskz_load_sd
+ // CHECK: call <8 x double> @llvm.masked.load.v8f64.p0v8f64(
return _mm_maskz_load_sd (__U, __W);
}
diff --git a/test/CodeGen/avx512ifmavl-builtins.c b/test/CodeGen/avx512ifmavl-builtins.c
index c59af0ec6d06..4aeec336ad94 100644
--- a/test/CodeGen/avx512ifmavl-builtins.c
+++ b/test/CodeGen/avx512ifmavl-builtins.c
@@ -1,6 +1,4 @@
-// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin -target-feature +avx512ifma -target-feature +avx512vl -emit-llvm -o - -Wall -Werror | FileCheck %s
-
-#define __MM_MALLOC_H
+// RUN: %clang_cc1 %s -ffreestanding -triple=x86_64-apple-darwin -target-feature +avx512ifma -target-feature +avx512vl -emit-llvm -o - -Wall -Werror | FileCheck %s
#include <immintrin.h>
diff --git a/test/CodeGen/avx512vl-builtins.c b/test/CodeGen/avx512vl-builtins.c
index c64b7bcec23e..b4fc86da704b 100644
--- a/test/CodeGen/avx512vl-builtins.c
+++ b/test/CodeGen/avx512vl-builtins.c
@@ -2502,56 +2502,82 @@ __m256 test_mm256_maskz_mul_ps(__mmask8 __U, __m256 __A, __m256 __B) {
}
__m128i test_mm_mask_abs_epi32(__m128i __W, __mmask8 __U, __m128i __A) {
// CHECK-LABEL: @test_mm_mask_abs_epi32
- // CHECK: @llvm.x86.ssse3.pabs.d.128
- // CHECK: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}
+ // CHECK: [[SUB:%.*]] = sub <4 x i32> zeroinitializer, [[A:%.*]]
+ // CHECK: [[CMP:%.*]] = icmp sgt <4 x i32> [[A]], zeroinitializer
+ // CHECK: [[SEL:%.*]] = select <4 x i1> [[CMP]], <4 x i32> [[A]], <4 x i32> [[SUB]]
+ // CHECK: select <4 x i1> %{{.*}}, <4 x i32> [[SEL]], <4 x i32> %{{.*}}
return _mm_mask_abs_epi32(__W,__U,__A);
}
__m128i test_mm_maskz_abs_epi32(__mmask8 __U, __m128i __A) {
// CHECK-LABEL: @test_mm_maskz_abs_epi32
- // CHECK: @llvm.x86.ssse3.pabs.d.128
- // CHECK: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}
+ // CHECK: [[SUB:%.*]] = sub <4 x i32> zeroinitializer, [[A:%.*]]
+ // CHECK: [[CMP:%.*]] = icmp sgt <4 x i32> [[A]], zeroinitializer
+ // CHECK: [[SEL:%.*]] = select <4 x i1> [[CMP]], <4 x i32> [[A]], <4 x i32> [[SUB]]
+ // CHECK: select <4 x i1> %{{.*}}, <4 x i32> [[SEL]], <4 x i32> %{{.*}}
return _mm_maskz_abs_epi32(__U,__A);
}
__m256i test_mm256_mask_abs_epi32(__m256i __W, __mmask8 __U, __m256i __A) {
// CHECK-LABEL: @test_mm256_mask_abs_epi32
- // CHECK: @llvm.x86.avx2.pabs.d
- // CHECK: select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}}
+ // CHECK: [[SUB:%.*]] = sub <8 x i32> zeroinitializer, [[A:%.*]]
+ // CHECK: [[CMP:%.*]] = icmp sgt <8 x i32> [[A]], zeroinitializer
+ // CHECK: [[SEL:%.*]] = select <8 x i1> [[CMP]], <8 x i32> [[A]], <8 x i32> [[SUB]]
+ // CHECK: select <8 x i1> %{{.*}}, <8 x i32> [[SEL]], <8 x i32> %{{.*}}
return _mm256_mask_abs_epi32(__W,__U,__A);
}
__m256i test_mm256_maskz_abs_epi32(__mmask8 __U, __m256i __A) {
// CHECK-LABEL: @test_mm256_maskz_abs_epi32
- // CHECK: @llvm.x86.avx2.pabs.d
- // CHECK: select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}}
+ // CHECK: [[SUB:%.*]] = sub <8 x i32> zeroinitializer, [[A:%.*]]
+ // CHECK: [[CMP:%.*]] = icmp sgt <8 x i32> [[A]], zeroinitializer
+ // CHECK: [[SEL:%.*]] = select <8 x i1> [[CMP]], <8 x i32> [[A]], <8 x i32> [[SUB]]
+ // CHECK: select <8 x i1> %{{.*}}, <8 x i32> [[SEL]], <8 x i32> %{{.*}}
return _mm256_maskz_abs_epi32(__U,__A);
}
__m128i test_mm_abs_epi64(__m128i __A) {
// CHECK-LABEL: @test_mm_abs_epi64
- // CHECK: @llvm.x86.avx512.mask.pabs.q.128
+ // CHECK: [[SUB:%.*]] = sub <2 x i64> zeroinitializer, [[A:%.*]]
+ // CHECK: [[CMP:%.*]] = icmp sgt <2 x i64> [[A]], zeroinitializer
+ // CHECK: select <2 x i1> [[CMP]], <2 x i64> [[A]], <2 x i64> [[SUB]]
+
return _mm_abs_epi64(__A);
}
__m128i test_mm_mask_abs_epi64(__m128i __W, __mmask8 __U, __m128i __A) {
// CHECK-LABEL: @test_mm_mask_abs_epi64
- // CHECK: @llvm.x86.avx512.mask.pabs.q.128
+ // CHECK: [[SUB:%.*]] = sub <2 x i64> zeroinitializer, [[A:%.*]]
+ // CHECK: [[CMP:%.*]] = icmp sgt <2 x i64> [[A]], zeroinitializer
+ // CHECK: [[SEL:%.*]] = select <2 x i1> [[CMP]], <2 x i64> [[A]], <2 x i64> [[SUB]]
+ // CHECK: select <2 x i1> %{{.*}}, <2 x i64> [[SEL]], <2 x i64> %{{.*}}
+
return _mm_mask_abs_epi64(__W,__U,__A);
}
__m128i test_mm_maskz_abs_epi64(__mmask8 __U, __m128i __A) {
// CHECK-LABEL: @test_mm_maskz_abs_epi64
- // CHECK: @llvm.x86.avx512.mask.pabs.q.128
+ // CHECK: [[SUB:%.*]] = sub <2 x i64> zeroinitializer, [[A:%.*]]
+ // CHECK: [[CMP:%.*]] = icmp sgt <2 x i64> [[A]], zeroinitializer
+ // CHECK: [[SEL:%.*]] = select <2 x i1> [[CMP]], <2 x i64> [[A]], <2 x i64> [[SUB]]
+ // CHECK: select <2 x i1> %{{.*}}, <2 x i64> [[SEL]], <2 x i64> %{{.*}}
return _mm_maskz_abs_epi64(__U,__A);
}
__m256i test_mm256_abs_epi64(__m256i __A) {
// CHECK-LABEL: @test_mm256_abs_epi64
- // CHECK: @llvm.x86.avx512.mask.pabs.q.256
+ // CHECK: [[SUB:%.*]] = sub <4 x i64> zeroinitializer, [[A:%.*]]
+ // CHECK: [[CMP:%.*]] = icmp sgt <4 x i64> [[A]], zeroinitializer
+ // CHECK: select <4 x i1> [[CMP]], <4 x i64> [[A]], <4 x i64> [[SUB]]
return _mm256_abs_epi64(__A);
}
__m256i test_mm256_mask_abs_epi64(__m256i __W, __mmask8 __U, __m256i __A) {
// CHECK-LABEL: @test_mm256_mask_abs_epi64
- // CHECK: @llvm.x86.avx512.mask.pabs.q.256
+ // CHECK: [[SUB:%.*]] = sub <4 x i64> zeroinitializer, [[A:%.*]]
+ // CHECK: [[CMP:%.*]] = icmp sgt <4 x i64> [[A]], zeroinitializer
+ // CHECK: [[SEL:%.*]] = select <4 x i1> [[CMP]], <4 x i64> [[A]], <4 x i64> [[SUB]]
+ // CHECK: select <4 x i1> %{{.*}}, <4 x i64> [[SEL]], <4 x i64> %{{.*}}
return _mm256_mask_abs_epi64(__W,__U,__A);
}
__m256i test_mm256_maskz_abs_epi64(__mmask8 __U, __m256i __A) {
// CHECK-LABEL: @test_mm256_maskz_abs_epi64
- // CHECK: @llvm.x86.avx512.mask.pabs.q.256
+ // CHECK: [[SUB:%.*]] = sub <4 x i64> zeroinitializer, [[A:%.*]]
+ // CHECK: [[CMP:%.*]] = icmp sgt <4 x i64> [[A]], zeroinitializer
+ // CHECK: [[SEL:%.*]] = select <4 x i1> [[CMP]], <4 x i64> [[A]], <4 x i64> [[SUB]]
+ // CHECK: select <4 x i1> %{{.*}}, <4 x i64> [[SEL]], <4 x i64> %{{.*}}
return _mm256_maskz_abs_epi64(__U,__A);
}
__m128i test_mm_maskz_max_epi32(__mmask8 __M, __m128i __A, __m128i __B) {
@@ -4486,50 +4512,92 @@ __m256d test_mm256_maskz_movedup_pd(__mmask8 __U, __m256d __A) {
__m128i test_mm_mask_set1_epi32(__m128i __O, __mmask8 __M) {
// CHECK-LABEL: @test_mm_mask_set1_epi32
- // CHECK: @llvm.x86.avx512.mask.pbroadcast.d.gpr.128
+ // CHECK: insertelement <4 x i32> undef, i32 %{{.*}}, i32 0
+ // CHECK: insertelement <4 x i32> %{{.*}}32 1
+ // CHECK: insertelement <4 x i32> %{{.*}}32 2
+ // CHECK: insertelement <4 x i32> %{{.*}}32 3
+ // CHECK: shufflevector <8 x i1> %{{.*}}, <8 x i1> %{{.*}}, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
+ // CHECK: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}
return _mm_mask_set1_epi32(__O, __M, 5);
}
__m128i test_mm_maskz_set1_epi32(__mmask8 __M) {
// CHECK-LABEL: @test_mm_maskz_set1_epi32
- // CHECK: @llvm.x86.avx512.mask.pbroadcast.d.gpr.128
+ // CHECK: insertelement <4 x i32> undef, i32 %{{.*}}, i32 0
+ // CHECK: insertelement <4 x i32> %{{.*}}32 1
+ // CHECK: insertelement <4 x i32> %{{.*}}32 2
+ // CHECK: insertelement <4 x i32> %{{.*}}32 3
+ // CHECK: shufflevector <8 x i1> %{{.*}}, <8 x i1> %{{.*}}, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
+ // CHECK: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}
return _mm_maskz_set1_epi32(__M, 5);
}
__m256i test_mm256_mask_set1_epi32(__m256i __O, __mmask8 __M) {
// CHECK-LABEL: @test_mm256_mask_set1_epi32
- // CHECK: @llvm.x86.avx512.mask.pbroadcast.d.gpr.256
+ // CHECK: insertelement <8 x i32> undef, i32 %{{.*}}, i32 0
+ // CHECK: insertelement <8 x i32> %{{.*}}, i32 %{{.*}}, i32 1
+ // CHECK: insertelement <8 x i32> %{{.*}}, i32 %{{.*}}, i32 2
+ // CHECK: insertelement <8 x i32> %{{.*}}, i32 %{{.*}}, i32 3
+ // CHECK: insertelement <8 x i32> %{{.*}}, i32 %{{.*}}, i32 4
+ // CHECK: insertelement <8 x i32> %{{.*}}, i32 %{{.*}}, i32 5
+ // CHECK: insertelement <8 x i32> %{{.*}}, i32 %{{.*}}, i32 6
+ // CHECK: insertelement <8 x i32> %{{.*}}, i32 %{{.*}}, i32 7
+ // CHECK: select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}}
return _mm256_mask_set1_epi32(__O, __M, 5);
}
__m256i test_mm256_maskz_set1_epi32(__mmask8 __M) {
// CHECK-LABEL: @test_mm256_maskz_set1_epi32
- // CHECK: @llvm.x86.avx512.mask.pbroadcast.d.gpr.256
+ // CHECK: insertelement <8 x i32> undef, i32 %{{.*}}, i32 0
+ // CHECK: insertelement <8 x i32> %{{.*}}, i32 %{{.*}}, i32 1
+ // CHECK: insertelement <8 x i32> %{{.*}}, i32 %{{.*}}, i32 2
+ // CHECK: insertelement <8 x i32> %{{.*}}, i32 %{{.*}}, i32 3
+ // CHECK: insertelement <8 x i32> %{{.*}}, i32 %{{.*}}, i32 4
+ // CHECK: insertelement <8 x i32> %{{.*}}, i32 %{{.*}}, i32 5
+ // CHECK: insertelement <8 x i32> %{{.*}}, i32 %{{.*}}, i32 6
+ // CHECK: insertelement <8 x i32> %{{.*}}, i32 %{{.*}}, i32 7
+ // CHECK: select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}}
return _mm256_maskz_set1_epi32(__M, 5);
}
#ifdef __x86_64__
__m128i test_mm_mask_set1_epi64(__m128i __O, __mmask8 __M, long long __A) {
// CHECK-LABEL: @test_mm_mask_set1_epi64
- // CHECK: @llvm.x86.avx512.mask.pbroadcast.q.gpr.128
+ // CHECK: insertelement <2 x i64> undef, i64 %{{.*}}, i32 0
+ // CHECK: insertelement <2 x i64> %{{.*}}, i64 %{{.*}}, i32 1
+ // CHECK: shufflevector <8 x i1> %{{.*}}, <8 x i1> %{{.*}}, <2 x i32> <i32 0, i32 1>
+ // CHECK: select <2 x i1> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}}
return _mm_mask_set1_epi64(__O, __M, __A);
}
__m128i test_mm_maskz_set1_epi64(__mmask8 __M, long long __A) {
// CHECK-LABEL: @test_mm_maskz_set1_epi64
- // CHECK: @llvm.x86.avx512.mask.pbroadcast.q.gpr.128
+ // CHECK: insertelement <2 x i64> undef, i64 %{{.*}}, i32 0
+ // CHECK: insertelement <2 x i64> %{{.*}}, i64 %{{.*}}, i32 1
+ // CHECK: shufflevector <8 x i1> %{{.*}}, <8 x i1> %{{.*}}, <2 x i32> <i32 0, i32 1>
+ // CHECK: select <2 x i1> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}}
return _mm_maskz_set1_epi64(__M, __A);
}
__m256i test_mm256_mask_set1_epi64(__m256i __O, __mmask8 __M, long long __A) {
// CHECK-LABEL: @test_mm256_mask_set1_epi64
- // CHECK: @llvm.x86.avx512.mask.pbroadcast.q.gpr.256
+ // CHECK: insertelement <4 x i64> undef, i64 %{{.*}}, i32 0
+ // CHECK: insertelement <4 x i64> %{{.*}}, i64 %{{.*}}, i32 1
+ // CHECK: insertelement <4 x i64> %{{.*}}, i64 %{{.*}}, i32 2
+ // CHECK: insertelement <4 x i64> %{{.*}}, i64 %{{.*}}, i32 3
+ // CHECK: shufflevector <8 x i1> %{{.*}}, <8 x i1> %{{.*}}, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
+ // CHECK: select <4 x i1> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}}
return _mm256_mask_set1_epi64(__O, __M, __A);
}
__m256i test_mm256_maskz_set1_epi64(__mmask8 __M, long long __A) {
// CHECK-LABEL: @test_mm256_maskz_set1_epi64
- // CHECK: @llvm.x86.avx512.mask.pbroadcast.q.gpr.256
+ // CHECK: insertelement <4 x i64> undef, i64 %{{.*}}, i32 0
+ // CHECK: insertelement <4 x i64> %{{.*}}, i64 %{{.*}}, i32 1
+ // CHECK: insertelement <4 x i64> %{{.*}}, i64 %{{.*}}, i32 2
+ // CHECK: insertelement <4 x i64> %{{.*}}, i64 %{{.*}}, i32 3
+ // CHECK: shufflevector <8 x i1> %{{.*}}, <8 x i1> %{{.*}}, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
+ // CHECK: select <4 x i1> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}}
return _mm256_maskz_set1_epi64(__M, __A);
}
#endif
@@ -5120,99 +5188,124 @@ __m256 test_mm256_maskz_permutevar_ps(__mmask8 __U, __m256 __A, __m256i __C) {
__mmask8 test_mm_test_epi32_mask(__m128i __A, __m128i __B) {
// CHECK-LABEL: @test_mm_test_epi32_mask
- // CHECK: @llvm.x86.avx512.ptestm.d.128
+ // CHECK: and <2 x i64> %{{.*}}, %{{.*}}
+ // CHECK: icmp ne <4 x i32> %{{.*}}, %{{.*}}
return _mm_test_epi32_mask(__A, __B);
}
__mmask8 test_mm_mask_test_epi32_mask(__mmask8 __U, __m128i __A, __m128i __B) {
// CHECK-LABEL: @test_mm_mask_test_epi32_mask
- // CHECK: @llvm.x86.avx512.ptestm.d.128
+ // CHECK: and <2 x i64> %{{.*}}, %{{.*}}
+ // CHECK: icmp ne <4 x i32> %{{.*}}, %{{.*}}
+ // CHECK: and <4 x i1> %{{.*}}, %{{.*}}
return _mm_mask_test_epi32_mask(__U, __A, __B);
}
__mmask8 test_mm256_test_epi32_mask(__m256i __A, __m256i __B) {
// CHECK-LABEL: @test_mm256_test_epi32_mask
- // CHECK: @llvm.x86.avx512.ptestm.d.256
+ // CHECK: and <4 x i64> %{{.*}}, %{{.*}}
+ // CHECK: icmp ne <8 x i32> %{{.*}}, %{{.*}}
return _mm256_test_epi32_mask(__A, __B);
}
__mmask8 test_mm256_mask_test_epi32_mask(__mmask8 __U, __m256i __A, __m256i __B) {
// CHECK-LABEL: @test_mm256_mask_test_epi32_mask
- // CHECK: @llvm.x86.avx512.ptestm.d.256
+ // CHECK: and <4 x i64> %{{.*}}, %{{.*}}
+ // CHECK: icmp ne <8 x i32> %{{.*}}, %{{.*}}
+ // CHECK: and <8 x i1> %{{.*}}, %{{.*}}
return _mm256_mask_test_epi32_mask(__U, __A, __B);
}
__mmask8 test_mm_test_epi64_mask(__m128i __A, __m128i __B) {
// CHECK-LABEL: @test_mm_test_epi64_mask
- // CHECK: @llvm.x86.avx512.ptestm.q.128
+ // CHECK: and <2 x i64> %{{.*}}, %{{.*}}
+ // CHECK: icmp ne <2 x i64> %{{.*}}, %{{.*}}
return _mm_test_epi64_mask(__A, __B);
}
__mmask8 test_mm_mask_test_epi64_mask(__mmask8 __U, __m128i __A, __m128i __B) {
// CHECK-LABEL: @test_mm_mask_test_epi64_mask
- // CHECK: @llvm.x86.avx512.ptestm.q.128
+ // CHECK: and <2 x i64> %{{.*}}, %{{.*}}
+ // CHECK: icmp ne <2 x i64> %{{.*}}, %{{.*}}
+ // CHECK: and <2 x i1> %{{.*}}, %{{.*}}
return _mm_mask_test_epi64_mask(__U, __A, __B);
}
__mmask8 test_mm256_test_epi64_mask(__m256i __A, __m256i __B) {
// CHECK-LABEL: @test_mm256_test_epi64_mask
- // CHECK: @llvm.x86.avx512.ptestm.q.256
+ // CHECK: and <4 x i64> %{{.*}}, %{{.*}}
+ // CHECK: icmp ne <4 x i64> %{{.*}}, %{{.*}}
return _mm256_test_epi64_mask(__A, __B);
}
__mmask8 test_mm256_mask_test_epi64_mask(__mmask8 __U, __m256i __A, __m256i __B) {
// CHECK-LABEL: @test_mm256_mask_test_epi64_mask
- // CHECK: @llvm.x86.avx512.ptestm.q.256
+ // CHECK: and <4 x i64> %{{.*}}, %{{.*}}
+ // CHECK: icmp ne <4 x i64> %{{.*}}, %{{.*}}
+ // CHECK: and <4 x i1> %{{.*}}, %{{.*}}
return _mm256_mask_test_epi64_mask(__U, __A, __B);
}
__mmask8 test_mm_testn_epi32_mask(__m128i __A, __m128i __B) {
// CHECK-LABEL: @test_mm_testn_epi32_mask
- // CHECK: @llvm.x86.avx512.ptestnm.d.128
+ // CHECK: and <2 x i64> %{{.*}}, %{{.*}}
+ // CHECK: icmp eq <4 x i32> %{{.*}}, %{{.*}}
return _mm_testn_epi32_mask(__A, __B);
}
__mmask8 test_mm_mask_testn_epi32_mask(__mmask8 __U, __m128i __A, __m128i __B) {
// CHECK-LABEL: @test_mm_mask_testn_epi32_mask
- // CHECK: @llvm.x86.avx512.ptestnm.d.128
+ // CHECK: and <2 x i64> %{{.*}}, %{{.*}}
+ // CHECK: icmp eq <4 x i32> %{{.*}}, %{{.*}}
+ // CHECK: and <4 x i1> %{{.*}}, %{{.*}}
return _mm_mask_testn_epi32_mask(__U, __A, __B);
}
__mmask8 test_mm256_testn_epi32_mask(__m256i __A, __m256i __B) {
// CHECK-LABEL: @test_mm256_testn_epi32_mask
- // CHECK: @llvm.x86.avx512.ptestnm.d.256
+ // CHECK: and <4 x i64> %{{.*}}, %{{.*}}
+ // CHECK: icmp eq <8 x i32> %{{.*}}, %{{.*}}
return _mm256_testn_epi32_mask(__A, __B);
}
__mmask8 test_mm256_mask_testn_epi32_mask(__mmask8 __U, __m256i __A, __m256i __B) {
// CHECK-LABEL: @test_mm256_mask_testn_epi32_mask
- // CHECK: @llvm.x86.avx512.ptestnm.d.256
+ // CHECK: and <4 x i64> %{{.*}}, %{{.*}}
+ // CHECK: icmp eq <8 x i32> %{{.*}}, %{{.*}}
+ // CHECK: and <8 x i1> %{{.*}}, %{{.*}}
return _mm256_mask_testn_epi32_mask(__U, __A, __B);
}
__mmask8 test_mm_testn_epi64_mask(__m128i __A, __m128i __B) {
// CHECK-LABEL: @test_mm_testn_epi64_mask
- // CHECK: @llvm.x86.avx512.ptestnm.q.128
+ // CHECK: and <2 x i64> %{{.*}}, %{{.*}}
+ // CHECK: icmp eq <2 x i64> %{{.*}}, %{{.*}}
return _mm_testn_epi64_mask(__A, __B);
}
__mmask8 test_mm_mask_testn_epi64_mask(__mmask8 __U, __m128i __A, __m128i __B) {
// CHECK-LABEL: @test_mm_mask_testn_epi64_mask
- // CHECK: @llvm.x86.avx512.ptestnm.q.128
+ // CHECK: and <2 x i64> %{{.*}}, %{{.*}}
+ // CHECK: icmp eq <2 x i64> %{{.*}}, %{{.*}}
+ // CHECK: and <2 x i1> %{{.*}}, %{{.*}}
return _mm_mask_testn_epi64_mask(__U, __A, __B);
}
__mmask8 test_mm256_testn_epi64_mask(__m256i __A, __m256i __B) {
// CHECK-LABEL: @test_mm256_testn_epi64_mask
- // CHECK: @llvm.x86.avx512.ptestnm.q.256
+ // CHECK: and <4 x i64> %{{.*}}, %{{.*}}
+ // CHECK: icmp eq <4 x i64> %{{.*}}, %{{.*}}
return _mm256_testn_epi64_mask(__A, __B);
}
__mmask8 test_mm256_mask_testn_epi64_mask(__mmask8 __U, __m256i __A, __m256i __B) {
// CHECK-LABEL: @test_mm256_mask_testn_epi64_mask
- // CHECK: @llvm.x86.avx512.ptestnm.q.256
+ // CHECK: and <4 x i64> %{{.*}}, %{{.*}}
+ // CHECK: icmp eq <4 x i64> %{{.*}}, %{{.*}}
+ // CHECK: and <4 x i1> %{{.*}}, %{{.*}}
return _mm256_mask_testn_epi64_mask(__U, __A, __B);
}
+
__m128i test_mm_mask_unpackhi_epi32(__m128i __W, __mmask8 __U, __m128i __A, __m128i __B) {
// CHECK-LABEL: @test_mm_mask_unpackhi_epi32
// CHECK: shufflevector <4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> <i32 2, i32 6, i32 3, i32 7>
@@ -5534,73 +5627,85 @@ __m256i test_mm256_maskz_ternarylogic_epi64(__mmask8 __U, __m256i __A, __m256i _
}
__m256 test_mm256_shuffle_f32x4(__m256 __A, __m256 __B) {
// CHECK-LABEL: @test_mm256_shuffle_f32x4
- // CHECK: @llvm.x86.avx512.mask.shuf.f32x4
+ // CHECK: shufflevector <8 x float> %{{.*}}, <8 x float> %{{.*}}, <8 x i32> <i32 4, i32 5, i32 6, i32 7, i32 12, i32 13, i32 14, i32 15>
return _mm256_shuffle_f32x4(__A, __B, 3);
}
__m256 test_mm256_mask_shuffle_f32x4(__m256 __W, __mmask8 __U, __m256 __A, __m256 __B) {
// CHECK-LABEL: @test_mm256_mask_shuffle_f32x4
- // CHECK: @llvm.x86.avx512.mask.shuf.f32x4
+ // CHECK: shufflevector <8 x float> %{{.*}}, <8 x float> %{{.*}}, <8 x i32> <i32 4, i32 5, i32 6, i32 7, i32 12, i32 13, i32 14, i32 15>
+ // CHECK: select <8 x i1> %{{.*}}, <8 x float> %{{.*}}, <8 x float> %{{.*}}
return _mm256_mask_shuffle_f32x4(__W, __U, __A, __B, 3);
}
__m256 test_mm256_maskz_shuffle_f32x4(__mmask8 __U, __m256 __A, __m256 __B) {
// CHECK-LABEL: @test_mm256_maskz_shuffle_f32x4
- // CHECK: @llvm.x86.avx512.mask.shuf.f32x4
+ // CHECK: shufflevector <8 x float> %{{.*}}, <8 x float> %{{.*}}, <8 x i32> <i32 4, i32 5, i32 6, i32 7, i32 12, i32 13, i32 14, i32 15>
+ // CHECK: select <8 x i1> %{{.*}}, <8 x float> %{{.*}}, <8 x float> %{{.*}}
return _mm256_maskz_shuffle_f32x4(__U, __A, __B, 3);
}
__m256d test_mm256_shuffle_f64x2(__m256d __A, __m256d __B) {
// CHECK-LABEL: @test_mm256_shuffle_f64x2
- // CHECK: @llvm.x86.avx512.mask.shuf.f64x2
+ // CHECK: shufflevector <4 x double> %{{.*}}, <4 x double> %{{.*}}, <4 x i32> <i32 2, i32 3, i32 6, i32 7>
return _mm256_shuffle_f64x2(__A, __B, 3);
}
__m256d test_mm256_mask_shuffle_f64x2(__m256d __W, __mmask8 __U, __m256d __A, __m256d __B) {
// CHECK-LABEL: @test_mm256_mask_shuffle_f64x2
- // CHECK: @llvm.x86.avx512.mask.shuf.f64x2
+ // CHECK: shufflevector <4 x double> %{{.*}}, <4 x double> %{{.*}}, <4 x i32> <i32 2, i32 3, i32 6, i32 7>
+ // CHECK: shufflevector <8 x i1> %{{.*}}, <8 x i1> %{{.*}}, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
+ // CHECK: select <4 x i1> %{{.*}}, <4 x double> %{{.*}}, <4 x double> %{{.*}}
return _mm256_mask_shuffle_f64x2(__W, __U, __A, __B, 3);
}
__m256d test_mm256_maskz_shuffle_f64x2(__mmask8 __U, __m256d __A, __m256d __B) {
// CHECK-LABEL: @test_mm256_maskz_shuffle_f64x2
- // CHECK: @llvm.x86.avx512.mask.shuf.f64x2
+ // CHECK: shufflevector <4 x double> %{{.*}}, <4 x double> %{{.*}}, <4 x i32> <i32 2, i32 3, i32 6, i32 7>
+ // CHECK: shufflevector <8 x i1> %{{.*}}, <8 x i1> %{{.*}}, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
+ // CHECK: select <4 x i1> %{{.*}}, <4 x double> %{{.*}}, <4 x double> %{{.*}}
return _mm256_maskz_shuffle_f64x2(__U, __A, __B, 3);
}
__m256i test_mm256_shuffle_i32x4(__m256i __A, __m256i __B) {
// CHECK-LABEL: @test_mm256_shuffle_i32x4
- // CHECK: @llvm.x86.avx512.mask.shuf.i32x4
+ // CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> %{{.*}}, <4 x i32> <i32 2, i32 3, i32 6, i32 7>
return _mm256_shuffle_i32x4(__A, __B, 3);
}
__m256i test_mm256_mask_shuffle_i32x4(__m256i __W, __mmask8 __U, __m256i __A, __m256i __B) {
// CHECK-LABEL: @test_mm256_mask_shuffle_i32x4
- // CHECK: @llvm.x86.avx512.mask.shuf.i32x4
+ // CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> %{{.*}}, <4 x i32> <i32 2, i32 3, i32 6, i32 7>
+ // CHECK: select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}}
return _mm256_mask_shuffle_i32x4(__W, __U, __A, __B, 3);
}
__m256i test_mm256_maskz_shuffle_i32x4(__mmask8 __U, __m256i __A, __m256i __B) {
// CHECK-LABEL: @test_mm256_maskz_shuffle_i32x4
- // CHECK: @llvm.x86.avx512.mask.shuf.i32x4
+ // CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> %{{.*}}, <4 x i32> <i32 2, i32 3, i32 6, i32 7>
+ // CHECK: select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}}
return _mm256_maskz_shuffle_i32x4(__U, __A, __B, 3);
}
__m256i test_mm256_shuffle_i64x2(__m256i __A, __m256i __B) {
// CHECK-LABEL: @test_mm256_shuffle_i64x2
- // CHECK: @llvm.x86.avx512.mask.shuf.i64x2
+ // CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> %{{.*}}, <4 x i32> <i32 2, i32 3, i32 6, i32 7>
return _mm256_shuffle_i64x2(__A, __B, 3);
}
__m256i test_mm256_mask_shuffle_i64x2(__m256i __W, __mmask8 __U, __m256i __A, __m256i __B) {
// CHECK-LABEL: @test_mm256_mask_shuffle_i64x2
- // CHECK: @llvm.x86.avx512.mask.shuf.i64x2
+ // CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> %{{.*}}, <4 x i32> <i32 2, i32 3, i32 6, i32 7>
+ // CHECK: shufflevector <8 x i1> %{{.*}}, <8 x i1> %{{.*}}, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
+ // CHECK: select <4 x i1> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}}
return _mm256_mask_shuffle_i64x2(__W, __U, __A, __B, 3);
}
__m256i test_mm256_maskz_shuffle_i64x2(__mmask8 __U, __m256i __A, __m256i __B) {
// CHECK-LABEL: @test_mm256_maskz_shuffle_i64x2
- // CHECK: @llvm.x86.avx512.mask.shuf.i64x2
+ // CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> %{{.*}}, <4 x i32> <i32 2, i32 3, i32 6, i32 7>
+ // CHECK: shufflevector <8 x i1> %{{.*}}, <8 x i1> %{{.*}}, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
+ // CHECK: select <4 x i1> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}}
return _mm256_maskz_shuffle_i64x2(__U, __A, __B, 3);
}
diff --git a/test/CodeGen/avx512vlbw-builtins.c b/test/CodeGen/avx512vlbw-builtins.c
index 5a7283608bc3..23fbd4026aaa 100644
--- a/test/CodeGen/avx512vlbw-builtins.c
+++ b/test/CodeGen/avx512vlbw-builtins.c
@@ -898,57 +898,73 @@ __m256i test_mm256_mask_blend_epi16(__mmask16 __U, __m256i __A, __m256i __W) {
__m128i test_mm_mask_abs_epi8(__m128i __W, __mmask16 __U, __m128i __A) {
// CHECK-LABEL: @test_mm_mask_abs_epi8
- // CHECK: @llvm.x86.ssse3.pabs.b
- // CHECK: select <16 x i1> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}}
+ // CHECK: [[SUB:%.*]] = sub <16 x i8> zeroinitializer, [[A:%.*]]
+ // CHECK: [[CMP:%.*]] = icmp sgt <16 x i8> [[A]], zeroinitializer
+ // CHECK: [[SEL:%.*]] = select <16 x i1> [[CMP]], <16 x i8> [[A]], <16 x i8> [[SUB]]
+ // CHECK: select <16 x i1> %{{.*}}, <16 x i8> [[SEL]], <16 x i8> %{{.*}}
return _mm_mask_abs_epi8(__W,__U,__A);
}
__m128i test_mm_maskz_abs_epi8(__mmask16 __U, __m128i __A) {
// CHECK-LABEL: @test_mm_maskz_abs_epi8
- // CHECK: @llvm.x86.ssse3.pabs.b
- // CHECK: select <16 x i1> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}}
+ // CHECK: [[SUB:%.*]] = sub <16 x i8> zeroinitializer, [[A:%.*]]
+ // CHECK: [[CMP:%.*]] = icmp sgt <16 x i8> [[A]], zeroinitializer
+ // CHECK: [[SEL:%.*]] = select <16 x i1> [[CMP]], <16 x i8> [[A]], <16 x i8> [[SUB]]
+ // CHECK: select <16 x i1> %{{.*}}, <16 x i8> [[SEL]], <16 x i8> %{{.*}}
return _mm_maskz_abs_epi8(__U,__A);
}
__m256i test_mm256_mask_abs_epi8(__m256i __W, __mmask32 __U, __m256i __A) {
// CHECK-LABEL: @test_mm256_mask_abs_epi8
- // CHECK: @llvm.x86.avx2.pabs.b
- // CHECK: select <32 x i1> %{{.*}}, <32 x i8> %{{.*}}, <32 x i8> %{{.*}}
+ // CHECK: [[SUB:%.*]] = sub <32 x i8> zeroinitializer, [[A:%.*]]
+ // CHECK: [[CMP:%.*]] = icmp sgt <32 x i8> [[A]], zeroinitializer
+ // CHECK: [[SEL:%.*]] = select <32 x i1> [[CMP]], <32 x i8> [[A]], <32 x i8> [[SUB]]
+ // CHECK: select <32 x i1> %{{.*}}, <32 x i8> [[SEL]], <32 x i8> %{{.*}}
return _mm256_mask_abs_epi8(__W,__U,__A);
}
__m256i test_mm256_maskz_abs_epi8(__mmask32 __U, __m256i __A) {
// CHECK-LABEL: @test_mm256_maskz_abs_epi8
- // CHECK: @llvm.x86.avx2.pabs.b
- // CHECK: select <32 x i1> %{{.*}}, <32 x i8> %{{.*}}, <32 x i8> %{{.*}}
+ // CHECK: [[SUB:%.*]] = sub <32 x i8> zeroinitializer, [[A:%.*]]
+ // CHECK: [[CMP:%.*]] = icmp sgt <32 x i8> [[A]], zeroinitializer
+ // CHECK: [[SEL:%.*]] = select <32 x i1> [[CMP]], <32 x i8> [[A]], <32 x i8> [[SUB]]
+ // CHECK: select <32 x i1> %{{.*}}, <32 x i8> [[SEL]], <32 x i8> %{{.*}}
return _mm256_maskz_abs_epi8(__U,__A);
}
__m128i test_mm_mask_abs_epi16(__m128i __W, __mmask8 __U, __m128i __A) {
// CHECK-LABEL: @test_mm_mask_abs_epi16
- // CHECK: @llvm.x86.ssse3.pabs.w
- // CHECK: select <8 x i1> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}
+ // CHECK: [[SUB:%.*]] = sub <8 x i16> zeroinitializer, [[A:%.*]]
+ // CHECK: [[CMP:%.*]] = icmp sgt <8 x i16> [[A]], zeroinitializer
+ // CHECK: [[SEL:%.*]] = select <8 x i1> [[CMP]], <8 x i16> [[A]], <8 x i16> [[SUB]]
+ // CHECK: select <8 x i1> %{{.*}}, <8 x i16> [[SEL]], <8 x i16> %{{.*}}
return _mm_mask_abs_epi16(__W,__U,__A);
}
__m128i test_mm_maskz_abs_epi16(__mmask8 __U, __m128i __A) {
// CHECK-LABEL: @test_mm_maskz_abs_epi16
- // CHECK: @llvm.x86.ssse3.pabs.w
- // CHECK: select <8 x i1> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}
+ // CHECK: [[SUB:%.*]] = sub <8 x i16> zeroinitializer, [[A:%.*]]
+ // CHECK: [[CMP:%.*]] = icmp sgt <8 x i16> [[A]], zeroinitializer
+ // CHECK: [[SEL:%.*]] = select <8 x i1> [[CMP]], <8 x i16> [[A]], <8 x i16> [[SUB]]
+ // CHECK: select <8 x i1> %{{.*}}, <8 x i16> [[SEL]], <8 x i16> %{{.*}}
return _mm_maskz_abs_epi16(__U,__A);
}
__m256i test_mm256_mask_abs_epi16(__m256i __W, __mmask16 __U, __m256i __A) {
// CHECK-LABEL: @test_mm256_mask_abs_epi16
- // CHECK: @llvm.x86.avx2.pabs.w
- // CHECK: select <16 x i1> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}}
+ // CHECK: [[SUB:%.*]] = sub <16 x i16> zeroinitializer, [[A:%.*]]
+ // CHECK: [[CMP:%.*]] = icmp sgt <16 x i16> [[A]], zeroinitializer
+ // CHECK: [[SEL:%.*]] = select <16 x i1> [[CMP]], <16 x i16> [[A]], <16 x i16> [[SUB]]
+ // CHECK: select <16 x i1> %{{.*}}, <16 x i16> [[SEL]], <16 x i16> %{{.*}}
return _mm256_mask_abs_epi16(__W,__U,__A);
}
__m256i test_mm256_maskz_abs_epi16(__mmask16 __U, __m256i __A) {
// CHECK-LABEL: @test_mm256_maskz_abs_epi16
- // CHECK: @llvm.x86.avx2.pabs.w
- // CHECK: select <16 x i1> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}}
+ // CHECK: [[SUB:%.*]] = sub <16 x i16> zeroinitializer, [[A:%.*]]
+ // CHECK: [[CMP:%.*]] = icmp sgt <16 x i16> [[A]], zeroinitializer
+ // CHECK: [[SEL:%.*]] = select <16 x i1> [[CMP]], <16 x i16> [[A]], <16 x i16> [[SUB]]
+ // CHECK: select <16 x i1> %{{.*}}, <16 x i16> [[SEL]], <16 x i16> %{{.*}}
return _mm256_maskz_abs_epi16(__U,__A);
}
@@ -1155,49 +1171,101 @@ __m256i test_mm256_maskz_adds_epu16(__mmask16 __U, __m256i __A, __m256i __B) {
}
__m128i test_mm_mask_avg_epu8(__m128i __W, __mmask16 __U, __m128i __A, __m128i __B) {
// CHECK-LABEL: @test_mm_mask_avg_epu8
- // CHECK: @llvm.x86.sse2.pavg.b
+ // CHECK-NOT: @llvm.x86.sse2.pavg.b
+ // CHECK: zext <16 x i8> %{{.*}} to <16 x i16>
+ // CHECK: zext <16 x i8> %{{.*}} to <16 x i16>
+ // CHECK: add <16 x i16> %{{.*}}, %{{.*}}
+ // CHECK: add <16 x i16> %{{.*}}, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
+ // CHECK: lshr <16 x i16> %{{.*}}, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
+ // CHECK: trunc <16 x i16> %{{.*}} to <16 x i8>
// CHECK: select <16 x i1> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}}
return _mm_mask_avg_epu8(__W,__U,__A,__B);
}
__m128i test_mm_maskz_avg_epu8(__mmask16 __U, __m128i __A, __m128i __B) {
// CHECK-LABEL: @test_mm_maskz_avg_epu8
- // CHECK: @llvm.x86.sse2.pavg.b
+ // CHECK-NOT: @llvm.x86.sse2.pavg.b
+ // CHECK: zext <16 x i8> %{{.*}} to <16 x i16>
+ // CHECK: zext <16 x i8> %{{.*}} to <16 x i16>
+ // CHECK: add <16 x i16> %{{.*}}, %{{.*}}
+ // CHECK: add <16 x i16> %{{.*}}, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
+ // CHECK: lshr <16 x i16> %{{.*}}, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
+ // CHECK: trunc <16 x i16> %{{.*}} to <16 x i8>
+ // CHECK: store <2 x i64> zeroinitializer
// CHECK: select <16 x i1> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}}
return _mm_maskz_avg_epu8(__U,__A,__B);
}
__m256i test_mm256_mask_avg_epu8(__m256i __W, __mmask32 __U, __m256i __A, __m256i __B) {
// CHECK-LABEL: @test_mm256_mask_avg_epu8
- // CHECK: @llvm.x86.avx2.pavg.b
+ // CHECK-NOT: @llvm.x86.avx2.pavg.b
+ // CHECK: zext <32 x i8> %{{.*}} to <32 x i16>
+ // CHECK: zext <32 x i8> %{{.*}} to <32 x i16>
+ // CHECK: add <32 x i16> %{{.*}}, %{{.*}}
+ // CHECK: add <32 x i16> %{{.*}}, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
+ // CHECK: lshr <32 x i16> %{{.*}}, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
+ // CHECK: trunc <32 x i16> %{{.*}} to <32 x i8>
// CHECK: select <32 x i1> %{{.*}}, <32 x i8> %{{.*}}, <32 x i8> %{{.*}}
return _mm256_mask_avg_epu8(__W,__U,__A,__B);
}
__m256i test_mm256_maskz_avg_epu8(__mmask32 __U, __m256i __A, __m256i __B) {
// CHECK-LABEL: @test_mm256_maskz_avg_epu8
- // CHECK: @llvm.x86.avx2.pavg.b
+ // CHECK-NOT: @llvm.x86.avx2.pavg.b
+ // CHECK: zext <32 x i8> %{{.*}} to <32 x i16>
+ // CHECK: zext <32 x i8> %{{.*}} to <32 x i16>
+ // CHECK: add <32 x i16> %{{.*}}, %{{.*}}
+ // CHECK: add <32 x i16> %{{.*}}, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
+ // CHECK: lshr <32 x i16> %{{.*}}, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
+ // CHECK: trunc <32 x i16> %{{.*}} to <32 x i8>
+ // CHECK: store <4 x i64> zeroinitializer
// CHECK: select <32 x i1> %{{.*}}, <32 x i8> %{{.*}}, <32 x i8> %{{.*}}
return _mm256_maskz_avg_epu8(__U,__A,__B);
}
__m128i test_mm_mask_avg_epu16(__m128i __W, __mmask8 __U, __m128i __A, __m128i __B) {
// CHECK-LABEL: @test_mm_mask_avg_epu16
- // CHECK: @llvm.x86.sse2.pavg.w
+ // CHECK-NOT: @llvm.x86.sse2.pavg.w
+ // CHECK: zext <8 x i16> %{{.*}} to <8 x i32>
+ // CHECK: zext <8 x i16> %{{.*}} to <8 x i32>
+ // CHECK: add <8 x i32> %{{.*}}, %{{.*}}
+ // CHECK: add <8 x i32> %{{.*}}, <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1>
+ // CHECK: lshr <8 x i32> %{{.*}}, <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1>
+ // CHECK: trunc <8 x i32> %{{.*}} to <8 x i16>
// CHECK: select <8 x i1> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}
return _mm_mask_avg_epu16(__W,__U,__A,__B);
}
__m128i test_mm_maskz_avg_epu16(__mmask8 __U, __m128i __A, __m128i __B) {
// CHECK-LABEL: @test_mm_maskz_avg_epu16
- // CHECK: @llvm.x86.sse2.pavg.w
+ // CHECK-NOT: @llvm.x86.sse2.pavg.w
+ // CHECK: zext <8 x i16> %{{.*}} to <8 x i32>
+ // CHECK: zext <8 x i16> %{{.*}} to <8 x i32>
+ // CHECK: add <8 x i32> %{{.*}}, %{{.*}}
+ // CHECK: add <8 x i32> %{{.*}}, <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1>
+ // CHECK: lshr <8 x i32> %{{.*}}, <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1>
+ // CHECK: trunc <8 x i32> %{{.*}} to <8 x i16>
+ // CHECK: store <2 x i64> zeroinitializer
// CHECK: select <8 x i1> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}
return _mm_maskz_avg_epu16(__U,__A,__B);
}
__m256i test_mm256_mask_avg_epu16(__m256i __W, __mmask16 __U, __m256i __A, __m256i __B) {
// CHECK-LABEL: @test_mm256_mask_avg_epu16
- // CHECK: @llvm.x86.avx2.pavg.w
+ // CHECK-NOT: @llvm.x86.avx2.pavg.w
+ // CHECK: zext <16 x i16> %{{.*}} to <16 x i32>
+ // CHECK: zext <16 x i16> %{{.*}} to <16 x i32>
+ // CHECK: add <16 x i32> %{{.*}}, %{{.*}}
+ // CHECK: add <16 x i32> %{{.*}}, <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1>
+ // CHECK: lshr <16 x i32> %{{.*}}, <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1>
+ // CHECK: trunc <16 x i32> %{{.*}} to <16 x i16>
// CHECK: select <16 x i1> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}}
return _mm256_mask_avg_epu16(__W,__U,__A,__B);
}
__m256i test_mm256_maskz_avg_epu16(__mmask16 __U, __m256i __A, __m256i __B) {
// CHECK-LABEL: @test_mm256_maskz_avg_epu16
- // CHECK: @llvm.x86.avx2.pavg.w
+ // CHECK-NOT: @llvm.x86.avx2.pavg.w
+ // CHECK: zext <16 x i16> %{{.*}} to <16 x i32>
+ // CHECK: zext <16 x i16> %{{.*}} to <16 x i32>
+ // CHECK: add <16 x i32> %{{.*}}, %{{.*}}
+ // CHECK: add <16 x i32> %{{.*}}, <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1>
+ // CHECK: lshr <16 x i32> %{{.*}}, <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1>
+ // CHECK: trunc <16 x i32> %{{.*}} to <16 x i16>
+ // CHECK: store <4 x i64> zeroinitializer
// CHECK: select <16 x i1> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}}
return _mm256_maskz_avg_epu16(__U,__A,__B);
}
@@ -2413,97 +2481,121 @@ void test_mm256_mask_storeu_epi8(void *__P, __mmask32 __U, __m256i __A) {
}
__mmask16 test_mm_test_epi8_mask(__m128i __A, __m128i __B) {
// CHECK-LABEL: @test_mm_test_epi8_mask
- // CHECK: @llvm.x86.avx512.ptestm.b.128
+ // CHECK: and <2 x i64> %{{.*}}, %{{.*}}
+ // CHECK: icmp ne <16 x i8> %{{.*}}, %{{.*}}
return _mm_test_epi8_mask(__A, __B);
}
__mmask16 test_mm_mask_test_epi8_mask(__mmask16 __U, __m128i __A, __m128i __B) {
// CHECK-LABEL: @test_mm_mask_test_epi8_mask
- // CHECK: @llvm.x86.avx512.ptestm.b.128
+ // CHECK: and <2 x i64> %{{.*}}, %{{.*}}
+ // CHECK: icmp ne <16 x i8> %{{.*}}, %{{.*}}
+ // CHECK: and <16 x i1> %{{.*}}, %{{.*}}
return _mm_mask_test_epi8_mask(__U, __A, __B);
}
__mmask32 test_mm256_test_epi8_mask(__m256i __A, __m256i __B) {
// CHECK-LABEL: @test_mm256_test_epi8_mask
- // CHECK: @llvm.x86.avx512.ptestm.b.256
+ // CHECK: and <4 x i64> %{{.*}}, %{{.*}}
+ // CHECK: icmp ne <32 x i8> %{{.*}}, %{{.*}}
return _mm256_test_epi8_mask(__A, __B);
}
__mmask32 test_mm256_mask_test_epi8_mask(__mmask32 __U, __m256i __A, __m256i __B) {
// CHECK-LABEL: @test_mm256_mask_test_epi8_mask
- // CHECK: @llvm.x86.avx512.ptestm.b.256
+ // CHECK: and <4 x i64> %{{.*}}, %{{.*}}
+ // CHECK: icmp ne <32 x i8> %{{.*}}, %{{.*}}
+ // CHECK: and <32 x i1> %{{.*}}, %{{.*}}
return _mm256_mask_test_epi8_mask(__U, __A, __B);
}
__mmask8 test_mm_test_epi16_mask(__m128i __A, __m128i __B) {
// CHECK-LABEL: @test_mm_test_epi16_mask
- // CHECK: @llvm.x86.avx512.ptestm.w.128
+ // CHECK: and <2 x i64> %{{.*}}, %{{.*}}
+ // CHECK: icmp ne <8 x i16> %{{.*}}, %{{.*}}
return _mm_test_epi16_mask(__A, __B);
}
__mmask8 test_mm_mask_test_epi16_mask(__mmask8 __U, __m128i __A, __m128i __B) {
// CHECK-LABEL: @test_mm_mask_test_epi16_mask
- // CHECK: @llvm.x86.avx512.ptestm.w.128
+ // CHECK: and <2 x i64> %{{.*}}, %{{.*}}
+ // CHECK: icmp ne <8 x i16> %{{.*}}, %{{.*}}
+ // CHECK: and <8 x i1> %{{.*}}, %{{.*}}
return _mm_mask_test_epi16_mask(__U, __A, __B);
}
__mmask16 test_mm256_test_epi16_mask(__m256i __A, __m256i __B) {
// CHECK-LABEL: @test_mm256_test_epi16_mask
- // CHECK: @llvm.x86.avx512.ptestm.w.256
+ // CHECK: and <4 x i64> %{{.*}}, %{{.*}}
+ // CHECK: icmp ne <16 x i16> %{{.*}}, %{{.*}}
return _mm256_test_epi16_mask(__A, __B);
}
__mmask16 test_mm256_mask_test_epi16_mask(__mmask16 __U, __m256i __A, __m256i __B) {
// CHECK-LABEL: @test_mm256_mask_test_epi16_mask
- // CHECK: @llvm.x86.avx512.ptestm.w.256
+ // CHECK: and <4 x i64> %{{.*}}, %{{.*}}
+ // CHECK: icmp ne <16 x i16> %{{.*}}, %{{.*}}
+ // CHECK: and <16 x i1> %{{.*}}, %{{.*}}
return _mm256_mask_test_epi16_mask(__U, __A, __B);
}
__mmask16 test_mm_testn_epi8_mask(__m128i __A, __m128i __B) {
// CHECK-LABEL: @test_mm_testn_epi8_mask
- // CHECK: @llvm.x86.avx512.ptestnm.b.128
+ // CHECK: and <2 x i64> %{{.*}}, %{{.*}}
+ // CHECK: icmp eq <16 x i8> %{{.*}}, %{{.*}}
return _mm_testn_epi8_mask(__A, __B);
}
__mmask16 test_mm_mask_testn_epi8_mask(__mmask16 __U, __m128i __A, __m128i __B) {
// CHECK-LABEL: @test_mm_mask_testn_epi8_mask
- // CHECK: @llvm.x86.avx512.ptestnm.b.128
+ // CHECK: and <2 x i64> %{{.*}}, %{{.*}}
+ // CHECK: icmp eq <16 x i8> %{{.*}}, %{{.*}}
+ // CHECK: and <16 x i1> %{{.*}}, %{{.*}}
return _mm_mask_testn_epi8_mask(__U, __A, __B);
}
__mmask32 test_mm256_testn_epi8_mask(__m256i __A, __m256i __B) {
// CHECK-LABEL: @test_mm256_testn_epi8_mask
- // CHECK: @llvm.x86.avx512.ptestnm.b.256
+ // CHECK: and <4 x i64> %{{.*}}, %{{.*}}
+ // CHECK: icmp eq <32 x i8> %{{.*}}, %{{.*}}
return _mm256_testn_epi8_mask(__A, __B);
}
__mmask32 test_mm256_mask_testn_epi8_mask(__mmask32 __U, __m256i __A, __m256i __B) {
// CHECK-LABEL: @test_mm256_mask_testn_epi8_mask
- // CHECK: @llvm.x86.avx512.ptestnm.b.256
+ // CHECK: and <4 x i64> %{{.*}}, %{{.*}}
+ // CHECK: icmp eq <32 x i8> %{{.*}}, %{{.*}}
+ // CHECK: and <32 x i1> %{{.*}}, %{{.*}}
return _mm256_mask_testn_epi8_mask(__U, __A, __B);
}
__mmask8 test_mm_testn_epi16_mask(__m128i __A, __m128i __B) {
// CHECK-LABEL: @test_mm_testn_epi16_mask
- // CHECK: @llvm.x86.avx512.ptestnm.w.128
+ // CHECK: and <2 x i64> %{{.*}}, %{{.*}}
+ // CHECK: icmp eq <8 x i16> %{{.*}}, %{{.*}}
return _mm_testn_epi16_mask(__A, __B);
}
__mmask8 test_mm_mask_testn_epi16_mask(__mmask8 __U, __m128i __A, __m128i __B) {
// CHECK-LABEL: @test_mm_mask_testn_epi16_mask
- // CHECK: @llvm.x86.avx512.ptestnm.w.128
+ // CHECK: and <2 x i64> %{{.*}}, %{{.*}}
+ // CHECK: icmp eq <8 x i16> %{{.*}}, %{{.*}}
+ // CHECK: and <8 x i1> %{{.*}}, %{{.*}}
return _mm_mask_testn_epi16_mask(__U, __A, __B);
}
__mmask16 test_mm256_testn_epi16_mask(__m256i __A, __m256i __B) {
// CHECK-LABEL: @test_mm256_testn_epi16_mask
- // CHECK: @llvm.x86.avx512.ptestnm.w.256
+ // CHECK: and <4 x i64> %{{.*}}, %{{.*}}
+ // CHECK: icmp eq <16 x i16> %{{.*}}, %{{.*}}
return _mm256_testn_epi16_mask(__A, __B);
}
__mmask16 test_mm256_mask_testn_epi16_mask(__mmask16 __U, __m256i __A, __m256i __B) {
// CHECK-LABEL: @test_mm256_mask_testn_epi16_mask
- // CHECK: @llvm.x86.avx512.ptestnm.w.256
+ // CHECK: and <4 x i64> %{{.*}}, %{{.*}}
+ // CHECK: icmp eq <16 x i16> %{{.*}}, %{{.*}}
+ // CHECK: and <16 x i1> %{{.*}}, %{{.*}}
return _mm256_mask_testn_epi16_mask(__U, __A, __B);
}
@@ -2602,28 +2694,195 @@ __m256i test_mm256_maskz_broadcastw_epi16(__mmask16 __M, __m128i __A) {
// CHECK: select <16 x i1> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}}
return _mm256_maskz_broadcastw_epi16(__M, __A);
}
+__m128i test_mm_mask_set1_epi8 (__m128i __O, __mmask16 __M, char __A){
+ // CHECK-LABEL: @test_mm_mask_set1_epi8
+ // CHECK: insertelement <16 x i8> undef, i8 %{{.*}}, i32 0
+ // CHECK: insertelement <16 x i8> %{{.*}}, i8 %{{.*}}, i32 1
+ // CHECK: insertelement <16 x i8> %{{.*}}, i8 %{{.*}}, i32 2
+ // CHECK: insertelement <16 x i8> %{{.*}}, i8 %{{.*}}, i32 3
+ // CHECK: insertelement <16 x i8> %{{.*}}, i8 %{{.*}}, i32 4
+ // CHECK: insertelement <16 x i8> %{{.*}}, i8 %{{.*}}, i32 5
+ // CHECK: insertelement <16 x i8> %{{.*}}, i8 %{{.*}}, i32 6
+ // CHECK: insertelement <16 x i8> %{{.*}}, i8 %{{.*}}, i32 7
+ // CHECK: insertelement <16 x i8> %{{.*}}, i8 %{{.*}}, i32 8
+ // CHECK: insertelement <16 x i8> %{{.*}}, i8 %{{.*}}, i32 9
+ // CHECK: insertelement <16 x i8> %{{.*}}, i8 %{{.*}}, i32 10
+ // CHECK: insertelement <16 x i8> %{{.*}}, i8 %{{.*}}, i32 11
+ // CHECK: insertelement <16 x i8> %{{.*}}, i8 %{{.*}}, i32 12
+ // CHECK: insertelement <16 x i8> %{{.*}}, i8 %{{.*}}, i32 13
+ // CHECK: insertelement <16 x i8> %{{.*}}, i8 %{{.*}}, i32 14
+ // CHECK: insertelement <16 x i8> %{{.*}}, i8 %{{.*}}, i32 15
+ // CHECK: select <16 x i1> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}}
+ return _mm_mask_set1_epi8(__O, __M, __A);
+}
+__m128i test_mm_maskz_set1_epi8 ( __mmask16 __M, char __A){
+ // CHECK-LABEL: @test_mm_maskz_set1_epi8
+ // CHECK: insertelement <16 x i8> undef, i8 %{{.*}}, i32 0
+ // CHECK: insertelement <16 x i8> %{{.*}}, i8 %{{.*}}, i32 1
+ // CHECK: insertelement <16 x i8> %{{.*}}, i8 %{{.*}}, i32 2
+ // CHECK: insertelement <16 x i8> %{{.*}}, i8 %{{.*}}, i32 3
+ // CHECK: insertelement <16 x i8> %{{.*}}, i8 %{{.*}}, i32 4
+ // CHECK: insertelement <16 x i8> %{{.*}}, i8 %{{.*}}, i32 5
+ // CHECK: insertelement <16 x i8> %{{.*}}, i8 %{{.*}}, i32 6
+ // CHECK: insertelement <16 x i8> %{{.*}}, i8 %{{.*}}, i32 7
+ // CHECK: insertelement <16 x i8> %{{.*}}, i8 %{{.*}}, i32 8
+ // CHECK: insertelement <16 x i8> %{{.*}}, i8 %{{.*}}, i32 9
+ // CHECK: insertelement <16 x i8> %{{.*}}, i8 %{{.*}}, i32 10
+ // CHECK: insertelement <16 x i8> %{{.*}}, i8 %{{.*}}, i32 11
+ // CHECK: insertelement <16 x i8> %{{.*}}, i8 %{{.*}}, i32 12
+ // CHECK: insertelement <16 x i8> %{{.*}}, i8 %{{.*}}, i32 13
+ // CHECK: insertelement <16 x i8> %{{.*}}, i8 %{{.*}}, i32 14
+ // CHECK: insertelement <16 x i8> %{{.*}}, i8 %{{.*}}, i32 15
+ // CHECK: select <16 x i1> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}}
+ return _mm_maskz_set1_epi8( __M, __A);
+}
+
+__m256i test_mm256_mask_set1_epi8(__m256i __O, __mmask32 __M, char __A) {
+ // CHECK-LABEL: @test_mm256_mask_set1_epi8
+ // CHECK: insertelement <32 x i8> undef, i8 %{{.*}}, i32 0
+ // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 1
+ // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 2
+ // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 3
+ // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 4
+ // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 5
+ // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 6
+ // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 7
+ // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 8
+ // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 9
+ // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 10
+ // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 11
+ // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 12
+ // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 13
+ // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 14
+ // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 15
+ // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 16
+ // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 17
+ // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 18
+ // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 19
+ // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 20
+ // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 21
+ // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 22
+ // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 23
+ // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 24
+ // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 25
+ // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 26
+ // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 27
+ // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 28
+ // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 29
+ // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 30
+ // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 31
+ // CHECK: select <32 x i1> %{{.*}}, <32 x i8> %{{.*}}, <32 x i8> %{{.*}}
+ return _mm256_mask_set1_epi8(__O, __M, __A);
+}
+
+__m256i test_mm256_maskz_set1_epi8( __mmask32 __M, char __A) {
+ // CHECK-LABEL: @test_mm256_maskz_set1_epi8
+ // CHECK: insertelement <32 x i8> undef, i8 %{{.*}}, i32 0
+ // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 1
+ // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 2
+ // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 3
+ // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 4
+ // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 5
+ // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 6
+ // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 7
+ // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 8
+ // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 9
+ // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 10
+ // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 11
+ // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 12
+ // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 13
+ // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 14
+ // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 15
+ // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 16
+ // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 17
+ // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 18
+ // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 19
+ // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 20
+ // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 21
+ // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 22
+ // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 23
+ // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 24
+ // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 25
+ // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 26
+ // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 27
+ // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 28
+ // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 29
+ // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 30
+ // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 31
+ // CHECK: select <32 x i1> %{{.*}}, <32 x i8> %{{.*}}, <32 x i8> %{{.*}}
+ return _mm256_maskz_set1_epi8( __M, __A);
+}
+
__m256i test_mm256_mask_set1_epi16(__m256i __O, __mmask16 __M, short __A) {
// CHECK-LABEL: @test_mm256_mask_set1_epi16
- // CHECK: @llvm.x86.avx512.mask.pbroadcast.w.gpr.256
+ // CHECK: insertelement <16 x i16> undef, i16 %{{.*}}, i32 0
+ // CHECK: insertelement <16 x i16> %{{.*}}, i16 %{{.*}}, i32 1
+ // CHECK: insertelement <16 x i16> %{{.*}}, i16 %{{.*}}, i32 2
+ // CHECK: insertelement <16 x i16> %{{.*}}, i16 %{{.*}}, i32 3
+ // CHECK: insertelement <16 x i16> %{{.*}}, i16 %{{.*}}, i32 4
+ // CHECK: insertelement <16 x i16> %{{.*}}, i16 %{{.*}}, i32 5
+ // CHECK: insertelement <16 x i16> %{{.*}}, i16 %{{.*}}, i32 6
+ // CHECK: insertelement <16 x i16> %{{.*}}, i16 %{{.*}}, i32 7
+ // CHECK: insertelement <16 x i16> %{{.*}}, i16 %{{.*}}, i32 8
+ // CHECK: insertelement <16 x i16> %{{.*}}, i16 %{{.*}}, i32 9
+ // CHECK: insertelement <16 x i16> %{{.*}}, i16 %{{.*}}, i32 10
+ // CHECK: insertelement <16 x i16> %{{.*}}, i16 %{{.*}}, i32 11
+ // CHECK: insertelement <16 x i16> %{{.*}}, i16 %{{.*}}, i32 12
+ // CHECK: insertelement <16 x i16> %{{.*}}, i16 %{{.*}}, i32 13
+ // CHECK: insertelement <16 x i16> %{{.*}}, i16 %{{.*}}, i32 14
+ // CHECK: insertelement <16 x i16> %{{.*}}, i16 %{{.*}}, i32 15
+ // CHECK: select <16 x i1> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}}
return _mm256_mask_set1_epi16(__O, __M, __A);
}
__m256i test_mm256_maskz_set1_epi16(__mmask16 __M, short __A) {
// CHECK-LABEL: @test_mm256_maskz_set1_epi16
- // CHECK: @llvm.x86.avx512.mask.pbroadcast.w.gpr.256
+ // CHECK: insertelement <16 x i16> undef, i16 %{{.*}}, i32 0
+ // CHECK: insertelement <16 x i16> %{{.*}}, i16 %{{.*}}, i32 1
+ // CHECK: insertelement <16 x i16> %{{.*}}, i16 %{{.*}}, i32 2
+ // CHECK: insertelement <16 x i16> %{{.*}}, i16 %{{.*}}, i32 3
+ // CHECK: insertelement <16 x i16> %{{.*}}, i16 %{{.*}}, i32 4
+ // CHECK: insertelement <16 x i16> %{{.*}}, i16 %{{.*}}, i32 5
+ // CHECK: insertelement <16 x i16> %{{.*}}, i16 %{{.*}}, i32 6
+ // CHECK: insertelement <16 x i16> %{{.*}}, i16 %{{.*}}, i32 7
+ // CHECK: insertelement <16 x i16> %{{.*}}, i16 %{{.*}}, i32 8
+ // CHECK: insertelement <16 x i16> %{{.*}}, i16 %{{.*}}, i32 9
+ // CHECK: insertelement <16 x i16> %{{.*}}, i16 %{{.*}}, i32 10
+ // CHECK: insertelement <16 x i16> %{{.*}}, i16 %{{.*}}, i32 11
+ // CHECK: insertelement <16 x i16> %{{.*}}, i16 %{{.*}}, i32 12
+ // CHECK: insertelement <16 x i16> %{{.*}}, i16 %{{.*}}, i32 13
+ // CHECK: insertelement <16 x i16> %{{.*}}, i16 %{{.*}}, i32 14
+ // CHECK: insertelement <16 x i16> %{{.*}}, i16 %{{.*}}, i32 15
+ // CHECK: select <16 x i1> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}}
return _mm256_maskz_set1_epi16(__M, __A);
}
__m128i test_mm_mask_set1_epi16(__m128i __O, __mmask8 __M, short __A) {
// CHECK-LABEL: @test_mm_mask_set1_epi16
- // CHECK: @llvm.x86.avx512.mask.pbroadcast.w.gpr.128
+ // CHECK: insertelement <8 x i16> undef, i16 %{{.*}}, i32 0
+ // CHECK: insertelement <8 x i16> %{{.*}}, i16 %{{.*}}, i32 1
+ // CHECK: insertelement <8 x i16> %{{.*}}, i16 %{{.*}}, i32 2
+ // CHECK: insertelement <8 x i16> %{{.*}}, i16 %{{.*}}, i32 3
+ // CHECK: insertelement <8 x i16> %{{.*}}, i16 %{{.*}}, i32 4
+ // CHECK: insertelement <8 x i16> %{{.*}}, i16 %{{.*}}, i32 5
+ // CHECK: insertelement <8 x i16> %{{.*}}, i16 %{{.*}}, i32 6
+ // CHECK: insertelement <8 x i16> %{{.*}}, i16 %{{.*}}, i32 7
+ // CHECK: select <8 x i1> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}
return _mm_mask_set1_epi16(__O, __M, __A);
}
__m128i test_mm_maskz_set1_epi16(__mmask8 __M, short __A) {
// CHECK-LABEL: @test_mm_maskz_set1_epi16
- // CHECK: @llvm.x86.avx512.mask.pbroadcast.w.gpr.128
+ // CHECK: insertelement <8 x i16> undef, i16 %{{.*}}, i32 0
+ // CHECK: insertelement <8 x i16> %{{.*}}, i16 %{{.*}}, i32 1
+ // CHECK: insertelement <8 x i16> %{{.*}}, i16 %{{.*}}, i32 2
+ // CHECK: insertelement <8 x i16> %{{.*}}, i16 %{{.*}}, i32 3
+ // CHECK: insertelement <8 x i16> %{{.*}}, i16 %{{.*}}, i32 4
+ // CHECK: insertelement <8 x i16> %{{.*}}, i16 %{{.*}}, i32 5
+ // CHECK: insertelement <8 x i16> %{{.*}}, i16 %{{.*}}, i32 6
+ // CHECK: insertelement <8 x i16> %{{.*}}, i16 %{{.*}}, i32 7
+ // CHECK: select <8 x i1> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}
return _mm_maskz_set1_epi16(__M, __A);
}
__m128i test_mm_permutexvar_epi16(__m128i __A, __m128i __B) {
diff --git a/test/CodeGen/avx512vlcd-builtins.c b/test/CodeGen/avx512vlcd-builtins.c
index 643f24f1d22c..376a342f76ee 100644
--- a/test/CodeGen/avx512vlcd-builtins.c
+++ b/test/CodeGen/avx512vlcd-builtins.c
@@ -3,28 +3,56 @@
#include <immintrin.h>
-__m128i test_mm_broadcastmb_epi64(__mmask8 __A) {
+__m128i test_mm_broadcastmb_epi64(__m128i a,__m128i b) {
// CHECK-LABEL: @test_mm_broadcastmb_epi64
- // CHECK: @llvm.x86.avx512.broadcastmb.128
- return _mm_broadcastmb_epi64(__A);
+ // CHECK: icmp eq <4 x i32> %{{.*}}, %{{.*}}
+ // CHECK: shufflevector <4 x i1> %{{.*}}, <4 x i1> zeroinitializer, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
+ // CHECK: bitcast <8 x i1> %{{.*}} to i8
+ // CHECK: zext i8 %{{.*}} to i64
+ // CHECK: insertelement <2 x i64> undef, i64 %{{.*}}, i32 0
+ // CHECK: insertelement <2 x i64> %{{.*}}, i64 %{{.*}}, i32 1
+ return _mm_broadcastmb_epi64(_mm_cmpeq_epi32_mask (a, b));
}
-__m256i test_mm256_broadcastmb_epi64(__mmask8 __A) {
+__m256i test_mm256_broadcastmb_epi64(__m256i a, __m256i b) {
// CHECK-LABEL: @test_mm256_broadcastmb_epi64
- // CHECK: @llvm.x86.avx512.broadcastmb.256
- return _mm256_broadcastmb_epi64(__A);
-}
-
-__m128i test_mm_broadcastmw_epi32(__mmask16 __A) {
+ // CHECK: icmp eq <4 x i64> %{{.*}}, %{{.*}}
+ // CHECK: shufflevector <4 x i1> %{{.*}}, <4 x i1> zeroinitializer, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
+ // CHECK: bitcast <8 x i1> %{{.*}} to i8
+ // CHECK: zext i8 %{{.*}} to i64
+ // CHECK: insertelement <4 x i64> undef, i64 %{{.*}}, i32 0
+ // CHECK: insertelement <4 x i64> %{{.*}}, i64 %{{.*}}, i32 1
+ // CHECK: insertelement <4 x i64> %{{.*}}, i64 %{{.*}}, i32 2
+ // CHECK: insertelement <4 x i64> %{{.*}}, i64 %{{.*}}, i32 3
+ return _mm256_broadcastmb_epi64(_mm256_cmpeq_epi64_mask ( a, b));
+}
+
+__m128i test_mm_broadcastmw_epi32(__m512i a, __m512i b) {
// CHECK-LABEL: @test_mm_broadcastmw_epi32
- // CHECK: @llvm.x86.avx512.broadcastmw.128
- return _mm_broadcastmw_epi32(__A);
+ // CHECK: icmp eq <16 x i32> %{{.*}}, %{{.*}}
+ // CHECK: bitcast <16 x i1> %{{.*}} to i16
+ // CHECK: zext i16 %{{.*}} to i32
+ // CHECK: insertelement <4 x i32> undef, i32 %{{.*}}, i32 0
+ // CHECK: insertelement <4 x i32> %{{.*}}, i32 %{{.*}}, i32 1
+ // CHECK: insertelement <4 x i32> %{{.*}}, i32 %{{.*}}, i32 2
+ // CHECK: insertelement <4 x i32> %{{.*}}, i32 %{{.*}}, i32 3
+ return _mm_broadcastmw_epi32(_mm512_cmpeq_epi32_mask ( a, b));
}
-__m256i test_mm256_broadcastmw_epi32(__mmask16 __A) {
+__m256i test_mm256_broadcastmw_epi32(__m512i a, __m512i b) {
// CHECK-LABEL: @test_mm256_broadcastmw_epi32
- // CHECK: @llvm.x86.avx512.broadcastmw.256
- return _mm256_broadcastmw_epi32(__A);
+ // CHECK: icmp eq <16 x i32> %{{.*}}, %{{.*}}
+ // CHECK: bitcast <16 x i1> %{{.*}} to i16
+ // CHECK: zext i16 %{{.*}} to i32
+ // CHECK: insertelement <8 x i32> undef, i32 %{{.*}}, i32 0
+ // CHECK: insertelement <8 x i32> %{{.*}}, i32 %{{.*}}, i32 1
+ // CHECK: insertelement <8 x i32> %{{.*}}, i32 %{{.*}}, i32 2
+ // CHECK: insertelement <8 x i32> %{{.*}}, i32 %{{.*}}, i32 3
+ // CHECK: insertelement <8 x i32> %{{.*}}, i32 %{{.*}}, i32 4
+ // CHECK: insertelement <8 x i32> %{{.*}}, i32 %{{.*}}, i32 5
+ // CHECK: insertelement <8 x i32> %{{.*}}, i32 %{{.*}}, i32 6
+ // CHECK: insertelement <8 x i32> %{{.*}}, i32 %{{.*}}, i32 7
+ return _mm256_broadcastmw_epi32(_mm512_cmpeq_epi32_mask ( a, b));
}
__m128i test_mm_conflict_epi64(__m128i __A) {
diff --git a/test/CodeGen/avx512vldq-builtins.c b/test/CodeGen/avx512vldq-builtins.c
index b18c811f845b..3ca4b2135ea7 100644
--- a/test/CodeGen/avx512vldq-builtins.c
+++ b/test/CodeGen/avx512vldq-builtins.c
@@ -909,19 +909,21 @@ __mmask8 test_mm256_movepi64_mask(__m256i __A) {
__m256 test_mm256_broadcast_f32x2(__m128 __A) {
// CHECK-LABEL: @test_mm256_broadcast_f32x2
- // CHECK: @llvm.x86.avx512.mask.broadcastf32x2
+ // CHECK: shufflevector <4 x float> %{{.*}}, <4 x float> zeroinitializer, <8 x i32> <i32 0, i32 1, i32 0, i32 1, i32 0, i32 1, i32 0, i32 1>
return _mm256_broadcast_f32x2(__A);
}
__m256 test_mm256_mask_broadcast_f32x2(__m256 __O, __mmask8 __M, __m128 __A) {
// CHECK-LABEL: @test_mm256_mask_broadcast_f32x2
- // CHECK: @llvm.x86.avx512.mask.broadcastf32x2
+ // CHECK: shufflevector <4 x float> %{{.*}}, <4 x float> zeroinitializer, <8 x i32> <i32 0, i32 1, i32 0, i32 1, i32 0, i32 1, i32 0, i32 1>
+ // CHECK: select <8 x i1> %{{.*}}, <8 x float> %{{.*}}, <8 x float> %{{.*}}
return _mm256_mask_broadcast_f32x2(__O, __M, __A);
}
__m256 test_mm256_maskz_broadcast_f32x2(__mmask8 __M, __m128 __A) {
// CHECK-LABEL: @test_mm256_maskz_broadcast_f32x2
- // CHECK: @llvm.x86.avx512.mask.broadcastf32x2
+ // CHECK: shufflevector <4 x float> %{{.*}}, <4 x float> zeroinitializer, <8 x i32> <i32 0, i32 1, i32 0, i32 1, i32 0, i32 1, i32 0, i32 1>
+ // CHECK: select <8 x i1> %{{.*}}, <8 x float> %{{.*}}, <8 x float> %{{.*}}
return _mm256_maskz_broadcast_f32x2(__M, __A);
}
@@ -947,37 +949,41 @@ __m256d test_mm256_maskz_broadcast_f64x2(__mmask8 __M, double const* __A) {
__m128i test_mm_broadcast_i32x2(__m128i __A) {
// CHECK-LABEL: @test_mm_broadcast_i32x2
- // CHECK: @llvm.x86.avx512.mask.broadcasti32x2
+ // CHECK: shufflevector <4 x i32> %{{.*}}, <4 x i32> zeroinitializer, <4 x i32> <i32 0, i32 1, i32 0, i32 1>
return _mm_broadcast_i32x2(__A);
}
__m128i test_mm_mask_broadcast_i32x2(__m128i __O, __mmask8 __M, __m128i __A) {
// CHECK-LABEL: @test_mm_mask_broadcast_i32x2
- // CHECK: @llvm.x86.avx512.mask.broadcasti32x2
+ // CHECK: shufflevector <4 x i32> %{{.*}}, <4 x i32> zeroinitializer, <4 x i32> <i32 0, i32 1, i32 0, i32 1>
+ // CHECK: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}
return _mm_mask_broadcast_i32x2(__O, __M, __A);
}
__m128i test_mm_maskz_broadcast_i32x2(__mmask8 __M, __m128i __A) {
// CHECK-LABEL: @test_mm_maskz_broadcast_i32x2
- // CHECK: @llvm.x86.avx512.mask.broadcasti32x2
+ // CHECK: shufflevector <4 x i32> %{{.*}}, <4 x i32> zeroinitializer, <4 x i32> <i32 0, i32 1, i32 0, i32 1>
+ // CHECK: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}
return _mm_maskz_broadcast_i32x2(__M, __A);
}
__m256i test_mm256_broadcast_i32x2(__m128i __A) {
// CHECK-LABEL: @test_mm256_broadcast_i32x2
- // CHECK: @llvm.x86.avx512.mask.broadcasti32x2
+ // CHECK: shufflevector <4 x i32> %{{.*}}, <4 x i32> zeroinitializer, <8 x i32> <i32 0, i32 1, i32 0, i32 1, i32 0, i32 1, i32 0, i32 1>
return _mm256_broadcast_i32x2(__A);
}
__m256i test_mm256_mask_broadcast_i32x2(__m256i __O, __mmask8 __M, __m128i __A) {
// CHECK-LABEL: @test_mm256_mask_broadcast_i32x2
- // CHECK: @llvm.x86.avx512.mask.broadcasti32x2
+ // CHECK: shufflevector <4 x i32> %{{.*}}, <4 x i32> zeroinitializer, <8 x i32> <i32 0, i32 1, i32 0, i32 1, i32 0, i32 1, i32 0, i32 1>
+ // CHECK: select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}}
return _mm256_mask_broadcast_i32x2(__O, __M, __A);
}
__m256i test_mm256_maskz_broadcast_i32x2(__mmask8 __M, __m128i __A) {
// CHECK-LABEL: @test_mm256_maskz_broadcast_i32x2
- // CHECK: @llvm.x86.avx512.mask.broadcasti32x2
+ // CHECK: shufflevector <4 x i32> %{{.*}}, <4 x i32> zeroinitializer, <8 x i32> <i32 0, i32 1, i32 0, i32 1, i32 0, i32 1, i32 0, i32 1>
+ // CHECK: select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}}
return _mm256_maskz_broadcast_i32x2(__M, __A);
}
diff --git a/test/CodeGen/avx512vpopcntdqvlintrin.c b/test/CodeGen/avx512vpopcntdqvlintrin.c
new file mode 100644
index 000000000000..010cb6b4f344
--- /dev/null
+++ b/test/CodeGen/avx512vpopcntdqvlintrin.c
@@ -0,0 +1,73 @@
+// RUN: %clang_cc1 -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +avx512vpopcntdq -target-feature +avx512vl -emit-llvm -o - -Wall -Werror | FileCheck %s
+
+#include <immintrin.h>
+
+__m128i test_mm_popcnt_epi64(__m128i __A) {
+ // CHECK-LABEL: @test_mm_popcnt_epi64
+ // CHECK: @llvm.ctpop.v2i64
+ return _mm_popcnt_epi64(__A);
+}
+__m128i test_mm_mask_popcnt_epi64(__m128i __W, __mmask8 __U, __m128i __A) {
+ // CHECK-LABEL: @test_mm_mask_popcnt_epi64
+ // CHECK: @llvm.ctpop.v2i64
+ // CHECK: select <2 x i1> %{{.+}}, <2 x i64> %{{[0-9]+}}, <2 x i64> {{.*}}
+ return _mm_mask_popcnt_epi64(__W, __U, __A);
+}
+__m128i test_mm_maskz_popcnt_epi64(__mmask8 __U, __m128i __A) {
+ // CHECK-LABEL: @test_mm_maskz_popcnt_epi64
+ // CHECK: @llvm.ctpop.v2i64
+ // CHECK: select <2 x i1> %{{.+}}, <2 x i64> %{{[0-9]+}}, <2 x i64> {{.*}}
+ return _mm_maskz_popcnt_epi64(__U, __A);
+}
+__m128i test_mm_popcnt_epi32(__m128i __A) {
+ // CHECK-LABEL: @test_mm_popcnt_epi32
+ // CHECK: @llvm.ctpop.v4i32
+ return _mm_popcnt_epi32(__A);
+}
+__m128i test_mm_mask_popcnt_epi32(__m128i __W, __mmask8 __U, __m128i __A) {
+ // CHECK-LABEL: @test_mm_mask_popcnt_epi32
+ // CHECK: @llvm.ctpop.v4i32
+ // CHECK: select <4 x i1> %{{.+}}, <4 x i32> %{{[0-9]+}}, <4 x i32> {{.*}}
+ return _mm_mask_popcnt_epi32(__W, __U, __A);
+}
+__m128i test_mm_maskz_popcnt_epi32(__mmask8 __U, __m128i __A) {
+ // CHECK-LABEL: @test_mm_maskz_popcnt_epi32
+ // CHECK: @llvm.ctpop.v4i32
+ // CHECK: select <4 x i1> %{{.+}}, <4 x i32> %{{[0-9]+}}, <4 x i32> {{.*}}
+ return _mm_maskz_popcnt_epi32(__U, __A);
+}
+
+__m256i test_mm256_popcnt_epi64(__m256i __A) {
+ // CHECK-LABEL: @test_mm256_popcnt_epi64
+ // CHECK: @llvm.ctpop.v4i64
+ return _mm256_popcnt_epi64(__A);
+}
+__m256i test_mm256_mask_popcnt_epi64(__m256i __W, __mmask8 __U, __m256i __A) {
+ // CHECK-LABEL: @test_mm256_mask_popcnt_epi64
+ // CHECK: @llvm.ctpop.v4i64
+ // CHECK: select <4 x i1> %{{.+}}, <4 x i64> %{{[0-9]+}}, <4 x i64> {{.*}}
+ return _mm256_mask_popcnt_epi64(__W, __U, __A);
+}
+__m256i test_mm256_maskz_popcnt_epi64(__mmask8 __U, __m256i __A) {
+ // CHECK-LABEL: @test_mm256_maskz_popcnt_epi64
+ // CHECK: @llvm.ctpop.v4i64
+ // CHECK: select <4 x i1> %{{.+}}, <4 x i64> %{{[0-9]+}}, <4 x i64> {{.*}}
+ return _mm256_maskz_popcnt_epi64(__U, __A);
+}
+__m256i test_mm256_popcnt_epi32(__m256i __A) {
+ // CHECK-LABEL: @test_mm256_popcnt_epi32
+ // CHECK: @llvm.ctpop.v8i32
+ return _mm256_popcnt_epi32(__A);
+}
+__m256i test_mm256_mask_popcnt_epi32(__m256i __W, __mmask8 __U, __m256i __A) {
+ // CHECK-LABEL: @test_mm256_mask_popcnt_epi32
+ // CHECK: @llvm.ctpop.v8i32
+ // CHECK: select <8 x i1> %{{.+}}, <8 x i32> %{{[0-9]+}}, <8 x i32> {{.*}}
+ return _mm256_mask_popcnt_epi32(__W, __U, __A);
+}
+__m256i test_mm256_maskz_popcnt_epi32(__mmask8 __U, __m256i __A) {
+ // CHECK-LABEL: @test_mm256_maskz_popcnt_epi32
+ // CHECK: @llvm.ctpop.v8i32
+ // CHECK: select <8 x i1> %{{.+}}, <8 x i32> %{{[0-9]+}}, <8 x i32> {{.*}}
+ return _mm256_maskz_popcnt_epi32(__U, __A);
+}
diff --git a/test/CodeGen/blocks-opencl.cl b/test/CodeGen/blocks-opencl.cl
deleted file mode 100644
index 12513331e9d4..000000000000
--- a/test/CodeGen/blocks-opencl.cl
+++ /dev/null
@@ -1,17 +0,0 @@
-// RUN: %clang_cc1 -O0 %s -ffake-address-space-map -emit-llvm -o - -fblocks -triple x86_64-unknown-unknown | FileCheck %s
-// This used to crash due to trying to generate a bitcase from a cstring
-// in the constant address space to i8* in AS0.
-
-void dummy(float (^const op)(float)) {
-}
-
-// CHECK: i8 addrspace(2)* getelementptr inbounds ([9 x i8], [9 x i8] addrspace(2)* @.str, i32 0, i32 0)
-
-kernel void test_block()
-{
- float (^const X)(float) = ^(float x) {
- return x + 42.0f;
- };
- dummy(X);
-}
-
diff --git a/test/CodeGen/bounds-checking.c b/test/CodeGen/bounds-checking.c
index 90b7f0f6523e..2e6a08650dd9 100644
--- a/test/CodeGen/bounds-checking.c
+++ b/test/CodeGen/bounds-checking.c
@@ -1,5 +1,9 @@
// RUN: %clang_cc1 -fsanitize=local-bounds -emit-llvm -triple x86_64-apple-darwin10 %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fsanitize=local-bounds -fexperimental-new-pass-manager -emit-llvm -triple x86_64-apple-darwin10 %s -o - | FileCheck %s
// RUN: %clang_cc1 -fsanitize=array-bounds -O -fsanitize-trap=array-bounds -emit-llvm -triple x86_64-apple-darwin10 -DNO_DYNAMIC %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fsanitize=array-bounds -O -fsanitize-trap=array-bounds -fexperimental-new-pass-manager -emit-llvm -triple x86_64-apple-darwin10 -DNO_DYNAMIC %s -o - | FileCheck %s
+//
+// REQUIRES: x86-registered-target
// CHECK-LABEL: @f
double f(int b, int i) {
diff --git a/test/CodeGen/builtin-clflushopt.c b/test/CodeGen/builtin-clflushopt.c
index 93861164c4a8..f82ac4638f40 100644
--- a/test/CodeGen/builtin-clflushopt.c
+++ b/test/CodeGen/builtin-clflushopt.c
@@ -1,7 +1,7 @@
-// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin -target-feature +clflushopt -emit-llvm -o - -Wall -Werror | FileCheck %s
-#define __MM_MALLOC_H
+// RUN: %clang_cc1 %s -ffreestanding -triple=x86_64-apple-darwin -target-feature +clflushopt -emit-llvm -o - -Wall -Werror | FileCheck %s
+
+#include <x86intrin.h>
-#include <immintrin.h>
void test_mm_clflushopt(char * __m) {
//CHECK-LABEL: @test_mm_clflushopt
//CHECK: @llvm.x86.clflushopt
diff --git a/test/CodeGen/builtin-clwb.c b/test/CodeGen/builtin-clwb.c
new file mode 100644
index 000000000000..96d00a6a7ca1
--- /dev/null
+++ b/test/CodeGen/builtin-clwb.c
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 %s -ffreestanding -triple=x86_64-apple-darwin -target-feature +clwb -emit-llvm -o - -Wall -Werror | FileCheck %s
+
+#include <x86intrin.h>
+
+void test_mm_clwb(const void *__m) {
+ //CHECK-LABEL: @test_mm_clwb
+ //CHECK: @llvm.x86.clwb
+ _mm_clwb(__m);
+}
diff --git a/test/CodeGen/builtin-clzero.c b/test/CodeGen/builtin-clzero.c
index c9960ced12ec..f9ecb9ddb526 100644
--- a/test/CodeGen/builtin-clzero.c
+++ b/test/CodeGen/builtin-clzero.c
@@ -1,7 +1,7 @@
-// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin -target-feature +clzero -emit-llvm -o - -Wall -Werror | FileCheck %s
-#define __MM_MALLOC_H
+// RUN: %clang_cc1 %s -ffreestanding -triple=x86_64-apple-darwin -target-feature +clzero -emit-llvm -o - -Wall -Werror | FileCheck %s
#include <x86intrin.h>
+
void test_mm_clzero(void * __m) {
//CHECK-LABEL: @test_mm_clzero
//CHECK: @llvm.x86.clzero
diff --git a/test/CodeGen/builtin-cpu-is.c b/test/CodeGen/builtin-cpu-is.c
new file mode 100644
index 000000000000..f2a5f54a0c80
--- /dev/null
+++ b/test/CodeGen/builtin-cpu-is.c
@@ -0,0 +1,53 @@
+// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -emit-llvm < %s| FileCheck %s
+
+// Test that we have the structure definition, the gep offsets, the name of the
+// global, the bit grab, and the icmp correct.
+extern void a(const char *);
+
+void intel() {
+ if (__builtin_cpu_is("intel"))
+ a("intel");
+
+ // CHECK: [[LOAD:%[^ ]+]] = load i32, i32* getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, { i32, i32, i32, [1 x i32] }* @__cpu_model, i32 0, i32 0)
+ // CHECK: = icmp eq i32 [[LOAD]], 1
+}
+
+void amd() {
+ if (__builtin_cpu_is("amd"))
+ a("amd");
+
+ // CHECK: [[LOAD:%[^ ]+]] = load i32, i32* getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, { i32, i32, i32, [1 x i32] }* @__cpu_model, i32 0, i32 0)
+ // CHECK: = icmp eq i32 [[LOAD]], 2
+}
+
+void atom() {
+ if (__builtin_cpu_is("atom"))
+ a("atom");
+
+ // CHECK: [[LOAD:%[^ ]+]] = load i32, i32* getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, { i32, i32, i32, [1 x i32] }* @__cpu_model, i32 0, i32 1)
+ // CHECK: = icmp eq i32 [[LOAD]], 1
+}
+
+void amdfam10h() {
+ if (__builtin_cpu_is("amdfam10h"))
+ a("amdfam10h");
+
+ // CHECK: [[LOAD:%[^ ]+]] = load i32, i32* getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, { i32, i32, i32, [1 x i32] }* @__cpu_model, i32 0, i32 1)
+ // CHECK: = icmp eq i32 [[LOAD]], 4
+}
+
+void barcelona() {
+ if (__builtin_cpu_is("barcelona"))
+ a("barcelona");
+
+ // CHECK: [[LOAD:%[^ ]+]] = load i32, i32* getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, { i32, i32, i32, [1 x i32] }* @__cpu_model, i32 0, i32 2)
+ // CHECK: = icmp eq i32 [[LOAD]], 4
+}
+
+void nehalem() {
+ if (__builtin_cpu_is("nehalem"))
+ a("nehalem");
+
+ // CHECK: [[LOAD:%[^ ]+]] = load i32, i32* getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, { i32, i32, i32, [1 x i32] }* @__cpu_model, i32 0, i32 2)
+ // CHECK: = icmp eq i32 [[LOAD]], 1
+}
diff --git a/test/CodeGen/builtin-cpu-supports.c b/test/CodeGen/builtin-cpu-supports.c
index 96813923f279..b70f4aca9d43 100644
--- a/test/CodeGen/builtin-cpu-supports.c
+++ b/test/CodeGen/builtin-cpu-supports.c
@@ -5,6 +5,10 @@
extern void a(const char *);
int main() {
+ __builtin_cpu_init();
+
+ // CHECK: call void @__cpu_indicator_init
+
if (__builtin_cpu_supports("sse4.2"))
a("sse4.2");
diff --git a/test/CodeGen/builtin-sqrt.c b/test/CodeGen/builtin-sqrt.c
new file mode 100644
index 000000000000..5b275bf9066d
--- /dev/null
+++ b/test/CodeGen/builtin-sqrt.c
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fmath-errno -triple x86_64-apple-darwin %s -emit-llvm -o - | FileCheck %s --check-prefix=HAS_ERRNO
+// RUN: %clang_cc1 -triple x86_64-apple-darwin %s -emit-llvm -o - | FileCheck %s --check-prefix=NO_ERRNO
+
+float foo(float X) {
+ // HAS_ERRNO: call float @sqrtf(float
+ // NO_ERRNO: call float @llvm.sqrt.f32(float
+ return __builtin_sqrtf(X);
+}
+
+// HAS_ERRNO: declare float @sqrtf(float) [[ATTR:#[0-9]+]]
+// HAS_ERRNO-NOT: attributes [[ATTR]] = {{{.*}} readnone
+
+// NO_ERRNO: declare float @llvm.sqrt.f32(float) [[ATTR:#[0-9]+]]
+// NO_ERRNO: attributes [[ATTR]] = { nounwind readnone {{.*}}}
+
diff --git a/test/CodeGen/builtins-hexagon.c b/test/CodeGen/builtins-hexagon.c
index f9f5d495d02a..22835a23f292 100644
--- a/test/CodeGen/builtins-hexagon.c
+++ b/test/CodeGen/builtins-hexagon.c
@@ -1,2977 +1,3371 @@
// REQUIRES: hexagon-registered-target
// RUN: %clang_cc1 -triple hexagon-unknown-elf -emit-llvm %s -o - | FileCheck %s
-void foo() {
- int v16 __attribute__((__vector_size__(64)));
- int v32 __attribute__((__vector_size__(128)));
- int v64 __attribute__((__vector_size__(256)));
+void test() {
+ int v64 __attribute__((__vector_size__(64)));
+ int v128 __attribute__((__vector_size__(128)));
+ int v256 __attribute__((__vector_size__(256)));
- // The circ/brev intrinsics do not have _HEXAGON_ in the name.
- __builtin_brev_ldb(0, 0, 0);
- // CHECK: @llvm.hexagon.brev.ldb
- __builtin_brev_ldd(0, 0, 0);
- // CHECK: @llvm.hexagon.brev.ldd
- __builtin_brev_ldh(0, 0, 0);
- // CHECK: @llvm.hexagon.brev.ldh
- __builtin_brev_ldub(0, 0, 0);
- // CHECK: @llvm.hexagon.brev.ldub
- __builtin_brev_lduh(0, 0, 0);
- // CHECK: @llvm.hexagon.brev.lduh
- __builtin_brev_ldw(0, 0, 0);
- // CHECK: @llvm.hexagon.brev.ldw
- __builtin_brev_stb(0, 0, 0);
- // CHECK: @llvm.hexagon.brev.stb
- __builtin_brev_std(0, 0LL, 0);
- // CHECK: @llvm.hexagon.brev.std
- __builtin_brev_sth(0, 0, 0);
- // CHECK: @llvm.hexagon.brev.sth
- __builtin_brev_sthhi(0, 0, 0);
- // CHECK: @llvm.hexagon.brev.sthhi
- __builtin_brev_stw(0, 0, 0);
- // CHECK: @llvm.hexagon.brev.stw
- __builtin_circ_ldb(0, 0, 0, 0);
- // CHECK: llvm.hexagon.circ.ldb
- __builtin_circ_ldd(0, 0, 0, 0);
- // CHECK: llvm.hexagon.circ.ldd
- __builtin_circ_ldh(0, 0, 0, 0);
- // CHECK: llvm.hexagon.circ.ldh
- __builtin_circ_ldub(0, 0, 0, 0);
- // CHECK: llvm.hexagon.circ.ldub
- __builtin_circ_lduh(0, 0, 0, 0);
- // CHECK: llvm.hexagon.circ.lduh
- __builtin_circ_ldw(0, 0, 0, 0);
- // CHECK: llvm.hexagon.circ.ldw
- __builtin_circ_stb(0, 0, 0, 0);
- // CHECK: llvm.hexagon.circ.stb
- __builtin_circ_std(0, 0LL, 0, 0);
- // CHECK: llvm.hexagon.circ.std
- __builtin_circ_sth(0, 0, 0, 0);
- // CHECK: llvm.hexagon.circ.sth
- __builtin_circ_sthhi(0, 0, 0, 0);
- // CHECK: llvm.hexagon.circ.sthhi
- __builtin_circ_stw(0, 0, 0, 0);
- // CHECK: llvm.hexagon.circ.stw
-
- __builtin_HEXAGON_A2_abs(0);
// CHECK: @llvm.hexagon.A2.abs
- __builtin_HEXAGON_A2_absp(0);
+ __builtin_HEXAGON_A2_abs(0);
// CHECK: @llvm.hexagon.A2.absp
- __builtin_HEXAGON_A2_abssat(0);
+ __builtin_HEXAGON_A2_absp(0);
// CHECK: @llvm.hexagon.A2.abssat
- __builtin_HEXAGON_A2_add(0, 0);
+ __builtin_HEXAGON_A2_abssat(0);
// CHECK: @llvm.hexagon.A2.add
- __builtin_HEXAGON_A2_addh_h16_hh(0, 0);
+ __builtin_HEXAGON_A2_add(0, 0);
// CHECK: @llvm.hexagon.A2.addh.h16.hh
- __builtin_HEXAGON_A2_addh_h16_hl(0, 0);
+ __builtin_HEXAGON_A2_addh_h16_hh(0, 0);
// CHECK: @llvm.hexagon.A2.addh.h16.hl
- __builtin_HEXAGON_A2_addh_h16_lh(0, 0);
+ __builtin_HEXAGON_A2_addh_h16_hl(0, 0);
// CHECK: @llvm.hexagon.A2.addh.h16.lh
- __builtin_HEXAGON_A2_addh_h16_ll(0, 0);
+ __builtin_HEXAGON_A2_addh_h16_lh(0, 0);
// CHECK: @llvm.hexagon.A2.addh.h16.ll
- __builtin_HEXAGON_A2_addh_h16_sat_hh(0, 0);
+ __builtin_HEXAGON_A2_addh_h16_ll(0, 0);
// CHECK: @llvm.hexagon.A2.addh.h16.sat.hh
- __builtin_HEXAGON_A2_addh_h16_sat_hl(0, 0);
+ __builtin_HEXAGON_A2_addh_h16_sat_hh(0, 0);
// CHECK: @llvm.hexagon.A2.addh.h16.sat.hl
- __builtin_HEXAGON_A2_addh_h16_sat_lh(0, 0);
+ __builtin_HEXAGON_A2_addh_h16_sat_hl(0, 0);
// CHECK: @llvm.hexagon.A2.addh.h16.sat.lh
- __builtin_HEXAGON_A2_addh_h16_sat_ll(0, 0);
+ __builtin_HEXAGON_A2_addh_h16_sat_lh(0, 0);
// CHECK: @llvm.hexagon.A2.addh.h16.sat.ll
- __builtin_HEXAGON_A2_addh_l16_hl(0, 0);
+ __builtin_HEXAGON_A2_addh_h16_sat_ll(0, 0);
// CHECK: @llvm.hexagon.A2.addh.l16.hl
- __builtin_HEXAGON_A2_addh_l16_ll(0, 0);
+ __builtin_HEXAGON_A2_addh_l16_hl(0, 0);
// CHECK: @llvm.hexagon.A2.addh.l16.ll
- __builtin_HEXAGON_A2_addh_l16_sat_hl(0, 0);
+ __builtin_HEXAGON_A2_addh_l16_ll(0, 0);
// CHECK: @llvm.hexagon.A2.addh.l16.sat.hl
- __builtin_HEXAGON_A2_addh_l16_sat_ll(0, 0);
+ __builtin_HEXAGON_A2_addh_l16_sat_hl(0, 0);
// CHECK: @llvm.hexagon.A2.addh.l16.sat.ll
- __builtin_HEXAGON_A2_addi(0, 0);
+ __builtin_HEXAGON_A2_addh_l16_sat_ll(0, 0);
// CHECK: @llvm.hexagon.A2.addi
- __builtin_HEXAGON_A2_addp(0, 0);
+ __builtin_HEXAGON_A2_addi(0, 0);
// CHECK: @llvm.hexagon.A2.addp
- __builtin_HEXAGON_A2_addpsat(0, 0);
+ __builtin_HEXAGON_A2_addp(0, 0);
// CHECK: @llvm.hexagon.A2.addpsat
- __builtin_HEXAGON_A2_addsat(0, 0);
+ __builtin_HEXAGON_A2_addpsat(0, 0);
// CHECK: @llvm.hexagon.A2.addsat
- __builtin_HEXAGON_A2_addsp(0, 0);
+ __builtin_HEXAGON_A2_addsat(0, 0);
// CHECK: @llvm.hexagon.A2.addsp
- __builtin_HEXAGON_A2_and(0, 0);
+ __builtin_HEXAGON_A2_addsp(0, 0);
// CHECK: @llvm.hexagon.A2.and
- __builtin_HEXAGON_A2_andir(0, 0);
+ __builtin_HEXAGON_A2_and(0, 0);
// CHECK: @llvm.hexagon.A2.andir
- __builtin_HEXAGON_A2_andp(0, 0);
+ __builtin_HEXAGON_A2_andir(0, 0);
// CHECK: @llvm.hexagon.A2.andp
- __builtin_HEXAGON_A2_aslh(0);
+ __builtin_HEXAGON_A2_andp(0, 0);
// CHECK: @llvm.hexagon.A2.aslh
- __builtin_HEXAGON_A2_asrh(0);
+ __builtin_HEXAGON_A2_aslh(0);
// CHECK: @llvm.hexagon.A2.asrh
- __builtin_HEXAGON_A2_combine_hh(0, 0);
+ __builtin_HEXAGON_A2_asrh(0);
// CHECK: @llvm.hexagon.A2.combine.hh
- __builtin_HEXAGON_A2_combine_hl(0, 0);
+ __builtin_HEXAGON_A2_combine_hh(0, 0);
// CHECK: @llvm.hexagon.A2.combine.hl
- __builtin_HEXAGON_A2_combineii(0, 0);
- // CHECK: @llvm.hexagon.A2.combineii
- __builtin_HEXAGON_A2_combine_lh(0, 0);
+ __builtin_HEXAGON_A2_combine_hl(0, 0);
// CHECK: @llvm.hexagon.A2.combine.lh
- __builtin_HEXAGON_A2_combine_ll(0, 0);
+ __builtin_HEXAGON_A2_combine_lh(0, 0);
// CHECK: @llvm.hexagon.A2.combine.ll
- __builtin_HEXAGON_A2_combinew(0, 0);
+ __builtin_HEXAGON_A2_combine_ll(0, 0);
+ // CHECK: @llvm.hexagon.A2.combineii
+ __builtin_HEXAGON_A2_combineii(0, 0);
// CHECK: @llvm.hexagon.A2.combinew
- __builtin_HEXAGON_A2_max(0, 0);
+ __builtin_HEXAGON_A2_combinew(0, 0);
// CHECK: @llvm.hexagon.A2.max
- __builtin_HEXAGON_A2_maxp(0, 0);
+ __builtin_HEXAGON_A2_max(0, 0);
// CHECK: @llvm.hexagon.A2.maxp
- __builtin_HEXAGON_A2_maxu(0, 0);
+ __builtin_HEXAGON_A2_maxp(0, 0);
// CHECK: @llvm.hexagon.A2.maxu
- __builtin_HEXAGON_A2_maxup(0, 0);
+ __builtin_HEXAGON_A2_maxu(0, 0);
// CHECK: @llvm.hexagon.A2.maxup
- __builtin_HEXAGON_A2_min(0, 0);
+ __builtin_HEXAGON_A2_maxup(0, 0);
// CHECK: @llvm.hexagon.A2.min
- __builtin_HEXAGON_A2_minp(0, 0);
+ __builtin_HEXAGON_A2_min(0, 0);
// CHECK: @llvm.hexagon.A2.minp
- __builtin_HEXAGON_A2_minu(0, 0);
+ __builtin_HEXAGON_A2_minp(0, 0);
// CHECK: @llvm.hexagon.A2.minu
- __builtin_HEXAGON_A2_minup(0, 0);
+ __builtin_HEXAGON_A2_minu(0, 0);
// CHECK: @llvm.hexagon.A2.minup
- __builtin_HEXAGON_A2_neg(0);
+ __builtin_HEXAGON_A2_minup(0, 0);
// CHECK: @llvm.hexagon.A2.neg
- __builtin_HEXAGON_A2_negp(0);
+ __builtin_HEXAGON_A2_neg(0);
// CHECK: @llvm.hexagon.A2.negp
- __builtin_HEXAGON_A2_negsat(0);
+ __builtin_HEXAGON_A2_negp(0);
// CHECK: @llvm.hexagon.A2.negsat
- __builtin_HEXAGON_A2_not(0);
+ __builtin_HEXAGON_A2_negsat(0);
// CHECK: @llvm.hexagon.A2.not
- __builtin_HEXAGON_A2_notp(0);
+ __builtin_HEXAGON_A2_not(0);
// CHECK: @llvm.hexagon.A2.notp
- __builtin_HEXAGON_A2_or(0, 0);
+ __builtin_HEXAGON_A2_notp(0);
// CHECK: @llvm.hexagon.A2.or
- __builtin_HEXAGON_A2_orir(0, 0);
+ __builtin_HEXAGON_A2_or(0, 0);
// CHECK: @llvm.hexagon.A2.orir
- __builtin_HEXAGON_A2_orp(0, 0);
+ __builtin_HEXAGON_A2_orir(0, 0);
// CHECK: @llvm.hexagon.A2.orp
- __builtin_HEXAGON_A2_roundsat(0);
+ __builtin_HEXAGON_A2_orp(0, 0);
// CHECK: @llvm.hexagon.A2.roundsat
- __builtin_HEXAGON_A2_sat(0);
+ __builtin_HEXAGON_A2_roundsat(0);
// CHECK: @llvm.hexagon.A2.sat
- __builtin_HEXAGON_A2_satb(0);
+ __builtin_HEXAGON_A2_sat(0);
// CHECK: @llvm.hexagon.A2.satb
- __builtin_HEXAGON_A2_sath(0);
+ __builtin_HEXAGON_A2_satb(0);
// CHECK: @llvm.hexagon.A2.sath
- __builtin_HEXAGON_A2_satub(0);
+ __builtin_HEXAGON_A2_sath(0);
// CHECK: @llvm.hexagon.A2.satub
- __builtin_HEXAGON_A2_satuh(0);
+ __builtin_HEXAGON_A2_satub(0);
// CHECK: @llvm.hexagon.A2.satuh
- __builtin_HEXAGON_A2_sub(0, 0);
+ __builtin_HEXAGON_A2_satuh(0);
// CHECK: @llvm.hexagon.A2.sub
- __builtin_HEXAGON_A2_subh_h16_hh(0, 0);
+ __builtin_HEXAGON_A2_sub(0, 0);
// CHECK: @llvm.hexagon.A2.subh.h16.hh
- __builtin_HEXAGON_A2_subh_h16_hl(0, 0);
+ __builtin_HEXAGON_A2_subh_h16_hh(0, 0);
// CHECK: @llvm.hexagon.A2.subh.h16.hl
- __builtin_HEXAGON_A2_subh_h16_lh(0, 0);
+ __builtin_HEXAGON_A2_subh_h16_hl(0, 0);
// CHECK: @llvm.hexagon.A2.subh.h16.lh
- __builtin_HEXAGON_A2_subh_h16_ll(0, 0);
+ __builtin_HEXAGON_A2_subh_h16_lh(0, 0);
// CHECK: @llvm.hexagon.A2.subh.h16.ll
- __builtin_HEXAGON_A2_subh_h16_sat_hh(0, 0);
+ __builtin_HEXAGON_A2_subh_h16_ll(0, 0);
// CHECK: @llvm.hexagon.A2.subh.h16.sat.hh
- __builtin_HEXAGON_A2_subh_h16_sat_hl(0, 0);
+ __builtin_HEXAGON_A2_subh_h16_sat_hh(0, 0);
// CHECK: @llvm.hexagon.A2.subh.h16.sat.hl
- __builtin_HEXAGON_A2_subh_h16_sat_lh(0, 0);
+ __builtin_HEXAGON_A2_subh_h16_sat_hl(0, 0);
// CHECK: @llvm.hexagon.A2.subh.h16.sat.lh
- __builtin_HEXAGON_A2_subh_h16_sat_ll(0, 0);
+ __builtin_HEXAGON_A2_subh_h16_sat_lh(0, 0);
// CHECK: @llvm.hexagon.A2.subh.h16.sat.ll
- __builtin_HEXAGON_A2_subh_l16_hl(0, 0);
+ __builtin_HEXAGON_A2_subh_h16_sat_ll(0, 0);
// CHECK: @llvm.hexagon.A2.subh.l16.hl
- __builtin_HEXAGON_A2_subh_l16_ll(0, 0);
+ __builtin_HEXAGON_A2_subh_l16_hl(0, 0);
// CHECK: @llvm.hexagon.A2.subh.l16.ll
- __builtin_HEXAGON_A2_subh_l16_sat_hl(0, 0);
+ __builtin_HEXAGON_A2_subh_l16_ll(0, 0);
// CHECK: @llvm.hexagon.A2.subh.l16.sat.hl
- __builtin_HEXAGON_A2_subh_l16_sat_ll(0, 0);
+ __builtin_HEXAGON_A2_subh_l16_sat_hl(0, 0);
// CHECK: @llvm.hexagon.A2.subh.l16.sat.ll
- __builtin_HEXAGON_A2_subp(0, 0);
+ __builtin_HEXAGON_A2_subh_l16_sat_ll(0, 0);
// CHECK: @llvm.hexagon.A2.subp
- __builtin_HEXAGON_A2_subri(0, 0);
+ __builtin_HEXAGON_A2_subp(0, 0);
// CHECK: @llvm.hexagon.A2.subri
- __builtin_HEXAGON_A2_subsat(0, 0);
+ __builtin_HEXAGON_A2_subri(0, 0);
// CHECK: @llvm.hexagon.A2.subsat
- __builtin_HEXAGON_A2_svaddh(0, 0);
+ __builtin_HEXAGON_A2_subsat(0, 0);
// CHECK: @llvm.hexagon.A2.svaddh
- __builtin_HEXAGON_A2_svaddhs(0, 0);
+ __builtin_HEXAGON_A2_svaddh(0, 0);
// CHECK: @llvm.hexagon.A2.svaddhs
- __builtin_HEXAGON_A2_svadduhs(0, 0);
+ __builtin_HEXAGON_A2_svaddhs(0, 0);
// CHECK: @llvm.hexagon.A2.svadduhs
- __builtin_HEXAGON_A2_svavgh(0, 0);
+ __builtin_HEXAGON_A2_svadduhs(0, 0);
// CHECK: @llvm.hexagon.A2.svavgh
- __builtin_HEXAGON_A2_svavghs(0, 0);
+ __builtin_HEXAGON_A2_svavgh(0, 0);
// CHECK: @llvm.hexagon.A2.svavghs
- __builtin_HEXAGON_A2_svnavgh(0, 0);
+ __builtin_HEXAGON_A2_svavghs(0, 0);
// CHECK: @llvm.hexagon.A2.svnavgh
- __builtin_HEXAGON_A2_svsubh(0, 0);
+ __builtin_HEXAGON_A2_svnavgh(0, 0);
// CHECK: @llvm.hexagon.A2.svsubh
- __builtin_HEXAGON_A2_svsubhs(0, 0);
+ __builtin_HEXAGON_A2_svsubh(0, 0);
// CHECK: @llvm.hexagon.A2.svsubhs
- __builtin_HEXAGON_A2_svsubuhs(0, 0);
+ __builtin_HEXAGON_A2_svsubhs(0, 0);
// CHECK: @llvm.hexagon.A2.svsubuhs
- __builtin_HEXAGON_A2_swiz(0);
+ __builtin_HEXAGON_A2_svsubuhs(0, 0);
// CHECK: @llvm.hexagon.A2.swiz
- __builtin_HEXAGON_A2_sxtb(0);
+ __builtin_HEXAGON_A2_swiz(0);
// CHECK: @llvm.hexagon.A2.sxtb
- __builtin_HEXAGON_A2_sxth(0);
+ __builtin_HEXAGON_A2_sxtb(0);
// CHECK: @llvm.hexagon.A2.sxth
- __builtin_HEXAGON_A2_sxtw(0);
+ __builtin_HEXAGON_A2_sxth(0);
// CHECK: @llvm.hexagon.A2.sxtw
- __builtin_HEXAGON_A2_tfr(0);
+ __builtin_HEXAGON_A2_sxtw(0);
// CHECK: @llvm.hexagon.A2.tfr
- __builtin_HEXAGON_A2_tfrih(0, 0);
+ __builtin_HEXAGON_A2_tfr(0);
// CHECK: @llvm.hexagon.A2.tfrih
- __builtin_HEXAGON_A2_tfril(0, 0);
+ __builtin_HEXAGON_A2_tfrih(0, 0);
// CHECK: @llvm.hexagon.A2.tfril
- __builtin_HEXAGON_A2_tfrp(0);
+ __builtin_HEXAGON_A2_tfril(0, 0);
// CHECK: @llvm.hexagon.A2.tfrp
- __builtin_HEXAGON_A2_tfrpi(0);
+ __builtin_HEXAGON_A2_tfrp(0);
// CHECK: @llvm.hexagon.A2.tfrpi
- __builtin_HEXAGON_A2_tfrsi(0);
+ __builtin_HEXAGON_A2_tfrpi(0);
// CHECK: @llvm.hexagon.A2.tfrsi
- __builtin_HEXAGON_A2_vabsh(0);
+ __builtin_HEXAGON_A2_tfrsi(0);
// CHECK: @llvm.hexagon.A2.vabsh
- __builtin_HEXAGON_A2_vabshsat(0);
+ __builtin_HEXAGON_A2_vabsh(0);
// CHECK: @llvm.hexagon.A2.vabshsat
- __builtin_HEXAGON_A2_vabsw(0);
+ __builtin_HEXAGON_A2_vabshsat(0);
// CHECK: @llvm.hexagon.A2.vabsw
- __builtin_HEXAGON_A2_vabswsat(0);
+ __builtin_HEXAGON_A2_vabsw(0);
// CHECK: @llvm.hexagon.A2.vabswsat
- __builtin_HEXAGON_A2_vaddb_map(0, 0);
+ __builtin_HEXAGON_A2_vabswsat(0);
// CHECK: @llvm.hexagon.A2.vaddb.map
- __builtin_HEXAGON_A2_vaddh(0, 0);
+ __builtin_HEXAGON_A2_vaddb_map(0, 0);
// CHECK: @llvm.hexagon.A2.vaddh
- __builtin_HEXAGON_A2_vaddhs(0, 0);
+ __builtin_HEXAGON_A2_vaddh(0, 0);
// CHECK: @llvm.hexagon.A2.vaddhs
- __builtin_HEXAGON_A2_vaddub(0, 0);
+ __builtin_HEXAGON_A2_vaddhs(0, 0);
// CHECK: @llvm.hexagon.A2.vaddub
- __builtin_HEXAGON_A2_vaddubs(0, 0);
+ __builtin_HEXAGON_A2_vaddub(0, 0);
// CHECK: @llvm.hexagon.A2.vaddubs
- __builtin_HEXAGON_A2_vadduhs(0, 0);
+ __builtin_HEXAGON_A2_vaddubs(0, 0);
// CHECK: @llvm.hexagon.A2.vadduhs
- __builtin_HEXAGON_A2_vaddw(0, 0);
+ __builtin_HEXAGON_A2_vadduhs(0, 0);
// CHECK: @llvm.hexagon.A2.vaddw
- __builtin_HEXAGON_A2_vaddws(0, 0);
+ __builtin_HEXAGON_A2_vaddw(0, 0);
// CHECK: @llvm.hexagon.A2.vaddws
- __builtin_HEXAGON_A2_vavgh(0, 0);
+ __builtin_HEXAGON_A2_vaddws(0, 0);
// CHECK: @llvm.hexagon.A2.vavgh
- __builtin_HEXAGON_A2_vavghcr(0, 0);
+ __builtin_HEXAGON_A2_vavgh(0, 0);
// CHECK: @llvm.hexagon.A2.vavghcr
- __builtin_HEXAGON_A2_vavghr(0, 0);
+ __builtin_HEXAGON_A2_vavghcr(0, 0);
// CHECK: @llvm.hexagon.A2.vavghr
- __builtin_HEXAGON_A2_vavgub(0, 0);
+ __builtin_HEXAGON_A2_vavghr(0, 0);
// CHECK: @llvm.hexagon.A2.vavgub
- __builtin_HEXAGON_A2_vavgubr(0, 0);
+ __builtin_HEXAGON_A2_vavgub(0, 0);
// CHECK: @llvm.hexagon.A2.vavgubr
- __builtin_HEXAGON_A2_vavguh(0, 0);
+ __builtin_HEXAGON_A2_vavgubr(0, 0);
// CHECK: @llvm.hexagon.A2.vavguh
- __builtin_HEXAGON_A2_vavguhr(0, 0);
+ __builtin_HEXAGON_A2_vavguh(0, 0);
// CHECK: @llvm.hexagon.A2.vavguhr
- __builtin_HEXAGON_A2_vavguw(0, 0);
+ __builtin_HEXAGON_A2_vavguhr(0, 0);
// CHECK: @llvm.hexagon.A2.vavguw
- __builtin_HEXAGON_A2_vavguwr(0, 0);
+ __builtin_HEXAGON_A2_vavguw(0, 0);
// CHECK: @llvm.hexagon.A2.vavguwr
- __builtin_HEXAGON_A2_vavgw(0, 0);
+ __builtin_HEXAGON_A2_vavguwr(0, 0);
// CHECK: @llvm.hexagon.A2.vavgw
- __builtin_HEXAGON_A2_vavgwcr(0, 0);
+ __builtin_HEXAGON_A2_vavgw(0, 0);
// CHECK: @llvm.hexagon.A2.vavgwcr
- __builtin_HEXAGON_A2_vavgwr(0, 0);
+ __builtin_HEXAGON_A2_vavgwcr(0, 0);
// CHECK: @llvm.hexagon.A2.vavgwr
- __builtin_HEXAGON_A2_vcmpbeq(0, 0);
+ __builtin_HEXAGON_A2_vavgwr(0, 0);
// CHECK: @llvm.hexagon.A2.vcmpbeq
- __builtin_HEXAGON_A2_vcmpbgtu(0, 0);
+ __builtin_HEXAGON_A2_vcmpbeq(0, 0);
// CHECK: @llvm.hexagon.A2.vcmpbgtu
- __builtin_HEXAGON_A2_vcmpheq(0, 0);
+ __builtin_HEXAGON_A2_vcmpbgtu(0, 0);
// CHECK: @llvm.hexagon.A2.vcmpheq
- __builtin_HEXAGON_A2_vcmphgt(0, 0);
+ __builtin_HEXAGON_A2_vcmpheq(0, 0);
// CHECK: @llvm.hexagon.A2.vcmphgt
- __builtin_HEXAGON_A2_vcmphgtu(0, 0);
+ __builtin_HEXAGON_A2_vcmphgt(0, 0);
// CHECK: @llvm.hexagon.A2.vcmphgtu
- __builtin_HEXAGON_A2_vcmpweq(0, 0);
+ __builtin_HEXAGON_A2_vcmphgtu(0, 0);
// CHECK: @llvm.hexagon.A2.vcmpweq
- __builtin_HEXAGON_A2_vcmpwgt(0, 0);
+ __builtin_HEXAGON_A2_vcmpweq(0, 0);
// CHECK: @llvm.hexagon.A2.vcmpwgt
- __builtin_HEXAGON_A2_vcmpwgtu(0, 0);
+ __builtin_HEXAGON_A2_vcmpwgt(0, 0);
// CHECK: @llvm.hexagon.A2.vcmpwgtu
- __builtin_HEXAGON_A2_vconj(0);
+ __builtin_HEXAGON_A2_vcmpwgtu(0, 0);
// CHECK: @llvm.hexagon.A2.vconj
- __builtin_HEXAGON_A2_vmaxb(0, 0);
+ __builtin_HEXAGON_A2_vconj(0);
// CHECK: @llvm.hexagon.A2.vmaxb
- __builtin_HEXAGON_A2_vmaxh(0, 0);
+ __builtin_HEXAGON_A2_vmaxb(0, 0);
// CHECK: @llvm.hexagon.A2.vmaxh
- __builtin_HEXAGON_A2_vmaxub(0, 0);
+ __builtin_HEXAGON_A2_vmaxh(0, 0);
// CHECK: @llvm.hexagon.A2.vmaxub
- __builtin_HEXAGON_A2_vmaxuh(0, 0);
+ __builtin_HEXAGON_A2_vmaxub(0, 0);
// CHECK: @llvm.hexagon.A2.vmaxuh
- __builtin_HEXAGON_A2_vmaxuw(0, 0);
+ __builtin_HEXAGON_A2_vmaxuh(0, 0);
// CHECK: @llvm.hexagon.A2.vmaxuw
- __builtin_HEXAGON_A2_vmaxw(0, 0);
+ __builtin_HEXAGON_A2_vmaxuw(0, 0);
// CHECK: @llvm.hexagon.A2.vmaxw
- __builtin_HEXAGON_A2_vminb(0, 0);
+ __builtin_HEXAGON_A2_vmaxw(0, 0);
// CHECK: @llvm.hexagon.A2.vminb
- __builtin_HEXAGON_A2_vminh(0, 0);
+ __builtin_HEXAGON_A2_vminb(0, 0);
// CHECK: @llvm.hexagon.A2.vminh
- __builtin_HEXAGON_A2_vminub(0, 0);
+ __builtin_HEXAGON_A2_vminh(0, 0);
// CHECK: @llvm.hexagon.A2.vminub
- __builtin_HEXAGON_A2_vminuh(0, 0);
+ __builtin_HEXAGON_A2_vminub(0, 0);
// CHECK: @llvm.hexagon.A2.vminuh
- __builtin_HEXAGON_A2_vminuw(0, 0);
+ __builtin_HEXAGON_A2_vminuh(0, 0);
// CHECK: @llvm.hexagon.A2.vminuw
- __builtin_HEXAGON_A2_vminw(0, 0);
+ __builtin_HEXAGON_A2_vminuw(0, 0);
// CHECK: @llvm.hexagon.A2.vminw
- __builtin_HEXAGON_A2_vnavgh(0, 0);
+ __builtin_HEXAGON_A2_vminw(0, 0);
// CHECK: @llvm.hexagon.A2.vnavgh
- __builtin_HEXAGON_A2_vnavghcr(0, 0);
+ __builtin_HEXAGON_A2_vnavgh(0, 0);
// CHECK: @llvm.hexagon.A2.vnavghcr
- __builtin_HEXAGON_A2_vnavghr(0, 0);
+ __builtin_HEXAGON_A2_vnavghcr(0, 0);
// CHECK: @llvm.hexagon.A2.vnavghr
- __builtin_HEXAGON_A2_vnavgw(0, 0);
+ __builtin_HEXAGON_A2_vnavghr(0, 0);
// CHECK: @llvm.hexagon.A2.vnavgw
- __builtin_HEXAGON_A2_vnavgwcr(0, 0);
+ __builtin_HEXAGON_A2_vnavgw(0, 0);
// CHECK: @llvm.hexagon.A2.vnavgwcr
- __builtin_HEXAGON_A2_vnavgwr(0, 0);
+ __builtin_HEXAGON_A2_vnavgwcr(0, 0);
// CHECK: @llvm.hexagon.A2.vnavgwr
- __builtin_HEXAGON_A2_vraddub(0, 0);
+ __builtin_HEXAGON_A2_vnavgwr(0, 0);
// CHECK: @llvm.hexagon.A2.vraddub
- __builtin_HEXAGON_A2_vraddub_acc(0, 0, 0);
+ __builtin_HEXAGON_A2_vraddub(0, 0);
// CHECK: @llvm.hexagon.A2.vraddub.acc
- __builtin_HEXAGON_A2_vrsadub(0, 0);
+ __builtin_HEXAGON_A2_vraddub_acc(0, 0, 0);
// CHECK: @llvm.hexagon.A2.vrsadub
- __builtin_HEXAGON_A2_vrsadub_acc(0, 0, 0);
+ __builtin_HEXAGON_A2_vrsadub(0, 0);
// CHECK: @llvm.hexagon.A2.vrsadub.acc
- __builtin_HEXAGON_A2_vsubb_map(0, 0);
+ __builtin_HEXAGON_A2_vrsadub_acc(0, 0, 0);
// CHECK: @llvm.hexagon.A2.vsubb.map
- __builtin_HEXAGON_A2_vsubh(0, 0);
+ __builtin_HEXAGON_A2_vsubb_map(0, 0);
// CHECK: @llvm.hexagon.A2.vsubh
- __builtin_HEXAGON_A2_vsubhs(0, 0);
+ __builtin_HEXAGON_A2_vsubh(0, 0);
// CHECK: @llvm.hexagon.A2.vsubhs
- __builtin_HEXAGON_A2_vsubub(0, 0);
+ __builtin_HEXAGON_A2_vsubhs(0, 0);
// CHECK: @llvm.hexagon.A2.vsubub
- __builtin_HEXAGON_A2_vsububs(0, 0);
+ __builtin_HEXAGON_A2_vsubub(0, 0);
// CHECK: @llvm.hexagon.A2.vsububs
- __builtin_HEXAGON_A2_vsubuhs(0, 0);
+ __builtin_HEXAGON_A2_vsububs(0, 0);
// CHECK: @llvm.hexagon.A2.vsubuhs
- __builtin_HEXAGON_A2_vsubw(0, 0);
+ __builtin_HEXAGON_A2_vsubuhs(0, 0);
// CHECK: @llvm.hexagon.A2.vsubw
- __builtin_HEXAGON_A2_vsubws(0, 0);
+ __builtin_HEXAGON_A2_vsubw(0, 0);
// CHECK: @llvm.hexagon.A2.vsubws
- __builtin_HEXAGON_A2_xor(0, 0);
+ __builtin_HEXAGON_A2_vsubws(0, 0);
// CHECK: @llvm.hexagon.A2.xor
- __builtin_HEXAGON_A2_xorp(0, 0);
+ __builtin_HEXAGON_A2_xor(0, 0);
// CHECK: @llvm.hexagon.A2.xorp
- __builtin_HEXAGON_A2_zxtb(0);
+ __builtin_HEXAGON_A2_xorp(0, 0);
// CHECK: @llvm.hexagon.A2.zxtb
- __builtin_HEXAGON_A2_zxth(0);
+ __builtin_HEXAGON_A2_zxtb(0);
// CHECK: @llvm.hexagon.A2.zxth
- __builtin_HEXAGON_A4_andn(0, 0);
+ __builtin_HEXAGON_A2_zxth(0);
// CHECK: @llvm.hexagon.A4.andn
- __builtin_HEXAGON_A4_andnp(0, 0);
+ __builtin_HEXAGON_A4_andn(0, 0);
// CHECK: @llvm.hexagon.A4.andnp
- __builtin_HEXAGON_A4_bitsplit(0, 0);
+ __builtin_HEXAGON_A4_andnp(0, 0);
// CHECK: @llvm.hexagon.A4.bitsplit
- __builtin_HEXAGON_A4_bitspliti(0, 0);
+ __builtin_HEXAGON_A4_bitsplit(0, 0);
// CHECK: @llvm.hexagon.A4.bitspliti
- __builtin_HEXAGON_A4_boundscheck(0, 0);
+ __builtin_HEXAGON_A4_bitspliti(0, 0);
// CHECK: @llvm.hexagon.A4.boundscheck
- __builtin_HEXAGON_A4_cmpbeq(0, 0);
+ __builtin_HEXAGON_A4_boundscheck(0, 0);
// CHECK: @llvm.hexagon.A4.cmpbeq
- __builtin_HEXAGON_A4_cmpbeqi(0, 0);
+ __builtin_HEXAGON_A4_cmpbeq(0, 0);
// CHECK: @llvm.hexagon.A4.cmpbeqi
- __builtin_HEXAGON_A4_cmpbgt(0, 0);
+ __builtin_HEXAGON_A4_cmpbeqi(0, 0);
// CHECK: @llvm.hexagon.A4.cmpbgt
- __builtin_HEXAGON_A4_cmpbgti(0, 0);
+ __builtin_HEXAGON_A4_cmpbgt(0, 0);
// CHECK: @llvm.hexagon.A4.cmpbgti
- __builtin_HEXAGON_A4_cmpbgtu(0, 0);
+ __builtin_HEXAGON_A4_cmpbgti(0, 0);
// CHECK: @llvm.hexagon.A4.cmpbgtu
- __builtin_HEXAGON_A4_cmpbgtui(0, 0);
+ __builtin_HEXAGON_A4_cmpbgtu(0, 0);
// CHECK: @llvm.hexagon.A4.cmpbgtui
- __builtin_HEXAGON_A4_cmpheq(0, 0);
+ __builtin_HEXAGON_A4_cmpbgtui(0, 0);
// CHECK: @llvm.hexagon.A4.cmpheq
- __builtin_HEXAGON_A4_cmpheqi(0, 0);
+ __builtin_HEXAGON_A4_cmpheq(0, 0);
// CHECK: @llvm.hexagon.A4.cmpheqi
- __builtin_HEXAGON_A4_cmphgt(0, 0);
+ __builtin_HEXAGON_A4_cmpheqi(0, 0);
// CHECK: @llvm.hexagon.A4.cmphgt
- __builtin_HEXAGON_A4_cmphgti(0, 0);
+ __builtin_HEXAGON_A4_cmphgt(0, 0);
// CHECK: @llvm.hexagon.A4.cmphgti
- __builtin_HEXAGON_A4_cmphgtu(0, 0);
+ __builtin_HEXAGON_A4_cmphgti(0, 0);
// CHECK: @llvm.hexagon.A4.cmphgtu
- __builtin_HEXAGON_A4_cmphgtui(0, 0);
+ __builtin_HEXAGON_A4_cmphgtu(0, 0);
// CHECK: @llvm.hexagon.A4.cmphgtui
- __builtin_HEXAGON_A4_combineir(0, 0);
+ __builtin_HEXAGON_A4_cmphgtui(0, 0);
// CHECK: @llvm.hexagon.A4.combineir
- __builtin_HEXAGON_A4_combineri(0, 0);
+ __builtin_HEXAGON_A4_combineir(0, 0);
// CHECK: @llvm.hexagon.A4.combineri
- __builtin_HEXAGON_A4_cround_ri(0, 0);
+ __builtin_HEXAGON_A4_combineri(0, 0);
// CHECK: @llvm.hexagon.A4.cround.ri
- __builtin_HEXAGON_A4_cround_rr(0, 0);
+ __builtin_HEXAGON_A4_cround_ri(0, 0);
// CHECK: @llvm.hexagon.A4.cround.rr
- __builtin_HEXAGON_A4_modwrapu(0, 0);
+ __builtin_HEXAGON_A4_cround_rr(0, 0);
// CHECK: @llvm.hexagon.A4.modwrapu
- __builtin_HEXAGON_A4_orn(0, 0);
+ __builtin_HEXAGON_A4_modwrapu(0, 0);
// CHECK: @llvm.hexagon.A4.orn
- __builtin_HEXAGON_A4_ornp(0, 0);
+ __builtin_HEXAGON_A4_orn(0, 0);
// CHECK: @llvm.hexagon.A4.ornp
- __builtin_HEXAGON_A4_rcmpeq(0, 0);
+ __builtin_HEXAGON_A4_ornp(0, 0);
// CHECK: @llvm.hexagon.A4.rcmpeq
- __builtin_HEXAGON_A4_rcmpeqi(0, 0);
+ __builtin_HEXAGON_A4_rcmpeq(0, 0);
// CHECK: @llvm.hexagon.A4.rcmpeqi
- __builtin_HEXAGON_A4_rcmpneq(0, 0);
+ __builtin_HEXAGON_A4_rcmpeqi(0, 0);
// CHECK: @llvm.hexagon.A4.rcmpneq
- __builtin_HEXAGON_A4_rcmpneqi(0, 0);
+ __builtin_HEXAGON_A4_rcmpneq(0, 0);
// CHECK: @llvm.hexagon.A4.rcmpneqi
- __builtin_HEXAGON_A4_round_ri(0, 0);
+ __builtin_HEXAGON_A4_rcmpneqi(0, 0);
// CHECK: @llvm.hexagon.A4.round.ri
- __builtin_HEXAGON_A4_round_ri_sat(0, 0);
+ __builtin_HEXAGON_A4_round_ri(0, 0);
// CHECK: @llvm.hexagon.A4.round.ri.sat
- __builtin_HEXAGON_A4_round_rr(0, 0);
+ __builtin_HEXAGON_A4_round_ri_sat(0, 0);
// CHECK: @llvm.hexagon.A4.round.rr
- __builtin_HEXAGON_A4_round_rr_sat(0, 0);
+ __builtin_HEXAGON_A4_round_rr(0, 0);
// CHECK: @llvm.hexagon.A4.round.rr.sat
- __builtin_HEXAGON_A4_tlbmatch(0, 0);
+ __builtin_HEXAGON_A4_round_rr_sat(0, 0);
// CHECK: @llvm.hexagon.A4.tlbmatch
- __builtin_HEXAGON_A4_vcmpbeq_any(0, 0);
+ __builtin_HEXAGON_A4_tlbmatch(0, 0);
// CHECK: @llvm.hexagon.A4.vcmpbeq.any
- __builtin_HEXAGON_A4_vcmpbeqi(0, 0);
+ __builtin_HEXAGON_A4_vcmpbeq_any(0, 0);
// CHECK: @llvm.hexagon.A4.vcmpbeqi
- __builtin_HEXAGON_A4_vcmpbgt(0, 0);
+ __builtin_HEXAGON_A4_vcmpbeqi(0, 0);
// CHECK: @llvm.hexagon.A4.vcmpbgt
- __builtin_HEXAGON_A4_vcmpbgti(0, 0);
+ __builtin_HEXAGON_A4_vcmpbgt(0, 0);
// CHECK: @llvm.hexagon.A4.vcmpbgti
- __builtin_HEXAGON_A4_vcmpbgtui(0, 0);
+ __builtin_HEXAGON_A4_vcmpbgti(0, 0);
// CHECK: @llvm.hexagon.A4.vcmpbgtui
- __builtin_HEXAGON_A4_vcmpheqi(0, 0);
+ __builtin_HEXAGON_A4_vcmpbgtui(0, 0);
// CHECK: @llvm.hexagon.A4.vcmpheqi
- __builtin_HEXAGON_A4_vcmphgti(0, 0);
+ __builtin_HEXAGON_A4_vcmpheqi(0, 0);
// CHECK: @llvm.hexagon.A4.vcmphgti
- __builtin_HEXAGON_A4_vcmphgtui(0, 0);
+ __builtin_HEXAGON_A4_vcmphgti(0, 0);
// CHECK: @llvm.hexagon.A4.vcmphgtui
- __builtin_HEXAGON_A4_vcmpweqi(0, 0);
+ __builtin_HEXAGON_A4_vcmphgtui(0, 0);
// CHECK: @llvm.hexagon.A4.vcmpweqi
- __builtin_HEXAGON_A4_vcmpwgti(0, 0);
+ __builtin_HEXAGON_A4_vcmpweqi(0, 0);
// CHECK: @llvm.hexagon.A4.vcmpwgti
- __builtin_HEXAGON_A4_vcmpwgtui(0, 0);
+ __builtin_HEXAGON_A4_vcmpwgti(0, 0);
// CHECK: @llvm.hexagon.A4.vcmpwgtui
- __builtin_HEXAGON_A4_vrmaxh(0, 0, 0);
+ __builtin_HEXAGON_A4_vcmpwgtui(0, 0);
// CHECK: @llvm.hexagon.A4.vrmaxh
- __builtin_HEXAGON_A4_vrmaxuh(0, 0, 0);
+ __builtin_HEXAGON_A4_vrmaxh(0, 0, 0);
// CHECK: @llvm.hexagon.A4.vrmaxuh
- __builtin_HEXAGON_A4_vrmaxuw(0, 0, 0);
+ __builtin_HEXAGON_A4_vrmaxuh(0, 0, 0);
// CHECK: @llvm.hexagon.A4.vrmaxuw
- __builtin_HEXAGON_A4_vrmaxw(0, 0, 0);
+ __builtin_HEXAGON_A4_vrmaxuw(0, 0, 0);
// CHECK: @llvm.hexagon.A4.vrmaxw
- __builtin_HEXAGON_A4_vrminh(0, 0, 0);
+ __builtin_HEXAGON_A4_vrmaxw(0, 0, 0);
// CHECK: @llvm.hexagon.A4.vrminh
- __builtin_HEXAGON_A4_vrminuh(0, 0, 0);
+ __builtin_HEXAGON_A4_vrminh(0, 0, 0);
// CHECK: @llvm.hexagon.A4.vrminuh
- __builtin_HEXAGON_A4_vrminuw(0, 0, 0);
+ __builtin_HEXAGON_A4_vrminuh(0, 0, 0);
// CHECK: @llvm.hexagon.A4.vrminuw
- __builtin_HEXAGON_A4_vrminw(0, 0, 0);
+ __builtin_HEXAGON_A4_vrminuw(0, 0, 0);
// CHECK: @llvm.hexagon.A4.vrminw
- __builtin_HEXAGON_A5_vaddhubs(0, 0);
+ __builtin_HEXAGON_A4_vrminw(0, 0, 0);
// CHECK: @llvm.hexagon.A5.vaddhubs
- __builtin_HEXAGON_C2_all8(0);
+ __builtin_HEXAGON_A5_vaddhubs(0, 0);
+ // CHECK: @llvm.hexagon.A6.vcmpbeq.notany
+ __builtin_HEXAGON_A6_vcmpbeq_notany(0, 0);
+ // CHECK: @llvm.hexagon.A6.vcmpbeq.notany.128B
+ __builtin_HEXAGON_A6_vcmpbeq_notany_128B(0, 0);
// CHECK: @llvm.hexagon.C2.all8
- __builtin_HEXAGON_C2_and(0, 0);
+ __builtin_HEXAGON_C2_all8(0);
// CHECK: @llvm.hexagon.C2.and
- __builtin_HEXAGON_C2_andn(0, 0);
+ __builtin_HEXAGON_C2_and(0, 0);
// CHECK: @llvm.hexagon.C2.andn
- __builtin_HEXAGON_C2_any8(0);
+ __builtin_HEXAGON_C2_andn(0, 0);
// CHECK: @llvm.hexagon.C2.any8
- __builtin_HEXAGON_C2_bitsclr(0, 0);
+ __builtin_HEXAGON_C2_any8(0);
// CHECK: @llvm.hexagon.C2.bitsclr
- __builtin_HEXAGON_C2_bitsclri(0, 0);
+ __builtin_HEXAGON_C2_bitsclr(0, 0);
// CHECK: @llvm.hexagon.C2.bitsclri
- __builtin_HEXAGON_C2_bitsset(0, 0);
+ __builtin_HEXAGON_C2_bitsclri(0, 0);
// CHECK: @llvm.hexagon.C2.bitsset
- __builtin_HEXAGON_C2_cmpeq(0, 0);
+ __builtin_HEXAGON_C2_bitsset(0, 0);
// CHECK: @llvm.hexagon.C2.cmpeq
- __builtin_HEXAGON_C2_cmpeqi(0, 0);
+ __builtin_HEXAGON_C2_cmpeq(0, 0);
// CHECK: @llvm.hexagon.C2.cmpeqi
- __builtin_HEXAGON_C2_cmpeqp(0, 0);
+ __builtin_HEXAGON_C2_cmpeqi(0, 0);
// CHECK: @llvm.hexagon.C2.cmpeqp
- __builtin_HEXAGON_C2_cmpgei(0, 0);
+ __builtin_HEXAGON_C2_cmpeqp(0, 0);
// CHECK: @llvm.hexagon.C2.cmpgei
- __builtin_HEXAGON_C2_cmpgeui(0, 0);
+ __builtin_HEXAGON_C2_cmpgei(0, 0);
// CHECK: @llvm.hexagon.C2.cmpgeui
- __builtin_HEXAGON_C2_cmpgt(0, 0);
+ __builtin_HEXAGON_C2_cmpgeui(0, 0);
// CHECK: @llvm.hexagon.C2.cmpgt
- __builtin_HEXAGON_C2_cmpgti(0, 0);
+ __builtin_HEXAGON_C2_cmpgt(0, 0);
// CHECK: @llvm.hexagon.C2.cmpgti
- __builtin_HEXAGON_C2_cmpgtp(0, 0);
+ __builtin_HEXAGON_C2_cmpgti(0, 0);
// CHECK: @llvm.hexagon.C2.cmpgtp
- __builtin_HEXAGON_C2_cmpgtu(0, 0);
+ __builtin_HEXAGON_C2_cmpgtp(0, 0);
// CHECK: @llvm.hexagon.C2.cmpgtu
- __builtin_HEXAGON_C2_cmpgtui(0, 0);
+ __builtin_HEXAGON_C2_cmpgtu(0, 0);
// CHECK: @llvm.hexagon.C2.cmpgtui
- __builtin_HEXAGON_C2_cmpgtup(0, 0);
+ __builtin_HEXAGON_C2_cmpgtui(0, 0);
// CHECK: @llvm.hexagon.C2.cmpgtup
- __builtin_HEXAGON_C2_cmplt(0, 0);
+ __builtin_HEXAGON_C2_cmpgtup(0, 0);
// CHECK: @llvm.hexagon.C2.cmplt
- __builtin_HEXAGON_C2_cmpltu(0, 0);
+ __builtin_HEXAGON_C2_cmplt(0, 0);
// CHECK: @llvm.hexagon.C2.cmpltu
- __builtin_HEXAGON_C2_mask(0);
+ __builtin_HEXAGON_C2_cmpltu(0, 0);
// CHECK: @llvm.hexagon.C2.mask
- __builtin_HEXAGON_C2_mux(0, 0, 0);
+ __builtin_HEXAGON_C2_mask(0);
// CHECK: @llvm.hexagon.C2.mux
- __builtin_HEXAGON_C2_muxii(0, 0, 0);
+ __builtin_HEXAGON_C2_mux(0, 0, 0);
// CHECK: @llvm.hexagon.C2.muxii
- __builtin_HEXAGON_C2_muxir(0, 0, 0);
+ __builtin_HEXAGON_C2_muxii(0, 0, 0);
// CHECK: @llvm.hexagon.C2.muxir
- __builtin_HEXAGON_C2_muxri(0, 0, 0);
+ __builtin_HEXAGON_C2_muxir(0, 0, 0);
// CHECK: @llvm.hexagon.C2.muxri
- __builtin_HEXAGON_C2_not(0);
+ __builtin_HEXAGON_C2_muxri(0, 0, 0);
// CHECK: @llvm.hexagon.C2.not
- __builtin_HEXAGON_C2_or (0, 0);
- // CHECK: @llvm.hexagon.C2.or
- __builtin_HEXAGON_C2_orn(0, 0);
+ __builtin_HEXAGON_C2_not(0);
+ // CHECK: @llvm.hexagon.C2.or
+ __builtin_HEXAGON_C2_or(0, 0);
// CHECK: @llvm.hexagon.C2.orn
- __builtin_HEXAGON_C2_pxfer_map(0);
+ __builtin_HEXAGON_C2_orn(0, 0);
// CHECK: @llvm.hexagon.C2.pxfer.map
- __builtin_HEXAGON_C2_tfrpr(0);
+ __builtin_HEXAGON_C2_pxfer_map(0);
// CHECK: @llvm.hexagon.C2.tfrpr
- __builtin_HEXAGON_C2_tfrrp(0);
+ __builtin_HEXAGON_C2_tfrpr(0);
// CHECK: @llvm.hexagon.C2.tfrrp
- __builtin_HEXAGON_C2_vitpack(0, 0);
+ __builtin_HEXAGON_C2_tfrrp(0);
// CHECK: @llvm.hexagon.C2.vitpack
- __builtin_HEXAGON_C2_vmux(0, 0, 0);
+ __builtin_HEXAGON_C2_vitpack(0, 0);
// CHECK: @llvm.hexagon.C2.vmux
- __builtin_HEXAGON_C2_xor(0, 0);
+ __builtin_HEXAGON_C2_vmux(0, 0, 0);
// CHECK: @llvm.hexagon.C2.xor
- __builtin_HEXAGON_C4_and_and(0, 0, 0);
+ __builtin_HEXAGON_C2_xor(0, 0);
// CHECK: @llvm.hexagon.C4.and.and
- __builtin_HEXAGON_C4_and_andn(0, 0, 0);
+ __builtin_HEXAGON_C4_and_and(0, 0, 0);
// CHECK: @llvm.hexagon.C4.and.andn
- __builtin_HEXAGON_C4_and_or(0, 0, 0);
+ __builtin_HEXAGON_C4_and_andn(0, 0, 0);
// CHECK: @llvm.hexagon.C4.and.or
- __builtin_HEXAGON_C4_and_orn(0, 0, 0);
+ __builtin_HEXAGON_C4_and_or(0, 0, 0);
// CHECK: @llvm.hexagon.C4.and.orn
- __builtin_HEXAGON_C4_cmplte(0, 0);
+ __builtin_HEXAGON_C4_and_orn(0, 0, 0);
// CHECK: @llvm.hexagon.C4.cmplte
- __builtin_HEXAGON_C4_cmpltei(0, 0);
+ __builtin_HEXAGON_C4_cmplte(0, 0);
// CHECK: @llvm.hexagon.C4.cmpltei
- __builtin_HEXAGON_C4_cmplteu(0, 0);
+ __builtin_HEXAGON_C4_cmpltei(0, 0);
// CHECK: @llvm.hexagon.C4.cmplteu
- __builtin_HEXAGON_C4_cmplteui(0, 0);
+ __builtin_HEXAGON_C4_cmplteu(0, 0);
// CHECK: @llvm.hexagon.C4.cmplteui
- __builtin_HEXAGON_C4_cmpneq(0, 0);
+ __builtin_HEXAGON_C4_cmplteui(0, 0);
// CHECK: @llvm.hexagon.C4.cmpneq
- __builtin_HEXAGON_C4_cmpneqi(0, 0);
+ __builtin_HEXAGON_C4_cmpneq(0, 0);
// CHECK: @llvm.hexagon.C4.cmpneqi
- __builtin_HEXAGON_C4_fastcorner9(0, 0);
+ __builtin_HEXAGON_C4_cmpneqi(0, 0);
// CHECK: @llvm.hexagon.C4.fastcorner9
- __builtin_HEXAGON_C4_fastcorner9_not(0, 0);
+ __builtin_HEXAGON_C4_fastcorner9(0, 0);
// CHECK: @llvm.hexagon.C4.fastcorner9.not
- __builtin_HEXAGON_C4_nbitsclr(0, 0);
+ __builtin_HEXAGON_C4_fastcorner9_not(0, 0);
// CHECK: @llvm.hexagon.C4.nbitsclr
- __builtin_HEXAGON_C4_nbitsclri(0, 0);
+ __builtin_HEXAGON_C4_nbitsclr(0, 0);
// CHECK: @llvm.hexagon.C4.nbitsclri
- __builtin_HEXAGON_C4_nbitsset(0, 0);
+ __builtin_HEXAGON_C4_nbitsclri(0, 0);
// CHECK: @llvm.hexagon.C4.nbitsset
- __builtin_HEXAGON_C4_or_and(0, 0, 0);
+ __builtin_HEXAGON_C4_nbitsset(0, 0);
// CHECK: @llvm.hexagon.C4.or.and
- __builtin_HEXAGON_C4_or_andn(0, 0, 0);
+ __builtin_HEXAGON_C4_or_and(0, 0, 0);
// CHECK: @llvm.hexagon.C4.or.andn
- __builtin_HEXAGON_C4_or_or(0, 0, 0);
+ __builtin_HEXAGON_C4_or_andn(0, 0, 0);
// CHECK: @llvm.hexagon.C4.or.or
- __builtin_HEXAGON_C4_or_orn(0, 0, 0);
+ __builtin_HEXAGON_C4_or_or(0, 0, 0);
// CHECK: @llvm.hexagon.C4.or.orn
- __builtin_HEXAGON_F2_conv_d2df(0);
+ __builtin_HEXAGON_C4_or_orn(0, 0, 0);
// CHECK: @llvm.hexagon.F2.conv.d2df
- __builtin_HEXAGON_F2_conv_d2sf(0);
+ __builtin_HEXAGON_F2_conv_d2df(0);
// CHECK: @llvm.hexagon.F2.conv.d2sf
- __builtin_HEXAGON_F2_conv_df2d(0.0);
+ __builtin_HEXAGON_F2_conv_d2sf(0);
// CHECK: @llvm.hexagon.F2.conv.df2d
- __builtin_HEXAGON_F2_conv_df2d_chop(0.0);
+ __builtin_HEXAGON_F2_conv_df2d(0.0);
// CHECK: @llvm.hexagon.F2.conv.df2d.chop
- __builtin_HEXAGON_F2_conv_df2sf(0.0);
+ __builtin_HEXAGON_F2_conv_df2d_chop(0.0);
// CHECK: @llvm.hexagon.F2.conv.df2sf
- __builtin_HEXAGON_F2_conv_df2ud(0.0);
+ __builtin_HEXAGON_F2_conv_df2sf(0.0);
// CHECK: @llvm.hexagon.F2.conv.df2ud
- __builtin_HEXAGON_F2_conv_df2ud_chop(0.0);
+ __builtin_HEXAGON_F2_conv_df2ud(0.0);
// CHECK: @llvm.hexagon.F2.conv.df2ud.chop
- __builtin_HEXAGON_F2_conv_df2uw(0.0);
+ __builtin_HEXAGON_F2_conv_df2ud_chop(0.0);
// CHECK: @llvm.hexagon.F2.conv.df2uw
- __builtin_HEXAGON_F2_conv_df2uw_chop(0.0);
+ __builtin_HEXAGON_F2_conv_df2uw(0.0);
// CHECK: @llvm.hexagon.F2.conv.df2uw.chop
- __builtin_HEXAGON_F2_conv_df2w(0.0);
+ __builtin_HEXAGON_F2_conv_df2uw_chop(0.0);
// CHECK: @llvm.hexagon.F2.conv.df2w
- __builtin_HEXAGON_F2_conv_df2w_chop(0.0);
+ __builtin_HEXAGON_F2_conv_df2w(0.0);
// CHECK: @llvm.hexagon.F2.conv.df2w.chop
- __builtin_HEXAGON_F2_conv_sf2d(0.0f);
+ __builtin_HEXAGON_F2_conv_df2w_chop(0.0);
// CHECK: @llvm.hexagon.F2.conv.sf2d
- __builtin_HEXAGON_F2_conv_sf2d_chop(0.0f);
+ __builtin_HEXAGON_F2_conv_sf2d(0.0f);
// CHECK: @llvm.hexagon.F2.conv.sf2d.chop
- __builtin_HEXAGON_F2_conv_sf2df(0.0f);
+ __builtin_HEXAGON_F2_conv_sf2d_chop(0.0f);
// CHECK: @llvm.hexagon.F2.conv.sf2df
- __builtin_HEXAGON_F2_conv_sf2ud(0.0f);
+ __builtin_HEXAGON_F2_conv_sf2df(0.0f);
// CHECK: @llvm.hexagon.F2.conv.sf2ud
- __builtin_HEXAGON_F2_conv_sf2ud_chop(0.0f);
+ __builtin_HEXAGON_F2_conv_sf2ud(0.0f);
// CHECK: @llvm.hexagon.F2.conv.sf2ud.chop
- __builtin_HEXAGON_F2_conv_sf2uw(0.0f);
+ __builtin_HEXAGON_F2_conv_sf2ud_chop(0.0f);
// CHECK: @llvm.hexagon.F2.conv.sf2uw
- __builtin_HEXAGON_F2_conv_sf2uw_chop(0.0f);
+ __builtin_HEXAGON_F2_conv_sf2uw(0.0f);
// CHECK: @llvm.hexagon.F2.conv.sf2uw.chop
- __builtin_HEXAGON_F2_conv_sf2w(0.0f);
+ __builtin_HEXAGON_F2_conv_sf2uw_chop(0.0f);
// CHECK: @llvm.hexagon.F2.conv.sf2w
- __builtin_HEXAGON_F2_conv_sf2w_chop(0.0f);
+ __builtin_HEXAGON_F2_conv_sf2w(0.0f);
// CHECK: @llvm.hexagon.F2.conv.sf2w.chop
- __builtin_HEXAGON_F2_conv_ud2df(0);
+ __builtin_HEXAGON_F2_conv_sf2w_chop(0.0f);
// CHECK: @llvm.hexagon.F2.conv.ud2df
- __builtin_HEXAGON_F2_conv_ud2sf(0);
+ __builtin_HEXAGON_F2_conv_ud2df(0);
// CHECK: @llvm.hexagon.F2.conv.ud2sf
- __builtin_HEXAGON_F2_conv_uw2df(0);
+ __builtin_HEXAGON_F2_conv_ud2sf(0);
// CHECK: @llvm.hexagon.F2.conv.uw2df
- __builtin_HEXAGON_F2_conv_uw2sf(0);
+ __builtin_HEXAGON_F2_conv_uw2df(0);
// CHECK: @llvm.hexagon.F2.conv.uw2sf
- __builtin_HEXAGON_F2_conv_w2df(0);
+ __builtin_HEXAGON_F2_conv_uw2sf(0);
// CHECK: @llvm.hexagon.F2.conv.w2df
- __builtin_HEXAGON_F2_conv_w2sf(0);
+ __builtin_HEXAGON_F2_conv_w2df(0);
// CHECK: @llvm.hexagon.F2.conv.w2sf
- __builtin_HEXAGON_F2_dfclass(0.0, 0);
+ __builtin_HEXAGON_F2_conv_w2sf(0);
// CHECK: @llvm.hexagon.F2.dfclass
- __builtin_HEXAGON_F2_dfcmpeq(0.0, 0.0);
+ __builtin_HEXAGON_F2_dfclass(0.0, 0);
// CHECK: @llvm.hexagon.F2.dfcmpeq
- __builtin_HEXAGON_F2_dfcmpge(0.0, 0.0);
+ __builtin_HEXAGON_F2_dfcmpeq(0.0, 0.0);
// CHECK: @llvm.hexagon.F2.dfcmpge
- __builtin_HEXAGON_F2_dfcmpgt(0.0, 0.0);
+ __builtin_HEXAGON_F2_dfcmpge(0.0, 0.0);
// CHECK: @llvm.hexagon.F2.dfcmpgt
- __builtin_HEXAGON_F2_dfcmpuo(0.0, 0.0);
+ __builtin_HEXAGON_F2_dfcmpgt(0.0, 0.0);
// CHECK: @llvm.hexagon.F2.dfcmpuo
- __builtin_HEXAGON_F2_dfimm_n(0);
+ __builtin_HEXAGON_F2_dfcmpuo(0.0, 0.0);
// CHECK: @llvm.hexagon.F2.dfimm.n
- __builtin_HEXAGON_F2_dfimm_p(0);
+ __builtin_HEXAGON_F2_dfimm_n(0);
// CHECK: @llvm.hexagon.F2.dfimm.p
- __builtin_HEXAGON_F2_sfadd(0.0f, 0.0f);
+ __builtin_HEXAGON_F2_dfimm_p(0);
// CHECK: @llvm.hexagon.F2.sfadd
- __builtin_HEXAGON_F2_sfclass(0.0f, 0);
+ __builtin_HEXAGON_F2_sfadd(0.0f, 0.0f);
// CHECK: @llvm.hexagon.F2.sfclass
- __builtin_HEXAGON_F2_sfcmpeq(0.0f, 0.0f);
+ __builtin_HEXAGON_F2_sfclass(0.0f, 0);
// CHECK: @llvm.hexagon.F2.sfcmpeq
- __builtin_HEXAGON_F2_sfcmpge(0.0f, 0.0f);
+ __builtin_HEXAGON_F2_sfcmpeq(0.0f, 0.0f);
// CHECK: @llvm.hexagon.F2.sfcmpge
- __builtin_HEXAGON_F2_sfcmpgt(0.0f, 0.0f);
+ __builtin_HEXAGON_F2_sfcmpge(0.0f, 0.0f);
// CHECK: @llvm.hexagon.F2.sfcmpgt
- __builtin_HEXAGON_F2_sfcmpuo(0.0f, 0.0f);
+ __builtin_HEXAGON_F2_sfcmpgt(0.0f, 0.0f);
// CHECK: @llvm.hexagon.F2.sfcmpuo
- __builtin_HEXAGON_F2_sffixupd(0.0f, 0.0f);
+ __builtin_HEXAGON_F2_sfcmpuo(0.0f, 0.0f);
// CHECK: @llvm.hexagon.F2.sffixupd
- __builtin_HEXAGON_F2_sffixupn(0.0f, 0.0f);
+ __builtin_HEXAGON_F2_sffixupd(0.0f, 0.0f);
// CHECK: @llvm.hexagon.F2.sffixupn
- __builtin_HEXAGON_F2_sffixupr(0.0f);
+ __builtin_HEXAGON_F2_sffixupn(0.0f, 0.0f);
// CHECK: @llvm.hexagon.F2.sffixupr
- __builtin_HEXAGON_F2_sffma(0.0f, 0.0f, 0.0f);
+ __builtin_HEXAGON_F2_sffixupr(0.0f);
// CHECK: @llvm.hexagon.F2.sffma
- __builtin_HEXAGON_F2_sffma_lib(0.0f, 0.0f, 0.0f);
+ __builtin_HEXAGON_F2_sffma(0.0f, 0.0f, 0.0f);
// CHECK: @llvm.hexagon.F2.sffma.lib
- __builtin_HEXAGON_F2_sffma_sc(0.0f, 0.0f, 0.0f, 0);
+ __builtin_HEXAGON_F2_sffma_lib(0.0f, 0.0f, 0.0f);
// CHECK: @llvm.hexagon.F2.sffma.sc
- __builtin_HEXAGON_F2_sffms(0.0f, 0.0f, 0.0f);
+ __builtin_HEXAGON_F2_sffma_sc(0.0f, 0.0f, 0.0f, 0);
// CHECK: @llvm.hexagon.F2.sffms
- __builtin_HEXAGON_F2_sffms_lib(0.0f, 0.0f, 0.0f);
+ __builtin_HEXAGON_F2_sffms(0.0f, 0.0f, 0.0f);
// CHECK: @llvm.hexagon.F2.sffms.lib
- __builtin_HEXAGON_F2_sfimm_n(0);
+ __builtin_HEXAGON_F2_sffms_lib(0.0f, 0.0f, 0.0f);
// CHECK: @llvm.hexagon.F2.sfimm.n
- __builtin_HEXAGON_F2_sfimm_p(0);
+ __builtin_HEXAGON_F2_sfimm_n(0);
// CHECK: @llvm.hexagon.F2.sfimm.p
- __builtin_HEXAGON_F2_sfmax(0.0f, 0.0f);
+ __builtin_HEXAGON_F2_sfimm_p(0);
// CHECK: @llvm.hexagon.F2.sfmax
- __builtin_HEXAGON_F2_sfmin(0.0f, 0.0f);
+ __builtin_HEXAGON_F2_sfmax(0.0f, 0.0f);
// CHECK: @llvm.hexagon.F2.sfmin
- __builtin_HEXAGON_F2_sfmpy(0.0f, 0.0f);
+ __builtin_HEXAGON_F2_sfmin(0.0f, 0.0f);
// CHECK: @llvm.hexagon.F2.sfmpy
- __builtin_HEXAGON_F2_sfsub(0.0f, 0.0f);
+ __builtin_HEXAGON_F2_sfmpy(0.0f, 0.0f);
// CHECK: @llvm.hexagon.F2.sfsub
- __builtin_HEXAGON_M2_acci(0, 0, 0);
+ __builtin_HEXAGON_F2_sfsub(0.0f, 0.0f);
// CHECK: @llvm.hexagon.M2.acci
- __builtin_HEXAGON_M2_accii(0, 0, 0);
+ __builtin_HEXAGON_M2_acci(0, 0, 0);
// CHECK: @llvm.hexagon.M2.accii
- __builtin_HEXAGON_M2_cmaci_s0(0, 0, 0);
+ __builtin_HEXAGON_M2_accii(0, 0, 0);
// CHECK: @llvm.hexagon.M2.cmaci.s0
- __builtin_HEXAGON_M2_cmacr_s0(0, 0, 0);
+ __builtin_HEXAGON_M2_cmaci_s0(0, 0, 0);
// CHECK: @llvm.hexagon.M2.cmacr.s0
- __builtin_HEXAGON_M2_cmacsc_s0(0, 0, 0);
- // CHECK: @llvm.hexagon.M2.cmacsc.s0
- __builtin_HEXAGON_M2_cmacsc_s1(0, 0, 0);
- // CHECK: @llvm.hexagon.M2.cmacsc.s1
- __builtin_HEXAGON_M2_cmacs_s0(0, 0, 0);
+ __builtin_HEXAGON_M2_cmacr_s0(0, 0, 0);
// CHECK: @llvm.hexagon.M2.cmacs.s0
- __builtin_HEXAGON_M2_cmacs_s1(0, 0, 0);
+ __builtin_HEXAGON_M2_cmacs_s0(0, 0, 0);
// CHECK: @llvm.hexagon.M2.cmacs.s1
- __builtin_HEXAGON_M2_cmpyi_s0(0, 0);
+ __builtin_HEXAGON_M2_cmacs_s1(0, 0, 0);
+ // CHECK: @llvm.hexagon.M2.cmacsc.s0
+ __builtin_HEXAGON_M2_cmacsc_s0(0, 0, 0);
+ // CHECK: @llvm.hexagon.M2.cmacsc.s1
+ __builtin_HEXAGON_M2_cmacsc_s1(0, 0, 0);
// CHECK: @llvm.hexagon.M2.cmpyi.s0
- __builtin_HEXAGON_M2_cmpyr_s0(0, 0);
+ __builtin_HEXAGON_M2_cmpyi_s0(0, 0);
// CHECK: @llvm.hexagon.M2.cmpyr.s0
- __builtin_HEXAGON_M2_cmpyrsc_s0(0, 0);
- // CHECK: @llvm.hexagon.M2.cmpyrsc.s0
- __builtin_HEXAGON_M2_cmpyrsc_s1(0, 0);
- // CHECK: @llvm.hexagon.M2.cmpyrsc.s1
- __builtin_HEXAGON_M2_cmpyrs_s0(0, 0);
+ __builtin_HEXAGON_M2_cmpyr_s0(0, 0);
// CHECK: @llvm.hexagon.M2.cmpyrs.s0
- __builtin_HEXAGON_M2_cmpyrs_s1(0, 0);
+ __builtin_HEXAGON_M2_cmpyrs_s0(0, 0);
// CHECK: @llvm.hexagon.M2.cmpyrs.s1
- __builtin_HEXAGON_M2_cmpysc_s0(0, 0);
- // CHECK: @llvm.hexagon.M2.cmpysc.s0
- __builtin_HEXAGON_M2_cmpysc_s1(0, 0);
- // CHECK: @llvm.hexagon.M2.cmpysc.s1
- __builtin_HEXAGON_M2_cmpys_s0(0, 0);
+ __builtin_HEXAGON_M2_cmpyrs_s1(0, 0);
+ // CHECK: @llvm.hexagon.M2.cmpyrsc.s0
+ __builtin_HEXAGON_M2_cmpyrsc_s0(0, 0);
+ // CHECK: @llvm.hexagon.M2.cmpyrsc.s1
+ __builtin_HEXAGON_M2_cmpyrsc_s1(0, 0);
// CHECK: @llvm.hexagon.M2.cmpys.s0
- __builtin_HEXAGON_M2_cmpys_s1(0, 0);
+ __builtin_HEXAGON_M2_cmpys_s0(0, 0);
// CHECK: @llvm.hexagon.M2.cmpys.s1
- __builtin_HEXAGON_M2_cnacsc_s0(0, 0, 0);
- // CHECK: @llvm.hexagon.M2.cnacsc.s0
- __builtin_HEXAGON_M2_cnacsc_s1(0, 0, 0);
- // CHECK: @llvm.hexagon.M2.cnacsc.s1
- __builtin_HEXAGON_M2_cnacs_s0(0, 0, 0);
+ __builtin_HEXAGON_M2_cmpys_s1(0, 0);
+ // CHECK: @llvm.hexagon.M2.cmpysc.s0
+ __builtin_HEXAGON_M2_cmpysc_s0(0, 0);
+ // CHECK: @llvm.hexagon.M2.cmpysc.s1
+ __builtin_HEXAGON_M2_cmpysc_s1(0, 0);
// CHECK: @llvm.hexagon.M2.cnacs.s0
- __builtin_HEXAGON_M2_cnacs_s1(0, 0, 0);
+ __builtin_HEXAGON_M2_cnacs_s0(0, 0, 0);
// CHECK: @llvm.hexagon.M2.cnacs.s1
- __builtin_HEXAGON_M2_dpmpyss_acc_s0(0, 0, 0);
+ __builtin_HEXAGON_M2_cnacs_s1(0, 0, 0);
+ // CHECK: @llvm.hexagon.M2.cnacsc.s0
+ __builtin_HEXAGON_M2_cnacsc_s0(0, 0, 0);
+ // CHECK: @llvm.hexagon.M2.cnacsc.s1
+ __builtin_HEXAGON_M2_cnacsc_s1(0, 0, 0);
// CHECK: @llvm.hexagon.M2.dpmpyss.acc.s0
- __builtin_HEXAGON_M2_dpmpyss_nac_s0(0, 0, 0);
+ __builtin_HEXAGON_M2_dpmpyss_acc_s0(0, 0, 0);
// CHECK: @llvm.hexagon.M2.dpmpyss.nac.s0
- __builtin_HEXAGON_M2_dpmpyss_rnd_s0(0, 0);
+ __builtin_HEXAGON_M2_dpmpyss_nac_s0(0, 0, 0);
// CHECK: @llvm.hexagon.M2.dpmpyss.rnd.s0
- __builtin_HEXAGON_M2_dpmpyss_s0(0, 0);
+ __builtin_HEXAGON_M2_dpmpyss_rnd_s0(0, 0);
// CHECK: @llvm.hexagon.M2.dpmpyss.s0
- __builtin_HEXAGON_M2_dpmpyuu_acc_s0(0, 0, 0);
+ __builtin_HEXAGON_M2_dpmpyss_s0(0, 0);
// CHECK: @llvm.hexagon.M2.dpmpyuu.acc.s0
- __builtin_HEXAGON_M2_dpmpyuu_nac_s0(0, 0, 0);
+ __builtin_HEXAGON_M2_dpmpyuu_acc_s0(0, 0, 0);
// CHECK: @llvm.hexagon.M2.dpmpyuu.nac.s0
- __builtin_HEXAGON_M2_dpmpyuu_s0(0, 0);
+ __builtin_HEXAGON_M2_dpmpyuu_nac_s0(0, 0, 0);
// CHECK: @llvm.hexagon.M2.dpmpyuu.s0
- __builtin_HEXAGON_M2_hmmpyh_rs1(0, 0);
+ __builtin_HEXAGON_M2_dpmpyuu_s0(0, 0);
// CHECK: @llvm.hexagon.M2.hmmpyh.rs1
- __builtin_HEXAGON_M2_hmmpyh_s1(0, 0);
+ __builtin_HEXAGON_M2_hmmpyh_rs1(0, 0);
// CHECK: @llvm.hexagon.M2.hmmpyh.s1
- __builtin_HEXAGON_M2_hmmpyl_rs1(0, 0);
+ __builtin_HEXAGON_M2_hmmpyh_s1(0, 0);
// CHECK: @llvm.hexagon.M2.hmmpyl.rs1
- __builtin_HEXAGON_M2_hmmpyl_s1(0, 0);
+ __builtin_HEXAGON_M2_hmmpyl_rs1(0, 0);
// CHECK: @llvm.hexagon.M2.hmmpyl.s1
- __builtin_HEXAGON_M2_maci(0, 0, 0);
+ __builtin_HEXAGON_M2_hmmpyl_s1(0, 0);
// CHECK: @llvm.hexagon.M2.maci
- __builtin_HEXAGON_M2_macsin(0, 0, 0);
+ __builtin_HEXAGON_M2_maci(0, 0, 0);
// CHECK: @llvm.hexagon.M2.macsin
- __builtin_HEXAGON_M2_macsip(0, 0, 0);
+ __builtin_HEXAGON_M2_macsin(0, 0, 0);
// CHECK: @llvm.hexagon.M2.macsip
- __builtin_HEXAGON_M2_mmachs_rs0(0, 0, 0);
+ __builtin_HEXAGON_M2_macsip(0, 0, 0);
// CHECK: @llvm.hexagon.M2.mmachs.rs0
- __builtin_HEXAGON_M2_mmachs_rs1(0, 0, 0);
+ __builtin_HEXAGON_M2_mmachs_rs0(0, 0, 0);
// CHECK: @llvm.hexagon.M2.mmachs.rs1
- __builtin_HEXAGON_M2_mmachs_s0(0, 0, 0);
+ __builtin_HEXAGON_M2_mmachs_rs1(0, 0, 0);
// CHECK: @llvm.hexagon.M2.mmachs.s0
- __builtin_HEXAGON_M2_mmachs_s1(0, 0, 0);
+ __builtin_HEXAGON_M2_mmachs_s0(0, 0, 0);
// CHECK: @llvm.hexagon.M2.mmachs.s1
- __builtin_HEXAGON_M2_mmacls_rs0(0, 0, 0);
+ __builtin_HEXAGON_M2_mmachs_s1(0, 0, 0);
// CHECK: @llvm.hexagon.M2.mmacls.rs0
- __builtin_HEXAGON_M2_mmacls_rs1(0, 0, 0);
+ __builtin_HEXAGON_M2_mmacls_rs0(0, 0, 0);
// CHECK: @llvm.hexagon.M2.mmacls.rs1
- __builtin_HEXAGON_M2_mmacls_s0(0, 0, 0);
+ __builtin_HEXAGON_M2_mmacls_rs1(0, 0, 0);
// CHECK: @llvm.hexagon.M2.mmacls.s0
- __builtin_HEXAGON_M2_mmacls_s1(0, 0, 0);
+ __builtin_HEXAGON_M2_mmacls_s0(0, 0, 0);
// CHECK: @llvm.hexagon.M2.mmacls.s1
- __builtin_HEXAGON_M2_mmacuhs_rs0(0, 0, 0);
+ __builtin_HEXAGON_M2_mmacls_s1(0, 0, 0);
// CHECK: @llvm.hexagon.M2.mmacuhs.rs0
- __builtin_HEXAGON_M2_mmacuhs_rs1(0, 0, 0);
+ __builtin_HEXAGON_M2_mmacuhs_rs0(0, 0, 0);
// CHECK: @llvm.hexagon.M2.mmacuhs.rs1
- __builtin_HEXAGON_M2_mmacuhs_s0(0, 0, 0);
+ __builtin_HEXAGON_M2_mmacuhs_rs1(0, 0, 0);
// CHECK: @llvm.hexagon.M2.mmacuhs.s0
- __builtin_HEXAGON_M2_mmacuhs_s1(0, 0, 0);
+ __builtin_HEXAGON_M2_mmacuhs_s0(0, 0, 0);
// CHECK: @llvm.hexagon.M2.mmacuhs.s1
- __builtin_HEXAGON_M2_mmaculs_rs0(0, 0, 0);
+ __builtin_HEXAGON_M2_mmacuhs_s1(0, 0, 0);
// CHECK: @llvm.hexagon.M2.mmaculs.rs0
- __builtin_HEXAGON_M2_mmaculs_rs1(0, 0, 0);
+ __builtin_HEXAGON_M2_mmaculs_rs0(0, 0, 0);
// CHECK: @llvm.hexagon.M2.mmaculs.rs1
- __builtin_HEXAGON_M2_mmaculs_s0(0, 0, 0);
+ __builtin_HEXAGON_M2_mmaculs_rs1(0, 0, 0);
// CHECK: @llvm.hexagon.M2.mmaculs.s0
- __builtin_HEXAGON_M2_mmaculs_s1(0, 0, 0);
+ __builtin_HEXAGON_M2_mmaculs_s0(0, 0, 0);
// CHECK: @llvm.hexagon.M2.mmaculs.s1
- __builtin_HEXAGON_M2_mmpyh_rs0(0, 0);
+ __builtin_HEXAGON_M2_mmaculs_s1(0, 0, 0);
// CHECK: @llvm.hexagon.M2.mmpyh.rs0
- __builtin_HEXAGON_M2_mmpyh_rs1(0, 0);
+ __builtin_HEXAGON_M2_mmpyh_rs0(0, 0);
// CHECK: @llvm.hexagon.M2.mmpyh.rs1
- __builtin_HEXAGON_M2_mmpyh_s0(0, 0);
+ __builtin_HEXAGON_M2_mmpyh_rs1(0, 0);
// CHECK: @llvm.hexagon.M2.mmpyh.s0
- __builtin_HEXAGON_M2_mmpyh_s1(0, 0);
+ __builtin_HEXAGON_M2_mmpyh_s0(0, 0);
// CHECK: @llvm.hexagon.M2.mmpyh.s1
- __builtin_HEXAGON_M2_mmpyl_rs0(0, 0);
+ __builtin_HEXAGON_M2_mmpyh_s1(0, 0);
// CHECK: @llvm.hexagon.M2.mmpyl.rs0
- __builtin_HEXAGON_M2_mmpyl_rs1(0, 0);
+ __builtin_HEXAGON_M2_mmpyl_rs0(0, 0);
// CHECK: @llvm.hexagon.M2.mmpyl.rs1
- __builtin_HEXAGON_M2_mmpyl_s0(0, 0);
+ __builtin_HEXAGON_M2_mmpyl_rs1(0, 0);
// CHECK: @llvm.hexagon.M2.mmpyl.s0
- __builtin_HEXAGON_M2_mmpyl_s1(0, 0);
+ __builtin_HEXAGON_M2_mmpyl_s0(0, 0);
// CHECK: @llvm.hexagon.M2.mmpyl.s1
- __builtin_HEXAGON_M2_mmpyuh_rs0(0, 0);
+ __builtin_HEXAGON_M2_mmpyl_s1(0, 0);
// CHECK: @llvm.hexagon.M2.mmpyuh.rs0
- __builtin_HEXAGON_M2_mmpyuh_rs1(0, 0);
+ __builtin_HEXAGON_M2_mmpyuh_rs0(0, 0);
// CHECK: @llvm.hexagon.M2.mmpyuh.rs1
- __builtin_HEXAGON_M2_mmpyuh_s0(0, 0);
+ __builtin_HEXAGON_M2_mmpyuh_rs1(0, 0);
// CHECK: @llvm.hexagon.M2.mmpyuh.s0
- __builtin_HEXAGON_M2_mmpyuh_s1(0, 0);
+ __builtin_HEXAGON_M2_mmpyuh_s0(0, 0);
// CHECK: @llvm.hexagon.M2.mmpyuh.s1
- __builtin_HEXAGON_M2_mmpyul_rs0(0, 0);
+ __builtin_HEXAGON_M2_mmpyuh_s1(0, 0);
// CHECK: @llvm.hexagon.M2.mmpyul.rs0
- __builtin_HEXAGON_M2_mmpyul_rs1(0, 0);
+ __builtin_HEXAGON_M2_mmpyul_rs0(0, 0);
// CHECK: @llvm.hexagon.M2.mmpyul.rs1
- __builtin_HEXAGON_M2_mmpyul_s0(0, 0);
+ __builtin_HEXAGON_M2_mmpyul_rs1(0, 0);
// CHECK: @llvm.hexagon.M2.mmpyul.s0
- __builtin_HEXAGON_M2_mmpyul_s1(0, 0);
+ __builtin_HEXAGON_M2_mmpyul_s0(0, 0);
// CHECK: @llvm.hexagon.M2.mmpyul.s1
- __builtin_HEXAGON_M2_mpy_acc_hh_s0(0, 0, 0);
+ __builtin_HEXAGON_M2_mmpyul_s1(0, 0);
// CHECK: @llvm.hexagon.M2.mpy.acc.hh.s0
- __builtin_HEXAGON_M2_mpy_acc_hh_s1(0, 0, 0);
+ __builtin_HEXAGON_M2_mpy_acc_hh_s0(0, 0, 0);
// CHECK: @llvm.hexagon.M2.mpy.acc.hh.s1
- __builtin_HEXAGON_M2_mpy_acc_hl_s0(0, 0, 0);
+ __builtin_HEXAGON_M2_mpy_acc_hh_s1(0, 0, 0);
// CHECK: @llvm.hexagon.M2.mpy.acc.hl.s0
- __builtin_HEXAGON_M2_mpy_acc_hl_s1(0, 0, 0);
+ __builtin_HEXAGON_M2_mpy_acc_hl_s0(0, 0, 0);
// CHECK: @llvm.hexagon.M2.mpy.acc.hl.s1
- __builtin_HEXAGON_M2_mpy_acc_lh_s0(0, 0, 0);
+ __builtin_HEXAGON_M2_mpy_acc_hl_s1(0, 0, 0);
// CHECK: @llvm.hexagon.M2.mpy.acc.lh.s0
- __builtin_HEXAGON_M2_mpy_acc_lh_s1(0, 0, 0);
+ __builtin_HEXAGON_M2_mpy_acc_lh_s0(0, 0, 0);
// CHECK: @llvm.hexagon.M2.mpy.acc.lh.s1
- __builtin_HEXAGON_M2_mpy_acc_ll_s0(0, 0, 0);
+ __builtin_HEXAGON_M2_mpy_acc_lh_s1(0, 0, 0);
// CHECK: @llvm.hexagon.M2.mpy.acc.ll.s0
- __builtin_HEXAGON_M2_mpy_acc_ll_s1(0, 0, 0);
+ __builtin_HEXAGON_M2_mpy_acc_ll_s0(0, 0, 0);
// CHECK: @llvm.hexagon.M2.mpy.acc.ll.s1
- __builtin_HEXAGON_M2_mpy_acc_sat_hh_s0(0, 0, 0);
+ __builtin_HEXAGON_M2_mpy_acc_ll_s1(0, 0, 0);
// CHECK: @llvm.hexagon.M2.mpy.acc.sat.hh.s0
- __builtin_HEXAGON_M2_mpy_acc_sat_hh_s1(0, 0, 0);
+ __builtin_HEXAGON_M2_mpy_acc_sat_hh_s0(0, 0, 0);
// CHECK: @llvm.hexagon.M2.mpy.acc.sat.hh.s1
- __builtin_HEXAGON_M2_mpy_acc_sat_hl_s0(0, 0, 0);
+ __builtin_HEXAGON_M2_mpy_acc_sat_hh_s1(0, 0, 0);
// CHECK: @llvm.hexagon.M2.mpy.acc.sat.hl.s0
- __builtin_HEXAGON_M2_mpy_acc_sat_hl_s1(0, 0, 0);
+ __builtin_HEXAGON_M2_mpy_acc_sat_hl_s0(0, 0, 0);
// CHECK: @llvm.hexagon.M2.mpy.acc.sat.hl.s1
- __builtin_HEXAGON_M2_mpy_acc_sat_lh_s0(0, 0, 0);
+ __builtin_HEXAGON_M2_mpy_acc_sat_hl_s1(0, 0, 0);
// CHECK: @llvm.hexagon.M2.mpy.acc.sat.lh.s0
- __builtin_HEXAGON_M2_mpy_acc_sat_lh_s1(0, 0, 0);
+ __builtin_HEXAGON_M2_mpy_acc_sat_lh_s0(0, 0, 0);
// CHECK: @llvm.hexagon.M2.mpy.acc.sat.lh.s1
- __builtin_HEXAGON_M2_mpy_acc_sat_ll_s0(0, 0, 0);
+ __builtin_HEXAGON_M2_mpy_acc_sat_lh_s1(0, 0, 0);
// CHECK: @llvm.hexagon.M2.mpy.acc.sat.ll.s0
- __builtin_HEXAGON_M2_mpy_acc_sat_ll_s1(0, 0, 0);
+ __builtin_HEXAGON_M2_mpy_acc_sat_ll_s0(0, 0, 0);
// CHECK: @llvm.hexagon.M2.mpy.acc.sat.ll.s1
- __builtin_HEXAGON_M2_mpyd_acc_hh_s0(0, 0, 0);
- // CHECK: @llvm.hexagon.M2.mpyd.acc.hh.s0
- __builtin_HEXAGON_M2_mpyd_acc_hh_s1(0, 0, 0);
- // CHECK: @llvm.hexagon.M2.mpyd.acc.hh.s1
- __builtin_HEXAGON_M2_mpyd_acc_hl_s0(0, 0, 0);
- // CHECK: @llvm.hexagon.M2.mpyd.acc.hl.s0
- __builtin_HEXAGON_M2_mpyd_acc_hl_s1(0, 0, 0);
- // CHECK: @llvm.hexagon.M2.mpyd.acc.hl.s1
- __builtin_HEXAGON_M2_mpyd_acc_lh_s0(0, 0, 0);
- // CHECK: @llvm.hexagon.M2.mpyd.acc.lh.s0
- __builtin_HEXAGON_M2_mpyd_acc_lh_s1(0, 0, 0);
- // CHECK: @llvm.hexagon.M2.mpyd.acc.lh.s1
- __builtin_HEXAGON_M2_mpyd_acc_ll_s0(0, 0, 0);
- // CHECK: @llvm.hexagon.M2.mpyd.acc.ll.s0
- __builtin_HEXAGON_M2_mpyd_acc_ll_s1(0, 0, 0);
- // CHECK: @llvm.hexagon.M2.mpyd.acc.ll.s1
- __builtin_HEXAGON_M2_mpyd_hh_s0(0, 0);
- // CHECK: @llvm.hexagon.M2.mpyd.hh.s0
- __builtin_HEXAGON_M2_mpyd_hh_s1(0, 0);
- // CHECK: @llvm.hexagon.M2.mpyd.hh.s1
- __builtin_HEXAGON_M2_mpyd_hl_s0(0, 0);
- // CHECK: @llvm.hexagon.M2.mpyd.hl.s0
- __builtin_HEXAGON_M2_mpyd_hl_s1(0, 0);
- // CHECK: @llvm.hexagon.M2.mpyd.hl.s1
- __builtin_HEXAGON_M2_mpyd_lh_s0(0, 0);
- // CHECK: @llvm.hexagon.M2.mpyd.lh.s0
- __builtin_HEXAGON_M2_mpyd_lh_s1(0, 0);
- // CHECK: @llvm.hexagon.M2.mpyd.lh.s1
- __builtin_HEXAGON_M2_mpyd_ll_s0(0, 0);
- // CHECK: @llvm.hexagon.M2.mpyd.ll.s0
- __builtin_HEXAGON_M2_mpyd_ll_s1(0, 0);
- // CHECK: @llvm.hexagon.M2.mpyd.ll.s1
- __builtin_HEXAGON_M2_mpyd_nac_hh_s0(0, 0, 0);
- // CHECK: @llvm.hexagon.M2.mpyd.nac.hh.s0
- __builtin_HEXAGON_M2_mpyd_nac_hh_s1(0, 0, 0);
- // CHECK: @llvm.hexagon.M2.mpyd.nac.hh.s1
- __builtin_HEXAGON_M2_mpyd_nac_hl_s0(0, 0, 0);
- // CHECK: @llvm.hexagon.M2.mpyd.nac.hl.s0
- __builtin_HEXAGON_M2_mpyd_nac_hl_s1(0, 0, 0);
- // CHECK: @llvm.hexagon.M2.mpyd.nac.hl.s1
- __builtin_HEXAGON_M2_mpyd_nac_lh_s0(0, 0, 0);
- // CHECK: @llvm.hexagon.M2.mpyd.nac.lh.s0
- __builtin_HEXAGON_M2_mpyd_nac_lh_s1(0, 0, 0);
- // CHECK: @llvm.hexagon.M2.mpyd.nac.lh.s1
- __builtin_HEXAGON_M2_mpyd_nac_ll_s0(0, 0, 0);
- // CHECK: @llvm.hexagon.M2.mpyd.nac.ll.s0
- __builtin_HEXAGON_M2_mpyd_nac_ll_s1(0, 0, 0);
- // CHECK: @llvm.hexagon.M2.mpyd.nac.ll.s1
- __builtin_HEXAGON_M2_mpyd_rnd_hh_s0(0, 0);
- // CHECK: @llvm.hexagon.M2.mpyd.rnd.hh.s0
- __builtin_HEXAGON_M2_mpyd_rnd_hh_s1(0, 0);
- // CHECK: @llvm.hexagon.M2.mpyd.rnd.hh.s1
- __builtin_HEXAGON_M2_mpyd_rnd_hl_s0(0, 0);
- // CHECK: @llvm.hexagon.M2.mpyd.rnd.hl.s0
- __builtin_HEXAGON_M2_mpyd_rnd_hl_s1(0, 0);
- // CHECK: @llvm.hexagon.M2.mpyd.rnd.hl.s1
- __builtin_HEXAGON_M2_mpyd_rnd_lh_s0(0, 0);
- // CHECK: @llvm.hexagon.M2.mpyd.rnd.lh.s0
- __builtin_HEXAGON_M2_mpyd_rnd_lh_s1(0, 0);
- // CHECK: @llvm.hexagon.M2.mpyd.rnd.lh.s1
- __builtin_HEXAGON_M2_mpyd_rnd_ll_s0(0, 0);
- // CHECK: @llvm.hexagon.M2.mpyd.rnd.ll.s0
- __builtin_HEXAGON_M2_mpyd_rnd_ll_s1(0, 0);
- // CHECK: @llvm.hexagon.M2.mpyd.rnd.ll.s1
- __builtin_HEXAGON_M2_mpy_hh_s0(0, 0);
+ __builtin_HEXAGON_M2_mpy_acc_sat_ll_s1(0, 0, 0);
// CHECK: @llvm.hexagon.M2.mpy.hh.s0
- __builtin_HEXAGON_M2_mpy_hh_s1(0, 0);
+ __builtin_HEXAGON_M2_mpy_hh_s0(0, 0);
// CHECK: @llvm.hexagon.M2.mpy.hh.s1
- __builtin_HEXAGON_M2_mpy_hl_s0(0, 0);
+ __builtin_HEXAGON_M2_mpy_hh_s1(0, 0);
// CHECK: @llvm.hexagon.M2.mpy.hl.s0
- __builtin_HEXAGON_M2_mpy_hl_s1(0, 0);
+ __builtin_HEXAGON_M2_mpy_hl_s0(0, 0);
// CHECK: @llvm.hexagon.M2.mpy.hl.s1
- __builtin_HEXAGON_M2_mpyi(0, 0);
- // CHECK: @llvm.hexagon.M2.mpyi
- __builtin_HEXAGON_M2_mpy_lh_s0(0, 0);
+ __builtin_HEXAGON_M2_mpy_hl_s1(0, 0);
// CHECK: @llvm.hexagon.M2.mpy.lh.s0
- __builtin_HEXAGON_M2_mpy_lh_s1(0, 0);
+ __builtin_HEXAGON_M2_mpy_lh_s0(0, 0);
// CHECK: @llvm.hexagon.M2.mpy.lh.s1
- __builtin_HEXAGON_M2_mpy_ll_s0(0, 0);
+ __builtin_HEXAGON_M2_mpy_lh_s1(0, 0);
// CHECK: @llvm.hexagon.M2.mpy.ll.s0
- __builtin_HEXAGON_M2_mpy_ll_s1(0, 0);
+ __builtin_HEXAGON_M2_mpy_ll_s0(0, 0);
// CHECK: @llvm.hexagon.M2.mpy.ll.s1
- __builtin_HEXAGON_M2_mpy_nac_hh_s0(0, 0, 0);
+ __builtin_HEXAGON_M2_mpy_ll_s1(0, 0);
// CHECK: @llvm.hexagon.M2.mpy.nac.hh.s0
- __builtin_HEXAGON_M2_mpy_nac_hh_s1(0, 0, 0);
+ __builtin_HEXAGON_M2_mpy_nac_hh_s0(0, 0, 0);
// CHECK: @llvm.hexagon.M2.mpy.nac.hh.s1
- __builtin_HEXAGON_M2_mpy_nac_hl_s0(0, 0, 0);
+ __builtin_HEXAGON_M2_mpy_nac_hh_s1(0, 0, 0);
// CHECK: @llvm.hexagon.M2.mpy.nac.hl.s0
- __builtin_HEXAGON_M2_mpy_nac_hl_s1(0, 0, 0);
+ __builtin_HEXAGON_M2_mpy_nac_hl_s0(0, 0, 0);
// CHECK: @llvm.hexagon.M2.mpy.nac.hl.s1
- __builtin_HEXAGON_M2_mpy_nac_lh_s0(0, 0, 0);
+ __builtin_HEXAGON_M2_mpy_nac_hl_s1(0, 0, 0);
// CHECK: @llvm.hexagon.M2.mpy.nac.lh.s0
- __builtin_HEXAGON_M2_mpy_nac_lh_s1(0, 0, 0);
+ __builtin_HEXAGON_M2_mpy_nac_lh_s0(0, 0, 0);
// CHECK: @llvm.hexagon.M2.mpy.nac.lh.s1
- __builtin_HEXAGON_M2_mpy_nac_ll_s0(0, 0, 0);
+ __builtin_HEXAGON_M2_mpy_nac_lh_s1(0, 0, 0);
// CHECK: @llvm.hexagon.M2.mpy.nac.ll.s0
- __builtin_HEXAGON_M2_mpy_nac_ll_s1(0, 0, 0);
+ __builtin_HEXAGON_M2_mpy_nac_ll_s0(0, 0, 0);
// CHECK: @llvm.hexagon.M2.mpy.nac.ll.s1
- __builtin_HEXAGON_M2_mpy_nac_sat_hh_s0(0, 0, 0);
+ __builtin_HEXAGON_M2_mpy_nac_ll_s1(0, 0, 0);
// CHECK: @llvm.hexagon.M2.mpy.nac.sat.hh.s0
- __builtin_HEXAGON_M2_mpy_nac_sat_hh_s1(0, 0, 0);
+ __builtin_HEXAGON_M2_mpy_nac_sat_hh_s0(0, 0, 0);
// CHECK: @llvm.hexagon.M2.mpy.nac.sat.hh.s1
- __builtin_HEXAGON_M2_mpy_nac_sat_hl_s0(0, 0, 0);
+ __builtin_HEXAGON_M2_mpy_nac_sat_hh_s1(0, 0, 0);
// CHECK: @llvm.hexagon.M2.mpy.nac.sat.hl.s0
- __builtin_HEXAGON_M2_mpy_nac_sat_hl_s1(0, 0, 0);
+ __builtin_HEXAGON_M2_mpy_nac_sat_hl_s0(0, 0, 0);
// CHECK: @llvm.hexagon.M2.mpy.nac.sat.hl.s1
- __builtin_HEXAGON_M2_mpy_nac_sat_lh_s0(0, 0, 0);
+ __builtin_HEXAGON_M2_mpy_nac_sat_hl_s1(0, 0, 0);
// CHECK: @llvm.hexagon.M2.mpy.nac.sat.lh.s0
- __builtin_HEXAGON_M2_mpy_nac_sat_lh_s1(0, 0, 0);
+ __builtin_HEXAGON_M2_mpy_nac_sat_lh_s0(0, 0, 0);
// CHECK: @llvm.hexagon.M2.mpy.nac.sat.lh.s1
- __builtin_HEXAGON_M2_mpy_nac_sat_ll_s0(0, 0, 0);
+ __builtin_HEXAGON_M2_mpy_nac_sat_lh_s1(0, 0, 0);
// CHECK: @llvm.hexagon.M2.mpy.nac.sat.ll.s0
- __builtin_HEXAGON_M2_mpy_nac_sat_ll_s1(0, 0, 0);
+ __builtin_HEXAGON_M2_mpy_nac_sat_ll_s0(0, 0, 0);
// CHECK: @llvm.hexagon.M2.mpy.nac.sat.ll.s1
- __builtin_HEXAGON_M2_mpy_rnd_hh_s0(0, 0);
+ __builtin_HEXAGON_M2_mpy_nac_sat_ll_s1(0, 0, 0);
// CHECK: @llvm.hexagon.M2.mpy.rnd.hh.s0
- __builtin_HEXAGON_M2_mpy_rnd_hh_s1(0, 0);
+ __builtin_HEXAGON_M2_mpy_rnd_hh_s0(0, 0);
// CHECK: @llvm.hexagon.M2.mpy.rnd.hh.s1
- __builtin_HEXAGON_M2_mpy_rnd_hl_s0(0, 0);
+ __builtin_HEXAGON_M2_mpy_rnd_hh_s1(0, 0);
// CHECK: @llvm.hexagon.M2.mpy.rnd.hl.s0
- __builtin_HEXAGON_M2_mpy_rnd_hl_s1(0, 0);
+ __builtin_HEXAGON_M2_mpy_rnd_hl_s0(0, 0);
// CHECK: @llvm.hexagon.M2.mpy.rnd.hl.s1
- __builtin_HEXAGON_M2_mpy_rnd_lh_s0(0, 0);
+ __builtin_HEXAGON_M2_mpy_rnd_hl_s1(0, 0);
// CHECK: @llvm.hexagon.M2.mpy.rnd.lh.s0
- __builtin_HEXAGON_M2_mpy_rnd_lh_s1(0, 0);
+ __builtin_HEXAGON_M2_mpy_rnd_lh_s0(0, 0);
// CHECK: @llvm.hexagon.M2.mpy.rnd.lh.s1
- __builtin_HEXAGON_M2_mpy_rnd_ll_s0(0, 0);
+ __builtin_HEXAGON_M2_mpy_rnd_lh_s1(0, 0);
// CHECK: @llvm.hexagon.M2.mpy.rnd.ll.s0
- __builtin_HEXAGON_M2_mpy_rnd_ll_s1(0, 0);
+ __builtin_HEXAGON_M2_mpy_rnd_ll_s0(0, 0);
// CHECK: @llvm.hexagon.M2.mpy.rnd.ll.s1
- __builtin_HEXAGON_M2_mpy_sat_hh_s0(0, 0);
+ __builtin_HEXAGON_M2_mpy_rnd_ll_s1(0, 0);
// CHECK: @llvm.hexagon.M2.mpy.sat.hh.s0
- __builtin_HEXAGON_M2_mpy_sat_hh_s1(0, 0);
+ __builtin_HEXAGON_M2_mpy_sat_hh_s0(0, 0);
// CHECK: @llvm.hexagon.M2.mpy.sat.hh.s1
- __builtin_HEXAGON_M2_mpy_sat_hl_s0(0, 0);
+ __builtin_HEXAGON_M2_mpy_sat_hh_s1(0, 0);
// CHECK: @llvm.hexagon.M2.mpy.sat.hl.s0
- __builtin_HEXAGON_M2_mpy_sat_hl_s1(0, 0);
+ __builtin_HEXAGON_M2_mpy_sat_hl_s0(0, 0);
// CHECK: @llvm.hexagon.M2.mpy.sat.hl.s1
- __builtin_HEXAGON_M2_mpy_sat_lh_s0(0, 0);
+ __builtin_HEXAGON_M2_mpy_sat_hl_s1(0, 0);
// CHECK: @llvm.hexagon.M2.mpy.sat.lh.s0
- __builtin_HEXAGON_M2_mpy_sat_lh_s1(0, 0);
+ __builtin_HEXAGON_M2_mpy_sat_lh_s0(0, 0);
// CHECK: @llvm.hexagon.M2.mpy.sat.lh.s1
- __builtin_HEXAGON_M2_mpy_sat_ll_s0(0, 0);
+ __builtin_HEXAGON_M2_mpy_sat_lh_s1(0, 0);
// CHECK: @llvm.hexagon.M2.mpy.sat.ll.s0
- __builtin_HEXAGON_M2_mpy_sat_ll_s1(0, 0);
+ __builtin_HEXAGON_M2_mpy_sat_ll_s0(0, 0);
// CHECK: @llvm.hexagon.M2.mpy.sat.ll.s1
- __builtin_HEXAGON_M2_mpy_sat_rnd_hh_s0(0, 0);
+ __builtin_HEXAGON_M2_mpy_sat_ll_s1(0, 0);
// CHECK: @llvm.hexagon.M2.mpy.sat.rnd.hh.s0
- __builtin_HEXAGON_M2_mpy_sat_rnd_hh_s1(0, 0);
+ __builtin_HEXAGON_M2_mpy_sat_rnd_hh_s0(0, 0);
// CHECK: @llvm.hexagon.M2.mpy.sat.rnd.hh.s1
- __builtin_HEXAGON_M2_mpy_sat_rnd_hl_s0(0, 0);
+ __builtin_HEXAGON_M2_mpy_sat_rnd_hh_s1(0, 0);
// CHECK: @llvm.hexagon.M2.mpy.sat.rnd.hl.s0
- __builtin_HEXAGON_M2_mpy_sat_rnd_hl_s1(0, 0);
+ __builtin_HEXAGON_M2_mpy_sat_rnd_hl_s0(0, 0);
// CHECK: @llvm.hexagon.M2.mpy.sat.rnd.hl.s1
- __builtin_HEXAGON_M2_mpy_sat_rnd_lh_s0(0, 0);
+ __builtin_HEXAGON_M2_mpy_sat_rnd_hl_s1(0, 0);
// CHECK: @llvm.hexagon.M2.mpy.sat.rnd.lh.s0
- __builtin_HEXAGON_M2_mpy_sat_rnd_lh_s1(0, 0);
+ __builtin_HEXAGON_M2_mpy_sat_rnd_lh_s0(0, 0);
// CHECK: @llvm.hexagon.M2.mpy.sat.rnd.lh.s1
- __builtin_HEXAGON_M2_mpy_sat_rnd_ll_s0(0, 0);
+ __builtin_HEXAGON_M2_mpy_sat_rnd_lh_s1(0, 0);
// CHECK: @llvm.hexagon.M2.mpy.sat.rnd.ll.s0
- __builtin_HEXAGON_M2_mpy_sat_rnd_ll_s1(0, 0);
+ __builtin_HEXAGON_M2_mpy_sat_rnd_ll_s0(0, 0);
// CHECK: @llvm.hexagon.M2.mpy.sat.rnd.ll.s1
- __builtin_HEXAGON_M2_mpysmi(0, 0);
+ __builtin_HEXAGON_M2_mpy_sat_rnd_ll_s1(0, 0);
+ // CHECK: @llvm.hexagon.M2.mpy.up
+ __builtin_HEXAGON_M2_mpy_up(0, 0);
+ // CHECK: @llvm.hexagon.M2.mpy.up.s1
+ __builtin_HEXAGON_M2_mpy_up_s1(0, 0);
+ // CHECK: @llvm.hexagon.M2.mpy.up.s1.sat
+ __builtin_HEXAGON_M2_mpy_up_s1_sat(0, 0);
+ // CHECK: @llvm.hexagon.M2.mpyd.acc.hh.s0
+ __builtin_HEXAGON_M2_mpyd_acc_hh_s0(0, 0, 0);
+ // CHECK: @llvm.hexagon.M2.mpyd.acc.hh.s1
+ __builtin_HEXAGON_M2_mpyd_acc_hh_s1(0, 0, 0);
+ // CHECK: @llvm.hexagon.M2.mpyd.acc.hl.s0
+ __builtin_HEXAGON_M2_mpyd_acc_hl_s0(0, 0, 0);
+ // CHECK: @llvm.hexagon.M2.mpyd.acc.hl.s1
+ __builtin_HEXAGON_M2_mpyd_acc_hl_s1(0, 0, 0);
+ // CHECK: @llvm.hexagon.M2.mpyd.acc.lh.s0
+ __builtin_HEXAGON_M2_mpyd_acc_lh_s0(0, 0, 0);
+ // CHECK: @llvm.hexagon.M2.mpyd.acc.lh.s1
+ __builtin_HEXAGON_M2_mpyd_acc_lh_s1(0, 0, 0);
+ // CHECK: @llvm.hexagon.M2.mpyd.acc.ll.s0
+ __builtin_HEXAGON_M2_mpyd_acc_ll_s0(0, 0, 0);
+ // CHECK: @llvm.hexagon.M2.mpyd.acc.ll.s1
+ __builtin_HEXAGON_M2_mpyd_acc_ll_s1(0, 0, 0);
+ // CHECK: @llvm.hexagon.M2.mpyd.hh.s0
+ __builtin_HEXAGON_M2_mpyd_hh_s0(0, 0);
+ // CHECK: @llvm.hexagon.M2.mpyd.hh.s1
+ __builtin_HEXAGON_M2_mpyd_hh_s1(0, 0);
+ // CHECK: @llvm.hexagon.M2.mpyd.hl.s0
+ __builtin_HEXAGON_M2_mpyd_hl_s0(0, 0);
+ // CHECK: @llvm.hexagon.M2.mpyd.hl.s1
+ __builtin_HEXAGON_M2_mpyd_hl_s1(0, 0);
+ // CHECK: @llvm.hexagon.M2.mpyd.lh.s0
+ __builtin_HEXAGON_M2_mpyd_lh_s0(0, 0);
+ // CHECK: @llvm.hexagon.M2.mpyd.lh.s1
+ __builtin_HEXAGON_M2_mpyd_lh_s1(0, 0);
+ // CHECK: @llvm.hexagon.M2.mpyd.ll.s0
+ __builtin_HEXAGON_M2_mpyd_ll_s0(0, 0);
+ // CHECK: @llvm.hexagon.M2.mpyd.ll.s1
+ __builtin_HEXAGON_M2_mpyd_ll_s1(0, 0);
+ // CHECK: @llvm.hexagon.M2.mpyd.nac.hh.s0
+ __builtin_HEXAGON_M2_mpyd_nac_hh_s0(0, 0, 0);
+ // CHECK: @llvm.hexagon.M2.mpyd.nac.hh.s1
+ __builtin_HEXAGON_M2_mpyd_nac_hh_s1(0, 0, 0);
+ // CHECK: @llvm.hexagon.M2.mpyd.nac.hl.s0
+ __builtin_HEXAGON_M2_mpyd_nac_hl_s0(0, 0, 0);
+ // CHECK: @llvm.hexagon.M2.mpyd.nac.hl.s1
+ __builtin_HEXAGON_M2_mpyd_nac_hl_s1(0, 0, 0);
+ // CHECK: @llvm.hexagon.M2.mpyd.nac.lh.s0
+ __builtin_HEXAGON_M2_mpyd_nac_lh_s0(0, 0, 0);
+ // CHECK: @llvm.hexagon.M2.mpyd.nac.lh.s1
+ __builtin_HEXAGON_M2_mpyd_nac_lh_s1(0, 0, 0);
+ // CHECK: @llvm.hexagon.M2.mpyd.nac.ll.s0
+ __builtin_HEXAGON_M2_mpyd_nac_ll_s0(0, 0, 0);
+ // CHECK: @llvm.hexagon.M2.mpyd.nac.ll.s1
+ __builtin_HEXAGON_M2_mpyd_nac_ll_s1(0, 0, 0);
+ // CHECK: @llvm.hexagon.M2.mpyd.rnd.hh.s0
+ __builtin_HEXAGON_M2_mpyd_rnd_hh_s0(0, 0);
+ // CHECK: @llvm.hexagon.M2.mpyd.rnd.hh.s1
+ __builtin_HEXAGON_M2_mpyd_rnd_hh_s1(0, 0);
+ // CHECK: @llvm.hexagon.M2.mpyd.rnd.hl.s0
+ __builtin_HEXAGON_M2_mpyd_rnd_hl_s0(0, 0);
+ // CHECK: @llvm.hexagon.M2.mpyd.rnd.hl.s1
+ __builtin_HEXAGON_M2_mpyd_rnd_hl_s1(0, 0);
+ // CHECK: @llvm.hexagon.M2.mpyd.rnd.lh.s0
+ __builtin_HEXAGON_M2_mpyd_rnd_lh_s0(0, 0);
+ // CHECK: @llvm.hexagon.M2.mpyd.rnd.lh.s1
+ __builtin_HEXAGON_M2_mpyd_rnd_lh_s1(0, 0);
+ // CHECK: @llvm.hexagon.M2.mpyd.rnd.ll.s0
+ __builtin_HEXAGON_M2_mpyd_rnd_ll_s0(0, 0);
+ // CHECK: @llvm.hexagon.M2.mpyd.rnd.ll.s1
+ __builtin_HEXAGON_M2_mpyd_rnd_ll_s1(0, 0);
+ // CHECK: @llvm.hexagon.M2.mpyi
+ __builtin_HEXAGON_M2_mpyi(0, 0);
// CHECK: @llvm.hexagon.M2.mpysmi
- __builtin_HEXAGON_M2_mpysu_up(0, 0);
+ __builtin_HEXAGON_M2_mpysmi(0, 0);
// CHECK: @llvm.hexagon.M2.mpysu.up
- __builtin_HEXAGON_M2_mpyu_acc_hh_s0(0, 0, 0);
+ __builtin_HEXAGON_M2_mpysu_up(0, 0);
// CHECK: @llvm.hexagon.M2.mpyu.acc.hh.s0
- __builtin_HEXAGON_M2_mpyu_acc_hh_s1(0, 0, 0);
+ __builtin_HEXAGON_M2_mpyu_acc_hh_s0(0, 0, 0);
// CHECK: @llvm.hexagon.M2.mpyu.acc.hh.s1
- __builtin_HEXAGON_M2_mpyu_acc_hl_s0(0, 0, 0);
+ __builtin_HEXAGON_M2_mpyu_acc_hh_s1(0, 0, 0);
// CHECK: @llvm.hexagon.M2.mpyu.acc.hl.s0
- __builtin_HEXAGON_M2_mpyu_acc_hl_s1(0, 0, 0);
+ __builtin_HEXAGON_M2_mpyu_acc_hl_s0(0, 0, 0);
// CHECK: @llvm.hexagon.M2.mpyu.acc.hl.s1
- __builtin_HEXAGON_M2_mpyu_acc_lh_s0(0, 0, 0);
+ __builtin_HEXAGON_M2_mpyu_acc_hl_s1(0, 0, 0);
// CHECK: @llvm.hexagon.M2.mpyu.acc.lh.s0
- __builtin_HEXAGON_M2_mpyu_acc_lh_s1(0, 0, 0);
+ __builtin_HEXAGON_M2_mpyu_acc_lh_s0(0, 0, 0);
// CHECK: @llvm.hexagon.M2.mpyu.acc.lh.s1
- __builtin_HEXAGON_M2_mpyu_acc_ll_s0(0, 0, 0);
+ __builtin_HEXAGON_M2_mpyu_acc_lh_s1(0, 0, 0);
// CHECK: @llvm.hexagon.M2.mpyu.acc.ll.s0
- __builtin_HEXAGON_M2_mpyu_acc_ll_s1(0, 0, 0);
+ __builtin_HEXAGON_M2_mpyu_acc_ll_s0(0, 0, 0);
// CHECK: @llvm.hexagon.M2.mpyu.acc.ll.s1
- __builtin_HEXAGON_M2_mpyud_acc_hh_s0(0, 0, 0);
+ __builtin_HEXAGON_M2_mpyu_acc_ll_s1(0, 0, 0);
+ // CHECK: @llvm.hexagon.M2.mpyu.hh.s0
+ __builtin_HEXAGON_M2_mpyu_hh_s0(0, 0);
+ // CHECK: @llvm.hexagon.M2.mpyu.hh.s1
+ __builtin_HEXAGON_M2_mpyu_hh_s1(0, 0);
+ // CHECK: @llvm.hexagon.M2.mpyu.hl.s0
+ __builtin_HEXAGON_M2_mpyu_hl_s0(0, 0);
+ // CHECK: @llvm.hexagon.M2.mpyu.hl.s1
+ __builtin_HEXAGON_M2_mpyu_hl_s1(0, 0);
+ // CHECK: @llvm.hexagon.M2.mpyu.lh.s0
+ __builtin_HEXAGON_M2_mpyu_lh_s0(0, 0);
+ // CHECK: @llvm.hexagon.M2.mpyu.lh.s1
+ __builtin_HEXAGON_M2_mpyu_lh_s1(0, 0);
+ // CHECK: @llvm.hexagon.M2.mpyu.ll.s0
+ __builtin_HEXAGON_M2_mpyu_ll_s0(0, 0);
+ // CHECK: @llvm.hexagon.M2.mpyu.ll.s1
+ __builtin_HEXAGON_M2_mpyu_ll_s1(0, 0);
+ // CHECK: @llvm.hexagon.M2.mpyu.nac.hh.s0
+ __builtin_HEXAGON_M2_mpyu_nac_hh_s0(0, 0, 0);
+ // CHECK: @llvm.hexagon.M2.mpyu.nac.hh.s1
+ __builtin_HEXAGON_M2_mpyu_nac_hh_s1(0, 0, 0);
+ // CHECK: @llvm.hexagon.M2.mpyu.nac.hl.s0
+ __builtin_HEXAGON_M2_mpyu_nac_hl_s0(0, 0, 0);
+ // CHECK: @llvm.hexagon.M2.mpyu.nac.hl.s1
+ __builtin_HEXAGON_M2_mpyu_nac_hl_s1(0, 0, 0);
+ // CHECK: @llvm.hexagon.M2.mpyu.nac.lh.s0
+ __builtin_HEXAGON_M2_mpyu_nac_lh_s0(0, 0, 0);
+ // CHECK: @llvm.hexagon.M2.mpyu.nac.lh.s1
+ __builtin_HEXAGON_M2_mpyu_nac_lh_s1(0, 0, 0);
+ // CHECK: @llvm.hexagon.M2.mpyu.nac.ll.s0
+ __builtin_HEXAGON_M2_mpyu_nac_ll_s0(0, 0, 0);
+ // CHECK: @llvm.hexagon.M2.mpyu.nac.ll.s1
+ __builtin_HEXAGON_M2_mpyu_nac_ll_s1(0, 0, 0);
+ // CHECK: @llvm.hexagon.M2.mpyu.up
+ __builtin_HEXAGON_M2_mpyu_up(0, 0);
// CHECK: @llvm.hexagon.M2.mpyud.acc.hh.s0
- __builtin_HEXAGON_M2_mpyud_acc_hh_s1(0, 0, 0);
+ __builtin_HEXAGON_M2_mpyud_acc_hh_s0(0, 0, 0);
// CHECK: @llvm.hexagon.M2.mpyud.acc.hh.s1
- __builtin_HEXAGON_M2_mpyud_acc_hl_s0(0, 0, 0);
+ __builtin_HEXAGON_M2_mpyud_acc_hh_s1(0, 0, 0);
// CHECK: @llvm.hexagon.M2.mpyud.acc.hl.s0
- __builtin_HEXAGON_M2_mpyud_acc_hl_s1(0, 0, 0);
+ __builtin_HEXAGON_M2_mpyud_acc_hl_s0(0, 0, 0);
// CHECK: @llvm.hexagon.M2.mpyud.acc.hl.s1
- __builtin_HEXAGON_M2_mpyud_acc_lh_s0(0, 0, 0);
+ __builtin_HEXAGON_M2_mpyud_acc_hl_s1(0, 0, 0);
// CHECK: @llvm.hexagon.M2.mpyud.acc.lh.s0
- __builtin_HEXAGON_M2_mpyud_acc_lh_s1(0, 0, 0);
+ __builtin_HEXAGON_M2_mpyud_acc_lh_s0(0, 0, 0);
// CHECK: @llvm.hexagon.M2.mpyud.acc.lh.s1
- __builtin_HEXAGON_M2_mpyud_acc_ll_s0(0, 0, 0);
+ __builtin_HEXAGON_M2_mpyud_acc_lh_s1(0, 0, 0);
// CHECK: @llvm.hexagon.M2.mpyud.acc.ll.s0
- __builtin_HEXAGON_M2_mpyud_acc_ll_s1(0, 0, 0);
+ __builtin_HEXAGON_M2_mpyud_acc_ll_s0(0, 0, 0);
// CHECK: @llvm.hexagon.M2.mpyud.acc.ll.s1
- __builtin_HEXAGON_M2_mpyud_hh_s0(0, 0);
+ __builtin_HEXAGON_M2_mpyud_acc_ll_s1(0, 0, 0);
// CHECK: @llvm.hexagon.M2.mpyud.hh.s0
- __builtin_HEXAGON_M2_mpyud_hh_s1(0, 0);
+ __builtin_HEXAGON_M2_mpyud_hh_s0(0, 0);
// CHECK: @llvm.hexagon.M2.mpyud.hh.s1
- __builtin_HEXAGON_M2_mpyud_hl_s0(0, 0);
+ __builtin_HEXAGON_M2_mpyud_hh_s1(0, 0);
// CHECK: @llvm.hexagon.M2.mpyud.hl.s0
- __builtin_HEXAGON_M2_mpyud_hl_s1(0, 0);
+ __builtin_HEXAGON_M2_mpyud_hl_s0(0, 0);
// CHECK: @llvm.hexagon.M2.mpyud.hl.s1
- __builtin_HEXAGON_M2_mpyud_lh_s0(0, 0);
+ __builtin_HEXAGON_M2_mpyud_hl_s1(0, 0);
// CHECK: @llvm.hexagon.M2.mpyud.lh.s0
- __builtin_HEXAGON_M2_mpyud_lh_s1(0, 0);
+ __builtin_HEXAGON_M2_mpyud_lh_s0(0, 0);
// CHECK: @llvm.hexagon.M2.mpyud.lh.s1
- __builtin_HEXAGON_M2_mpyud_ll_s0(0, 0);
+ __builtin_HEXAGON_M2_mpyud_lh_s1(0, 0);
// CHECK: @llvm.hexagon.M2.mpyud.ll.s0
- __builtin_HEXAGON_M2_mpyud_ll_s1(0, 0);
+ __builtin_HEXAGON_M2_mpyud_ll_s0(0, 0);
// CHECK: @llvm.hexagon.M2.mpyud.ll.s1
- __builtin_HEXAGON_M2_mpyud_nac_hh_s0(0, 0, 0);
+ __builtin_HEXAGON_M2_mpyud_ll_s1(0, 0);
// CHECK: @llvm.hexagon.M2.mpyud.nac.hh.s0
- __builtin_HEXAGON_M2_mpyud_nac_hh_s1(0, 0, 0);
+ __builtin_HEXAGON_M2_mpyud_nac_hh_s0(0, 0, 0);
// CHECK: @llvm.hexagon.M2.mpyud.nac.hh.s1
- __builtin_HEXAGON_M2_mpyud_nac_hl_s0(0, 0, 0);
+ __builtin_HEXAGON_M2_mpyud_nac_hh_s1(0, 0, 0);
// CHECK: @llvm.hexagon.M2.mpyud.nac.hl.s0
- __builtin_HEXAGON_M2_mpyud_nac_hl_s1(0, 0, 0);
+ __builtin_HEXAGON_M2_mpyud_nac_hl_s0(0, 0, 0);
// CHECK: @llvm.hexagon.M2.mpyud.nac.hl.s1
- __builtin_HEXAGON_M2_mpyud_nac_lh_s0(0, 0, 0);
+ __builtin_HEXAGON_M2_mpyud_nac_hl_s1(0, 0, 0);
// CHECK: @llvm.hexagon.M2.mpyud.nac.lh.s0
- __builtin_HEXAGON_M2_mpyud_nac_lh_s1(0, 0, 0);
+ __builtin_HEXAGON_M2_mpyud_nac_lh_s0(0, 0, 0);
// CHECK: @llvm.hexagon.M2.mpyud.nac.lh.s1
- __builtin_HEXAGON_M2_mpyud_nac_ll_s0(0, 0, 0);
+ __builtin_HEXAGON_M2_mpyud_nac_lh_s1(0, 0, 0);
// CHECK: @llvm.hexagon.M2.mpyud.nac.ll.s0
- __builtin_HEXAGON_M2_mpyud_nac_ll_s1(0, 0, 0);
+ __builtin_HEXAGON_M2_mpyud_nac_ll_s0(0, 0, 0);
// CHECK: @llvm.hexagon.M2.mpyud.nac.ll.s1
- __builtin_HEXAGON_M2_mpyu_hh_s0(0, 0);
- // CHECK: @llvm.hexagon.M2.mpyu.hh.s0
- __builtin_HEXAGON_M2_mpyu_hh_s1(0, 0);
- // CHECK: @llvm.hexagon.M2.mpyu.hh.s1
- __builtin_HEXAGON_M2_mpyu_hl_s0(0, 0);
- // CHECK: @llvm.hexagon.M2.mpyu.hl.s0
- __builtin_HEXAGON_M2_mpyu_hl_s1(0, 0);
- // CHECK: @llvm.hexagon.M2.mpyu.hl.s1
- __builtin_HEXAGON_M2_mpyui(0, 0);
+ __builtin_HEXAGON_M2_mpyud_nac_ll_s1(0, 0, 0);
// CHECK: @llvm.hexagon.M2.mpyui
- __builtin_HEXAGON_M2_mpyu_lh_s0(0, 0);
- // CHECK: @llvm.hexagon.M2.mpyu.lh.s0
- __builtin_HEXAGON_M2_mpyu_lh_s1(0, 0);
- // CHECK: @llvm.hexagon.M2.mpyu.lh.s1
- __builtin_HEXAGON_M2_mpyu_ll_s0(0, 0);
- // CHECK: @llvm.hexagon.M2.mpyu.ll.s0
- __builtin_HEXAGON_M2_mpyu_ll_s1(0, 0);
- // CHECK: @llvm.hexagon.M2.mpyu.ll.s1
- __builtin_HEXAGON_M2_mpyu_nac_hh_s0(0, 0, 0);
- // CHECK: @llvm.hexagon.M2.mpyu.nac.hh.s0
- __builtin_HEXAGON_M2_mpyu_nac_hh_s1(0, 0, 0);
- // CHECK: @llvm.hexagon.M2.mpyu.nac.hh.s1
- __builtin_HEXAGON_M2_mpyu_nac_hl_s0(0, 0, 0);
- // CHECK: @llvm.hexagon.M2.mpyu.nac.hl.s0
- __builtin_HEXAGON_M2_mpyu_nac_hl_s1(0, 0, 0);
- // CHECK: @llvm.hexagon.M2.mpyu.nac.hl.s1
- __builtin_HEXAGON_M2_mpyu_nac_lh_s0(0, 0, 0);
- // CHECK: @llvm.hexagon.M2.mpyu.nac.lh.s0
- __builtin_HEXAGON_M2_mpyu_nac_lh_s1(0, 0, 0);
- // CHECK: @llvm.hexagon.M2.mpyu.nac.lh.s1
- __builtin_HEXAGON_M2_mpyu_nac_ll_s0(0, 0, 0);
- // CHECK: @llvm.hexagon.M2.mpyu.nac.ll.s0
- __builtin_HEXAGON_M2_mpyu_nac_ll_s1(0, 0, 0);
- // CHECK: @llvm.hexagon.M2.mpyu.nac.ll.s1
- __builtin_HEXAGON_M2_mpy_up(0, 0);
- // CHECK: @llvm.hexagon.M2.mpy.up
- __builtin_HEXAGON_M2_mpy_up_s1(0, 0);
- // CHECK: @llvm.hexagon.M2.mpy.up.s1
- __builtin_HEXAGON_M2_mpy_up_s1_sat(0, 0);
- // CHECK: @llvm.hexagon.M2.mpy.up.s1.sat
- __builtin_HEXAGON_M2_mpyu_up(0, 0);
- // CHECK: @llvm.hexagon.M2.mpyu.up
- __builtin_HEXAGON_M2_nacci(0, 0, 0);
+ __builtin_HEXAGON_M2_mpyui(0, 0);
// CHECK: @llvm.hexagon.M2.nacci
- __builtin_HEXAGON_M2_naccii(0, 0, 0);
+ __builtin_HEXAGON_M2_nacci(0, 0, 0);
// CHECK: @llvm.hexagon.M2.naccii
- __builtin_HEXAGON_M2_subacc(0, 0, 0);
+ __builtin_HEXAGON_M2_naccii(0, 0, 0);
// CHECK: @llvm.hexagon.M2.subacc
- __builtin_HEXAGON_M2_vabsdiffh(0, 0);
+ __builtin_HEXAGON_M2_subacc(0, 0, 0);
// CHECK: @llvm.hexagon.M2.vabsdiffh
- __builtin_HEXAGON_M2_vabsdiffw(0, 0);
+ __builtin_HEXAGON_M2_vabsdiffh(0, 0);
// CHECK: @llvm.hexagon.M2.vabsdiffw
- __builtin_HEXAGON_M2_vcmac_s0_sat_i(0, 0, 0);
+ __builtin_HEXAGON_M2_vabsdiffw(0, 0);
// CHECK: @llvm.hexagon.M2.vcmac.s0.sat.i
- __builtin_HEXAGON_M2_vcmac_s0_sat_r(0, 0, 0);
+ __builtin_HEXAGON_M2_vcmac_s0_sat_i(0, 0, 0);
// CHECK: @llvm.hexagon.M2.vcmac.s0.sat.r
- __builtin_HEXAGON_M2_vcmpy_s0_sat_i(0, 0);
+ __builtin_HEXAGON_M2_vcmac_s0_sat_r(0, 0, 0);
// CHECK: @llvm.hexagon.M2.vcmpy.s0.sat.i
- __builtin_HEXAGON_M2_vcmpy_s0_sat_r(0, 0);
+ __builtin_HEXAGON_M2_vcmpy_s0_sat_i(0, 0);
// CHECK: @llvm.hexagon.M2.vcmpy.s0.sat.r
- __builtin_HEXAGON_M2_vcmpy_s1_sat_i(0, 0);
+ __builtin_HEXAGON_M2_vcmpy_s0_sat_r(0, 0);
// CHECK: @llvm.hexagon.M2.vcmpy.s1.sat.i
- __builtin_HEXAGON_M2_vcmpy_s1_sat_r(0, 0);
+ __builtin_HEXAGON_M2_vcmpy_s1_sat_i(0, 0);
// CHECK: @llvm.hexagon.M2.vcmpy.s1.sat.r
- __builtin_HEXAGON_M2_vdmacs_s0(0, 0, 0);
+ __builtin_HEXAGON_M2_vcmpy_s1_sat_r(0, 0);
// CHECK: @llvm.hexagon.M2.vdmacs.s0
- __builtin_HEXAGON_M2_vdmacs_s1(0, 0, 0);
+ __builtin_HEXAGON_M2_vdmacs_s0(0, 0, 0);
// CHECK: @llvm.hexagon.M2.vdmacs.s1
- __builtin_HEXAGON_M2_vdmpyrs_s0(0, 0);
+ __builtin_HEXAGON_M2_vdmacs_s1(0, 0, 0);
// CHECK: @llvm.hexagon.M2.vdmpyrs.s0
- __builtin_HEXAGON_M2_vdmpyrs_s1(0, 0);
+ __builtin_HEXAGON_M2_vdmpyrs_s0(0, 0);
// CHECK: @llvm.hexagon.M2.vdmpyrs.s1
- __builtin_HEXAGON_M2_vdmpys_s0(0, 0);
+ __builtin_HEXAGON_M2_vdmpyrs_s1(0, 0);
// CHECK: @llvm.hexagon.M2.vdmpys.s0
- __builtin_HEXAGON_M2_vdmpys_s1(0, 0);
+ __builtin_HEXAGON_M2_vdmpys_s0(0, 0);
// CHECK: @llvm.hexagon.M2.vdmpys.s1
- __builtin_HEXAGON_M2_vmac2(0, 0, 0);
+ __builtin_HEXAGON_M2_vdmpys_s1(0, 0);
// CHECK: @llvm.hexagon.M2.vmac2
- __builtin_HEXAGON_M2_vmac2es(0, 0, 0);
+ __builtin_HEXAGON_M2_vmac2(0, 0, 0);
// CHECK: @llvm.hexagon.M2.vmac2es
- __builtin_HEXAGON_M2_vmac2es_s0(0, 0, 0);
+ __builtin_HEXAGON_M2_vmac2es(0, 0, 0);
// CHECK: @llvm.hexagon.M2.vmac2es.s0
- __builtin_HEXAGON_M2_vmac2es_s1(0, 0, 0);
+ __builtin_HEXAGON_M2_vmac2es_s0(0, 0, 0);
// CHECK: @llvm.hexagon.M2.vmac2es.s1
- __builtin_HEXAGON_M2_vmac2s_s0(0, 0, 0);
+ __builtin_HEXAGON_M2_vmac2es_s1(0, 0, 0);
// CHECK: @llvm.hexagon.M2.vmac2s.s0
- __builtin_HEXAGON_M2_vmac2s_s1(0, 0, 0);
+ __builtin_HEXAGON_M2_vmac2s_s0(0, 0, 0);
// CHECK: @llvm.hexagon.M2.vmac2s.s1
- __builtin_HEXAGON_M2_vmac2su_s0(0, 0, 0);
+ __builtin_HEXAGON_M2_vmac2s_s1(0, 0, 0);
// CHECK: @llvm.hexagon.M2.vmac2su.s0
- __builtin_HEXAGON_M2_vmac2su_s1(0, 0, 0);
+ __builtin_HEXAGON_M2_vmac2su_s0(0, 0, 0);
// CHECK: @llvm.hexagon.M2.vmac2su.s1
- __builtin_HEXAGON_M2_vmpy2es_s0(0, 0);
+ __builtin_HEXAGON_M2_vmac2su_s1(0, 0, 0);
// CHECK: @llvm.hexagon.M2.vmpy2es.s0
- __builtin_HEXAGON_M2_vmpy2es_s1(0, 0);
+ __builtin_HEXAGON_M2_vmpy2es_s0(0, 0);
// CHECK: @llvm.hexagon.M2.vmpy2es.s1
- __builtin_HEXAGON_M2_vmpy2s_s0(0, 0);
+ __builtin_HEXAGON_M2_vmpy2es_s1(0, 0);
// CHECK: @llvm.hexagon.M2.vmpy2s.s0
- __builtin_HEXAGON_M2_vmpy2s_s0pack(0, 0);
+ __builtin_HEXAGON_M2_vmpy2s_s0(0, 0);
// CHECK: @llvm.hexagon.M2.vmpy2s.s0pack
- __builtin_HEXAGON_M2_vmpy2s_s1(0, 0);
+ __builtin_HEXAGON_M2_vmpy2s_s0pack(0, 0);
// CHECK: @llvm.hexagon.M2.vmpy2s.s1
- __builtin_HEXAGON_M2_vmpy2s_s1pack(0, 0);
+ __builtin_HEXAGON_M2_vmpy2s_s1(0, 0);
// CHECK: @llvm.hexagon.M2.vmpy2s.s1pack
- __builtin_HEXAGON_M2_vmpy2su_s0(0, 0);
+ __builtin_HEXAGON_M2_vmpy2s_s1pack(0, 0);
// CHECK: @llvm.hexagon.M2.vmpy2su.s0
- __builtin_HEXAGON_M2_vmpy2su_s1(0, 0);
+ __builtin_HEXAGON_M2_vmpy2su_s0(0, 0);
// CHECK: @llvm.hexagon.M2.vmpy2su.s1
- __builtin_HEXAGON_M2_vraddh(0, 0);
+ __builtin_HEXAGON_M2_vmpy2su_s1(0, 0);
// CHECK: @llvm.hexagon.M2.vraddh
- __builtin_HEXAGON_M2_vradduh(0, 0);
+ __builtin_HEXAGON_M2_vraddh(0, 0);
// CHECK: @llvm.hexagon.M2.vradduh
- __builtin_HEXAGON_M2_vrcmaci_s0(0, 0, 0);
+ __builtin_HEXAGON_M2_vradduh(0, 0);
// CHECK: @llvm.hexagon.M2.vrcmaci.s0
- __builtin_HEXAGON_M2_vrcmaci_s0c(0, 0, 0);
+ __builtin_HEXAGON_M2_vrcmaci_s0(0, 0, 0);
// CHECK: @llvm.hexagon.M2.vrcmaci.s0c
- __builtin_HEXAGON_M2_vrcmacr_s0(0, 0, 0);
+ __builtin_HEXAGON_M2_vrcmaci_s0c(0, 0, 0);
// CHECK: @llvm.hexagon.M2.vrcmacr.s0
- __builtin_HEXAGON_M2_vrcmacr_s0c(0, 0, 0);
+ __builtin_HEXAGON_M2_vrcmacr_s0(0, 0, 0);
// CHECK: @llvm.hexagon.M2.vrcmacr.s0c
- __builtin_HEXAGON_M2_vrcmpyi_s0(0, 0);
+ __builtin_HEXAGON_M2_vrcmacr_s0c(0, 0, 0);
// CHECK: @llvm.hexagon.M2.vrcmpyi.s0
- __builtin_HEXAGON_M2_vrcmpyi_s0c(0, 0);
+ __builtin_HEXAGON_M2_vrcmpyi_s0(0, 0);
// CHECK: @llvm.hexagon.M2.vrcmpyi.s0c
- __builtin_HEXAGON_M2_vrcmpyr_s0(0, 0);
+ __builtin_HEXAGON_M2_vrcmpyi_s0c(0, 0);
// CHECK: @llvm.hexagon.M2.vrcmpyr.s0
- __builtin_HEXAGON_M2_vrcmpyr_s0c(0, 0);
+ __builtin_HEXAGON_M2_vrcmpyr_s0(0, 0);
// CHECK: @llvm.hexagon.M2.vrcmpyr.s0c
- __builtin_HEXAGON_M2_vrcmpys_acc_s1(0, 0, 0);
+ __builtin_HEXAGON_M2_vrcmpyr_s0c(0, 0);
// CHECK: @llvm.hexagon.M2.vrcmpys.acc.s1
- __builtin_HEXAGON_M2_vrcmpys_s1(0, 0);
+ __builtin_HEXAGON_M2_vrcmpys_acc_s1(0, 0, 0);
// CHECK: @llvm.hexagon.M2.vrcmpys.s1
- __builtin_HEXAGON_M2_vrcmpys_s1rp(0, 0);
+ __builtin_HEXAGON_M2_vrcmpys_s1(0, 0);
// CHECK: @llvm.hexagon.M2.vrcmpys.s1rp
- __builtin_HEXAGON_M2_vrmac_s0(0, 0, 0);
+ __builtin_HEXAGON_M2_vrcmpys_s1rp(0, 0);
// CHECK: @llvm.hexagon.M2.vrmac.s0
- __builtin_HEXAGON_M2_vrmpy_s0(0, 0);
+ __builtin_HEXAGON_M2_vrmac_s0(0, 0, 0);
// CHECK: @llvm.hexagon.M2.vrmpy.s0
- __builtin_HEXAGON_M2_xor_xacc(0, 0, 0);
+ __builtin_HEXAGON_M2_vrmpy_s0(0, 0);
// CHECK: @llvm.hexagon.M2.xor.xacc
- __builtin_HEXAGON_M4_and_and(0, 0, 0);
+ __builtin_HEXAGON_M2_xor_xacc(0, 0, 0);
// CHECK: @llvm.hexagon.M4.and.and
- __builtin_HEXAGON_M4_and_andn(0, 0, 0);
+ __builtin_HEXAGON_M4_and_and(0, 0, 0);
// CHECK: @llvm.hexagon.M4.and.andn
- __builtin_HEXAGON_M4_and_or(0, 0, 0);
+ __builtin_HEXAGON_M4_and_andn(0, 0, 0);
// CHECK: @llvm.hexagon.M4.and.or
- __builtin_HEXAGON_M4_and_xor(0, 0, 0);
+ __builtin_HEXAGON_M4_and_or(0, 0, 0);
// CHECK: @llvm.hexagon.M4.and.xor
- __builtin_HEXAGON_M4_cmpyi_wh(0, 0);
+ __builtin_HEXAGON_M4_and_xor(0, 0, 0);
// CHECK: @llvm.hexagon.M4.cmpyi.wh
- __builtin_HEXAGON_M4_cmpyi_whc(0, 0);
+ __builtin_HEXAGON_M4_cmpyi_wh(0, 0);
// CHECK: @llvm.hexagon.M4.cmpyi.whc
- __builtin_HEXAGON_M4_cmpyr_wh(0, 0);
+ __builtin_HEXAGON_M4_cmpyi_whc(0, 0);
// CHECK: @llvm.hexagon.M4.cmpyr.wh
- __builtin_HEXAGON_M4_cmpyr_whc(0, 0);
+ __builtin_HEXAGON_M4_cmpyr_wh(0, 0);
// CHECK: @llvm.hexagon.M4.cmpyr.whc
- __builtin_HEXAGON_M4_mac_up_s1_sat(0, 0, 0);
+ __builtin_HEXAGON_M4_cmpyr_whc(0, 0);
// CHECK: @llvm.hexagon.M4.mac.up.s1.sat
- __builtin_HEXAGON_M4_mpyri_addi(0, 0, 0);
+ __builtin_HEXAGON_M4_mac_up_s1_sat(0, 0, 0);
// CHECK: @llvm.hexagon.M4.mpyri.addi
- __builtin_HEXAGON_M4_mpyri_addr(0, 0, 0);
+ __builtin_HEXAGON_M4_mpyri_addi(0, 0, 0);
// CHECK: @llvm.hexagon.M4.mpyri.addr
- __builtin_HEXAGON_M4_mpyri_addr_u2(0, 0, 0);
+ __builtin_HEXAGON_M4_mpyri_addr(0, 0, 0);
// CHECK: @llvm.hexagon.M4.mpyri.addr.u2
- __builtin_HEXAGON_M4_mpyrr_addi(0, 0, 0);
+ __builtin_HEXAGON_M4_mpyri_addr_u2(0, 0, 0);
// CHECK: @llvm.hexagon.M4.mpyrr.addi
- __builtin_HEXAGON_M4_mpyrr_addr(0, 0, 0);
+ __builtin_HEXAGON_M4_mpyrr_addi(0, 0, 0);
// CHECK: @llvm.hexagon.M4.mpyrr.addr
- __builtin_HEXAGON_M4_nac_up_s1_sat(0, 0, 0);
+ __builtin_HEXAGON_M4_mpyrr_addr(0, 0, 0);
// CHECK: @llvm.hexagon.M4.nac.up.s1.sat
- __builtin_HEXAGON_M4_or_and(0, 0, 0);
+ __builtin_HEXAGON_M4_nac_up_s1_sat(0, 0, 0);
// CHECK: @llvm.hexagon.M4.or.and
- __builtin_HEXAGON_M4_or_andn(0, 0, 0);
+ __builtin_HEXAGON_M4_or_and(0, 0, 0);
// CHECK: @llvm.hexagon.M4.or.andn
- __builtin_HEXAGON_M4_or_or(0, 0, 0);
+ __builtin_HEXAGON_M4_or_andn(0, 0, 0);
// CHECK: @llvm.hexagon.M4.or.or
- __builtin_HEXAGON_M4_or_xor(0, 0, 0);
+ __builtin_HEXAGON_M4_or_or(0, 0, 0);
// CHECK: @llvm.hexagon.M4.or.xor
- __builtin_HEXAGON_M4_pmpyw(0, 0);
+ __builtin_HEXAGON_M4_or_xor(0, 0, 0);
// CHECK: @llvm.hexagon.M4.pmpyw
- __builtin_HEXAGON_M4_pmpyw_acc(0, 0, 0);
+ __builtin_HEXAGON_M4_pmpyw(0, 0);
// CHECK: @llvm.hexagon.M4.pmpyw.acc
- __builtin_HEXAGON_M4_vpmpyh(0, 0);
+ __builtin_HEXAGON_M4_pmpyw_acc(0, 0, 0);
// CHECK: @llvm.hexagon.M4.vpmpyh
- __builtin_HEXAGON_M4_vpmpyh_acc(0, 0, 0);
+ __builtin_HEXAGON_M4_vpmpyh(0, 0);
// CHECK: @llvm.hexagon.M4.vpmpyh.acc
- __builtin_HEXAGON_M4_vrmpyeh_acc_s0(0, 0, 0);
+ __builtin_HEXAGON_M4_vpmpyh_acc(0, 0, 0);
// CHECK: @llvm.hexagon.M4.vrmpyeh.acc.s0
- __builtin_HEXAGON_M4_vrmpyeh_acc_s1(0, 0, 0);
+ __builtin_HEXAGON_M4_vrmpyeh_acc_s0(0, 0, 0);
// CHECK: @llvm.hexagon.M4.vrmpyeh.acc.s1
- __builtin_HEXAGON_M4_vrmpyeh_s0(0, 0);
+ __builtin_HEXAGON_M4_vrmpyeh_acc_s1(0, 0, 0);
// CHECK: @llvm.hexagon.M4.vrmpyeh.s0
- __builtin_HEXAGON_M4_vrmpyeh_s1(0, 0);
+ __builtin_HEXAGON_M4_vrmpyeh_s0(0, 0);
// CHECK: @llvm.hexagon.M4.vrmpyeh.s1
- __builtin_HEXAGON_M4_vrmpyoh_acc_s0(0, 0, 0);
+ __builtin_HEXAGON_M4_vrmpyeh_s1(0, 0);
// CHECK: @llvm.hexagon.M4.vrmpyoh.acc.s0
- __builtin_HEXAGON_M4_vrmpyoh_acc_s1(0, 0, 0);
+ __builtin_HEXAGON_M4_vrmpyoh_acc_s0(0, 0, 0);
// CHECK: @llvm.hexagon.M4.vrmpyoh.acc.s1
- __builtin_HEXAGON_M4_vrmpyoh_s0(0, 0);
+ __builtin_HEXAGON_M4_vrmpyoh_acc_s1(0, 0, 0);
// CHECK: @llvm.hexagon.M4.vrmpyoh.s0
- __builtin_HEXAGON_M4_vrmpyoh_s1(0, 0);
+ __builtin_HEXAGON_M4_vrmpyoh_s0(0, 0);
// CHECK: @llvm.hexagon.M4.vrmpyoh.s1
- __builtin_HEXAGON_M4_xor_and(0, 0, 0);
+ __builtin_HEXAGON_M4_vrmpyoh_s1(0, 0);
// CHECK: @llvm.hexagon.M4.xor.and
- __builtin_HEXAGON_M4_xor_andn(0, 0, 0);
+ __builtin_HEXAGON_M4_xor_and(0, 0, 0);
// CHECK: @llvm.hexagon.M4.xor.andn
- __builtin_HEXAGON_M4_xor_or(0, 0, 0);
+ __builtin_HEXAGON_M4_xor_andn(0, 0, 0);
// CHECK: @llvm.hexagon.M4.xor.or
- __builtin_HEXAGON_M4_xor_xacc(0, 0, 0);
+ __builtin_HEXAGON_M4_xor_or(0, 0, 0);
// CHECK: @llvm.hexagon.M4.xor.xacc
- __builtin_HEXAGON_M5_vdmacbsu(0, 0, 0);
+ __builtin_HEXAGON_M4_xor_xacc(0, 0, 0);
// CHECK: @llvm.hexagon.M5.vdmacbsu
- __builtin_HEXAGON_M5_vdmpybsu(0, 0);
+ __builtin_HEXAGON_M5_vdmacbsu(0, 0, 0);
// CHECK: @llvm.hexagon.M5.vdmpybsu
- __builtin_HEXAGON_M5_vmacbsu(0, 0, 0);
+ __builtin_HEXAGON_M5_vdmpybsu(0, 0);
// CHECK: @llvm.hexagon.M5.vmacbsu
- __builtin_HEXAGON_M5_vmacbuu(0, 0, 0);
+ __builtin_HEXAGON_M5_vmacbsu(0, 0, 0);
// CHECK: @llvm.hexagon.M5.vmacbuu
- __builtin_HEXAGON_M5_vmpybsu(0, 0);
+ __builtin_HEXAGON_M5_vmacbuu(0, 0, 0);
// CHECK: @llvm.hexagon.M5.vmpybsu
- __builtin_HEXAGON_M5_vmpybuu(0, 0);
+ __builtin_HEXAGON_M5_vmpybsu(0, 0);
// CHECK: @llvm.hexagon.M5.vmpybuu
- __builtin_HEXAGON_M5_vrmacbsu(0, 0, 0);
+ __builtin_HEXAGON_M5_vmpybuu(0, 0);
// CHECK: @llvm.hexagon.M5.vrmacbsu
- __builtin_HEXAGON_M5_vrmacbuu(0, 0, 0);
+ __builtin_HEXAGON_M5_vrmacbsu(0, 0, 0);
// CHECK: @llvm.hexagon.M5.vrmacbuu
- __builtin_HEXAGON_M5_vrmpybsu(0, 0);
+ __builtin_HEXAGON_M5_vrmacbuu(0, 0, 0);
// CHECK: @llvm.hexagon.M5.vrmpybsu
- __builtin_HEXAGON_M5_vrmpybuu(0, 0);
+ __builtin_HEXAGON_M5_vrmpybsu(0, 0);
// CHECK: @llvm.hexagon.M5.vrmpybuu
- __builtin_HEXAGON_S2_addasl_rrri(0, 0, 0);
+ __builtin_HEXAGON_M5_vrmpybuu(0, 0);
+ // CHECK: @llvm.hexagon.M6.vabsdiffb
+ __builtin_HEXAGON_M6_vabsdiffb(0, 0);
+ // CHECK: @llvm.hexagon.M6.vabsdiffub
+ __builtin_HEXAGON_M6_vabsdiffub(0, 0);
// CHECK: @llvm.hexagon.S2.addasl.rrri
- __builtin_HEXAGON_S2_asl_i_p(0, 0);
+ __builtin_HEXAGON_S2_addasl_rrri(0, 0, 0);
// CHECK: @llvm.hexagon.S2.asl.i.p
- __builtin_HEXAGON_S2_asl_i_p_acc(0, 0, 0);
+ __builtin_HEXAGON_S2_asl_i_p(0, 0);
// CHECK: @llvm.hexagon.S2.asl.i.p.acc
- __builtin_HEXAGON_S2_asl_i_p_and(0, 0, 0);
+ __builtin_HEXAGON_S2_asl_i_p_acc(0, 0, 0);
// CHECK: @llvm.hexagon.S2.asl.i.p.and
- __builtin_HEXAGON_S2_asl_i_p_nac(0, 0, 0);
+ __builtin_HEXAGON_S2_asl_i_p_and(0, 0, 0);
// CHECK: @llvm.hexagon.S2.asl.i.p.nac
- __builtin_HEXAGON_S2_asl_i_p_or(0, 0, 0);
+ __builtin_HEXAGON_S2_asl_i_p_nac(0, 0, 0);
// CHECK: @llvm.hexagon.S2.asl.i.p.or
- __builtin_HEXAGON_S2_asl_i_p_xacc(0, 0, 0);
+ __builtin_HEXAGON_S2_asl_i_p_or(0, 0, 0);
// CHECK: @llvm.hexagon.S2.asl.i.p.xacc
- __builtin_HEXAGON_S2_asl_i_r(0, 0);
+ __builtin_HEXAGON_S2_asl_i_p_xacc(0, 0, 0);
// CHECK: @llvm.hexagon.S2.asl.i.r
- __builtin_HEXAGON_S2_asl_i_r_acc(0, 0, 0);
+ __builtin_HEXAGON_S2_asl_i_r(0, 0);
// CHECK: @llvm.hexagon.S2.asl.i.r.acc
- __builtin_HEXAGON_S2_asl_i_r_and(0, 0, 0);
+ __builtin_HEXAGON_S2_asl_i_r_acc(0, 0, 0);
// CHECK: @llvm.hexagon.S2.asl.i.r.and
- __builtin_HEXAGON_S2_asl_i_r_nac(0, 0, 0);
+ __builtin_HEXAGON_S2_asl_i_r_and(0, 0, 0);
// CHECK: @llvm.hexagon.S2.asl.i.r.nac
- __builtin_HEXAGON_S2_asl_i_r_or(0, 0, 0);
+ __builtin_HEXAGON_S2_asl_i_r_nac(0, 0, 0);
// CHECK: @llvm.hexagon.S2.asl.i.r.or
- __builtin_HEXAGON_S2_asl_i_r_sat(0, 0);
+ __builtin_HEXAGON_S2_asl_i_r_or(0, 0, 0);
// CHECK: @llvm.hexagon.S2.asl.i.r.sat
- __builtin_HEXAGON_S2_asl_i_r_xacc(0, 0, 0);
+ __builtin_HEXAGON_S2_asl_i_r_sat(0, 0);
// CHECK: @llvm.hexagon.S2.asl.i.r.xacc
- __builtin_HEXAGON_S2_asl_i_vh(0, 0);
+ __builtin_HEXAGON_S2_asl_i_r_xacc(0, 0, 0);
// CHECK: @llvm.hexagon.S2.asl.i.vh
- __builtin_HEXAGON_S2_asl_i_vw(0, 0);
+ __builtin_HEXAGON_S2_asl_i_vh(0, 0);
// CHECK: @llvm.hexagon.S2.asl.i.vw
- __builtin_HEXAGON_S2_asl_r_p(0, 0);
+ __builtin_HEXAGON_S2_asl_i_vw(0, 0);
// CHECK: @llvm.hexagon.S2.asl.r.p
- __builtin_HEXAGON_S2_asl_r_p_acc(0, 0, 0);
+ __builtin_HEXAGON_S2_asl_r_p(0, 0);
// CHECK: @llvm.hexagon.S2.asl.r.p.acc
- __builtin_HEXAGON_S2_asl_r_p_and(0, 0, 0);
+ __builtin_HEXAGON_S2_asl_r_p_acc(0, 0, 0);
// CHECK: @llvm.hexagon.S2.asl.r.p.and
- __builtin_HEXAGON_S2_asl_r_p_nac(0, 0, 0);
+ __builtin_HEXAGON_S2_asl_r_p_and(0, 0, 0);
// CHECK: @llvm.hexagon.S2.asl.r.p.nac
- __builtin_HEXAGON_S2_asl_r_p_or(0, 0, 0);
+ __builtin_HEXAGON_S2_asl_r_p_nac(0, 0, 0);
// CHECK: @llvm.hexagon.S2.asl.r.p.or
- __builtin_HEXAGON_S2_asl_r_p_xor(0, 0, 0);
+ __builtin_HEXAGON_S2_asl_r_p_or(0, 0, 0);
// CHECK: @llvm.hexagon.S2.asl.r.p.xor
- __builtin_HEXAGON_S2_asl_r_r(0, 0);
+ __builtin_HEXAGON_S2_asl_r_p_xor(0, 0, 0);
// CHECK: @llvm.hexagon.S2.asl.r.r
- __builtin_HEXAGON_S2_asl_r_r_acc(0, 0, 0);
+ __builtin_HEXAGON_S2_asl_r_r(0, 0);
// CHECK: @llvm.hexagon.S2.asl.r.r.acc
- __builtin_HEXAGON_S2_asl_r_r_and(0, 0, 0);
+ __builtin_HEXAGON_S2_asl_r_r_acc(0, 0, 0);
// CHECK: @llvm.hexagon.S2.asl.r.r.and
- __builtin_HEXAGON_S2_asl_r_r_nac(0, 0, 0);
+ __builtin_HEXAGON_S2_asl_r_r_and(0, 0, 0);
// CHECK: @llvm.hexagon.S2.asl.r.r.nac
- __builtin_HEXAGON_S2_asl_r_r_or(0, 0, 0);
+ __builtin_HEXAGON_S2_asl_r_r_nac(0, 0, 0);
// CHECK: @llvm.hexagon.S2.asl.r.r.or
- __builtin_HEXAGON_S2_asl_r_r_sat(0, 0);
+ __builtin_HEXAGON_S2_asl_r_r_or(0, 0, 0);
// CHECK: @llvm.hexagon.S2.asl.r.r.sat
- __builtin_HEXAGON_S2_asl_r_vh(0, 0);
+ __builtin_HEXAGON_S2_asl_r_r_sat(0, 0);
// CHECK: @llvm.hexagon.S2.asl.r.vh
- __builtin_HEXAGON_S2_asl_r_vw(0, 0);
+ __builtin_HEXAGON_S2_asl_r_vh(0, 0);
// CHECK: @llvm.hexagon.S2.asl.r.vw
- __builtin_HEXAGON_S2_asr_i_p(0, 0);
+ __builtin_HEXAGON_S2_asl_r_vw(0, 0);
// CHECK: @llvm.hexagon.S2.asr.i.p
- __builtin_HEXAGON_S2_asr_i_p_acc(0, 0, 0);
+ __builtin_HEXAGON_S2_asr_i_p(0, 0);
// CHECK: @llvm.hexagon.S2.asr.i.p.acc
- __builtin_HEXAGON_S2_asr_i_p_and(0, 0, 0);
+ __builtin_HEXAGON_S2_asr_i_p_acc(0, 0, 0);
// CHECK: @llvm.hexagon.S2.asr.i.p.and
- __builtin_HEXAGON_S2_asr_i_p_nac(0, 0, 0);
+ __builtin_HEXAGON_S2_asr_i_p_and(0, 0, 0);
// CHECK: @llvm.hexagon.S2.asr.i.p.nac
- __builtin_HEXAGON_S2_asr_i_p_or(0, 0, 0);
+ __builtin_HEXAGON_S2_asr_i_p_nac(0, 0, 0);
// CHECK: @llvm.hexagon.S2.asr.i.p.or
- __builtin_HEXAGON_S2_asr_i_p_rnd(0, 0);
+ __builtin_HEXAGON_S2_asr_i_p_or(0, 0, 0);
// CHECK: @llvm.hexagon.S2.asr.i.p.rnd
- __builtin_HEXAGON_S2_asr_i_p_rnd_goodsyntax(0, 0);
+ __builtin_HEXAGON_S2_asr_i_p_rnd(0, 0);
// CHECK: @llvm.hexagon.S2.asr.i.p.rnd.goodsyntax
- __builtin_HEXAGON_S2_asr_i_r(0, 0);
+ __builtin_HEXAGON_S2_asr_i_p_rnd_goodsyntax(0, 0);
// CHECK: @llvm.hexagon.S2.asr.i.r
- __builtin_HEXAGON_S2_asr_i_r_acc(0, 0, 0);
+ __builtin_HEXAGON_S2_asr_i_r(0, 0);
// CHECK: @llvm.hexagon.S2.asr.i.r.acc
- __builtin_HEXAGON_S2_asr_i_r_and(0, 0, 0);
+ __builtin_HEXAGON_S2_asr_i_r_acc(0, 0, 0);
// CHECK: @llvm.hexagon.S2.asr.i.r.and
- __builtin_HEXAGON_S2_asr_i_r_nac(0, 0, 0);
+ __builtin_HEXAGON_S2_asr_i_r_and(0, 0, 0);
// CHECK: @llvm.hexagon.S2.asr.i.r.nac
- __builtin_HEXAGON_S2_asr_i_r_or(0, 0, 0);
+ __builtin_HEXAGON_S2_asr_i_r_nac(0, 0, 0);
// CHECK: @llvm.hexagon.S2.asr.i.r.or
- __builtin_HEXAGON_S2_asr_i_r_rnd(0, 0);
+ __builtin_HEXAGON_S2_asr_i_r_or(0, 0, 0);
// CHECK: @llvm.hexagon.S2.asr.i.r.rnd
- __builtin_HEXAGON_S2_asr_i_r_rnd_goodsyntax(0, 0);
+ __builtin_HEXAGON_S2_asr_i_r_rnd(0, 0);
// CHECK: @llvm.hexagon.S2.asr.i.r.rnd.goodsyntax
- __builtin_HEXAGON_S2_asr_i_svw_trun(0, 0);
+ __builtin_HEXAGON_S2_asr_i_r_rnd_goodsyntax(0, 0);
// CHECK: @llvm.hexagon.S2.asr.i.svw.trun
- __builtin_HEXAGON_S2_asr_i_vh(0, 0);
+ __builtin_HEXAGON_S2_asr_i_svw_trun(0, 0);
// CHECK: @llvm.hexagon.S2.asr.i.vh
- __builtin_HEXAGON_S2_asr_i_vw(0, 0);
+ __builtin_HEXAGON_S2_asr_i_vh(0, 0);
// CHECK: @llvm.hexagon.S2.asr.i.vw
- __builtin_HEXAGON_S2_asr_r_p(0, 0);
+ __builtin_HEXAGON_S2_asr_i_vw(0, 0);
// CHECK: @llvm.hexagon.S2.asr.r.p
- __builtin_HEXAGON_S2_asr_r_p_acc(0, 0, 0);
+ __builtin_HEXAGON_S2_asr_r_p(0, 0);
// CHECK: @llvm.hexagon.S2.asr.r.p.acc
- __builtin_HEXAGON_S2_asr_r_p_and(0, 0, 0);
+ __builtin_HEXAGON_S2_asr_r_p_acc(0, 0, 0);
// CHECK: @llvm.hexagon.S2.asr.r.p.and
- __builtin_HEXAGON_S2_asr_r_p_nac(0, 0, 0);
+ __builtin_HEXAGON_S2_asr_r_p_and(0, 0, 0);
// CHECK: @llvm.hexagon.S2.asr.r.p.nac
- __builtin_HEXAGON_S2_asr_r_p_or(0, 0, 0);
+ __builtin_HEXAGON_S2_asr_r_p_nac(0, 0, 0);
// CHECK: @llvm.hexagon.S2.asr.r.p.or
- __builtin_HEXAGON_S2_asr_r_p_xor(0, 0, 0);
+ __builtin_HEXAGON_S2_asr_r_p_or(0, 0, 0);
// CHECK: @llvm.hexagon.S2.asr.r.p.xor
- __builtin_HEXAGON_S2_asr_r_r(0, 0);
+ __builtin_HEXAGON_S2_asr_r_p_xor(0, 0, 0);
// CHECK: @llvm.hexagon.S2.asr.r.r
- __builtin_HEXAGON_S2_asr_r_r_acc(0, 0, 0);
+ __builtin_HEXAGON_S2_asr_r_r(0, 0);
// CHECK: @llvm.hexagon.S2.asr.r.r.acc
- __builtin_HEXAGON_S2_asr_r_r_and(0, 0, 0);
+ __builtin_HEXAGON_S2_asr_r_r_acc(0, 0, 0);
// CHECK: @llvm.hexagon.S2.asr.r.r.and
- __builtin_HEXAGON_S2_asr_r_r_nac(0, 0, 0);
+ __builtin_HEXAGON_S2_asr_r_r_and(0, 0, 0);
// CHECK: @llvm.hexagon.S2.asr.r.r.nac
- __builtin_HEXAGON_S2_asr_r_r_or(0, 0, 0);
+ __builtin_HEXAGON_S2_asr_r_r_nac(0, 0, 0);
// CHECK: @llvm.hexagon.S2.asr.r.r.or
- __builtin_HEXAGON_S2_asr_r_r_sat(0, 0);
+ __builtin_HEXAGON_S2_asr_r_r_or(0, 0, 0);
// CHECK: @llvm.hexagon.S2.asr.r.r.sat
- __builtin_HEXAGON_S2_asr_r_svw_trun(0, 0);
+ __builtin_HEXAGON_S2_asr_r_r_sat(0, 0);
// CHECK: @llvm.hexagon.S2.asr.r.svw.trun
- __builtin_HEXAGON_S2_asr_r_vh(0, 0);
+ __builtin_HEXAGON_S2_asr_r_svw_trun(0, 0);
// CHECK: @llvm.hexagon.S2.asr.r.vh
- __builtin_HEXAGON_S2_asr_r_vw(0, 0);
+ __builtin_HEXAGON_S2_asr_r_vh(0, 0);
// CHECK: @llvm.hexagon.S2.asr.r.vw
- __builtin_HEXAGON_S2_brev(0);
+ __builtin_HEXAGON_S2_asr_r_vw(0, 0);
// CHECK: @llvm.hexagon.S2.brev
- __builtin_HEXAGON_S2_brevp(0);
+ __builtin_HEXAGON_S2_brev(0);
// CHECK: @llvm.hexagon.S2.brevp
- __builtin_HEXAGON_S2_cabacencbin(0, 0, 0);
+ __builtin_HEXAGON_S2_brevp(0);
// CHECK: @llvm.hexagon.S2.cabacencbin
- __builtin_HEXAGON_S2_cl0(0);
+ __builtin_HEXAGON_S2_cabacencbin(0, 0, 0);
// CHECK: @llvm.hexagon.S2.cl0
- __builtin_HEXAGON_S2_cl0p(0);
+ __builtin_HEXAGON_S2_cl0(0);
// CHECK: @llvm.hexagon.S2.cl0p
- __builtin_HEXAGON_S2_cl1(0);
+ __builtin_HEXAGON_S2_cl0p(0);
// CHECK: @llvm.hexagon.S2.cl1
- __builtin_HEXAGON_S2_cl1p(0);
+ __builtin_HEXAGON_S2_cl1(0);
// CHECK: @llvm.hexagon.S2.cl1p
- __builtin_HEXAGON_S2_clb(0);
+ __builtin_HEXAGON_S2_cl1p(0);
// CHECK: @llvm.hexagon.S2.clb
- __builtin_HEXAGON_S2_clbnorm(0);
+ __builtin_HEXAGON_S2_clb(0);
// CHECK: @llvm.hexagon.S2.clbnorm
- __builtin_HEXAGON_S2_clbp(0);
+ __builtin_HEXAGON_S2_clbnorm(0);
// CHECK: @llvm.hexagon.S2.clbp
- __builtin_HEXAGON_S2_clrbit_i(0, 0);
+ __builtin_HEXAGON_S2_clbp(0);
// CHECK: @llvm.hexagon.S2.clrbit.i
- __builtin_HEXAGON_S2_clrbit_r(0, 0);
+ __builtin_HEXAGON_S2_clrbit_i(0, 0);
// CHECK: @llvm.hexagon.S2.clrbit.r
- __builtin_HEXAGON_S2_ct0(0);
+ __builtin_HEXAGON_S2_clrbit_r(0, 0);
// CHECK: @llvm.hexagon.S2.ct0
- __builtin_HEXAGON_S2_ct0p(0);
+ __builtin_HEXAGON_S2_ct0(0);
// CHECK: @llvm.hexagon.S2.ct0p
- __builtin_HEXAGON_S2_ct1(0);
+ __builtin_HEXAGON_S2_ct0p(0);
// CHECK: @llvm.hexagon.S2.ct1
- __builtin_HEXAGON_S2_ct1p(0);
+ __builtin_HEXAGON_S2_ct1(0);
// CHECK: @llvm.hexagon.S2.ct1p
- __builtin_HEXAGON_S2_deinterleave(0);
+ __builtin_HEXAGON_S2_ct1p(0);
// CHECK: @llvm.hexagon.S2.deinterleave
- __builtin_HEXAGON_S2_extractu(0, 0, 0);
+ __builtin_HEXAGON_S2_deinterleave(0);
// CHECK: @llvm.hexagon.S2.extractu
- __builtin_HEXAGON_S2_extractup(0, 0, 0);
+ __builtin_HEXAGON_S2_extractu(0, 0, 0);
+ // CHECK: @llvm.hexagon.S2.extractu.rp
+ __builtin_HEXAGON_S2_extractu_rp(0, 0);
// CHECK: @llvm.hexagon.S2.extractup
- __builtin_HEXAGON_S2_extractup_rp(0, 0);
+ __builtin_HEXAGON_S2_extractup(0, 0, 0);
// CHECK: @llvm.hexagon.S2.extractup.rp
- __builtin_HEXAGON_S2_extractu_rp(0, 0);
- // CHECK: @llvm.hexagon.S2.extractu.rp
- __builtin_HEXAGON_S2_insert(0, 0, 0, 0);
+ __builtin_HEXAGON_S2_extractup_rp(0, 0);
// CHECK: @llvm.hexagon.S2.insert
- __builtin_HEXAGON_S2_insertp(0, 0, 0, 0);
+ __builtin_HEXAGON_S2_insert(0, 0, 0, 0);
+ // CHECK: @llvm.hexagon.S2.insert.rp
+ __builtin_HEXAGON_S2_insert_rp(0, 0, 0);
// CHECK: @llvm.hexagon.S2.insertp
- __builtin_HEXAGON_S2_insertp_rp(0, 0, 0);
+ __builtin_HEXAGON_S2_insertp(0, 0, 0, 0);
// CHECK: @llvm.hexagon.S2.insertp.rp
- __builtin_HEXAGON_S2_insert_rp(0, 0, 0);
- // CHECK: @llvm.hexagon.S2.insert.rp
- __builtin_HEXAGON_S2_interleave(0);
+ __builtin_HEXAGON_S2_insertp_rp(0, 0, 0);
// CHECK: @llvm.hexagon.S2.interleave
- __builtin_HEXAGON_S2_lfsp(0, 0);
+ __builtin_HEXAGON_S2_interleave(0);
// CHECK: @llvm.hexagon.S2.lfsp
- __builtin_HEXAGON_S2_lsl_r_p(0, 0);
+ __builtin_HEXAGON_S2_lfsp(0, 0);
// CHECK: @llvm.hexagon.S2.lsl.r.p
- __builtin_HEXAGON_S2_lsl_r_p_acc(0, 0, 0);
+ __builtin_HEXAGON_S2_lsl_r_p(0, 0);
// CHECK: @llvm.hexagon.S2.lsl.r.p.acc
- __builtin_HEXAGON_S2_lsl_r_p_and(0, 0, 0);
+ __builtin_HEXAGON_S2_lsl_r_p_acc(0, 0, 0);
// CHECK: @llvm.hexagon.S2.lsl.r.p.and
- __builtin_HEXAGON_S2_lsl_r_p_nac(0, 0, 0);
+ __builtin_HEXAGON_S2_lsl_r_p_and(0, 0, 0);
// CHECK: @llvm.hexagon.S2.lsl.r.p.nac
- __builtin_HEXAGON_S2_lsl_r_p_or(0, 0, 0);
+ __builtin_HEXAGON_S2_lsl_r_p_nac(0, 0, 0);
// CHECK: @llvm.hexagon.S2.lsl.r.p.or
- __builtin_HEXAGON_S2_lsl_r_p_xor(0, 0, 0);
+ __builtin_HEXAGON_S2_lsl_r_p_or(0, 0, 0);
// CHECK: @llvm.hexagon.S2.lsl.r.p.xor
- __builtin_HEXAGON_S2_lsl_r_r(0, 0);
+ __builtin_HEXAGON_S2_lsl_r_p_xor(0, 0, 0);
// CHECK: @llvm.hexagon.S2.lsl.r.r
- __builtin_HEXAGON_S2_lsl_r_r_acc(0, 0, 0);
+ __builtin_HEXAGON_S2_lsl_r_r(0, 0);
// CHECK: @llvm.hexagon.S2.lsl.r.r.acc
- __builtin_HEXAGON_S2_lsl_r_r_and(0, 0, 0);
+ __builtin_HEXAGON_S2_lsl_r_r_acc(0, 0, 0);
// CHECK: @llvm.hexagon.S2.lsl.r.r.and
- __builtin_HEXAGON_S2_lsl_r_r_nac(0, 0, 0);
+ __builtin_HEXAGON_S2_lsl_r_r_and(0, 0, 0);
// CHECK: @llvm.hexagon.S2.lsl.r.r.nac
- __builtin_HEXAGON_S2_lsl_r_r_or(0, 0, 0);
+ __builtin_HEXAGON_S2_lsl_r_r_nac(0, 0, 0);
// CHECK: @llvm.hexagon.S2.lsl.r.r.or
- __builtin_HEXAGON_S2_lsl_r_vh(0, 0);
+ __builtin_HEXAGON_S2_lsl_r_r_or(0, 0, 0);
// CHECK: @llvm.hexagon.S2.lsl.r.vh
- __builtin_HEXAGON_S2_lsl_r_vw(0, 0);
+ __builtin_HEXAGON_S2_lsl_r_vh(0, 0);
// CHECK: @llvm.hexagon.S2.lsl.r.vw
- __builtin_HEXAGON_S2_lsr_i_p(0, 0);
+ __builtin_HEXAGON_S2_lsl_r_vw(0, 0);
// CHECK: @llvm.hexagon.S2.lsr.i.p
- __builtin_HEXAGON_S2_lsr_i_p_acc(0, 0, 0);
+ __builtin_HEXAGON_S2_lsr_i_p(0, 0);
// CHECK: @llvm.hexagon.S2.lsr.i.p.acc
- __builtin_HEXAGON_S2_lsr_i_p_and(0, 0, 0);
+ __builtin_HEXAGON_S2_lsr_i_p_acc(0, 0, 0);
// CHECK: @llvm.hexagon.S2.lsr.i.p.and
- __builtin_HEXAGON_S2_lsr_i_p_nac(0, 0, 0);
+ __builtin_HEXAGON_S2_lsr_i_p_and(0, 0, 0);
// CHECK: @llvm.hexagon.S2.lsr.i.p.nac
- __builtin_HEXAGON_S2_lsr_i_p_or(0, 0, 0);
+ __builtin_HEXAGON_S2_lsr_i_p_nac(0, 0, 0);
// CHECK: @llvm.hexagon.S2.lsr.i.p.or
- __builtin_HEXAGON_S2_lsr_i_p_xacc(0, 0, 0);
+ __builtin_HEXAGON_S2_lsr_i_p_or(0, 0, 0);
// CHECK: @llvm.hexagon.S2.lsr.i.p.xacc
- __builtin_HEXAGON_S2_lsr_i_r(0, 0);
+ __builtin_HEXAGON_S2_lsr_i_p_xacc(0, 0, 0);
// CHECK: @llvm.hexagon.S2.lsr.i.r
- __builtin_HEXAGON_S2_lsr_i_r_acc(0, 0, 0);
+ __builtin_HEXAGON_S2_lsr_i_r(0, 0);
// CHECK: @llvm.hexagon.S2.lsr.i.r.acc
- __builtin_HEXAGON_S2_lsr_i_r_and(0, 0, 0);
+ __builtin_HEXAGON_S2_lsr_i_r_acc(0, 0, 0);
// CHECK: @llvm.hexagon.S2.lsr.i.r.and
- __builtin_HEXAGON_S2_lsr_i_r_nac(0, 0, 0);
+ __builtin_HEXAGON_S2_lsr_i_r_and(0, 0, 0);
// CHECK: @llvm.hexagon.S2.lsr.i.r.nac
- __builtin_HEXAGON_S2_lsr_i_r_or(0, 0, 0);
+ __builtin_HEXAGON_S2_lsr_i_r_nac(0, 0, 0);
// CHECK: @llvm.hexagon.S2.lsr.i.r.or
- __builtin_HEXAGON_S2_lsr_i_r_xacc(0, 0, 0);
+ __builtin_HEXAGON_S2_lsr_i_r_or(0, 0, 0);
// CHECK: @llvm.hexagon.S2.lsr.i.r.xacc
- __builtin_HEXAGON_S2_lsr_i_vh(0, 0);
+ __builtin_HEXAGON_S2_lsr_i_r_xacc(0, 0, 0);
// CHECK: @llvm.hexagon.S2.lsr.i.vh
- __builtin_HEXAGON_S2_lsr_i_vw(0, 0);
+ __builtin_HEXAGON_S2_lsr_i_vh(0, 0);
// CHECK: @llvm.hexagon.S2.lsr.i.vw
- __builtin_HEXAGON_S2_lsr_r_p(0, 0);
+ __builtin_HEXAGON_S2_lsr_i_vw(0, 0);
// CHECK: @llvm.hexagon.S2.lsr.r.p
- __builtin_HEXAGON_S2_lsr_r_p_acc(0, 0, 0);
+ __builtin_HEXAGON_S2_lsr_r_p(0, 0);
// CHECK: @llvm.hexagon.S2.lsr.r.p.acc
- __builtin_HEXAGON_S2_lsr_r_p_and(0, 0, 0);
+ __builtin_HEXAGON_S2_lsr_r_p_acc(0, 0, 0);
// CHECK: @llvm.hexagon.S2.lsr.r.p.and
- __builtin_HEXAGON_S2_lsr_r_p_nac(0, 0, 0);
+ __builtin_HEXAGON_S2_lsr_r_p_and(0, 0, 0);
// CHECK: @llvm.hexagon.S2.lsr.r.p.nac
- __builtin_HEXAGON_S2_lsr_r_p_or(0, 0, 0);
+ __builtin_HEXAGON_S2_lsr_r_p_nac(0, 0, 0);
// CHECK: @llvm.hexagon.S2.lsr.r.p.or
- __builtin_HEXAGON_S2_lsr_r_p_xor(0, 0, 0);
+ __builtin_HEXAGON_S2_lsr_r_p_or(0, 0, 0);
// CHECK: @llvm.hexagon.S2.lsr.r.p.xor
- __builtin_HEXAGON_S2_lsr_r_r(0, 0);
+ __builtin_HEXAGON_S2_lsr_r_p_xor(0, 0, 0);
// CHECK: @llvm.hexagon.S2.lsr.r.r
- __builtin_HEXAGON_S2_lsr_r_r_acc(0, 0, 0);
+ __builtin_HEXAGON_S2_lsr_r_r(0, 0);
// CHECK: @llvm.hexagon.S2.lsr.r.r.acc
- __builtin_HEXAGON_S2_lsr_r_r_and(0, 0, 0);
+ __builtin_HEXAGON_S2_lsr_r_r_acc(0, 0, 0);
// CHECK: @llvm.hexagon.S2.lsr.r.r.and
- __builtin_HEXAGON_S2_lsr_r_r_nac(0, 0, 0);
+ __builtin_HEXAGON_S2_lsr_r_r_and(0, 0, 0);
// CHECK: @llvm.hexagon.S2.lsr.r.r.nac
- __builtin_HEXAGON_S2_lsr_r_r_or(0, 0, 0);
+ __builtin_HEXAGON_S2_lsr_r_r_nac(0, 0, 0);
// CHECK: @llvm.hexagon.S2.lsr.r.r.or
- __builtin_HEXAGON_S2_lsr_r_vh(0, 0);
+ __builtin_HEXAGON_S2_lsr_r_r_or(0, 0, 0);
// CHECK: @llvm.hexagon.S2.lsr.r.vh
- __builtin_HEXAGON_S2_lsr_r_vw(0, 0);
+ __builtin_HEXAGON_S2_lsr_r_vh(0, 0);
// CHECK: @llvm.hexagon.S2.lsr.r.vw
- __builtin_HEXAGON_S2_packhl(0, 0);
+ __builtin_HEXAGON_S2_lsr_r_vw(0, 0);
// CHECK: @llvm.hexagon.S2.packhl
- __builtin_HEXAGON_S2_parityp(0, 0);
+ __builtin_HEXAGON_S2_packhl(0, 0);
// CHECK: @llvm.hexagon.S2.parityp
- __builtin_HEXAGON_S2_setbit_i(0, 0);
+ __builtin_HEXAGON_S2_parityp(0, 0);
// CHECK: @llvm.hexagon.S2.setbit.i
- __builtin_HEXAGON_S2_setbit_r(0, 0);
+ __builtin_HEXAGON_S2_setbit_i(0, 0);
// CHECK: @llvm.hexagon.S2.setbit.r
- __builtin_HEXAGON_S2_shuffeb(0, 0);
+ __builtin_HEXAGON_S2_setbit_r(0, 0);
// CHECK: @llvm.hexagon.S2.shuffeb
- __builtin_HEXAGON_S2_shuffeh(0, 0);
+ __builtin_HEXAGON_S2_shuffeb(0, 0);
// CHECK: @llvm.hexagon.S2.shuffeh
- __builtin_HEXAGON_S2_shuffob(0, 0);
+ __builtin_HEXAGON_S2_shuffeh(0, 0);
// CHECK: @llvm.hexagon.S2.shuffob
- __builtin_HEXAGON_S2_shuffoh(0, 0);
+ __builtin_HEXAGON_S2_shuffob(0, 0);
// CHECK: @llvm.hexagon.S2.shuffoh
- __builtin_HEXAGON_S2_svsathb(0);
+ __builtin_HEXAGON_S2_shuffoh(0, 0);
// CHECK: @llvm.hexagon.S2.svsathb
- __builtin_HEXAGON_S2_svsathub(0);
+ __builtin_HEXAGON_S2_svsathb(0);
// CHECK: @llvm.hexagon.S2.svsathub
- __builtin_HEXAGON_S2_tableidxb_goodsyntax(0, 0, 0, 0);
+ __builtin_HEXAGON_S2_svsathub(0);
// CHECK: @llvm.hexagon.S2.tableidxb.goodsyntax
- __builtin_HEXAGON_S2_tableidxd_goodsyntax(0, 0, 0, 0);
+ __builtin_HEXAGON_S2_tableidxb_goodsyntax(0, 0, 0, 0);
// CHECK: @llvm.hexagon.S2.tableidxd.goodsyntax
- __builtin_HEXAGON_S2_tableidxh_goodsyntax(0, 0, 0, 0);
+ __builtin_HEXAGON_S2_tableidxd_goodsyntax(0, 0, 0, 0);
// CHECK: @llvm.hexagon.S2.tableidxh.goodsyntax
- __builtin_HEXAGON_S2_tableidxw_goodsyntax(0, 0, 0, 0);
+ __builtin_HEXAGON_S2_tableidxh_goodsyntax(0, 0, 0, 0);
// CHECK: @llvm.hexagon.S2.tableidxw.goodsyntax
- __builtin_HEXAGON_S2_togglebit_i(0, 0);
+ __builtin_HEXAGON_S2_tableidxw_goodsyntax(0, 0, 0, 0);
// CHECK: @llvm.hexagon.S2.togglebit.i
- __builtin_HEXAGON_S2_togglebit_r(0, 0);
+ __builtin_HEXAGON_S2_togglebit_i(0, 0);
// CHECK: @llvm.hexagon.S2.togglebit.r
- __builtin_HEXAGON_S2_tstbit_i(0, 0);
+ __builtin_HEXAGON_S2_togglebit_r(0, 0);
// CHECK: @llvm.hexagon.S2.tstbit.i
- __builtin_HEXAGON_S2_tstbit_r(0, 0);
+ __builtin_HEXAGON_S2_tstbit_i(0, 0);
// CHECK: @llvm.hexagon.S2.tstbit.r
- __builtin_HEXAGON_S2_valignib(0, 0, 0);
+ __builtin_HEXAGON_S2_tstbit_r(0, 0);
// CHECK: @llvm.hexagon.S2.valignib
- __builtin_HEXAGON_S2_valignrb(0, 0, 0);
+ __builtin_HEXAGON_S2_valignib(0, 0, 0);
// CHECK: @llvm.hexagon.S2.valignrb
- __builtin_HEXAGON_S2_vcnegh(0, 0);
+ __builtin_HEXAGON_S2_valignrb(0, 0, 0);
// CHECK: @llvm.hexagon.S2.vcnegh
- __builtin_HEXAGON_S2_vcrotate(0, 0);
+ __builtin_HEXAGON_S2_vcnegh(0, 0);
// CHECK: @llvm.hexagon.S2.vcrotate
- __builtin_HEXAGON_S2_vrcnegh(0, 0, 0);
+ __builtin_HEXAGON_S2_vcrotate(0, 0);
// CHECK: @llvm.hexagon.S2.vrcnegh
- __builtin_HEXAGON_S2_vrndpackwh(0);
+ __builtin_HEXAGON_S2_vrcnegh(0, 0, 0);
// CHECK: @llvm.hexagon.S2.vrndpackwh
- __builtin_HEXAGON_S2_vrndpackwhs(0);
+ __builtin_HEXAGON_S2_vrndpackwh(0);
// CHECK: @llvm.hexagon.S2.vrndpackwhs
- __builtin_HEXAGON_S2_vsathb(0);
+ __builtin_HEXAGON_S2_vrndpackwhs(0);
// CHECK: @llvm.hexagon.S2.vsathb
- __builtin_HEXAGON_S2_vsathb_nopack(0);
+ __builtin_HEXAGON_S2_vsathb(0);
// CHECK: @llvm.hexagon.S2.vsathb.nopack
- __builtin_HEXAGON_S2_vsathub(0);
+ __builtin_HEXAGON_S2_vsathb_nopack(0);
// CHECK: @llvm.hexagon.S2.vsathub
- __builtin_HEXAGON_S2_vsathub_nopack(0);
+ __builtin_HEXAGON_S2_vsathub(0);
// CHECK: @llvm.hexagon.S2.vsathub.nopack
- __builtin_HEXAGON_S2_vsatwh(0);
+ __builtin_HEXAGON_S2_vsathub_nopack(0);
// CHECK: @llvm.hexagon.S2.vsatwh
- __builtin_HEXAGON_S2_vsatwh_nopack(0);
+ __builtin_HEXAGON_S2_vsatwh(0);
// CHECK: @llvm.hexagon.S2.vsatwh.nopack
- __builtin_HEXAGON_S2_vsatwuh(0);
+ __builtin_HEXAGON_S2_vsatwh_nopack(0);
// CHECK: @llvm.hexagon.S2.vsatwuh
- __builtin_HEXAGON_S2_vsatwuh_nopack(0);
+ __builtin_HEXAGON_S2_vsatwuh(0);
// CHECK: @llvm.hexagon.S2.vsatwuh.nopack
- __builtin_HEXAGON_S2_vsplatrb(0);
+ __builtin_HEXAGON_S2_vsatwuh_nopack(0);
// CHECK: @llvm.hexagon.S2.vsplatrb
- __builtin_HEXAGON_S2_vsplatrh(0);
+ __builtin_HEXAGON_S2_vsplatrb(0);
// CHECK: @llvm.hexagon.S2.vsplatrh
- __builtin_HEXAGON_S2_vspliceib(0, 0, 0);
+ __builtin_HEXAGON_S2_vsplatrh(0);
// CHECK: @llvm.hexagon.S2.vspliceib
- __builtin_HEXAGON_S2_vsplicerb(0, 0, 0);
+ __builtin_HEXAGON_S2_vspliceib(0, 0, 0);
// CHECK: @llvm.hexagon.S2.vsplicerb
- __builtin_HEXAGON_S2_vsxtbh(0);
+ __builtin_HEXAGON_S2_vsplicerb(0, 0, 0);
// CHECK: @llvm.hexagon.S2.vsxtbh
- __builtin_HEXAGON_S2_vsxthw(0);
+ __builtin_HEXAGON_S2_vsxtbh(0);
// CHECK: @llvm.hexagon.S2.vsxthw
- __builtin_HEXAGON_S2_vtrunehb(0);
+ __builtin_HEXAGON_S2_vsxthw(0);
// CHECK: @llvm.hexagon.S2.vtrunehb
- __builtin_HEXAGON_S2_vtrunewh(0, 0);
+ __builtin_HEXAGON_S2_vtrunehb(0);
// CHECK: @llvm.hexagon.S2.vtrunewh
- __builtin_HEXAGON_S2_vtrunohb(0);
+ __builtin_HEXAGON_S2_vtrunewh(0, 0);
// CHECK: @llvm.hexagon.S2.vtrunohb
- __builtin_HEXAGON_S2_vtrunowh(0, 0);
+ __builtin_HEXAGON_S2_vtrunohb(0);
// CHECK: @llvm.hexagon.S2.vtrunowh
- __builtin_HEXAGON_S2_vzxtbh(0);
+ __builtin_HEXAGON_S2_vtrunowh(0, 0);
// CHECK: @llvm.hexagon.S2.vzxtbh
- __builtin_HEXAGON_S2_vzxthw(0);
+ __builtin_HEXAGON_S2_vzxtbh(0);
// CHECK: @llvm.hexagon.S2.vzxthw
- __builtin_HEXAGON_S4_addaddi(0, 0, 0);
+ __builtin_HEXAGON_S2_vzxthw(0);
// CHECK: @llvm.hexagon.S4.addaddi
- __builtin_HEXAGON_S4_addi_asl_ri(0, 0, 0);
+ __builtin_HEXAGON_S4_addaddi(0, 0, 0);
// CHECK: @llvm.hexagon.S4.addi.asl.ri
- __builtin_HEXAGON_S4_addi_lsr_ri(0, 0, 0);
+ __builtin_HEXAGON_S4_addi_asl_ri(0, 0, 0);
// CHECK: @llvm.hexagon.S4.addi.lsr.ri
- __builtin_HEXAGON_S4_andi_asl_ri(0, 0, 0);
+ __builtin_HEXAGON_S4_addi_lsr_ri(0, 0, 0);
// CHECK: @llvm.hexagon.S4.andi.asl.ri
- __builtin_HEXAGON_S4_andi_lsr_ri(0, 0, 0);
+ __builtin_HEXAGON_S4_andi_asl_ri(0, 0, 0);
// CHECK: @llvm.hexagon.S4.andi.lsr.ri
- __builtin_HEXAGON_S4_clbaddi(0, 0);
+ __builtin_HEXAGON_S4_andi_lsr_ri(0, 0, 0);
// CHECK: @llvm.hexagon.S4.clbaddi
- __builtin_HEXAGON_S4_clbpaddi(0, 0);
+ __builtin_HEXAGON_S4_clbaddi(0, 0);
// CHECK: @llvm.hexagon.S4.clbpaddi
- __builtin_HEXAGON_S4_clbpnorm(0);
+ __builtin_HEXAGON_S4_clbpaddi(0, 0);
// CHECK: @llvm.hexagon.S4.clbpnorm
- __builtin_HEXAGON_S4_extract(0, 0, 0);
+ __builtin_HEXAGON_S4_clbpnorm(0);
// CHECK: @llvm.hexagon.S4.extract
- __builtin_HEXAGON_S4_extractp(0, 0, 0);
+ __builtin_HEXAGON_S4_extract(0, 0, 0);
+ // CHECK: @llvm.hexagon.S4.extract.rp
+ __builtin_HEXAGON_S4_extract_rp(0, 0);
// CHECK: @llvm.hexagon.S4.extractp
- __builtin_HEXAGON_S4_extractp_rp(0, 0);
+ __builtin_HEXAGON_S4_extractp(0, 0, 0);
// CHECK: @llvm.hexagon.S4.extractp.rp
- __builtin_HEXAGON_S4_extract_rp(0, 0);
- // CHECK: @llvm.hexagon.S4.extract.rp
- __builtin_HEXAGON_S4_lsli(0, 0);
+ __builtin_HEXAGON_S4_extractp_rp(0, 0);
// CHECK: @llvm.hexagon.S4.lsli
- __builtin_HEXAGON_S4_ntstbit_i(0, 0);
+ __builtin_HEXAGON_S4_lsli(0, 0);
// CHECK: @llvm.hexagon.S4.ntstbit.i
- __builtin_HEXAGON_S4_ntstbit_r(0, 0);
+ __builtin_HEXAGON_S4_ntstbit_i(0, 0);
// CHECK: @llvm.hexagon.S4.ntstbit.r
- __builtin_HEXAGON_S4_or_andi(0, 0, 0);
+ __builtin_HEXAGON_S4_ntstbit_r(0, 0);
// CHECK: @llvm.hexagon.S4.or.andi
- __builtin_HEXAGON_S4_or_andix(0, 0, 0);
+ __builtin_HEXAGON_S4_or_andi(0, 0, 0);
// CHECK: @llvm.hexagon.S4.or.andix
- __builtin_HEXAGON_S4_ori_asl_ri(0, 0, 0);
+ __builtin_HEXAGON_S4_or_andix(0, 0, 0);
+ // CHECK: @llvm.hexagon.S4.or.ori
+ __builtin_HEXAGON_S4_or_ori(0, 0, 0);
// CHECK: @llvm.hexagon.S4.ori.asl.ri
- __builtin_HEXAGON_S4_ori_lsr_ri(0, 0, 0);
+ __builtin_HEXAGON_S4_ori_asl_ri(0, 0, 0);
// CHECK: @llvm.hexagon.S4.ori.lsr.ri
- __builtin_HEXAGON_S4_or_ori(0, 0, 0);
- // CHECK: @llvm.hexagon.S4.or.ori
- __builtin_HEXAGON_S4_parity(0, 0);
+ __builtin_HEXAGON_S4_ori_lsr_ri(0, 0, 0);
// CHECK: @llvm.hexagon.S4.parity
- __builtin_HEXAGON_S4_subaddi(0, 0, 0);
+ __builtin_HEXAGON_S4_parity(0, 0);
// CHECK: @llvm.hexagon.S4.subaddi
- __builtin_HEXAGON_S4_subi_asl_ri(0, 0, 0);
+ __builtin_HEXAGON_S4_subaddi(0, 0, 0);
// CHECK: @llvm.hexagon.S4.subi.asl.ri
- __builtin_HEXAGON_S4_subi_lsr_ri(0, 0, 0);
+ __builtin_HEXAGON_S4_subi_asl_ri(0, 0, 0);
// CHECK: @llvm.hexagon.S4.subi.lsr.ri
- __builtin_HEXAGON_S4_vrcrotate(0, 0, 0);
+ __builtin_HEXAGON_S4_subi_lsr_ri(0, 0, 0);
// CHECK: @llvm.hexagon.S4.vrcrotate
- __builtin_HEXAGON_S4_vrcrotate_acc(0, 0, 0, 0);
+ __builtin_HEXAGON_S4_vrcrotate(0, 0, 0);
// CHECK: @llvm.hexagon.S4.vrcrotate.acc
- __builtin_HEXAGON_S4_vxaddsubh(0, 0);
+ __builtin_HEXAGON_S4_vrcrotate_acc(0, 0, 0, 0);
// CHECK: @llvm.hexagon.S4.vxaddsubh
- __builtin_HEXAGON_S4_vxaddsubhr(0, 0);
+ __builtin_HEXAGON_S4_vxaddsubh(0, 0);
// CHECK: @llvm.hexagon.S4.vxaddsubhr
- __builtin_HEXAGON_S4_vxaddsubw(0, 0);
+ __builtin_HEXAGON_S4_vxaddsubhr(0, 0);
// CHECK: @llvm.hexagon.S4.vxaddsubw
- __builtin_HEXAGON_S4_vxsubaddh(0, 0);
+ __builtin_HEXAGON_S4_vxaddsubw(0, 0);
// CHECK: @llvm.hexagon.S4.vxsubaddh
- __builtin_HEXAGON_S4_vxsubaddhr(0, 0);
+ __builtin_HEXAGON_S4_vxsubaddh(0, 0);
// CHECK: @llvm.hexagon.S4.vxsubaddhr
- __builtin_HEXAGON_S4_vxsubaddw(0, 0);
+ __builtin_HEXAGON_S4_vxsubaddhr(0, 0);
// CHECK: @llvm.hexagon.S4.vxsubaddw
- __builtin_HEXAGON_S5_asrhub_rnd_sat_goodsyntax(0, 0);
+ __builtin_HEXAGON_S4_vxsubaddw(0, 0);
// CHECK: @llvm.hexagon.S5.asrhub.rnd.sat.goodsyntax
- __builtin_HEXAGON_S5_asrhub_sat(0, 0);
+ __builtin_HEXAGON_S5_asrhub_rnd_sat_goodsyntax(0, 0);
// CHECK: @llvm.hexagon.S5.asrhub.sat
- __builtin_HEXAGON_S5_popcountp(0);
+ __builtin_HEXAGON_S5_asrhub_sat(0, 0);
// CHECK: @llvm.hexagon.S5.popcountp
- __builtin_HEXAGON_S5_vasrhrnd_goodsyntax(0, 0);
+ __builtin_HEXAGON_S5_popcountp(0);
// CHECK: @llvm.hexagon.S5.vasrhrnd.goodsyntax
- __builtin_HEXAGON_S6_rol_i_p(0, 0);
+ __builtin_HEXAGON_S5_vasrhrnd_goodsyntax(0, 0);
// CHECK: @llvm.hexagon.S6.rol.i.p
- __builtin_HEXAGON_S6_rol_i_p_acc(0, 0, 0);
+ __builtin_HEXAGON_S6_rol_i_p(0, 0);
// CHECK: @llvm.hexagon.S6.rol.i.p.acc
- __builtin_HEXAGON_S6_rol_i_p_and(0, 0, 0);
+ __builtin_HEXAGON_S6_rol_i_p_acc(0, 0, 0);
// CHECK: @llvm.hexagon.S6.rol.i.p.and
- __builtin_HEXAGON_S6_rol_i_p_nac(0, 0, 0);
+ __builtin_HEXAGON_S6_rol_i_p_and(0, 0, 0);
// CHECK: @llvm.hexagon.S6.rol.i.p.nac
- __builtin_HEXAGON_S6_rol_i_p_or(0, 0, 0);
+ __builtin_HEXAGON_S6_rol_i_p_nac(0, 0, 0);
// CHECK: @llvm.hexagon.S6.rol.i.p.or
- __builtin_HEXAGON_S6_rol_i_p_xacc(0, 0, 0);
+ __builtin_HEXAGON_S6_rol_i_p_or(0, 0, 0);
// CHECK: @llvm.hexagon.S6.rol.i.p.xacc
- __builtin_HEXAGON_S6_rol_i_r(0, 0);
+ __builtin_HEXAGON_S6_rol_i_p_xacc(0, 0, 0);
// CHECK: @llvm.hexagon.S6.rol.i.r
- __builtin_HEXAGON_S6_rol_i_r_acc(0, 0, 0);
+ __builtin_HEXAGON_S6_rol_i_r(0, 0);
// CHECK: @llvm.hexagon.S6.rol.i.r.acc
- __builtin_HEXAGON_S6_rol_i_r_and(0, 0, 0);
+ __builtin_HEXAGON_S6_rol_i_r_acc(0, 0, 0);
// CHECK: @llvm.hexagon.S6.rol.i.r.and
- __builtin_HEXAGON_S6_rol_i_r_nac(0, 0, 0);
+ __builtin_HEXAGON_S6_rol_i_r_and(0, 0, 0);
// CHECK: @llvm.hexagon.S6.rol.i.r.nac
- __builtin_HEXAGON_S6_rol_i_r_or(0, 0, 0);
+ __builtin_HEXAGON_S6_rol_i_r_nac(0, 0, 0);
// CHECK: @llvm.hexagon.S6.rol.i.r.or
- __builtin_HEXAGON_S6_rol_i_r_xacc(0, 0, 0);
+ __builtin_HEXAGON_S6_rol_i_r_or(0, 0, 0);
// CHECK: @llvm.hexagon.S6.rol.i.r.xacc
- __builtin_HEXAGON_V6_extractw_128B(v32, 0);
- // CHECK: @llvm.hexagon.V6.extractw.128B
- __builtin_HEXAGON_V6_extractw(v16, 0);
+ __builtin_HEXAGON_S6_rol_i_r_xacc(0, 0, 0);
+ // CHECK: @llvm.hexagon.S6.vsplatrbp
+ __builtin_HEXAGON_S6_vsplatrbp(0);
+ // CHECK: @llvm.hexagon.S6.vtrunehb.ppp
+ __builtin_HEXAGON_S6_vtrunehb_ppp(0, 0);
+ // CHECK: @llvm.hexagon.S6.vtrunohb.ppp
+ __builtin_HEXAGON_S6_vtrunohb_ppp(0, 0);
// CHECK: @llvm.hexagon.V6.extractw
- __builtin_HEXAGON_V6_hi_128B(v64);
- // CHECK: @llvm.hexagon.V6.hi.128B
- __builtin_HEXAGON_V6_hi(v32);
+ __builtin_HEXAGON_V6_extractw(v64, 0);
+ // CHECK: @llvm.hexagon.V6.extractw.128B
+ __builtin_HEXAGON_V6_extractw_128B(v128, 0);
// CHECK: @llvm.hexagon.V6.hi
- __builtin_HEXAGON_V6_lo_128B(v64);
- // CHECK: @llvm.hexagon.V6.lo.128B
- __builtin_HEXAGON_V6_lo(v32);
+ __builtin_HEXAGON_V6_hi(v128);
+ // CHECK: @llvm.hexagon.V6.hi.128B
+ __builtin_HEXAGON_V6_hi_128B(v256);
// CHECK: @llvm.hexagon.V6.lo
- __builtin_HEXAGON_V6_lvsplatw(0);
+ __builtin_HEXAGON_V6_lo(v128);
+ // CHECK: @llvm.hexagon.V6.lo.128B
+ __builtin_HEXAGON_V6_lo_128B(v256);
+ // CHECK: @llvm.hexagon.V6.lvsplatb
+ __builtin_HEXAGON_V6_lvsplatb(0);
+ // CHECK: @llvm.hexagon.V6.lvsplatb.128B
+ __builtin_HEXAGON_V6_lvsplatb_128B(0);
+ // CHECK: @llvm.hexagon.V6.lvsplath
+ __builtin_HEXAGON_V6_lvsplath(0);
+ // CHECK: @llvm.hexagon.V6.lvsplath.128B
+ __builtin_HEXAGON_V6_lvsplath_128B(0);
// CHECK: @llvm.hexagon.V6.lvsplatw
- __builtin_HEXAGON_V6_lvsplatw_128B(0);
+ __builtin_HEXAGON_V6_lvsplatw(0);
// CHECK: @llvm.hexagon.V6.lvsplatw.128B
- __builtin_HEXAGON_V6_pred_and_128B(v32, v32);
+ __builtin_HEXAGON_V6_lvsplatw_128B(0);
+ // CHECK: @llvm.hexagon.V6.pred.and
+ __builtin_HEXAGON_V6_pred_and(v64, v64);
// CHECK: @llvm.hexagon.V6.pred.and.128B
- __builtin_HEXAGON_V6_pred_and_n_128B(v32, v32);
- // CHECK: @llvm.hexagon.V6.pred.and.n.128B
- __builtin_HEXAGON_V6_pred_and_n(v16, v16);
+ __builtin_HEXAGON_V6_pred_and_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.pred.and.n
- __builtin_HEXAGON_V6_pred_and(v16, v16);
- // CHECK: @llvm.hexagon.V6.pred.and
- __builtin_HEXAGON_V6_pred_not_128B(v32);
- // CHECK: @llvm.hexagon.V6.pred.not.128B
- __builtin_HEXAGON_V6_pred_not(v16);
+ __builtin_HEXAGON_V6_pred_and_n(v64, v64);
+ // CHECK: @llvm.hexagon.V6.pred.and.n.128B
+ __builtin_HEXAGON_V6_pred_and_n_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.pred.not
- __builtin_HEXAGON_V6_pred_or_128B(v32, v32);
+ __builtin_HEXAGON_V6_pred_not(v64);
+ // CHECK: @llvm.hexagon.V6.pred.not.128B
+ __builtin_HEXAGON_V6_pred_not_128B(v128);
+ // CHECK: @llvm.hexagon.V6.pred.or
+ __builtin_HEXAGON_V6_pred_or(v64, v64);
// CHECK: @llvm.hexagon.V6.pred.or.128B
- __builtin_HEXAGON_V6_pred_or_n_128B(v32, v32);
- // CHECK: @llvm.hexagon.V6.pred.or.n.128B
- __builtin_HEXAGON_V6_pred_or_n(v16, v16);
+ __builtin_HEXAGON_V6_pred_or_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.pred.or.n
- __builtin_HEXAGON_V6_pred_or(v16, v16);
- // CHECK: @llvm.hexagon.V6.pred.or
- __builtin_HEXAGON_V6_pred_scalar2(0);
+ __builtin_HEXAGON_V6_pred_or_n(v64, v64);
+ // CHECK: @llvm.hexagon.V6.pred.or.n.128B
+ __builtin_HEXAGON_V6_pred_or_n_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.pred.scalar2
- __builtin_HEXAGON_V6_pred_scalar2_128B(0);
+ __builtin_HEXAGON_V6_pred_scalar2(0);
// CHECK: @llvm.hexagon.V6.pred.scalar2.128B
- __builtin_HEXAGON_V6_pred_xor_128B(v32, v32);
- // CHECK: @llvm.hexagon.V6.pred.xor.128B
- __builtin_HEXAGON_V6_pred_xor(v16, v16);
+ __builtin_HEXAGON_V6_pred_scalar2_128B(0);
+ // CHECK: @llvm.hexagon.V6.pred.scalar2v2
+ __builtin_HEXAGON_V6_pred_scalar2v2(0);
+ // CHECK: @llvm.hexagon.V6.pred.scalar2v2.128B
+ __builtin_HEXAGON_V6_pred_scalar2v2_128B(0);
// CHECK: @llvm.hexagon.V6.pred.xor
- __builtin_HEXAGON_V6_vabsdiffh_128B(v32, v32);
- // CHECK: @llvm.hexagon.V6.vabsdiffh.128B
- __builtin_HEXAGON_V6_vabsdiffh(v16, v16);
+ __builtin_HEXAGON_V6_pred_xor(v64, v64);
+ // CHECK: @llvm.hexagon.V6.pred.xor.128B
+ __builtin_HEXAGON_V6_pred_xor_128B(v128, v128);
+ // CHECK: @llvm.hexagon.V6.shuffeqh
+ __builtin_HEXAGON_V6_shuffeqh(v64, v64);
+ // CHECK: @llvm.hexagon.V6.shuffeqh.128B
+ __builtin_HEXAGON_V6_shuffeqh_128B(v128, v128);
+ // CHECK: @llvm.hexagon.V6.shuffeqw
+ __builtin_HEXAGON_V6_shuffeqw(v64, v64);
+ // CHECK: @llvm.hexagon.V6.shuffeqw.128B
+ __builtin_HEXAGON_V6_shuffeqw_128B(v128, v128);
+ // CHECK: @llvm.hexagon.V6.vS32b.nqpred.ai
+ __builtin_HEXAGON_V6_vS32b_nqpred_ai(v64, 0, v64);
+ // CHECK: @llvm.hexagon.V6.vS32b.nqpred.ai.128B
+ __builtin_HEXAGON_V6_vS32b_nqpred_ai_128B(v128, 0, v128);
+ // CHECK: @llvm.hexagon.V6.vS32b.nt.nqpred.ai
+ __builtin_HEXAGON_V6_vS32b_nt_nqpred_ai(v64, 0, v64);
+ // CHECK: @llvm.hexagon.V6.vS32b.nt.nqpred.ai.128B
+ __builtin_HEXAGON_V6_vS32b_nt_nqpred_ai_128B(v128, 0, v128);
+ // CHECK: @llvm.hexagon.V6.vS32b.nt.qpred.ai
+ __builtin_HEXAGON_V6_vS32b_nt_qpred_ai(v64, 0, v64);
+ // CHECK: @llvm.hexagon.V6.vS32b.nt.qpred.ai.128B
+ __builtin_HEXAGON_V6_vS32b_nt_qpred_ai_128B(v128, 0, v128);
+ // CHECK: @llvm.hexagon.V6.vS32b.qpred.ai
+ __builtin_HEXAGON_V6_vS32b_qpred_ai(v64, 0, v64);
+ // CHECK: @llvm.hexagon.V6.vS32b.qpred.ai.128B
+ __builtin_HEXAGON_V6_vS32b_qpred_ai_128B(v128, 0, v128);
+ // CHECK: @llvm.hexagon.V6.vabsb
+ __builtin_HEXAGON_V6_vabsb(v64);
+ // CHECK: @llvm.hexagon.V6.vabsb.128B
+ __builtin_HEXAGON_V6_vabsb_128B(v128);
+ // CHECK: @llvm.hexagon.V6.vabsb.sat
+ __builtin_HEXAGON_V6_vabsb_sat(v64);
+ // CHECK: @llvm.hexagon.V6.vabsb.sat.128B
+ __builtin_HEXAGON_V6_vabsb_sat_128B(v128);
// CHECK: @llvm.hexagon.V6.vabsdiffh
- __builtin_HEXAGON_V6_vabsdiffub_128B(v32, v32);
- // CHECK: @llvm.hexagon.V6.vabsdiffub.128B
- __builtin_HEXAGON_V6_vabsdiffub(v16, v16);
+ __builtin_HEXAGON_V6_vabsdiffh(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vabsdiffh.128B
+ __builtin_HEXAGON_V6_vabsdiffh_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vabsdiffub
- __builtin_HEXAGON_V6_vabsdiffuh_128B(v32, v32);
- // CHECK: @llvm.hexagon.V6.vabsdiffuh.128B
- __builtin_HEXAGON_V6_vabsdiffuh(v16, v16);
+ __builtin_HEXAGON_V6_vabsdiffub(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vabsdiffub.128B
+ __builtin_HEXAGON_V6_vabsdiffub_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vabsdiffuh
- __builtin_HEXAGON_V6_vabsdiffw_128B(v32, v32);
- // CHECK: @llvm.hexagon.V6.vabsdiffw.128B
- __builtin_HEXAGON_V6_vabsdiffw(v16, v16);
+ __builtin_HEXAGON_V6_vabsdiffuh(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vabsdiffuh.128B
+ __builtin_HEXAGON_V6_vabsdiffuh_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vabsdiffw
- __builtin_HEXAGON_V6_vabsh_128B(v32);
+ __builtin_HEXAGON_V6_vabsdiffw(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vabsdiffw.128B
+ __builtin_HEXAGON_V6_vabsdiffw_128B(v128, v128);
+ // CHECK: @llvm.hexagon.V6.vabsh
+ __builtin_HEXAGON_V6_vabsh(v64);
// CHECK: @llvm.hexagon.V6.vabsh.128B
- __builtin_HEXAGON_V6_vabsh_sat_128B(v32);
- // CHECK: @llvm.hexagon.V6.vabsh.sat.128B
- __builtin_HEXAGON_V6_vabsh_sat(v16);
+ __builtin_HEXAGON_V6_vabsh_128B(v128);
// CHECK: @llvm.hexagon.V6.vabsh.sat
- __builtin_HEXAGON_V6_vabsh(v16);
- // CHECK: @llvm.hexagon.V6.vabsh
- __builtin_HEXAGON_V6_vabsw_128B(v32);
+ __builtin_HEXAGON_V6_vabsh_sat(v64);
+ // CHECK: @llvm.hexagon.V6.vabsh.sat.128B
+ __builtin_HEXAGON_V6_vabsh_sat_128B(v128);
+ // CHECK: @llvm.hexagon.V6.vabsw
+ __builtin_HEXAGON_V6_vabsw(v64);
// CHECK: @llvm.hexagon.V6.vabsw.128B
- __builtin_HEXAGON_V6_vabsw_sat_128B(v32);
- // CHECK: @llvm.hexagon.V6.vabsw.sat.128B
- __builtin_HEXAGON_V6_vabsw_sat(v16);
+ __builtin_HEXAGON_V6_vabsw_128B(v128);
// CHECK: @llvm.hexagon.V6.vabsw.sat
- __builtin_HEXAGON_V6_vabsw(v16);
- // CHECK: @llvm.hexagon.V6.vabsw
- __builtin_HEXAGON_V6_vaddb_128B(v32, v32);
+ __builtin_HEXAGON_V6_vabsw_sat(v64);
+ // CHECK: @llvm.hexagon.V6.vabsw.sat.128B
+ __builtin_HEXAGON_V6_vabsw_sat_128B(v128);
+ // CHECK: @llvm.hexagon.V6.vaddb
+ __builtin_HEXAGON_V6_vaddb(v64, v64);
// CHECK: @llvm.hexagon.V6.vaddb.128B
- __builtin_HEXAGON_V6_vaddb_dv_128B(v64, v64);
- // CHECK: @llvm.hexagon.V6.vaddb.dv.128B
- __builtin_HEXAGON_V6_vaddb_dv(v32, v32);
+ __builtin_HEXAGON_V6_vaddb_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vaddb.dv
- __builtin_HEXAGON_V6_vaddbnq_128B(v32, v32, v32);
- // CHECK: @llvm.hexagon.V6.vaddbnq.128B
- __builtin_HEXAGON_V6_vaddbnq(v16, v16, v16);
+ __builtin_HEXAGON_V6_vaddb_dv(v128, v128);
+ // CHECK: @llvm.hexagon.V6.vaddb.dv.128B
+ __builtin_HEXAGON_V6_vaddb_dv_128B(v256, v256);
// CHECK: @llvm.hexagon.V6.vaddbnq
- __builtin_HEXAGON_V6_vaddbq_128B(v32, v32, v32);
- // CHECK: @llvm.hexagon.V6.vaddbq.128B
- __builtin_HEXAGON_V6_vaddbq(v16, v16, v16);
+ __builtin_HEXAGON_V6_vaddbnq(v64, v64, v64);
+ // CHECK: @llvm.hexagon.V6.vaddbnq.128B
+ __builtin_HEXAGON_V6_vaddbnq_128B(v128, v128, v128);
// CHECK: @llvm.hexagon.V6.vaddbq
- __builtin_HEXAGON_V6_vaddb(v16, v16);
- // CHECK: @llvm.hexagon.V6.vaddb
- __builtin_HEXAGON_V6_vaddh_128B(v32, v32);
+ __builtin_HEXAGON_V6_vaddbq(v64, v64, v64);
+ // CHECK: @llvm.hexagon.V6.vaddbq.128B
+ __builtin_HEXAGON_V6_vaddbq_128B(v128, v128, v128);
+ // CHECK: @llvm.hexagon.V6.vaddbsat
+ __builtin_HEXAGON_V6_vaddbsat(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vaddbsat.128B
+ __builtin_HEXAGON_V6_vaddbsat_128B(v128, v128);
+ // CHECK: @llvm.hexagon.V6.vaddbsat.dv
+ __builtin_HEXAGON_V6_vaddbsat_dv(v128, v128);
+ // CHECK: @llvm.hexagon.V6.vaddbsat.dv.128B
+ __builtin_HEXAGON_V6_vaddbsat_dv_128B(v256, v256);
+ // CHECK: @llvm.hexagon.V6.vaddcarry
+ __builtin_HEXAGON_V6_vaddcarry(v64, v64, 0);
+ // CHECK: @llvm.hexagon.V6.vaddcarry.128B
+ __builtin_HEXAGON_V6_vaddcarry_128B(v128, v128, 0);
+ // CHECK: @llvm.hexagon.V6.vaddclbh
+ __builtin_HEXAGON_V6_vaddclbh(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vaddclbh.128B
+ __builtin_HEXAGON_V6_vaddclbh_128B(v128, v128);
+ // CHECK: @llvm.hexagon.V6.vaddclbw
+ __builtin_HEXAGON_V6_vaddclbw(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vaddclbw.128B
+ __builtin_HEXAGON_V6_vaddclbw_128B(v128, v128);
+ // CHECK: @llvm.hexagon.V6.vaddh
+ __builtin_HEXAGON_V6_vaddh(v64, v64);
// CHECK: @llvm.hexagon.V6.vaddh.128B
- __builtin_HEXAGON_V6_vaddh_dv_128B(v64, v64);
- // CHECK: @llvm.hexagon.V6.vaddh.dv.128B
- __builtin_HEXAGON_V6_vaddh_dv(v32, v32);
+ __builtin_HEXAGON_V6_vaddh_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vaddh.dv
- __builtin_HEXAGON_V6_vaddhnq_128B(v32, v32, v32);
- // CHECK: @llvm.hexagon.V6.vaddhnq.128B
- __builtin_HEXAGON_V6_vaddhnq(v16, v16, v16);
+ __builtin_HEXAGON_V6_vaddh_dv(v128, v128);
+ // CHECK: @llvm.hexagon.V6.vaddh.dv.128B
+ __builtin_HEXAGON_V6_vaddh_dv_128B(v256, v256);
// CHECK: @llvm.hexagon.V6.vaddhnq
- __builtin_HEXAGON_V6_vaddhq_128B(v32, v32, v32);
- // CHECK: @llvm.hexagon.V6.vaddhq.128B
- __builtin_HEXAGON_V6_vaddhq(v16, v16, v16);
+ __builtin_HEXAGON_V6_vaddhnq(v64, v64, v64);
+ // CHECK: @llvm.hexagon.V6.vaddhnq.128B
+ __builtin_HEXAGON_V6_vaddhnq_128B(v128, v128, v128);
// CHECK: @llvm.hexagon.V6.vaddhq
- __builtin_HEXAGON_V6_vaddhsat_128B(v32, v32);
+ __builtin_HEXAGON_V6_vaddhq(v64, v64, v64);
+ // CHECK: @llvm.hexagon.V6.vaddhq.128B
+ __builtin_HEXAGON_V6_vaddhq_128B(v128, v128, v128);
+ // CHECK: @llvm.hexagon.V6.vaddhsat
+ __builtin_HEXAGON_V6_vaddhsat(v64, v64);
// CHECK: @llvm.hexagon.V6.vaddhsat.128B
- __builtin_HEXAGON_V6_vaddhsat_dv_128B(v64, v64);
- // CHECK: @llvm.hexagon.V6.vaddhsat.dv.128B
- __builtin_HEXAGON_V6_vaddhsat_dv(v32, v32);
+ __builtin_HEXAGON_V6_vaddhsat_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vaddhsat.dv
- __builtin_HEXAGON_V6_vaddhsat(v16, v16);
- // CHECK: @llvm.hexagon.V6.vaddhsat
- __builtin_HEXAGON_V6_vaddh(v16, v16);
- // CHECK: @llvm.hexagon.V6.vaddh
- __builtin_HEXAGON_V6_vaddhw_128B(v32, v32);
- // CHECK: @llvm.hexagon.V6.vaddhw.128B
- __builtin_HEXAGON_V6_vaddhw(v16, v16);
+ __builtin_HEXAGON_V6_vaddhsat_dv(v128, v128);
+ // CHECK: @llvm.hexagon.V6.vaddhsat.dv.128B
+ __builtin_HEXAGON_V6_vaddhsat_dv_128B(v256, v256);
// CHECK: @llvm.hexagon.V6.vaddhw
- __builtin_HEXAGON_V6_vaddubh_128B(v32, v32);
- // CHECK: @llvm.hexagon.V6.vaddubh.128B
- __builtin_HEXAGON_V6_vaddubh(v16, v16);
+ __builtin_HEXAGON_V6_vaddhw(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vaddhw.128B
+ __builtin_HEXAGON_V6_vaddhw_128B(v128, v128);
+ // CHECK: @llvm.hexagon.V6.vaddhw.acc
+ __builtin_HEXAGON_V6_vaddhw_acc(v128, v64, v64);
+ // CHECK: @llvm.hexagon.V6.vaddhw.acc.128B
+ __builtin_HEXAGON_V6_vaddhw_acc_128B(v256, v128, v128);
// CHECK: @llvm.hexagon.V6.vaddubh
- __builtin_HEXAGON_V6_vaddubsat_128B(v32, v32);
+ __builtin_HEXAGON_V6_vaddubh(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vaddubh.128B
+ __builtin_HEXAGON_V6_vaddubh_128B(v128, v128);
+ // CHECK: @llvm.hexagon.V6.vaddubh.acc
+ __builtin_HEXAGON_V6_vaddubh_acc(v128, v64, v64);
+ // CHECK: @llvm.hexagon.V6.vaddubh.acc.128B
+ __builtin_HEXAGON_V6_vaddubh_acc_128B(v256, v128, v128);
+ // CHECK: @llvm.hexagon.V6.vaddubsat
+ __builtin_HEXAGON_V6_vaddubsat(v64, v64);
// CHECK: @llvm.hexagon.V6.vaddubsat.128B
- __builtin_HEXAGON_V6_vaddubsat_dv_128B(v64, v64);
- // CHECK: @llvm.hexagon.V6.vaddubsat.dv.128B
- __builtin_HEXAGON_V6_vaddubsat_dv(v32, v32);
+ __builtin_HEXAGON_V6_vaddubsat_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vaddubsat.dv
- __builtin_HEXAGON_V6_vaddubsat(v16, v16);
- // CHECK: @llvm.hexagon.V6.vaddubsat
- __builtin_HEXAGON_V6_vadduhsat_128B(v32, v32);
+ __builtin_HEXAGON_V6_vaddubsat_dv(v128, v128);
+ // CHECK: @llvm.hexagon.V6.vaddubsat.dv.128B
+ __builtin_HEXAGON_V6_vaddubsat_dv_128B(v256, v256);
+ // CHECK: @llvm.hexagon.V6.vaddububb.sat
+ __builtin_HEXAGON_V6_vaddububb_sat(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vaddububb.sat.128B
+ __builtin_HEXAGON_V6_vaddububb_sat_128B(v128, v128);
+ // CHECK: @llvm.hexagon.V6.vadduhsat
+ __builtin_HEXAGON_V6_vadduhsat(v64, v64);
// CHECK: @llvm.hexagon.V6.vadduhsat.128B
- __builtin_HEXAGON_V6_vadduhsat_dv_128B(v64, v64);
- // CHECK: @llvm.hexagon.V6.vadduhsat.dv.128B
- __builtin_HEXAGON_V6_vadduhsat_dv(v32, v32);
+ __builtin_HEXAGON_V6_vadduhsat_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vadduhsat.dv
- __builtin_HEXAGON_V6_vadduhsat(v16, v16);
- // CHECK: @llvm.hexagon.V6.vadduhsat
- __builtin_HEXAGON_V6_vadduhw_128B(v32, v32);
- // CHECK: @llvm.hexagon.V6.vadduhw.128B
- __builtin_HEXAGON_V6_vadduhw(v16, v16);
+ __builtin_HEXAGON_V6_vadduhsat_dv(v128, v128);
+ // CHECK: @llvm.hexagon.V6.vadduhsat.dv.128B
+ __builtin_HEXAGON_V6_vadduhsat_dv_128B(v256, v256);
// CHECK: @llvm.hexagon.V6.vadduhw
- __builtin_HEXAGON_V6_vaddw_128B(v32, v32);
+ __builtin_HEXAGON_V6_vadduhw(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vadduhw.128B
+ __builtin_HEXAGON_V6_vadduhw_128B(v128, v128);
+ // CHECK: @llvm.hexagon.V6.vadduhw.acc
+ __builtin_HEXAGON_V6_vadduhw_acc(v128, v64, v64);
+ // CHECK: @llvm.hexagon.V6.vadduhw.acc.128B
+ __builtin_HEXAGON_V6_vadduhw_acc_128B(v256, v128, v128);
+ // CHECK: @llvm.hexagon.V6.vadduwsat
+ __builtin_HEXAGON_V6_vadduwsat(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vadduwsat.128B
+ __builtin_HEXAGON_V6_vadduwsat_128B(v128, v128);
+ // CHECK: @llvm.hexagon.V6.vadduwsat.dv
+ __builtin_HEXAGON_V6_vadduwsat_dv(v128, v128);
+ // CHECK: @llvm.hexagon.V6.vadduwsat.dv.128B
+ __builtin_HEXAGON_V6_vadduwsat_dv_128B(v256, v256);
+ // CHECK: @llvm.hexagon.V6.vaddw
+ __builtin_HEXAGON_V6_vaddw(v64, v64);
// CHECK: @llvm.hexagon.V6.vaddw.128B
- __builtin_HEXAGON_V6_vaddw_dv_128B(v64, v64);
- // CHECK: @llvm.hexagon.V6.vaddw.dv.128B
- __builtin_HEXAGON_V6_vaddw_dv(v32, v32);
+ __builtin_HEXAGON_V6_vaddw_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vaddw.dv
- __builtin_HEXAGON_V6_vaddwnq_128B(v32, v32, v32);
- // CHECK: @llvm.hexagon.V6.vaddwnq.128B
- __builtin_HEXAGON_V6_vaddwnq(v16, v16, v16);
+ __builtin_HEXAGON_V6_vaddw_dv(v128, v128);
+ // CHECK: @llvm.hexagon.V6.vaddw.dv.128B
+ __builtin_HEXAGON_V6_vaddw_dv_128B(v256, v256);
// CHECK: @llvm.hexagon.V6.vaddwnq
- __builtin_HEXAGON_V6_vaddwq_128B(v32, v32, v32);
- // CHECK: @llvm.hexagon.V6.vaddwq.128B
- __builtin_HEXAGON_V6_vaddwq(v16, v16, v16);
+ __builtin_HEXAGON_V6_vaddwnq(v64, v64, v64);
+ // CHECK: @llvm.hexagon.V6.vaddwnq.128B
+ __builtin_HEXAGON_V6_vaddwnq_128B(v128, v128, v128);
// CHECK: @llvm.hexagon.V6.vaddwq
- __builtin_HEXAGON_V6_vaddwsat_128B(v32, v32);
+ __builtin_HEXAGON_V6_vaddwq(v64, v64, v64);
+ // CHECK: @llvm.hexagon.V6.vaddwq.128B
+ __builtin_HEXAGON_V6_vaddwq_128B(v128, v128, v128);
+ // CHECK: @llvm.hexagon.V6.vaddwsat
+ __builtin_HEXAGON_V6_vaddwsat(v64, v64);
// CHECK: @llvm.hexagon.V6.vaddwsat.128B
- __builtin_HEXAGON_V6_vaddwsat_dv_128B(v64, v64);
- // CHECK: @llvm.hexagon.V6.vaddwsat.dv.128B
- __builtin_HEXAGON_V6_vaddwsat_dv(v32, v32);
+ __builtin_HEXAGON_V6_vaddwsat_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vaddwsat.dv
- __builtin_HEXAGON_V6_vaddwsat(v16, v16);
- // CHECK: @llvm.hexagon.V6.vaddwsat
- __builtin_HEXAGON_V6_vaddw(v16, v16);
- // CHECK: @llvm.hexagon.V6.vaddw
- __builtin_HEXAGON_V6_valignb_128B(v32, v32, 0);
+ __builtin_HEXAGON_V6_vaddwsat_dv(v128, v128);
+ // CHECK: @llvm.hexagon.V6.vaddwsat.dv.128B
+ __builtin_HEXAGON_V6_vaddwsat_dv_128B(v256, v256);
+ // CHECK: @llvm.hexagon.V6.valignb
+ __builtin_HEXAGON_V6_valignb(v64, v64, 0);
// CHECK: @llvm.hexagon.V6.valignb.128B
- __builtin_HEXAGON_V6_valignbi_128B(v32, v32, 0);
- // CHECK: @llvm.hexagon.V6.valignbi.128B
- __builtin_HEXAGON_V6_valignbi(v16, v16, 0);
+ __builtin_HEXAGON_V6_valignb_128B(v128, v128, 0);
// CHECK: @llvm.hexagon.V6.valignbi
- __builtin_HEXAGON_V6_valignb(v16, v16, 0);
- // CHECK: @llvm.hexagon.V6.valignb
- __builtin_HEXAGON_V6_vand_128B(v32, v32);
+ __builtin_HEXAGON_V6_valignbi(v64, v64, 0);
+ // CHECK: @llvm.hexagon.V6.valignbi.128B
+ __builtin_HEXAGON_V6_valignbi_128B(v128, v128, 0);
+ // CHECK: @llvm.hexagon.V6.vand
+ __builtin_HEXAGON_V6_vand(v64, v64);
// CHECK: @llvm.hexagon.V6.vand.128B
- __builtin_HEXAGON_V6_vandqrt_128B(v32, 0);
+ __builtin_HEXAGON_V6_vand_128B(v128, v128);
+ // CHECK: @llvm.hexagon.V6.vandnqrt
+ __builtin_HEXAGON_V6_vandnqrt(v64, 0);
+ // CHECK: @llvm.hexagon.V6.vandnqrt.128B
+ __builtin_HEXAGON_V6_vandnqrt_128B(v128, 0);
+ // CHECK: @llvm.hexagon.V6.vandnqrt.acc
+ __builtin_HEXAGON_V6_vandnqrt_acc(v64, v64, 0);
+ // CHECK: @llvm.hexagon.V6.vandnqrt.acc.128B
+ __builtin_HEXAGON_V6_vandnqrt_acc_128B(v128, v128, 0);
+ // CHECK: @llvm.hexagon.V6.vandqrt
+ __builtin_HEXAGON_V6_vandqrt(v64, 0);
// CHECK: @llvm.hexagon.V6.vandqrt.128B
- __builtin_HEXAGON_V6_vandqrt_acc_128B(v32, v32, 0);
- // CHECK: @llvm.hexagon.V6.vandqrt.acc.128B
- __builtin_HEXAGON_V6_vandqrt_acc(v16, v16, 0);
+ __builtin_HEXAGON_V6_vandqrt_128B(v128, 0);
// CHECK: @llvm.hexagon.V6.vandqrt.acc
- __builtin_HEXAGON_V6_vandqrt(v16, 0);
- // CHECK: @llvm.hexagon.V6.vandqrt
- __builtin_HEXAGON_V6_vand(v16, v16);
- // CHECK: @llvm.hexagon.V6.vand
- __builtin_HEXAGON_V6_vandvrt_128B(v32, 0);
+ __builtin_HEXAGON_V6_vandqrt_acc(v64, v64, 0);
+ // CHECK: @llvm.hexagon.V6.vandqrt.acc.128B
+ __builtin_HEXAGON_V6_vandqrt_acc_128B(v128, v128, 0);
+ // CHECK: @llvm.hexagon.V6.vandvnqv
+ __builtin_HEXAGON_V6_vandvnqv(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vandvnqv.128B
+ __builtin_HEXAGON_V6_vandvnqv_128B(v128, v128);
+ // CHECK: @llvm.hexagon.V6.vandvqv
+ __builtin_HEXAGON_V6_vandvqv(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vandvqv.128B
+ __builtin_HEXAGON_V6_vandvqv_128B(v128, v128);
+ // CHECK: @llvm.hexagon.V6.vandvrt
+ __builtin_HEXAGON_V6_vandvrt(v64, 0);
// CHECK: @llvm.hexagon.V6.vandvrt.128B
- __builtin_HEXAGON_V6_vandvrt_acc_128B(v32, v32, 0);
- // CHECK: @llvm.hexagon.V6.vandvrt.acc.128B
- __builtin_HEXAGON_V6_vandvrt_acc(v16, v16, 0);
+ __builtin_HEXAGON_V6_vandvrt_128B(v128, 0);
// CHECK: @llvm.hexagon.V6.vandvrt.acc
- __builtin_HEXAGON_V6_vandvrt(v16, 0);
- // CHECK: @llvm.hexagon.V6.vandvrt
- __builtin_HEXAGON_V6_vaslh_128B(v32, 0);
- // CHECK: @llvm.hexagon.V6.vaslh.128B
- __builtin_HEXAGON_V6_vaslhv_128B(v32, v32);
- // CHECK: @llvm.hexagon.V6.vaslhv.128B
- __builtin_HEXAGON_V6_vaslh(v16, 0);
+ __builtin_HEXAGON_V6_vandvrt_acc(v64, v64, 0);
+ // CHECK: @llvm.hexagon.V6.vandvrt.acc.128B
+ __builtin_HEXAGON_V6_vandvrt_acc_128B(v128, v128, 0);
// CHECK: @llvm.hexagon.V6.vaslh
- __builtin_HEXAGON_V6_vaslhv(v16, v16);
+ __builtin_HEXAGON_V6_vaslh(v64, 0);
+ // CHECK: @llvm.hexagon.V6.vaslh.128B
+ __builtin_HEXAGON_V6_vaslh_128B(v128, 0);
+ // CHECK: @llvm.hexagon.V6.vaslh.acc
+ __builtin_HEXAGON_V6_vaslh_acc(v64, v64, 0);
+ // CHECK: @llvm.hexagon.V6.vaslh.acc.128B
+ __builtin_HEXAGON_V6_vaslh_acc_128B(v128, v128, 0);
// CHECK: @llvm.hexagon.V6.vaslhv
- __builtin_HEXAGON_V6_vaslw_128B(v32, 0);
+ __builtin_HEXAGON_V6_vaslhv(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vaslhv.128B
+ __builtin_HEXAGON_V6_vaslhv_128B(v128, v128);
+ // CHECK: @llvm.hexagon.V6.vaslw
+ __builtin_HEXAGON_V6_vaslw(v64, 0);
// CHECK: @llvm.hexagon.V6.vaslw.128B
- __builtin_HEXAGON_V6_vaslw_acc_128B(v32, v32, 0);
- // CHECK: @llvm.hexagon.V6.vaslw.acc.128B
- __builtin_HEXAGON_V6_vaslw_acc(v16, v16, 0);
+ __builtin_HEXAGON_V6_vaslw_128B(v128, 0);
// CHECK: @llvm.hexagon.V6.vaslw.acc
- __builtin_HEXAGON_V6_vaslwv_128B(v32, v32);
- // CHECK: @llvm.hexagon.V6.vaslwv.128B
- __builtin_HEXAGON_V6_vaslw(v16, 0);
- // CHECK: @llvm.hexagon.V6.vaslw
- __builtin_HEXAGON_V6_vaslwv(v16, v16);
+ __builtin_HEXAGON_V6_vaslw_acc(v64, v64, 0);
+ // CHECK: @llvm.hexagon.V6.vaslw.acc.128B
+ __builtin_HEXAGON_V6_vaslw_acc_128B(v128, v128, 0);
// CHECK: @llvm.hexagon.V6.vaslwv
- __builtin_HEXAGON_V6_vasrh_128B(v32, 0);
+ __builtin_HEXAGON_V6_vaslwv(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vaslwv.128B
+ __builtin_HEXAGON_V6_vaslwv_128B(v128, v128);
+ // CHECK: @llvm.hexagon.V6.vasrh
+ __builtin_HEXAGON_V6_vasrh(v64, 0);
// CHECK: @llvm.hexagon.V6.vasrh.128B
- __builtin_HEXAGON_V6_vasrhbrndsat_128B(v32, v32, 0);
- // CHECK: @llvm.hexagon.V6.vasrhbrndsat.128B
- __builtin_HEXAGON_V6_vasrhbrndsat(v16, v16, 0);
+ __builtin_HEXAGON_V6_vasrh_128B(v128, 0);
+ // CHECK: @llvm.hexagon.V6.vasrh.acc
+ __builtin_HEXAGON_V6_vasrh_acc(v64, v64, 0);
+ // CHECK: @llvm.hexagon.V6.vasrh.acc.128B
+ __builtin_HEXAGON_V6_vasrh_acc_128B(v128, v128, 0);
// CHECK: @llvm.hexagon.V6.vasrhbrndsat
- __builtin_HEXAGON_V6_vasrhubrndsat_128B(v32, v32, 0);
- // CHECK: @llvm.hexagon.V6.vasrhubrndsat.128B
- __builtin_HEXAGON_V6_vasrhubrndsat(v16, v16, 0);
+ __builtin_HEXAGON_V6_vasrhbrndsat(v64, v64, 0);
+ // CHECK: @llvm.hexagon.V6.vasrhbrndsat.128B
+ __builtin_HEXAGON_V6_vasrhbrndsat_128B(v128, v128, 0);
+ // CHECK: @llvm.hexagon.V6.vasrhbsat
+ __builtin_HEXAGON_V6_vasrhbsat(v64, v64, 0);
+ // CHECK: @llvm.hexagon.V6.vasrhbsat.128B
+ __builtin_HEXAGON_V6_vasrhbsat_128B(v128, v128, 0);
// CHECK: @llvm.hexagon.V6.vasrhubrndsat
- __builtin_HEXAGON_V6_vasrhubsat_128B(v32, v32, 0);
- // CHECK: @llvm.hexagon.V6.vasrhubsat.128B
- __builtin_HEXAGON_V6_vasrhubsat(v16, v16, 0);
+ __builtin_HEXAGON_V6_vasrhubrndsat(v64, v64, 0);
+ // CHECK: @llvm.hexagon.V6.vasrhubrndsat.128B
+ __builtin_HEXAGON_V6_vasrhubrndsat_128B(v128, v128, 0);
// CHECK: @llvm.hexagon.V6.vasrhubsat
- __builtin_HEXAGON_V6_vasrhv_128B(v32, v32);
- // CHECK: @llvm.hexagon.V6.vasrhv.128B
- __builtin_HEXAGON_V6_vasrh(v16, 0);
- // CHECK: @llvm.hexagon.V6.vasrh
- __builtin_HEXAGON_V6_vasrhv(v16, v16);
+ __builtin_HEXAGON_V6_vasrhubsat(v64, v64, 0);
+ // CHECK: @llvm.hexagon.V6.vasrhubsat.128B
+ __builtin_HEXAGON_V6_vasrhubsat_128B(v128, v128, 0);
// CHECK: @llvm.hexagon.V6.vasrhv
- __builtin_HEXAGON_V6_vasrw_128B(v32, 0);
+ __builtin_HEXAGON_V6_vasrhv(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vasrhv.128B
+ __builtin_HEXAGON_V6_vasrhv_128B(v128, v128);
+ // CHECK: @llvm.hexagon.V6.vasruhubrndsat
+ __builtin_HEXAGON_V6_vasruhubrndsat(v64, v64, 0);
+ // CHECK: @llvm.hexagon.V6.vasruhubrndsat.128B
+ __builtin_HEXAGON_V6_vasruhubrndsat_128B(v128, v128, 0);
+ // CHECK: @llvm.hexagon.V6.vasruhubsat
+ __builtin_HEXAGON_V6_vasruhubsat(v64, v64, 0);
+ // CHECK: @llvm.hexagon.V6.vasruhubsat.128B
+ __builtin_HEXAGON_V6_vasruhubsat_128B(v128, v128, 0);
+ // CHECK: @llvm.hexagon.V6.vasruwuhrndsat
+ __builtin_HEXAGON_V6_vasruwuhrndsat(v64, v64, 0);
+ // CHECK: @llvm.hexagon.V6.vasruwuhrndsat.128B
+ __builtin_HEXAGON_V6_vasruwuhrndsat_128B(v128, v128, 0);
+ // CHECK: @llvm.hexagon.V6.vasruwuhsat
+ __builtin_HEXAGON_V6_vasruwuhsat(v64, v64, 0);
+ // CHECK: @llvm.hexagon.V6.vasruwuhsat.128B
+ __builtin_HEXAGON_V6_vasruwuhsat_128B(v128, v128, 0);
+ // CHECK: @llvm.hexagon.V6.vasrw
+ __builtin_HEXAGON_V6_vasrw(v64, 0);
// CHECK: @llvm.hexagon.V6.vasrw.128B
- __builtin_HEXAGON_V6_vasrw_acc_128B(v32, v32, 0);
- // CHECK: @llvm.hexagon.V6.vasrw.acc.128B
- __builtin_HEXAGON_V6_vasrw_acc(v16, v16, 0);
+ __builtin_HEXAGON_V6_vasrw_128B(v128, 0);
// CHECK: @llvm.hexagon.V6.vasrw.acc
- __builtin_HEXAGON_V6_vasrwh_128B(v32, v32, 0);
+ __builtin_HEXAGON_V6_vasrw_acc(v64, v64, 0);
+ // CHECK: @llvm.hexagon.V6.vasrw.acc.128B
+ __builtin_HEXAGON_V6_vasrw_acc_128B(v128, v128, 0);
+ // CHECK: @llvm.hexagon.V6.vasrwh
+ __builtin_HEXAGON_V6_vasrwh(v64, v64, 0);
// CHECK: @llvm.hexagon.V6.vasrwh.128B
- __builtin_HEXAGON_V6_vasrwhrndsat_128B(v32, v32, 0);
- // CHECK: @llvm.hexagon.V6.vasrwhrndsat.128B
- __builtin_HEXAGON_V6_vasrwhrndsat(v16, v16, 0);
+ __builtin_HEXAGON_V6_vasrwh_128B(v128, v128, 0);
// CHECK: @llvm.hexagon.V6.vasrwhrndsat
- __builtin_HEXAGON_V6_vasrwhsat_128B(v32, v32, 0);
- // CHECK: @llvm.hexagon.V6.vasrwhsat.128B
- __builtin_HEXAGON_V6_vasrwhsat(v16, v16, 0);
+ __builtin_HEXAGON_V6_vasrwhrndsat(v64, v64, 0);
+ // CHECK: @llvm.hexagon.V6.vasrwhrndsat.128B
+ __builtin_HEXAGON_V6_vasrwhrndsat_128B(v128, v128, 0);
// CHECK: @llvm.hexagon.V6.vasrwhsat
- __builtin_HEXAGON_V6_vasrwh(v16, v16, 0);
- // CHECK: @llvm.hexagon.V6.vasrwh
- __builtin_HEXAGON_V6_vasrwuhsat_128B(v32, v32, 0);
- // CHECK: @llvm.hexagon.V6.vasrwuhsat.128B
- __builtin_HEXAGON_V6_vasrwuhsat(v16, v16, 0);
+ __builtin_HEXAGON_V6_vasrwhsat(v64, v64, 0);
+ // CHECK: @llvm.hexagon.V6.vasrwhsat.128B
+ __builtin_HEXAGON_V6_vasrwhsat_128B(v128, v128, 0);
+ // CHECK: @llvm.hexagon.V6.vasrwuhrndsat
+ __builtin_HEXAGON_V6_vasrwuhrndsat(v64, v64, 0);
+ // CHECK: @llvm.hexagon.V6.vasrwuhrndsat.128B
+ __builtin_HEXAGON_V6_vasrwuhrndsat_128B(v128, v128, 0);
// CHECK: @llvm.hexagon.V6.vasrwuhsat
- __builtin_HEXAGON_V6_vasrwv_128B(v32, v32);
- // CHECK: @llvm.hexagon.V6.vasrwv.128B
- __builtin_HEXAGON_V6_vasrw(v16, 0);
- // CHECK: @llvm.hexagon.V6.vasrw
- __builtin_HEXAGON_V6_vasrwv(v16, v16);
+ __builtin_HEXAGON_V6_vasrwuhsat(v64, v64, 0);
+ // CHECK: @llvm.hexagon.V6.vasrwuhsat.128B
+ __builtin_HEXAGON_V6_vasrwuhsat_128B(v128, v128, 0);
// CHECK: @llvm.hexagon.V6.vasrwv
- __builtin_HEXAGON_V6_vassign_128B(v32);
+ __builtin_HEXAGON_V6_vasrwv(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vasrwv.128B
+ __builtin_HEXAGON_V6_vasrwv_128B(v128, v128);
+ // CHECK: @llvm.hexagon.V6.vassign
+ __builtin_HEXAGON_V6_vassign(v64);
// CHECK: @llvm.hexagon.V6.vassign.128B
- __builtin_HEXAGON_V6_vassignp_128B(v64);
- // CHECK: @llvm.hexagon.V6.vassignp.128B
- __builtin_HEXAGON_V6_vassignp(v32);
+ __builtin_HEXAGON_V6_vassign_128B(v128);
// CHECK: @llvm.hexagon.V6.vassignp
- __builtin_HEXAGON_V6_vassign(v16);
- // CHECK: @llvm.hexagon.V6.vassign
- __builtin_HEXAGON_V6_vavgh_128B(v32, v32);
+ __builtin_HEXAGON_V6_vassignp(v128);
+ // CHECK: @llvm.hexagon.V6.vassignp.128B
+ __builtin_HEXAGON_V6_vassignp_128B(v256);
+ // CHECK: @llvm.hexagon.V6.vavgb
+ __builtin_HEXAGON_V6_vavgb(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vavgb.128B
+ __builtin_HEXAGON_V6_vavgb_128B(v128, v128);
+ // CHECK: @llvm.hexagon.V6.vavgbrnd
+ __builtin_HEXAGON_V6_vavgbrnd(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vavgbrnd.128B
+ __builtin_HEXAGON_V6_vavgbrnd_128B(v128, v128);
+ // CHECK: @llvm.hexagon.V6.vavgh
+ __builtin_HEXAGON_V6_vavgh(v64, v64);
// CHECK: @llvm.hexagon.V6.vavgh.128B
- __builtin_HEXAGON_V6_vavghrnd_128B(v32, v32);
- // CHECK: @llvm.hexagon.V6.vavghrnd.128B
- __builtin_HEXAGON_V6_vavghrnd(v16, v16);
+ __builtin_HEXAGON_V6_vavgh_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vavghrnd
- __builtin_HEXAGON_V6_vavgh(v16, v16);
- // CHECK: @llvm.hexagon.V6.vavgh
- __builtin_HEXAGON_V6_vavgub_128B(v32, v32);
+ __builtin_HEXAGON_V6_vavghrnd(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vavghrnd.128B
+ __builtin_HEXAGON_V6_vavghrnd_128B(v128, v128);
+ // CHECK: @llvm.hexagon.V6.vavgub
+ __builtin_HEXAGON_V6_vavgub(v64, v64);
// CHECK: @llvm.hexagon.V6.vavgub.128B
- __builtin_HEXAGON_V6_vavgubrnd_128B(v32, v32);
- // CHECK: @llvm.hexagon.V6.vavgubrnd.128B
- __builtin_HEXAGON_V6_vavgubrnd(v16, v16);
+ __builtin_HEXAGON_V6_vavgub_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vavgubrnd
- __builtin_HEXAGON_V6_vavgub(v16, v16);
- // CHECK: @llvm.hexagon.V6.vavgub
- __builtin_HEXAGON_V6_vavguh_128B(v32, v32);
+ __builtin_HEXAGON_V6_vavgubrnd(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vavgubrnd.128B
+ __builtin_HEXAGON_V6_vavgubrnd_128B(v128, v128);
+ // CHECK: @llvm.hexagon.V6.vavguh
+ __builtin_HEXAGON_V6_vavguh(v64, v64);
// CHECK: @llvm.hexagon.V6.vavguh.128B
- __builtin_HEXAGON_V6_vavguhrnd_128B(v32, v32);
- // CHECK: @llvm.hexagon.V6.vavguhrnd.128B
- __builtin_HEXAGON_V6_vavguhrnd(v16, v16);
+ __builtin_HEXAGON_V6_vavguh_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vavguhrnd
- __builtin_HEXAGON_V6_vavguh(v16, v16);
- // CHECK: @llvm.hexagon.V6.vavguh
- __builtin_HEXAGON_V6_vavgw_128B(v32, v32);
+ __builtin_HEXAGON_V6_vavguhrnd(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vavguhrnd.128B
+ __builtin_HEXAGON_V6_vavguhrnd_128B(v128, v128);
+ // CHECK: @llvm.hexagon.V6.vavguw
+ __builtin_HEXAGON_V6_vavguw(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vavguw.128B
+ __builtin_HEXAGON_V6_vavguw_128B(v128, v128);
+ // CHECK: @llvm.hexagon.V6.vavguwrnd
+ __builtin_HEXAGON_V6_vavguwrnd(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vavguwrnd.128B
+ __builtin_HEXAGON_V6_vavguwrnd_128B(v128, v128);
+ // CHECK: @llvm.hexagon.V6.vavgw
+ __builtin_HEXAGON_V6_vavgw(v64, v64);
// CHECK: @llvm.hexagon.V6.vavgw.128B
- __builtin_HEXAGON_V6_vavgwrnd_128B(v32, v32);
- // CHECK: @llvm.hexagon.V6.vavgwrnd.128B
- __builtin_HEXAGON_V6_vavgwrnd(v16, v16);
+ __builtin_HEXAGON_V6_vavgw_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vavgwrnd
- __builtin_HEXAGON_V6_vavgw(v16, v16);
- // CHECK: @llvm.hexagon.V6.vavgw
- __builtin_HEXAGON_V6_vcl0h_128B(v32);
- // CHECK: @llvm.hexagon.V6.vcl0h.128B
- __builtin_HEXAGON_V6_vcl0h(v16);
+ __builtin_HEXAGON_V6_vavgwrnd(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vavgwrnd.128B
+ __builtin_HEXAGON_V6_vavgwrnd_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vcl0h
- __builtin_HEXAGON_V6_vcl0w_128B(v32);
- // CHECK: @llvm.hexagon.V6.vcl0w.128B
- __builtin_HEXAGON_V6_vcl0w(v16);
+ __builtin_HEXAGON_V6_vcl0h(v64);
+ // CHECK: @llvm.hexagon.V6.vcl0h.128B
+ __builtin_HEXAGON_V6_vcl0h_128B(v128);
// CHECK: @llvm.hexagon.V6.vcl0w
- __builtin_HEXAGON_V6_vcombine_128B(v32, v32);
- // CHECK: @llvm.hexagon.V6.vcombine.128B
- __builtin_HEXAGON_V6_vcombine(v16, v16);
+ __builtin_HEXAGON_V6_vcl0w(v64);
+ // CHECK: @llvm.hexagon.V6.vcl0w.128B
+ __builtin_HEXAGON_V6_vcl0w_128B(v128);
// CHECK: @llvm.hexagon.V6.vcombine
- __builtin_HEXAGON_V6_vd0_128B();
- // CHECK: @llvm.hexagon.V6.vd0.128B
- __builtin_HEXAGON_V6_vd0();
+ __builtin_HEXAGON_V6_vcombine(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vcombine.128B
+ __builtin_HEXAGON_V6_vcombine_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vd0
- __builtin_HEXAGON_V6_vdealb_128B(v32);
+ __builtin_HEXAGON_V6_vd0();
+ // CHECK: @llvm.hexagon.V6.vd0.128B
+ __builtin_HEXAGON_V6_vd0_128B();
+ // CHECK: @llvm.hexagon.V6.vdd0
+ __builtin_HEXAGON_V6_vdd0();
+ // CHECK: @llvm.hexagon.V6.vdd0.128B
+ __builtin_HEXAGON_V6_vdd0_128B();
+ // CHECK: @llvm.hexagon.V6.vdealb
+ __builtin_HEXAGON_V6_vdealb(v64);
// CHECK: @llvm.hexagon.V6.vdealb.128B
- __builtin_HEXAGON_V6_vdealb4w_128B(v32, v32);
- // CHECK: @llvm.hexagon.V6.vdealb4w.128B
- __builtin_HEXAGON_V6_vdealb4w(v16, v16);
+ __builtin_HEXAGON_V6_vdealb_128B(v128);
// CHECK: @llvm.hexagon.V6.vdealb4w
- __builtin_HEXAGON_V6_vdealb(v16);
- // CHECK: @llvm.hexagon.V6.vdealb
- __builtin_HEXAGON_V6_vdealh_128B(v32);
- // CHECK: @llvm.hexagon.V6.vdealh.128B
- __builtin_HEXAGON_V6_vdealh(v16);
+ __builtin_HEXAGON_V6_vdealb4w(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vdealb4w.128B
+ __builtin_HEXAGON_V6_vdealb4w_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vdealh
- __builtin_HEXAGON_V6_vdealvdd_128B(v32, v32, 0);
- // CHECK: @llvm.hexagon.V6.vdealvdd.128B
- __builtin_HEXAGON_V6_vdealvdd(v16, v16, 0);
+ __builtin_HEXAGON_V6_vdealh(v64);
+ // CHECK: @llvm.hexagon.V6.vdealh.128B
+ __builtin_HEXAGON_V6_vdealh_128B(v128);
// CHECK: @llvm.hexagon.V6.vdealvdd
- __builtin_HEXAGON_V6_vdelta_128B(v32, v32);
- // CHECK: @llvm.hexagon.V6.vdelta.128B
- __builtin_HEXAGON_V6_vdelta(v16, v16);
+ __builtin_HEXAGON_V6_vdealvdd(v64, v64, 0);
+ // CHECK: @llvm.hexagon.V6.vdealvdd.128B
+ __builtin_HEXAGON_V6_vdealvdd_128B(v128, v128, 0);
// CHECK: @llvm.hexagon.V6.vdelta
- __builtin_HEXAGON_V6_vdmpybus_128B(v32, 0);
+ __builtin_HEXAGON_V6_vdelta(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vdelta.128B
+ __builtin_HEXAGON_V6_vdelta_128B(v128, v128);
+ // CHECK: @llvm.hexagon.V6.vdmpybus
+ __builtin_HEXAGON_V6_vdmpybus(v64, 0);
// CHECK: @llvm.hexagon.V6.vdmpybus.128B
- __builtin_HEXAGON_V6_vdmpybus_acc_128B(v32, v32, 0);
- // CHECK: @llvm.hexagon.V6.vdmpybus.acc.128B
- __builtin_HEXAGON_V6_vdmpybus_acc(v16, v16, 0);
+ __builtin_HEXAGON_V6_vdmpybus_128B(v128, 0);
// CHECK: @llvm.hexagon.V6.vdmpybus.acc
- __builtin_HEXAGON_V6_vdmpybus_dv_128B(v64, 0);
+ __builtin_HEXAGON_V6_vdmpybus_acc(v64, v64, 0);
+ // CHECK: @llvm.hexagon.V6.vdmpybus.acc.128B
+ __builtin_HEXAGON_V6_vdmpybus_acc_128B(v128, v128, 0);
+ // CHECK: @llvm.hexagon.V6.vdmpybus.dv
+ __builtin_HEXAGON_V6_vdmpybus_dv(v128, 0);
// CHECK: @llvm.hexagon.V6.vdmpybus.dv.128B
- __builtin_HEXAGON_V6_vdmpybus_dv_acc_128B(v64, v64, 0);
- // CHECK: @llvm.hexagon.V6.vdmpybus.dv.acc.128B
- __builtin_HEXAGON_V6_vdmpybus_dv_acc(v32, v32, 0);
+ __builtin_HEXAGON_V6_vdmpybus_dv_128B(v256, 0);
// CHECK: @llvm.hexagon.V6.vdmpybus.dv.acc
- __builtin_HEXAGON_V6_vdmpybus_dv(v32, 0);
- // CHECK: @llvm.hexagon.V6.vdmpybus.dv
- __builtin_HEXAGON_V6_vdmpybus(v16, 0);
- // CHECK: @llvm.hexagon.V6.vdmpybus
- __builtin_HEXAGON_V6_vdmpyhb_128B(v32, 0);
+ __builtin_HEXAGON_V6_vdmpybus_dv_acc(v128, v128, 0);
+ // CHECK: @llvm.hexagon.V6.vdmpybus.dv.acc.128B
+ __builtin_HEXAGON_V6_vdmpybus_dv_acc_128B(v256, v256, 0);
+ // CHECK: @llvm.hexagon.V6.vdmpyhb
+ __builtin_HEXAGON_V6_vdmpyhb(v64, 0);
// CHECK: @llvm.hexagon.V6.vdmpyhb.128B
- __builtin_HEXAGON_V6_vdmpyhb_acc_128B(v32, v32, 0);
- // CHECK: @llvm.hexagon.V6.vdmpyhb.acc.128B
- __builtin_HEXAGON_V6_vdmpyhb_acc(v16, v16, 0);
+ __builtin_HEXAGON_V6_vdmpyhb_128B(v128, 0);
// CHECK: @llvm.hexagon.V6.vdmpyhb.acc
- __builtin_HEXAGON_V6_vdmpyhb_dv_128B(v64, 0);
+ __builtin_HEXAGON_V6_vdmpyhb_acc(v64, v64, 0);
+ // CHECK: @llvm.hexagon.V6.vdmpyhb.acc.128B
+ __builtin_HEXAGON_V6_vdmpyhb_acc_128B(v128, v128, 0);
+ // CHECK: @llvm.hexagon.V6.vdmpyhb.dv
+ __builtin_HEXAGON_V6_vdmpyhb_dv(v128, 0);
// CHECK: @llvm.hexagon.V6.vdmpyhb.dv.128B
- __builtin_HEXAGON_V6_vdmpyhb_dv_acc_128B(v64, v64, 0);
- // CHECK: @llvm.hexagon.V6.vdmpyhb.dv.acc.128B
- __builtin_HEXAGON_V6_vdmpyhb_dv_acc(v32, v32, 0);
+ __builtin_HEXAGON_V6_vdmpyhb_dv_128B(v256, 0);
// CHECK: @llvm.hexagon.V6.vdmpyhb.dv.acc
- __builtin_HEXAGON_V6_vdmpyhb_dv(v32, 0);
- // CHECK: @llvm.hexagon.V6.vdmpyhb.dv
- __builtin_HEXAGON_V6_vdmpyhb(v16, 0);
- // CHECK: @llvm.hexagon.V6.vdmpyhb
- __builtin_HEXAGON_V6_vdmpyhisat_128B(v64, 0);
+ __builtin_HEXAGON_V6_vdmpyhb_dv_acc(v128, v128, 0);
+ // CHECK: @llvm.hexagon.V6.vdmpyhb.dv.acc.128B
+ __builtin_HEXAGON_V6_vdmpyhb_dv_acc_128B(v256, v256, 0);
+ // CHECK: @llvm.hexagon.V6.vdmpyhisat
+ __builtin_HEXAGON_V6_vdmpyhisat(v128, 0);
// CHECK: @llvm.hexagon.V6.vdmpyhisat.128B
- __builtin_HEXAGON_V6_vdmpyhisat_acc_128B(v32, v64, 0);
- // CHECK: @llvm.hexagon.V6.vdmpyhisat.acc.128B
- __builtin_HEXAGON_V6_vdmpyhisat_acc(v16, v32, 0);
+ __builtin_HEXAGON_V6_vdmpyhisat_128B(v256, 0);
// CHECK: @llvm.hexagon.V6.vdmpyhisat.acc
- __builtin_HEXAGON_V6_vdmpyhisat(v32, 0);
- // CHECK: @llvm.hexagon.V6.vdmpyhisat
- __builtin_HEXAGON_V6_vdmpyhsat_128B(v32, 0);
+ __builtin_HEXAGON_V6_vdmpyhisat_acc(v64, v128, 0);
+ // CHECK: @llvm.hexagon.V6.vdmpyhisat.acc.128B
+ __builtin_HEXAGON_V6_vdmpyhisat_acc_128B(v128, v256, 0);
+ // CHECK: @llvm.hexagon.V6.vdmpyhsat
+ __builtin_HEXAGON_V6_vdmpyhsat(v64, 0);
// CHECK: @llvm.hexagon.V6.vdmpyhsat.128B
- __builtin_HEXAGON_V6_vdmpyhsat_acc_128B(v32, v32, 0);
- // CHECK: @llvm.hexagon.V6.vdmpyhsat.acc.128B
- __builtin_HEXAGON_V6_vdmpyhsat_acc(v16, v16, 0);
+ __builtin_HEXAGON_V6_vdmpyhsat_128B(v128, 0);
// CHECK: @llvm.hexagon.V6.vdmpyhsat.acc
- __builtin_HEXAGON_V6_vdmpyhsat(v16, 0);
- // CHECK: @llvm.hexagon.V6.vdmpyhsat
- __builtin_HEXAGON_V6_vdmpyhsuisat_128B(v64, 0);
+ __builtin_HEXAGON_V6_vdmpyhsat_acc(v64, v64, 0);
+ // CHECK: @llvm.hexagon.V6.vdmpyhsat.acc.128B
+ __builtin_HEXAGON_V6_vdmpyhsat_acc_128B(v128, v128, 0);
+ // CHECK: @llvm.hexagon.V6.vdmpyhsuisat
+ __builtin_HEXAGON_V6_vdmpyhsuisat(v128, 0);
// CHECK: @llvm.hexagon.V6.vdmpyhsuisat.128B
- __builtin_HEXAGON_V6_vdmpyhsuisat_acc_128B(v32, v64, 0);
- // CHECK: @llvm.hexagon.V6.vdmpyhsuisat.acc.128B
- __builtin_HEXAGON_V6_vdmpyhsuisat_acc(v16, v32, 0);
+ __builtin_HEXAGON_V6_vdmpyhsuisat_128B(v256, 0);
// CHECK: @llvm.hexagon.V6.vdmpyhsuisat.acc
- __builtin_HEXAGON_V6_vdmpyhsuisat(v32, 0);
- // CHECK: @llvm.hexagon.V6.vdmpyhsuisat
- __builtin_HEXAGON_V6_vdmpyhsusat_128B(v32, 0);
+ __builtin_HEXAGON_V6_vdmpyhsuisat_acc(v64, v128, 0);
+ // CHECK: @llvm.hexagon.V6.vdmpyhsuisat.acc.128B
+ __builtin_HEXAGON_V6_vdmpyhsuisat_acc_128B(v128, v256, 0);
+ // CHECK: @llvm.hexagon.V6.vdmpyhsusat
+ __builtin_HEXAGON_V6_vdmpyhsusat(v64, 0);
// CHECK: @llvm.hexagon.V6.vdmpyhsusat.128B
- __builtin_HEXAGON_V6_vdmpyhsusat_acc_128B(v32, v32, 0);
- // CHECK: @llvm.hexagon.V6.vdmpyhsusat.acc.128B
- __builtin_HEXAGON_V6_vdmpyhsusat_acc(v16, v16, 0);
+ __builtin_HEXAGON_V6_vdmpyhsusat_128B(v128, 0);
// CHECK: @llvm.hexagon.V6.vdmpyhsusat.acc
- __builtin_HEXAGON_V6_vdmpyhsusat(v16, 0);
- // CHECK: @llvm.hexagon.V6.vdmpyhsusat
- __builtin_HEXAGON_V6_vdmpyhvsat_128B(v32, v32);
+ __builtin_HEXAGON_V6_vdmpyhsusat_acc(v64, v64, 0);
+ // CHECK: @llvm.hexagon.V6.vdmpyhsusat.acc.128B
+ __builtin_HEXAGON_V6_vdmpyhsusat_acc_128B(v128, v128, 0);
+ // CHECK: @llvm.hexagon.V6.vdmpyhvsat
+ __builtin_HEXAGON_V6_vdmpyhvsat(v64, v64);
// CHECK: @llvm.hexagon.V6.vdmpyhvsat.128B
- __builtin_HEXAGON_V6_vdmpyhvsat_acc_128B(v32, v32, v32);
- // CHECK: @llvm.hexagon.V6.vdmpyhvsat.acc.128B
- __builtin_HEXAGON_V6_vdmpyhvsat_acc(v16, v16, v16);
+ __builtin_HEXAGON_V6_vdmpyhvsat_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vdmpyhvsat.acc
- __builtin_HEXAGON_V6_vdmpyhvsat(v16, v16);
- // CHECK: @llvm.hexagon.V6.vdmpyhvsat
- __builtin_HEXAGON_V6_vdsaduh_128B(v64, 0);
+ __builtin_HEXAGON_V6_vdmpyhvsat_acc(v64, v64, v64);
+ // CHECK: @llvm.hexagon.V6.vdmpyhvsat.acc.128B
+ __builtin_HEXAGON_V6_vdmpyhvsat_acc_128B(v128, v128, v128);
+ // CHECK: @llvm.hexagon.V6.vdsaduh
+ __builtin_HEXAGON_V6_vdsaduh(v128, 0);
// CHECK: @llvm.hexagon.V6.vdsaduh.128B
- __builtin_HEXAGON_V6_vdsaduh_acc_128B(v64, v64, 0);
- // CHECK: @llvm.hexagon.V6.vdsaduh.acc.128B
- __builtin_HEXAGON_V6_vdsaduh_acc(v32, v32, 0);
+ __builtin_HEXAGON_V6_vdsaduh_128B(v256, 0);
// CHECK: @llvm.hexagon.V6.vdsaduh.acc
- __builtin_HEXAGON_V6_vdsaduh(v32, 0);
- // CHECK: @llvm.hexagon.V6.vdsaduh
- __builtin_HEXAGON_V6_veqb_128B(v32, v32);
+ __builtin_HEXAGON_V6_vdsaduh_acc(v128, v128, 0);
+ // CHECK: @llvm.hexagon.V6.vdsaduh.acc.128B
+ __builtin_HEXAGON_V6_vdsaduh_acc_128B(v256, v256, 0);
+ // CHECK: @llvm.hexagon.V6.veqb
+ __builtin_HEXAGON_V6_veqb(v64, v64);
// CHECK: @llvm.hexagon.V6.veqb.128B
- __builtin_HEXAGON_V6_veqb_and_128B(v32, v32, v32);
- // CHECK: @llvm.hexagon.V6.veqb.and.128B
- __builtin_HEXAGON_V6_veqb_and(v16, v16, v16);
+ __builtin_HEXAGON_V6_veqb_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.veqb.and
- __builtin_HEXAGON_V6_veqb_or_128B(v32, v32, v32);
- // CHECK: @llvm.hexagon.V6.veqb.or.128B
- __builtin_HEXAGON_V6_veqb_or(v16, v16, v16);
+ __builtin_HEXAGON_V6_veqb_and(v64, v64, v64);
+ // CHECK: @llvm.hexagon.V6.veqb.and.128B
+ __builtin_HEXAGON_V6_veqb_and_128B(v128, v128, v128);
// CHECK: @llvm.hexagon.V6.veqb.or
- __builtin_HEXAGON_V6_veqb(v16, v16);
- // CHECK: @llvm.hexagon.V6.veqb
- __builtin_HEXAGON_V6_veqb_xor_128B(v32, v32, v32);
- // CHECK: @llvm.hexagon.V6.veqb.xor.128B
- __builtin_HEXAGON_V6_veqb_xor(v16, v16, v16);
+ __builtin_HEXAGON_V6_veqb_or(v64, v64, v64);
+ // CHECK: @llvm.hexagon.V6.veqb.or.128B
+ __builtin_HEXAGON_V6_veqb_or_128B(v128, v128, v128);
// CHECK: @llvm.hexagon.V6.veqb.xor
- __builtin_HEXAGON_V6_veqh_128B(v32, v32);
+ __builtin_HEXAGON_V6_veqb_xor(v64, v64, v64);
+ // CHECK: @llvm.hexagon.V6.veqb.xor.128B
+ __builtin_HEXAGON_V6_veqb_xor_128B(v128, v128, v128);
+ // CHECK: @llvm.hexagon.V6.veqh
+ __builtin_HEXAGON_V6_veqh(v64, v64);
// CHECK: @llvm.hexagon.V6.veqh.128B
- __builtin_HEXAGON_V6_veqh_and_128B(v32, v32, v32);
- // CHECK: @llvm.hexagon.V6.veqh.and.128B
- __builtin_HEXAGON_V6_veqh_and(v16, v16, v16);
+ __builtin_HEXAGON_V6_veqh_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.veqh.and
- __builtin_HEXAGON_V6_veqh_or_128B(v32, v32, v32);
- // CHECK: @llvm.hexagon.V6.veqh.or.128B
- __builtin_HEXAGON_V6_veqh_or(v16, v16, v16);
+ __builtin_HEXAGON_V6_veqh_and(v64, v64, v64);
+ // CHECK: @llvm.hexagon.V6.veqh.and.128B
+ __builtin_HEXAGON_V6_veqh_and_128B(v128, v128, v128);
// CHECK: @llvm.hexagon.V6.veqh.or
- __builtin_HEXAGON_V6_veqh(v16, v16);
- // CHECK: @llvm.hexagon.V6.veqh
- __builtin_HEXAGON_V6_veqh_xor_128B(v32, v32, v32);
- // CHECK: @llvm.hexagon.V6.veqh.xor.128B
- __builtin_HEXAGON_V6_veqh_xor(v16, v16, v16);
+ __builtin_HEXAGON_V6_veqh_or(v64, v64, v64);
+ // CHECK: @llvm.hexagon.V6.veqh.or.128B
+ __builtin_HEXAGON_V6_veqh_or_128B(v128, v128, v128);
// CHECK: @llvm.hexagon.V6.veqh.xor
- __builtin_HEXAGON_V6_veqw_128B(v32, v32);
+ __builtin_HEXAGON_V6_veqh_xor(v64, v64, v64);
+ // CHECK: @llvm.hexagon.V6.veqh.xor.128B
+ __builtin_HEXAGON_V6_veqh_xor_128B(v128, v128, v128);
+ // CHECK: @llvm.hexagon.V6.veqw
+ __builtin_HEXAGON_V6_veqw(v64, v64);
// CHECK: @llvm.hexagon.V6.veqw.128B
- __builtin_HEXAGON_V6_veqw_and_128B(v32, v32, v32);
- // CHECK: @llvm.hexagon.V6.veqw.and.128B
- __builtin_HEXAGON_V6_veqw_and(v16, v16, v16);
+ __builtin_HEXAGON_V6_veqw_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.veqw.and
- __builtin_HEXAGON_V6_veqw_or_128B(v32, v32, v32);
- // CHECK: @llvm.hexagon.V6.veqw.or.128B
- __builtin_HEXAGON_V6_veqw_or(v16, v16, v16);
+ __builtin_HEXAGON_V6_veqw_and(v64, v64, v64);
+ // CHECK: @llvm.hexagon.V6.veqw.and.128B
+ __builtin_HEXAGON_V6_veqw_and_128B(v128, v128, v128);
// CHECK: @llvm.hexagon.V6.veqw.or
- __builtin_HEXAGON_V6_veqw(v16, v16);
- // CHECK: @llvm.hexagon.V6.veqw
- __builtin_HEXAGON_V6_veqw_xor_128B(v32, v32, v32);
- // CHECK: @llvm.hexagon.V6.veqw.xor.128B
- __builtin_HEXAGON_V6_veqw_xor(v16, v16, v16);
+ __builtin_HEXAGON_V6_veqw_or(v64, v64, v64);
+ // CHECK: @llvm.hexagon.V6.veqw.or.128B
+ __builtin_HEXAGON_V6_veqw_or_128B(v128, v128, v128);
// CHECK: @llvm.hexagon.V6.veqw.xor
- __builtin_HEXAGON_V6_vgtb_128B(v32, v32);
+ __builtin_HEXAGON_V6_veqw_xor(v64, v64, v64);
+ // CHECK: @llvm.hexagon.V6.veqw.xor.128B
+ __builtin_HEXAGON_V6_veqw_xor_128B(v128, v128, v128);
+ // CHECK: @llvm.hexagon.V6.vgathermh
+ __builtin_HEXAGON_V6_vgathermh(0, 0, 0, v64);
+ // CHECK: @llvm.hexagon.V6.vgathermh.128B
+ __builtin_HEXAGON_V6_vgathermh_128B(0, 0, 0, v128);
+ // CHECK: @llvm.hexagon.V6.vgathermhq
+ __builtin_HEXAGON_V6_vgathermhq(0, v64, 0, 0, v64);
+ // CHECK: @llvm.hexagon.V6.vgathermhq.128B
+ __builtin_HEXAGON_V6_vgathermhq_128B(0, v128, 0, 0, v128);
+ // CHECK: @llvm.hexagon.V6.vgathermhw
+ __builtin_HEXAGON_V6_vgathermhw(0, 0, 0, v128);
+ // CHECK: @llvm.hexagon.V6.vgathermhw.128B
+ __builtin_HEXAGON_V6_vgathermhw_128B(0, 0, 0, v256);
+ // CHECK: @llvm.hexagon.V6.vgathermhwq
+ __builtin_HEXAGON_V6_vgathermhwq(0, v64, 0, 0, v128);
+ // CHECK: @llvm.hexagon.V6.vgathermhwq.128B
+ __builtin_HEXAGON_V6_vgathermhwq_128B(0, v128, 0, 0, v256);
+ // CHECK: @llvm.hexagon.V6.vgathermw
+ __builtin_HEXAGON_V6_vgathermw(0, 0, 0, v64);
+ // CHECK: @llvm.hexagon.V6.vgathermw.128B
+ __builtin_HEXAGON_V6_vgathermw_128B(0, 0, 0, v128);
+ // CHECK: @llvm.hexagon.V6.vgathermwq
+ __builtin_HEXAGON_V6_vgathermwq(0, v64, 0, 0, v64);
+ // CHECK: @llvm.hexagon.V6.vgathermwq.128B
+ __builtin_HEXAGON_V6_vgathermwq_128B(0, v128, 0, 0, v128);
+ // CHECK: @llvm.hexagon.V6.vgtb
+ __builtin_HEXAGON_V6_vgtb(v64, v64);
// CHECK: @llvm.hexagon.V6.vgtb.128B
- __builtin_HEXAGON_V6_vgtb_and_128B(v32, v32, v32);
- // CHECK: @llvm.hexagon.V6.vgtb.and.128B
- __builtin_HEXAGON_V6_vgtb_and(v16, v16, v16);
+ __builtin_HEXAGON_V6_vgtb_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vgtb.and
- __builtin_HEXAGON_V6_vgtb_or_128B(v32, v32, v32);
- // CHECK: @llvm.hexagon.V6.vgtb.or.128B
- __builtin_HEXAGON_V6_vgtb_or(v16, v16, v16);
+ __builtin_HEXAGON_V6_vgtb_and(v64, v64, v64);
+ // CHECK: @llvm.hexagon.V6.vgtb.and.128B
+ __builtin_HEXAGON_V6_vgtb_and_128B(v128, v128, v128);
// CHECK: @llvm.hexagon.V6.vgtb.or
- __builtin_HEXAGON_V6_vgtb(v16, v16);
- // CHECK: @llvm.hexagon.V6.vgtb
- __builtin_HEXAGON_V6_vgtb_xor_128B(v32, v32, v32);
- // CHECK: @llvm.hexagon.V6.vgtb.xor.128B
- __builtin_HEXAGON_V6_vgtb_xor(v16, v16, v16);
+ __builtin_HEXAGON_V6_vgtb_or(v64, v64, v64);
+ // CHECK: @llvm.hexagon.V6.vgtb.or.128B
+ __builtin_HEXAGON_V6_vgtb_or_128B(v128, v128, v128);
// CHECK: @llvm.hexagon.V6.vgtb.xor
- __builtin_HEXAGON_V6_vgth_128B(v32, v32);
+ __builtin_HEXAGON_V6_vgtb_xor(v64, v64, v64);
+ // CHECK: @llvm.hexagon.V6.vgtb.xor.128B
+ __builtin_HEXAGON_V6_vgtb_xor_128B(v128, v128, v128);
+ // CHECK: @llvm.hexagon.V6.vgth
+ __builtin_HEXAGON_V6_vgth(v64, v64);
// CHECK: @llvm.hexagon.V6.vgth.128B
- __builtin_HEXAGON_V6_vgth_and_128B(v32, v32, v32);
- // CHECK: @llvm.hexagon.V6.vgth.and.128B
- __builtin_HEXAGON_V6_vgth_and(v16, v16, v16);
+ __builtin_HEXAGON_V6_vgth_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vgth.and
- __builtin_HEXAGON_V6_vgth_or_128B(v32, v32, v32);
- // CHECK: @llvm.hexagon.V6.vgth.or.128B
- __builtin_HEXAGON_V6_vgth_or(v16, v16, v16);
+ __builtin_HEXAGON_V6_vgth_and(v64, v64, v64);
+ // CHECK: @llvm.hexagon.V6.vgth.and.128B
+ __builtin_HEXAGON_V6_vgth_and_128B(v128, v128, v128);
// CHECK: @llvm.hexagon.V6.vgth.or
- __builtin_HEXAGON_V6_vgth(v16, v16);
- // CHECK: @llvm.hexagon.V6.vgth
- __builtin_HEXAGON_V6_vgth_xor_128B(v32, v32, v32);
- // CHECK: @llvm.hexagon.V6.vgth.xor.128B
- __builtin_HEXAGON_V6_vgth_xor(v16, v16, v16);
+ __builtin_HEXAGON_V6_vgth_or(v64, v64, v64);
+ // CHECK: @llvm.hexagon.V6.vgth.or.128B
+ __builtin_HEXAGON_V6_vgth_or_128B(v128, v128, v128);
// CHECK: @llvm.hexagon.V6.vgth.xor
- __builtin_HEXAGON_V6_vgtub_128B(v32, v32);
+ __builtin_HEXAGON_V6_vgth_xor(v64, v64, v64);
+ // CHECK: @llvm.hexagon.V6.vgth.xor.128B
+ __builtin_HEXAGON_V6_vgth_xor_128B(v128, v128, v128);
+ // CHECK: @llvm.hexagon.V6.vgtub
+ __builtin_HEXAGON_V6_vgtub(v64, v64);
// CHECK: @llvm.hexagon.V6.vgtub.128B
- __builtin_HEXAGON_V6_vgtub_and_128B(v32, v32, v32);
- // CHECK: @llvm.hexagon.V6.vgtub.and.128B
- __builtin_HEXAGON_V6_vgtub_and(v16, v16, v16);
+ __builtin_HEXAGON_V6_vgtub_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vgtub.and
- __builtin_HEXAGON_V6_vgtub_or_128B(v32, v32, v32);
- // CHECK: @llvm.hexagon.V6.vgtub.or.128B
- __builtin_HEXAGON_V6_vgtub_or(v16, v16, v16);
+ __builtin_HEXAGON_V6_vgtub_and(v64, v64, v64);
+ // CHECK: @llvm.hexagon.V6.vgtub.and.128B
+ __builtin_HEXAGON_V6_vgtub_and_128B(v128, v128, v128);
// CHECK: @llvm.hexagon.V6.vgtub.or
- __builtin_HEXAGON_V6_vgtub(v16, v16);
- // CHECK: @llvm.hexagon.V6.vgtub
- __builtin_HEXAGON_V6_vgtub_xor_128B(v32, v32, v32);
- // CHECK: @llvm.hexagon.V6.vgtub.xor.128B
- __builtin_HEXAGON_V6_vgtub_xor(v16, v16, v16);
+ __builtin_HEXAGON_V6_vgtub_or(v64, v64, v64);
+ // CHECK: @llvm.hexagon.V6.vgtub.or.128B
+ __builtin_HEXAGON_V6_vgtub_or_128B(v128, v128, v128);
// CHECK: @llvm.hexagon.V6.vgtub.xor
- __builtin_HEXAGON_V6_vgtuh_128B(v32, v32);
+ __builtin_HEXAGON_V6_vgtub_xor(v64, v64, v64);
+ // CHECK: @llvm.hexagon.V6.vgtub.xor.128B
+ __builtin_HEXAGON_V6_vgtub_xor_128B(v128, v128, v128);
+ // CHECK: @llvm.hexagon.V6.vgtuh
+ __builtin_HEXAGON_V6_vgtuh(v64, v64);
// CHECK: @llvm.hexagon.V6.vgtuh.128B
- __builtin_HEXAGON_V6_vgtuh_and_128B(v32, v32, v32);
- // CHECK: @llvm.hexagon.V6.vgtuh.and.128B
- __builtin_HEXAGON_V6_vgtuh_and(v16, v16, v16);
+ __builtin_HEXAGON_V6_vgtuh_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vgtuh.and
- __builtin_HEXAGON_V6_vgtuh_or_128B(v32, v32, v32);
- // CHECK: @llvm.hexagon.V6.vgtuh.or.128B
- __builtin_HEXAGON_V6_vgtuh_or(v16, v16, v16);
+ __builtin_HEXAGON_V6_vgtuh_and(v64, v64, v64);
+ // CHECK: @llvm.hexagon.V6.vgtuh.and.128B
+ __builtin_HEXAGON_V6_vgtuh_and_128B(v128, v128, v128);
// CHECK: @llvm.hexagon.V6.vgtuh.or
- __builtin_HEXAGON_V6_vgtuh(v16, v16);
- // CHECK: @llvm.hexagon.V6.vgtuh
- __builtin_HEXAGON_V6_vgtuh_xor_128B(v32, v32, v32);
- // CHECK: @llvm.hexagon.V6.vgtuh.xor.128B
- __builtin_HEXAGON_V6_vgtuh_xor(v16, v16, v16);
+ __builtin_HEXAGON_V6_vgtuh_or(v64, v64, v64);
+ // CHECK: @llvm.hexagon.V6.vgtuh.or.128B
+ __builtin_HEXAGON_V6_vgtuh_or_128B(v128, v128, v128);
// CHECK: @llvm.hexagon.V6.vgtuh.xor
- __builtin_HEXAGON_V6_vgtuw_128B(v32, v32);
+ __builtin_HEXAGON_V6_vgtuh_xor(v64, v64, v64);
+ // CHECK: @llvm.hexagon.V6.vgtuh.xor.128B
+ __builtin_HEXAGON_V6_vgtuh_xor_128B(v128, v128, v128);
+ // CHECK: @llvm.hexagon.V6.vgtuw
+ __builtin_HEXAGON_V6_vgtuw(v64, v64);
// CHECK: @llvm.hexagon.V6.vgtuw.128B
- __builtin_HEXAGON_V6_vgtuw_and_128B(v32, v32, v32);
- // CHECK: @llvm.hexagon.V6.vgtuw.and.128B
- __builtin_HEXAGON_V6_vgtuw_and(v16, v16, v16);
+ __builtin_HEXAGON_V6_vgtuw_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vgtuw.and
- __builtin_HEXAGON_V6_vgtuw_or_128B(v32, v32, v32);
- // CHECK: @llvm.hexagon.V6.vgtuw.or.128B
- __builtin_HEXAGON_V6_vgtuw_or(v16, v16, v16);
+ __builtin_HEXAGON_V6_vgtuw_and(v64, v64, v64);
+ // CHECK: @llvm.hexagon.V6.vgtuw.and.128B
+ __builtin_HEXAGON_V6_vgtuw_and_128B(v128, v128, v128);
// CHECK: @llvm.hexagon.V6.vgtuw.or
- __builtin_HEXAGON_V6_vgtuw(v16, v16);
- // CHECK: @llvm.hexagon.V6.vgtuw
- __builtin_HEXAGON_V6_vgtuw_xor_128B(v32, v32, v32);
- // CHECK: @llvm.hexagon.V6.vgtuw.xor.128B
- __builtin_HEXAGON_V6_vgtuw_xor(v16, v16, v16);
+ __builtin_HEXAGON_V6_vgtuw_or(v64, v64, v64);
+ // CHECK: @llvm.hexagon.V6.vgtuw.or.128B
+ __builtin_HEXAGON_V6_vgtuw_or_128B(v128, v128, v128);
// CHECK: @llvm.hexagon.V6.vgtuw.xor
- __builtin_HEXAGON_V6_vgtw_128B(v32, v32);
+ __builtin_HEXAGON_V6_vgtuw_xor(v64, v64, v64);
+ // CHECK: @llvm.hexagon.V6.vgtuw.xor.128B
+ __builtin_HEXAGON_V6_vgtuw_xor_128B(v128, v128, v128);
+ // CHECK: @llvm.hexagon.V6.vgtw
+ __builtin_HEXAGON_V6_vgtw(v64, v64);
// CHECK: @llvm.hexagon.V6.vgtw.128B
- __builtin_HEXAGON_V6_vgtw_and_128B(v32, v32, v32);
- // CHECK: @llvm.hexagon.V6.vgtw.and.128B
- __builtin_HEXAGON_V6_vgtw_and(v16, v16, v16);
+ __builtin_HEXAGON_V6_vgtw_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vgtw.and
- __builtin_HEXAGON_V6_vgtw_or_128B(v32, v32, v32);
- // CHECK: @llvm.hexagon.V6.vgtw.or.128B
- __builtin_HEXAGON_V6_vgtw_or(v16, v16, v16);
+ __builtin_HEXAGON_V6_vgtw_and(v64, v64, v64);
+ // CHECK: @llvm.hexagon.V6.vgtw.and.128B
+ __builtin_HEXAGON_V6_vgtw_and_128B(v128, v128, v128);
// CHECK: @llvm.hexagon.V6.vgtw.or
- __builtin_HEXAGON_V6_vgtw(v16, v16);
- // CHECK: @llvm.hexagon.V6.vgtw
- __builtin_HEXAGON_V6_vgtw_xor_128B(v32, v32, v32);
- // CHECK: @llvm.hexagon.V6.vgtw.xor.128B
- __builtin_HEXAGON_V6_vgtw_xor(v16, v16, v16);
+ __builtin_HEXAGON_V6_vgtw_or(v64, v64, v64);
+ // CHECK: @llvm.hexagon.V6.vgtw.or.128B
+ __builtin_HEXAGON_V6_vgtw_or_128B(v128, v128, v128);
// CHECK: @llvm.hexagon.V6.vgtw.xor
- __builtin_HEXAGON_V6_vinsertwr_128B(v32, 0);
- // CHECK: @llvm.hexagon.V6.vinsertwr.128B
- __builtin_HEXAGON_V6_vinsertwr(v16, 0);
+ __builtin_HEXAGON_V6_vgtw_xor(v64, v64, v64);
+ // CHECK: @llvm.hexagon.V6.vgtw.xor.128B
+ __builtin_HEXAGON_V6_vgtw_xor_128B(v128, v128, v128);
// CHECK: @llvm.hexagon.V6.vinsertwr
- __builtin_HEXAGON_V6_vlalignb_128B(v32, v32, 0);
+ __builtin_HEXAGON_V6_vinsertwr(v64, 0);
+ // CHECK: @llvm.hexagon.V6.vinsertwr.128B
+ __builtin_HEXAGON_V6_vinsertwr_128B(v128, 0);
+ // CHECK: @llvm.hexagon.V6.vlalignb
+ __builtin_HEXAGON_V6_vlalignb(v64, v64, 0);
// CHECK: @llvm.hexagon.V6.vlalignb.128B
- __builtin_HEXAGON_V6_vlalignbi_128B(v32, v32, 0);
- // CHECK: @llvm.hexagon.V6.vlalignbi.128B
- __builtin_HEXAGON_V6_vlalignbi(v16, v16, 0);
+ __builtin_HEXAGON_V6_vlalignb_128B(v128, v128, 0);
// CHECK: @llvm.hexagon.V6.vlalignbi
- __builtin_HEXAGON_V6_vlalignb(v16, v16, 0);
- // CHECK: @llvm.hexagon.V6.vlalignb
- __builtin_HEXAGON_V6_vlsrh_128B(v32, 0);
- // CHECK: @llvm.hexagon.V6.vlsrh.128B
- __builtin_HEXAGON_V6_vlsrhv_128B(v32, v32);
- // CHECK: @llvm.hexagon.V6.vlsrhv.128B
- __builtin_HEXAGON_V6_vlsrh(v16, 0);
+ __builtin_HEXAGON_V6_vlalignbi(v64, v64, 0);
+ // CHECK: @llvm.hexagon.V6.vlalignbi.128B
+ __builtin_HEXAGON_V6_vlalignbi_128B(v128, v128, 0);
+ // CHECK: @llvm.hexagon.V6.vlsrb
+ __builtin_HEXAGON_V6_vlsrb(v64, 0);
+ // CHECK: @llvm.hexagon.V6.vlsrb.128B
+ __builtin_HEXAGON_V6_vlsrb_128B(v128, 0);
// CHECK: @llvm.hexagon.V6.vlsrh
- __builtin_HEXAGON_V6_vlsrhv(v16, v16);
+ __builtin_HEXAGON_V6_vlsrh(v64, 0);
+ // CHECK: @llvm.hexagon.V6.vlsrh.128B
+ __builtin_HEXAGON_V6_vlsrh_128B(v128, 0);
// CHECK: @llvm.hexagon.V6.vlsrhv
- __builtin_HEXAGON_V6_vlsrw_128B(v32, 0);
- // CHECK: @llvm.hexagon.V6.vlsrw.128B
- __builtin_HEXAGON_V6_vlsrwv_128B(v32, v32);
- // CHECK: @llvm.hexagon.V6.vlsrwv.128B
- __builtin_HEXAGON_V6_vlsrw(v16, 0);
+ __builtin_HEXAGON_V6_vlsrhv(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vlsrhv.128B
+ __builtin_HEXAGON_V6_vlsrhv_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vlsrw
- __builtin_HEXAGON_V6_vlsrwv(v16, v16);
+ __builtin_HEXAGON_V6_vlsrw(v64, 0);
+ // CHECK: @llvm.hexagon.V6.vlsrw.128B
+ __builtin_HEXAGON_V6_vlsrw_128B(v128, 0);
// CHECK: @llvm.hexagon.V6.vlsrwv
- __builtin_HEXAGON_V6_vlutb_128B(v32, 0, 0);
- // CHECK: @llvm.hexagon.V6.vlutb.128B
- __builtin_HEXAGON_V6_vlutb_acc_128B(v32, v32, 0, 0);
- // CHECK: @llvm.hexagon.V6.vlutb.acc.128B
- __builtin_HEXAGON_V6_vlutb_acc(v16, v16, 0, 0);
- // CHECK: @llvm.hexagon.V6.vlutb.acc
- __builtin_HEXAGON_V6_vlutb_dv_128B(v64, 0, 0);
- // CHECK: @llvm.hexagon.V6.vlutb.dv.128B
- __builtin_HEXAGON_V6_vlutb_dv_acc_128B(v64, v64, 0, 0);
- // CHECK: @llvm.hexagon.V6.vlutb.dv.acc.128B
- __builtin_HEXAGON_V6_vlutb_dv_acc(v32, v32, 0, 0);
- // CHECK: @llvm.hexagon.V6.vlutb.dv.acc
- __builtin_HEXAGON_V6_vlutb_dv(v32, 0, 0);
- // CHECK: @llvm.hexagon.V6.vlutb.dv
- __builtin_HEXAGON_V6_vlutb(v16, 0, 0);
- // CHECK: @llvm.hexagon.V6.vlutb
- __builtin_HEXAGON_V6_vlutvvb_128B(v32, v32, 0);
+ __builtin_HEXAGON_V6_vlsrwv(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vlsrwv.128B
+ __builtin_HEXAGON_V6_vlsrwv_128B(v128, v128);
+ // CHECK: @llvm.hexagon.V6.vlut4
+ __builtin_HEXAGON_V6_vlut4(v64, 0);
+ // CHECK: @llvm.hexagon.V6.vlut4.128B
+ __builtin_HEXAGON_V6_vlut4_128B(v128, 0);
+ // CHECK: @llvm.hexagon.V6.vlutvvb
+ __builtin_HEXAGON_V6_vlutvvb(v64, v64, 0);
// CHECK: @llvm.hexagon.V6.vlutvvb.128B
- __builtin_HEXAGON_V6_vlutvvb_oracc_128B(v32, v32, v32, 0);
- // CHECK: @llvm.hexagon.V6.vlutvvb.oracc.128B
- __builtin_HEXAGON_V6_vlutvvb_oracc(v16, v16, v16, 0);
+ __builtin_HEXAGON_V6_vlutvvb_128B(v128, v128, 0);
+ // CHECK: @llvm.hexagon.V6.vlutvvb.nm
+ __builtin_HEXAGON_V6_vlutvvb_nm(v64, v64, 0);
+ // CHECK: @llvm.hexagon.V6.vlutvvb.nm.128B
+ __builtin_HEXAGON_V6_vlutvvb_nm_128B(v128, v128, 0);
// CHECK: @llvm.hexagon.V6.vlutvvb.oracc
- __builtin_HEXAGON_V6_vlutvvb(v16, v16, 0);
- // CHECK: @llvm.hexagon.V6.vlutvvb
- __builtin_HEXAGON_V6_vlutvwh_128B(v32, v32, 0);
+ __builtin_HEXAGON_V6_vlutvvb_oracc(v64, v64, v64, 0);
+ // CHECK: @llvm.hexagon.V6.vlutvvb.oracc.128B
+ __builtin_HEXAGON_V6_vlutvvb_oracc_128B(v128, v128, v128, 0);
+ // CHECK: @llvm.hexagon.V6.vlutvvb.oracci
+ __builtin_HEXAGON_V6_vlutvvb_oracci(v64, v64, v64, 0);
+ // CHECK: @llvm.hexagon.V6.vlutvvb.oracci.128B
+ __builtin_HEXAGON_V6_vlutvvb_oracci_128B(v128, v128, v128, 0);
+ // CHECK: @llvm.hexagon.V6.vlutvvbi
+ __builtin_HEXAGON_V6_vlutvvbi(v64, v64, 0);
+ // CHECK: @llvm.hexagon.V6.vlutvvbi.128B
+ __builtin_HEXAGON_V6_vlutvvbi_128B(v128, v128, 0);
+ // CHECK: @llvm.hexagon.V6.vlutvwh
+ __builtin_HEXAGON_V6_vlutvwh(v64, v64, 0);
// CHECK: @llvm.hexagon.V6.vlutvwh.128B
- __builtin_HEXAGON_V6_vlutvwh_oracc_128B(v64, v32, v32, 0);
- // CHECK: @llvm.hexagon.V6.vlutvwh.oracc.128B
- __builtin_HEXAGON_V6_vlutvwh_oracc(v32, v16, v16, 0);
+ __builtin_HEXAGON_V6_vlutvwh_128B(v128, v128, 0);
+ // CHECK: @llvm.hexagon.V6.vlutvwh.nm
+ __builtin_HEXAGON_V6_vlutvwh_nm(v64, v64, 0);
+ // CHECK: @llvm.hexagon.V6.vlutvwh.nm.128B
+ __builtin_HEXAGON_V6_vlutvwh_nm_128B(v128, v128, 0);
// CHECK: @llvm.hexagon.V6.vlutvwh.oracc
- __builtin_HEXAGON_V6_vlutvwh(v16, v16, 0);
- // CHECK: @llvm.hexagon.V6.vlutvwh
- __builtin_HEXAGON_V6_vmaxh_128B(v32, v32);
- // CHECK: @llvm.hexagon.V6.vmaxh.128B
- __builtin_HEXAGON_V6_vmaxh(v16, v16);
+ __builtin_HEXAGON_V6_vlutvwh_oracc(v128, v64, v64, 0);
+ // CHECK: @llvm.hexagon.V6.vlutvwh.oracc.128B
+ __builtin_HEXAGON_V6_vlutvwh_oracc_128B(v256, v128, v128, 0);
+ // CHECK: @llvm.hexagon.V6.vlutvwh.oracci
+ __builtin_HEXAGON_V6_vlutvwh_oracci(v128, v64, v64, 0);
+ // CHECK: @llvm.hexagon.V6.vlutvwh.oracci.128B
+ __builtin_HEXAGON_V6_vlutvwh_oracci_128B(v256, v128, v128, 0);
+ // CHECK: @llvm.hexagon.V6.vlutvwhi
+ __builtin_HEXAGON_V6_vlutvwhi(v64, v64, 0);
+ // CHECK: @llvm.hexagon.V6.vlutvwhi.128B
+ __builtin_HEXAGON_V6_vlutvwhi_128B(v128, v128, 0);
+ // CHECK: @llvm.hexagon.V6.vmaskedstorenq
+ __builtin_HEXAGON_V6_vmaskedstorenq(v64, 0, v64);
+ // CHECK: @llvm.hexagon.V6.vmaskedstorenq.128B
+ __builtin_HEXAGON_V6_vmaskedstorenq_128B(v128, 0, v128);
+ // CHECK: @llvm.hexagon.V6.vmaskedstorentnq
+ __builtin_HEXAGON_V6_vmaskedstorentnq(v64, 0, v64);
+ // CHECK: @llvm.hexagon.V6.vmaskedstorentnq.128B
+ __builtin_HEXAGON_V6_vmaskedstorentnq_128B(v128, 0, v128);
+ // CHECK: @llvm.hexagon.V6.vmaskedstorentq
+ __builtin_HEXAGON_V6_vmaskedstorentq(v64, 0, v64);
+ // CHECK: @llvm.hexagon.V6.vmaskedstorentq.128B
+ __builtin_HEXAGON_V6_vmaskedstorentq_128B(v128, 0, v128);
+ // CHECK: @llvm.hexagon.V6.vmaskedstoreq
+ __builtin_HEXAGON_V6_vmaskedstoreq(v64, 0, v64);
+ // CHECK: @llvm.hexagon.V6.vmaskedstoreq.128B
+ __builtin_HEXAGON_V6_vmaskedstoreq_128B(v128, 0, v128);
+ // CHECK: @llvm.hexagon.V6.vmaxb
+ __builtin_HEXAGON_V6_vmaxb(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vmaxb.128B
+ __builtin_HEXAGON_V6_vmaxb_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vmaxh
- __builtin_HEXAGON_V6_vmaxub_128B(v32, v32);
- // CHECK: @llvm.hexagon.V6.vmaxub.128B
- __builtin_HEXAGON_V6_vmaxub(v16, v16);
+ __builtin_HEXAGON_V6_vmaxh(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vmaxh.128B
+ __builtin_HEXAGON_V6_vmaxh_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vmaxub
- __builtin_HEXAGON_V6_vmaxuh_128B(v32, v32);
- // CHECK: @llvm.hexagon.V6.vmaxuh.128B
- __builtin_HEXAGON_V6_vmaxuh(v16, v16);
+ __builtin_HEXAGON_V6_vmaxub(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vmaxub.128B
+ __builtin_HEXAGON_V6_vmaxub_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vmaxuh
- __builtin_HEXAGON_V6_vmaxw_128B(v32, v32);
- // CHECK: @llvm.hexagon.V6.vmaxw.128B
- __builtin_HEXAGON_V6_vmaxw(v16, v16);
+ __builtin_HEXAGON_V6_vmaxuh(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vmaxuh.128B
+ __builtin_HEXAGON_V6_vmaxuh_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vmaxw
- __builtin_HEXAGON_V6_vminh_128B(v32, v32);
- // CHECK: @llvm.hexagon.V6.vminh.128B
- __builtin_HEXAGON_V6_vminh(v16, v16);
+ __builtin_HEXAGON_V6_vmaxw(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vmaxw.128B
+ __builtin_HEXAGON_V6_vmaxw_128B(v128, v128);
+ // CHECK: @llvm.hexagon.V6.vminb
+ __builtin_HEXAGON_V6_vminb(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vminb.128B
+ __builtin_HEXAGON_V6_vminb_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vminh
- __builtin_HEXAGON_V6_vminub_128B(v32, v32);
- // CHECK: @llvm.hexagon.V6.vminub.128B
- __builtin_HEXAGON_V6_vminub(v16, v16);
+ __builtin_HEXAGON_V6_vminh(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vminh.128B
+ __builtin_HEXAGON_V6_vminh_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vminub
- __builtin_HEXAGON_V6_vminuh_128B(v32, v32);
- // CHECK: @llvm.hexagon.V6.vminuh.128B
- __builtin_HEXAGON_V6_vminuh(v16, v16);
+ __builtin_HEXAGON_V6_vminub(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vminub.128B
+ __builtin_HEXAGON_V6_vminub_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vminuh
- __builtin_HEXAGON_V6_vminw_128B(v32, v32);
- // CHECK: @llvm.hexagon.V6.vminw.128B
- __builtin_HEXAGON_V6_vminw(v16, v16);
+ __builtin_HEXAGON_V6_vminuh(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vminuh.128B
+ __builtin_HEXAGON_V6_vminuh_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vminw
- __builtin_HEXAGON_V6_vmpabus_128B(v64, 0);
+ __builtin_HEXAGON_V6_vminw(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vminw.128B
+ __builtin_HEXAGON_V6_vminw_128B(v128, v128);
+ // CHECK: @llvm.hexagon.V6.vmpabus
+ __builtin_HEXAGON_V6_vmpabus(v128, 0);
// CHECK: @llvm.hexagon.V6.vmpabus.128B
- __builtin_HEXAGON_V6_vmpabus_acc_128B(v64, v64, 0);
- // CHECK: @llvm.hexagon.V6.vmpabus.acc.128B
- __builtin_HEXAGON_V6_vmpabus_acc(v32, v32, 0);
+ __builtin_HEXAGON_V6_vmpabus_128B(v256, 0);
// CHECK: @llvm.hexagon.V6.vmpabus.acc
- __builtin_HEXAGON_V6_vmpabusv_128B(v64, v64);
- // CHECK: @llvm.hexagon.V6.vmpabusv.128B
- __builtin_HEXAGON_V6_vmpabus(v32, 0);
- // CHECK: @llvm.hexagon.V6.vmpabus
- __builtin_HEXAGON_V6_vmpabusv(v32, v32);
+ __builtin_HEXAGON_V6_vmpabus_acc(v128, v128, 0);
+ // CHECK: @llvm.hexagon.V6.vmpabus.acc.128B
+ __builtin_HEXAGON_V6_vmpabus_acc_128B(v256, v256, 0);
// CHECK: @llvm.hexagon.V6.vmpabusv
- __builtin_HEXAGON_V6_vmpabuuv_128B(v64, v64);
- // CHECK: @llvm.hexagon.V6.vmpabuuv.128B
- __builtin_HEXAGON_V6_vmpabuuv(v32, v32);
+ __builtin_HEXAGON_V6_vmpabusv(v128, v128);
+ // CHECK: @llvm.hexagon.V6.vmpabusv.128B
+ __builtin_HEXAGON_V6_vmpabusv_128B(v256, v256);
+ // CHECK: @llvm.hexagon.V6.vmpabuu
+ __builtin_HEXAGON_V6_vmpabuu(v128, 0);
+ // CHECK: @llvm.hexagon.V6.vmpabuu.128B
+ __builtin_HEXAGON_V6_vmpabuu_128B(v256, 0);
+ // CHECK: @llvm.hexagon.V6.vmpabuu.acc
+ __builtin_HEXAGON_V6_vmpabuu_acc(v128, v128, 0);
+ // CHECK: @llvm.hexagon.V6.vmpabuu.acc.128B
+ __builtin_HEXAGON_V6_vmpabuu_acc_128B(v256, v256, 0);
// CHECK: @llvm.hexagon.V6.vmpabuuv
- __builtin_HEXAGON_V6_vmpahb_128B(v64, 0);
+ __builtin_HEXAGON_V6_vmpabuuv(v128, v128);
+ // CHECK: @llvm.hexagon.V6.vmpabuuv.128B
+ __builtin_HEXAGON_V6_vmpabuuv_128B(v256, v256);
+ // CHECK: @llvm.hexagon.V6.vmpahb
+ __builtin_HEXAGON_V6_vmpahb(v128, 0);
// CHECK: @llvm.hexagon.V6.vmpahb.128B
- __builtin_HEXAGON_V6_vmpahb_acc_128B(v64, v64, 0);
- // CHECK: @llvm.hexagon.V6.vmpahb.acc.128B
- __builtin_HEXAGON_V6_vmpahb_acc(v32, v32, 0);
+ __builtin_HEXAGON_V6_vmpahb_128B(v256, 0);
// CHECK: @llvm.hexagon.V6.vmpahb.acc
- __builtin_HEXAGON_V6_vmpahb(v32, 0);
- // CHECK: @llvm.hexagon.V6.vmpahb
- __builtin_HEXAGON_V6_vmpybus_128B(v32, 0);
+ __builtin_HEXAGON_V6_vmpahb_acc(v128, v128, 0);
+ // CHECK: @llvm.hexagon.V6.vmpahb.acc.128B
+ __builtin_HEXAGON_V6_vmpahb_acc_128B(v256, v256, 0);
+ // CHECK: @llvm.hexagon.V6.vmpahhsat
+ __builtin_HEXAGON_V6_vmpahhsat(v64, v64, 0);
+ // CHECK: @llvm.hexagon.V6.vmpahhsat.128B
+ __builtin_HEXAGON_V6_vmpahhsat_128B(v128, v128, 0);
+ // CHECK: @llvm.hexagon.V6.vmpauhb
+ __builtin_HEXAGON_V6_vmpauhb(v128, 0);
+ // CHECK: @llvm.hexagon.V6.vmpauhb.128B
+ __builtin_HEXAGON_V6_vmpauhb_128B(v256, 0);
+ // CHECK: @llvm.hexagon.V6.vmpauhb.acc
+ __builtin_HEXAGON_V6_vmpauhb_acc(v128, v128, 0);
+ // CHECK: @llvm.hexagon.V6.vmpauhb.acc.128B
+ __builtin_HEXAGON_V6_vmpauhb_acc_128B(v256, v256, 0);
+ // CHECK: @llvm.hexagon.V6.vmpauhuhsat
+ __builtin_HEXAGON_V6_vmpauhuhsat(v64, v64, 0);
+ // CHECK: @llvm.hexagon.V6.vmpauhuhsat.128B
+ __builtin_HEXAGON_V6_vmpauhuhsat_128B(v128, v128, 0);
+ // CHECK: @llvm.hexagon.V6.vmpsuhuhsat
+ __builtin_HEXAGON_V6_vmpsuhuhsat(v64, v64, 0);
+ // CHECK: @llvm.hexagon.V6.vmpsuhuhsat.128B
+ __builtin_HEXAGON_V6_vmpsuhuhsat_128B(v128, v128, 0);
+ // CHECK: @llvm.hexagon.V6.vmpybus
+ __builtin_HEXAGON_V6_vmpybus(v64, 0);
// CHECK: @llvm.hexagon.V6.vmpybus.128B
- __builtin_HEXAGON_V6_vmpybus_acc_128B(v64, v32, 0);
- // CHECK: @llvm.hexagon.V6.vmpybus.acc.128B
- __builtin_HEXAGON_V6_vmpybus_acc(v32, v16, 0);
+ __builtin_HEXAGON_V6_vmpybus_128B(v128, 0);
// CHECK: @llvm.hexagon.V6.vmpybus.acc
- __builtin_HEXAGON_V6_vmpybusv_128B(v32, v32);
+ __builtin_HEXAGON_V6_vmpybus_acc(v128, v64, 0);
+ // CHECK: @llvm.hexagon.V6.vmpybus.acc.128B
+ __builtin_HEXAGON_V6_vmpybus_acc_128B(v256, v128, 0);
+ // CHECK: @llvm.hexagon.V6.vmpybusv
+ __builtin_HEXAGON_V6_vmpybusv(v64, v64);
// CHECK: @llvm.hexagon.V6.vmpybusv.128B
- __builtin_HEXAGON_V6_vmpybus(v16, 0);
- // CHECK: @llvm.hexagon.V6.vmpybus
- __builtin_HEXAGON_V6_vmpybusv_acc_128B(v64, v32, v32);
- // CHECK: @llvm.hexagon.V6.vmpybusv.acc.128B
- __builtin_HEXAGON_V6_vmpybusv_acc(v32, v16, v16);
+ __builtin_HEXAGON_V6_vmpybusv_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vmpybusv.acc
- __builtin_HEXAGON_V6_vmpybusv(v16, v16);
- // CHECK: @llvm.hexagon.V6.vmpybusv
- __builtin_HEXAGON_V6_vmpybv_128B(v32, v32);
+ __builtin_HEXAGON_V6_vmpybusv_acc(v128, v64, v64);
+ // CHECK: @llvm.hexagon.V6.vmpybusv.acc.128B
+ __builtin_HEXAGON_V6_vmpybusv_acc_128B(v256, v128, v128);
+ // CHECK: @llvm.hexagon.V6.vmpybv
+ __builtin_HEXAGON_V6_vmpybv(v64, v64);
// CHECK: @llvm.hexagon.V6.vmpybv.128B
- __builtin_HEXAGON_V6_vmpybv_acc_128B(v64, v32, v32);
- // CHECK: @llvm.hexagon.V6.vmpybv.acc.128B
- __builtin_HEXAGON_V6_vmpybv_acc(v32, v16, v16);
+ __builtin_HEXAGON_V6_vmpybv_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vmpybv.acc
- __builtin_HEXAGON_V6_vmpybv(v16, v16);
- // CHECK: @llvm.hexagon.V6.vmpybv
- __builtin_HEXAGON_V6_vmpyewuh_128B(v32, v32);
- // CHECK: @llvm.hexagon.V6.vmpyewuh.128B
- __builtin_HEXAGON_V6_vmpyewuh(v16, v16);
+ __builtin_HEXAGON_V6_vmpybv_acc(v128, v64, v64);
+ // CHECK: @llvm.hexagon.V6.vmpybv.acc.128B
+ __builtin_HEXAGON_V6_vmpybv_acc_128B(v256, v128, v128);
// CHECK: @llvm.hexagon.V6.vmpyewuh
- __builtin_HEXAGON_V6_vmpyh_128B(v32, 0);
+ __builtin_HEXAGON_V6_vmpyewuh(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vmpyewuh.128B
+ __builtin_HEXAGON_V6_vmpyewuh_128B(v128, v128);
+ // CHECK: @llvm.hexagon.V6.vmpyewuh.64
+ __builtin_HEXAGON_V6_vmpyewuh_64(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vmpyewuh.64.128B
+ __builtin_HEXAGON_V6_vmpyewuh_64_128B(v128, v128);
+ // CHECK: @llvm.hexagon.V6.vmpyh
+ __builtin_HEXAGON_V6_vmpyh(v64, 0);
// CHECK: @llvm.hexagon.V6.vmpyh.128B
- __builtin_HEXAGON_V6_vmpyhsat_acc_128B(v64, v32, 0);
- // CHECK: @llvm.hexagon.V6.vmpyhsat.acc.128B
- __builtin_HEXAGON_V6_vmpyhsat_acc(v32, v16, 0);
+ __builtin_HEXAGON_V6_vmpyh_128B(v128, 0);
+ // CHECK: @llvm.hexagon.V6.vmpyh.acc
+ __builtin_HEXAGON_V6_vmpyh_acc(v128, v64, 0);
+ // CHECK: @llvm.hexagon.V6.vmpyh.acc.128B
+ __builtin_HEXAGON_V6_vmpyh_acc_128B(v256, v128, 0);
// CHECK: @llvm.hexagon.V6.vmpyhsat.acc
- __builtin_HEXAGON_V6_vmpyhsrs_128B(v32, 0);
- // CHECK: @llvm.hexagon.V6.vmpyhsrs.128B
- __builtin_HEXAGON_V6_vmpyhsrs(v16, 0);
+ __builtin_HEXAGON_V6_vmpyhsat_acc(v128, v64, 0);
+ // CHECK: @llvm.hexagon.V6.vmpyhsat.acc.128B
+ __builtin_HEXAGON_V6_vmpyhsat_acc_128B(v256, v128, 0);
// CHECK: @llvm.hexagon.V6.vmpyhsrs
- __builtin_HEXAGON_V6_vmpyhss_128B(v32, 0);
- // CHECK: @llvm.hexagon.V6.vmpyhss.128B
- __builtin_HEXAGON_V6_vmpyhss(v16, 0);
+ __builtin_HEXAGON_V6_vmpyhsrs(v64, 0);
+ // CHECK: @llvm.hexagon.V6.vmpyhsrs.128B
+ __builtin_HEXAGON_V6_vmpyhsrs_128B(v128, 0);
// CHECK: @llvm.hexagon.V6.vmpyhss
- __builtin_HEXAGON_V6_vmpyhus_128B(v32, v32);
+ __builtin_HEXAGON_V6_vmpyhss(v64, 0);
+ // CHECK: @llvm.hexagon.V6.vmpyhss.128B
+ __builtin_HEXAGON_V6_vmpyhss_128B(v128, 0);
+ // CHECK: @llvm.hexagon.V6.vmpyhus
+ __builtin_HEXAGON_V6_vmpyhus(v64, v64);
// CHECK: @llvm.hexagon.V6.vmpyhus.128B
- __builtin_HEXAGON_V6_vmpyhus_acc_128B(v64, v32, v32);
- // CHECK: @llvm.hexagon.V6.vmpyhus.acc.128B
- __builtin_HEXAGON_V6_vmpyhus_acc(v32, v16, v16);
+ __builtin_HEXAGON_V6_vmpyhus_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vmpyhus.acc
- __builtin_HEXAGON_V6_vmpyhus(v16, v16);
- // CHECK: @llvm.hexagon.V6.vmpyhus
- __builtin_HEXAGON_V6_vmpyhv_128B(v32, v32);
+ __builtin_HEXAGON_V6_vmpyhus_acc(v128, v64, v64);
+ // CHECK: @llvm.hexagon.V6.vmpyhus.acc.128B
+ __builtin_HEXAGON_V6_vmpyhus_acc_128B(v256, v128, v128);
+ // CHECK: @llvm.hexagon.V6.vmpyhv
+ __builtin_HEXAGON_V6_vmpyhv(v64, v64);
// CHECK: @llvm.hexagon.V6.vmpyhv.128B
- __builtin_HEXAGON_V6_vmpyh(v16, 0);
- // CHECK: @llvm.hexagon.V6.vmpyh
- __builtin_HEXAGON_V6_vmpyhv_acc_128B(v64, v32, v32);
- // CHECK: @llvm.hexagon.V6.vmpyhv.acc.128B
- __builtin_HEXAGON_V6_vmpyhv_acc(v32, v16, v16);
+ __builtin_HEXAGON_V6_vmpyhv_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vmpyhv.acc
- __builtin_HEXAGON_V6_vmpyhvsrs_128B(v32, v32);
- // CHECK: @llvm.hexagon.V6.vmpyhvsrs.128B
- __builtin_HEXAGON_V6_vmpyhvsrs(v16, v16);
+ __builtin_HEXAGON_V6_vmpyhv_acc(v128, v64, v64);
+ // CHECK: @llvm.hexagon.V6.vmpyhv.acc.128B
+ __builtin_HEXAGON_V6_vmpyhv_acc_128B(v256, v128, v128);
// CHECK: @llvm.hexagon.V6.vmpyhvsrs
- __builtin_HEXAGON_V6_vmpyhv(v16, v16);
- // CHECK: @llvm.hexagon.V6.vmpyhv
- __builtin_HEXAGON_V6_vmpyieoh_128B(v32, v32);
- // CHECK: @llvm.hexagon.V6.vmpyieoh.128B
- __builtin_HEXAGON_V6_vmpyieoh(v16, v16);
+ __builtin_HEXAGON_V6_vmpyhvsrs(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vmpyhvsrs.128B
+ __builtin_HEXAGON_V6_vmpyhvsrs_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vmpyieoh
- __builtin_HEXAGON_V6_vmpyiewh_acc_128B(v32, v32, v32);
- // CHECK: @llvm.hexagon.V6.vmpyiewh.acc.128B
- __builtin_HEXAGON_V6_vmpyiewh_acc(v16, v16, v16);
+ __builtin_HEXAGON_V6_vmpyieoh(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vmpyieoh.128B
+ __builtin_HEXAGON_V6_vmpyieoh_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vmpyiewh.acc
- __builtin_HEXAGON_V6_vmpyiewuh_128B(v32, v32);
+ __builtin_HEXAGON_V6_vmpyiewh_acc(v64, v64, v64);
+ // CHECK: @llvm.hexagon.V6.vmpyiewh.acc.128B
+ __builtin_HEXAGON_V6_vmpyiewh_acc_128B(v128, v128, v128);
+ // CHECK: @llvm.hexagon.V6.vmpyiewuh
+ __builtin_HEXAGON_V6_vmpyiewuh(v64, v64);
// CHECK: @llvm.hexagon.V6.vmpyiewuh.128B
- __builtin_HEXAGON_V6_vmpyiewuh_acc_128B(v32, v32, v32);
- // CHECK: @llvm.hexagon.V6.vmpyiewuh.acc.128B
- __builtin_HEXAGON_V6_vmpyiewuh_acc(v16, v16, v16);
+ __builtin_HEXAGON_V6_vmpyiewuh_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vmpyiewuh.acc
- __builtin_HEXAGON_V6_vmpyiewuh(v16, v16);
- // CHECK: @llvm.hexagon.V6.vmpyiewuh
- __builtin_HEXAGON_V6_vmpyih_128B(v32, v32);
+ __builtin_HEXAGON_V6_vmpyiewuh_acc(v64, v64, v64);
+ // CHECK: @llvm.hexagon.V6.vmpyiewuh.acc.128B
+ __builtin_HEXAGON_V6_vmpyiewuh_acc_128B(v128, v128, v128);
+ // CHECK: @llvm.hexagon.V6.vmpyih
+ __builtin_HEXAGON_V6_vmpyih(v64, v64);
// CHECK: @llvm.hexagon.V6.vmpyih.128B
- __builtin_HEXAGON_V6_vmpyih_acc_128B(v32, v32, v32);
- // CHECK: @llvm.hexagon.V6.vmpyih.acc.128B
- __builtin_HEXAGON_V6_vmpyih_acc(v16, v16, v16);
+ __builtin_HEXAGON_V6_vmpyih_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vmpyih.acc
- __builtin_HEXAGON_V6_vmpyihb_128B(v32, 0);
+ __builtin_HEXAGON_V6_vmpyih_acc(v64, v64, v64);
+ // CHECK: @llvm.hexagon.V6.vmpyih.acc.128B
+ __builtin_HEXAGON_V6_vmpyih_acc_128B(v128, v128, v128);
+ // CHECK: @llvm.hexagon.V6.vmpyihb
+ __builtin_HEXAGON_V6_vmpyihb(v64, 0);
// CHECK: @llvm.hexagon.V6.vmpyihb.128B
- __builtin_HEXAGON_V6_vmpyihb_acc_128B(v32, v32, 0);
- // CHECK: @llvm.hexagon.V6.vmpyihb.acc.128B
- __builtin_HEXAGON_V6_vmpyihb_acc(v16, v16, 0);
+ __builtin_HEXAGON_V6_vmpyihb_128B(v128, 0);
// CHECK: @llvm.hexagon.V6.vmpyihb.acc
- __builtin_HEXAGON_V6_vmpyihb(v16, 0);
- // CHECK: @llvm.hexagon.V6.vmpyihb
- __builtin_HEXAGON_V6_vmpyih(v16, v16);
- // CHECK: @llvm.hexagon.V6.vmpyih
- __builtin_HEXAGON_V6_vmpyiowh_128B(v32, v32);
- // CHECK: @llvm.hexagon.V6.vmpyiowh.128B
- __builtin_HEXAGON_V6_vmpyiowh(v16, v16);
+ __builtin_HEXAGON_V6_vmpyihb_acc(v64, v64, 0);
+ // CHECK: @llvm.hexagon.V6.vmpyihb.acc.128B
+ __builtin_HEXAGON_V6_vmpyihb_acc_128B(v128, v128, 0);
// CHECK: @llvm.hexagon.V6.vmpyiowh
- __builtin_HEXAGON_V6_vmpyiwb_128B(v32, 0);
+ __builtin_HEXAGON_V6_vmpyiowh(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vmpyiowh.128B
+ __builtin_HEXAGON_V6_vmpyiowh_128B(v128, v128);
+ // CHECK: @llvm.hexagon.V6.vmpyiwb
+ __builtin_HEXAGON_V6_vmpyiwb(v64, 0);
// CHECK: @llvm.hexagon.V6.vmpyiwb.128B
- __builtin_HEXAGON_V6_vmpyiwb_acc_128B(v32, v32, 0);
- // CHECK: @llvm.hexagon.V6.vmpyiwb.acc.128B
- __builtin_HEXAGON_V6_vmpyiwb_acc(v16, v16, 0);
+ __builtin_HEXAGON_V6_vmpyiwb_128B(v128, 0);
// CHECK: @llvm.hexagon.V6.vmpyiwb.acc
- __builtin_HEXAGON_V6_vmpyiwb(v16, 0);
- // CHECK: @llvm.hexagon.V6.vmpyiwb
- __builtin_HEXAGON_V6_vmpyiwh_128B(v32, 0);
+ __builtin_HEXAGON_V6_vmpyiwb_acc(v64, v64, 0);
+ // CHECK: @llvm.hexagon.V6.vmpyiwb.acc.128B
+ __builtin_HEXAGON_V6_vmpyiwb_acc_128B(v128, v128, 0);
+ // CHECK: @llvm.hexagon.V6.vmpyiwh
+ __builtin_HEXAGON_V6_vmpyiwh(v64, 0);
// CHECK: @llvm.hexagon.V6.vmpyiwh.128B
- __builtin_HEXAGON_V6_vmpyiwh_acc_128B(v32, v32, 0);
- // CHECK: @llvm.hexagon.V6.vmpyiwh.acc.128B
- __builtin_HEXAGON_V6_vmpyiwh_acc(v16, v16, 0);
+ __builtin_HEXAGON_V6_vmpyiwh_128B(v128, 0);
// CHECK: @llvm.hexagon.V6.vmpyiwh.acc
- __builtin_HEXAGON_V6_vmpyiwh(v16, 0);
- // CHECK: @llvm.hexagon.V6.vmpyiwh
- __builtin_HEXAGON_V6_vmpyowh_128B(v32, v32);
+ __builtin_HEXAGON_V6_vmpyiwh_acc(v64, v64, 0);
+ // CHECK: @llvm.hexagon.V6.vmpyiwh.acc.128B
+ __builtin_HEXAGON_V6_vmpyiwh_acc_128B(v128, v128, 0);
+ // CHECK: @llvm.hexagon.V6.vmpyiwub
+ __builtin_HEXAGON_V6_vmpyiwub(v64, 0);
+ // CHECK: @llvm.hexagon.V6.vmpyiwub.128B
+ __builtin_HEXAGON_V6_vmpyiwub_128B(v128, 0);
+ // CHECK: @llvm.hexagon.V6.vmpyiwub.acc
+ __builtin_HEXAGON_V6_vmpyiwub_acc(v64, v64, 0);
+ // CHECK: @llvm.hexagon.V6.vmpyiwub.acc.128B
+ __builtin_HEXAGON_V6_vmpyiwub_acc_128B(v128, v128, 0);
+ // CHECK: @llvm.hexagon.V6.vmpyowh
+ __builtin_HEXAGON_V6_vmpyowh(v64, v64);
// CHECK: @llvm.hexagon.V6.vmpyowh.128B
- __builtin_HEXAGON_V6_vmpyowh_rnd_128B(v32, v32);
+ __builtin_HEXAGON_V6_vmpyowh_128B(v128, v128);
+ // CHECK: @llvm.hexagon.V6.vmpyowh.64.acc
+ __builtin_HEXAGON_V6_vmpyowh_64_acc(v128, v64, v64);
+ // CHECK: @llvm.hexagon.V6.vmpyowh.64.acc.128B
+ __builtin_HEXAGON_V6_vmpyowh_64_acc_128B(v256, v128, v128);
+ // CHECK: @llvm.hexagon.V6.vmpyowh.rnd
+ __builtin_HEXAGON_V6_vmpyowh_rnd(v64, v64);
// CHECK: @llvm.hexagon.V6.vmpyowh.rnd.128B
- __builtin_HEXAGON_V6_vmpyowh_rnd_sacc_128B(v32, v32, v32);
- // CHECK: @llvm.hexagon.V6.vmpyowh.rnd.sacc.128B
- __builtin_HEXAGON_V6_vmpyowh_rnd_sacc(v16, v16, v16);
+ __builtin_HEXAGON_V6_vmpyowh_rnd_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vmpyowh.rnd.sacc
- __builtin_HEXAGON_V6_vmpyowh_rnd(v16, v16);
- // CHECK: @llvm.hexagon.V6.vmpyowh.rnd
- __builtin_HEXAGON_V6_vmpyowh_sacc_128B(v32, v32, v32);
- // CHECK: @llvm.hexagon.V6.vmpyowh.sacc.128B
- __builtin_HEXAGON_V6_vmpyowh_sacc(v16, v16, v16);
+ __builtin_HEXAGON_V6_vmpyowh_rnd_sacc(v64, v64, v64);
+ // CHECK: @llvm.hexagon.V6.vmpyowh.rnd.sacc.128B
+ __builtin_HEXAGON_V6_vmpyowh_rnd_sacc_128B(v128, v128, v128);
// CHECK: @llvm.hexagon.V6.vmpyowh.sacc
- __builtin_HEXAGON_V6_vmpyowh(v16, v16);
- // CHECK: @llvm.hexagon.V6.vmpyowh
- __builtin_HEXAGON_V6_vmpyub_128B(v32, 0);
+ __builtin_HEXAGON_V6_vmpyowh_sacc(v64, v64, v64);
+ // CHECK: @llvm.hexagon.V6.vmpyowh.sacc.128B
+ __builtin_HEXAGON_V6_vmpyowh_sacc_128B(v128, v128, v128);
+ // CHECK: @llvm.hexagon.V6.vmpyub
+ __builtin_HEXAGON_V6_vmpyub(v64, 0);
// CHECK: @llvm.hexagon.V6.vmpyub.128B
- __builtin_HEXAGON_V6_vmpyub_acc_128B(v64, v32, 0);
- // CHECK: @llvm.hexagon.V6.vmpyub.acc.128B
- __builtin_HEXAGON_V6_vmpyub_acc(v32, v16, 0);
+ __builtin_HEXAGON_V6_vmpyub_128B(v128, 0);
// CHECK: @llvm.hexagon.V6.vmpyub.acc
- __builtin_HEXAGON_V6_vmpyubv_128B(v32, v32);
+ __builtin_HEXAGON_V6_vmpyub_acc(v128, v64, 0);
+ // CHECK: @llvm.hexagon.V6.vmpyub.acc.128B
+ __builtin_HEXAGON_V6_vmpyub_acc_128B(v256, v128, 0);
+ // CHECK: @llvm.hexagon.V6.vmpyubv
+ __builtin_HEXAGON_V6_vmpyubv(v64, v64);
// CHECK: @llvm.hexagon.V6.vmpyubv.128B
- __builtin_HEXAGON_V6_vmpyub(v16, 0);
- // CHECK: @llvm.hexagon.V6.vmpyub
- __builtin_HEXAGON_V6_vmpyubv_acc_128B(v64, v32, v32);
- // CHECK: @llvm.hexagon.V6.vmpyubv.acc.128B
- __builtin_HEXAGON_V6_vmpyubv_acc(v32, v16, v16);
+ __builtin_HEXAGON_V6_vmpyubv_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vmpyubv.acc
- __builtin_HEXAGON_V6_vmpyubv(v16, v16);
- // CHECK: @llvm.hexagon.V6.vmpyubv
- __builtin_HEXAGON_V6_vmpyuh_128B(v32, 0);
+ __builtin_HEXAGON_V6_vmpyubv_acc(v128, v64, v64);
+ // CHECK: @llvm.hexagon.V6.vmpyubv.acc.128B
+ __builtin_HEXAGON_V6_vmpyubv_acc_128B(v256, v128, v128);
+ // CHECK: @llvm.hexagon.V6.vmpyuh
+ __builtin_HEXAGON_V6_vmpyuh(v64, 0);
// CHECK: @llvm.hexagon.V6.vmpyuh.128B
- __builtin_HEXAGON_V6_vmpyuh_acc_128B(v64, v32, 0);
- // CHECK: @llvm.hexagon.V6.vmpyuh.acc.128B
- __builtin_HEXAGON_V6_vmpyuh_acc(v32, v16, 0);
+ __builtin_HEXAGON_V6_vmpyuh_128B(v128, 0);
// CHECK: @llvm.hexagon.V6.vmpyuh.acc
- __builtin_HEXAGON_V6_vmpyuhv_128B(v32, v32);
+ __builtin_HEXAGON_V6_vmpyuh_acc(v128, v64, 0);
+ // CHECK: @llvm.hexagon.V6.vmpyuh.acc.128B
+ __builtin_HEXAGON_V6_vmpyuh_acc_128B(v256, v128, 0);
+ // CHECK: @llvm.hexagon.V6.vmpyuhe
+ __builtin_HEXAGON_V6_vmpyuhe(v64, 0);
+ // CHECK: @llvm.hexagon.V6.vmpyuhe.128B
+ __builtin_HEXAGON_V6_vmpyuhe_128B(v128, 0);
+ // CHECK: @llvm.hexagon.V6.vmpyuhe.acc
+ __builtin_HEXAGON_V6_vmpyuhe_acc(v64, v64, 0);
+ // CHECK: @llvm.hexagon.V6.vmpyuhe.acc.128B
+ __builtin_HEXAGON_V6_vmpyuhe_acc_128B(v128, v128, 0);
+ // CHECK: @llvm.hexagon.V6.vmpyuhv
+ __builtin_HEXAGON_V6_vmpyuhv(v64, v64);
// CHECK: @llvm.hexagon.V6.vmpyuhv.128B
- __builtin_HEXAGON_V6_vmpyuh(v16, 0);
- // CHECK: @llvm.hexagon.V6.vmpyuh
- __builtin_HEXAGON_V6_vmpyuhv_acc_128B(v64, v32, v32);
- // CHECK: @llvm.hexagon.V6.vmpyuhv.acc.128B
- __builtin_HEXAGON_V6_vmpyuhv_acc(v32, v16, v16);
+ __builtin_HEXAGON_V6_vmpyuhv_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vmpyuhv.acc
- __builtin_HEXAGON_V6_vmpyuhv(v16, v16);
- // CHECK: @llvm.hexagon.V6.vmpyuhv
- __builtin_HEXAGON_V6_vmux_128B(v32, v32, v32);
- // CHECK: @llvm.hexagon.V6.vmux.128B
- __builtin_HEXAGON_V6_vmux(v16, v16, v16);
+ __builtin_HEXAGON_V6_vmpyuhv_acc(v128, v64, v64);
+ // CHECK: @llvm.hexagon.V6.vmpyuhv.acc.128B
+ __builtin_HEXAGON_V6_vmpyuhv_acc_128B(v256, v128, v128);
// CHECK: @llvm.hexagon.V6.vmux
- __builtin_HEXAGON_V6_vnavgh_128B(v32, v32);
- // CHECK: @llvm.hexagon.V6.vnavgh.128B
- __builtin_HEXAGON_V6_vnavgh(v16, v16);
+ __builtin_HEXAGON_V6_vmux(v64, v64, v64);
+ // CHECK: @llvm.hexagon.V6.vmux.128B
+ __builtin_HEXAGON_V6_vmux_128B(v128, v128, v128);
+ // CHECK: @llvm.hexagon.V6.vnavgb
+ __builtin_HEXAGON_V6_vnavgb(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vnavgb.128B
+ __builtin_HEXAGON_V6_vnavgb_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vnavgh
- __builtin_HEXAGON_V6_vnavgub_128B(v32, v32);
- // CHECK: @llvm.hexagon.V6.vnavgub.128B
- __builtin_HEXAGON_V6_vnavgub(v16, v16);
+ __builtin_HEXAGON_V6_vnavgh(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vnavgh.128B
+ __builtin_HEXAGON_V6_vnavgh_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vnavgub
- __builtin_HEXAGON_V6_vnavgw_128B(v32, v32);
- // CHECK: @llvm.hexagon.V6.vnavgw.128B
- __builtin_HEXAGON_V6_vnavgw(v16, v16);
+ __builtin_HEXAGON_V6_vnavgub(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vnavgub.128B
+ __builtin_HEXAGON_V6_vnavgub_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vnavgw
- __builtin_HEXAGON_V6_vnormamth_128B(v32);
- // CHECK: @llvm.hexagon.V6.vnormamth.128B
- __builtin_HEXAGON_V6_vnormamth(v16);
+ __builtin_HEXAGON_V6_vnavgw(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vnavgw.128B
+ __builtin_HEXAGON_V6_vnavgw_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vnormamth
- __builtin_HEXAGON_V6_vnormamtw_128B(v32);
- // CHECK: @llvm.hexagon.V6.vnormamtw.128B
- __builtin_HEXAGON_V6_vnormamtw(v16);
+ __builtin_HEXAGON_V6_vnormamth(v64);
+ // CHECK: @llvm.hexagon.V6.vnormamth.128B
+ __builtin_HEXAGON_V6_vnormamth_128B(v128);
// CHECK: @llvm.hexagon.V6.vnormamtw
- __builtin_HEXAGON_V6_vnot_128B(v32);
- // CHECK: @llvm.hexagon.V6.vnot.128B
- __builtin_HEXAGON_V6_vnot(v16);
+ __builtin_HEXAGON_V6_vnormamtw(v64);
+ // CHECK: @llvm.hexagon.V6.vnormamtw.128B
+ __builtin_HEXAGON_V6_vnormamtw_128B(v128);
// CHECK: @llvm.hexagon.V6.vnot
- __builtin_HEXAGON_V6_vor_128B(v32, v32);
- // CHECK: @llvm.hexagon.V6.vor.128B
- __builtin_HEXAGON_V6_vor(v16, v16);
+ __builtin_HEXAGON_V6_vnot(v64);
+ // CHECK: @llvm.hexagon.V6.vnot.128B
+ __builtin_HEXAGON_V6_vnot_128B(v128);
// CHECK: @llvm.hexagon.V6.vor
- __builtin_HEXAGON_V6_vpackeb_128B(v32, v32);
- // CHECK: @llvm.hexagon.V6.vpackeb.128B
- __builtin_HEXAGON_V6_vpackeb(v16, v16);
+ __builtin_HEXAGON_V6_vor(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vor.128B
+ __builtin_HEXAGON_V6_vor_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vpackeb
- __builtin_HEXAGON_V6_vpackeh_128B(v32, v32);
- // CHECK: @llvm.hexagon.V6.vpackeh.128B
- __builtin_HEXAGON_V6_vpackeh(v16, v16);
+ __builtin_HEXAGON_V6_vpackeb(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vpackeb.128B
+ __builtin_HEXAGON_V6_vpackeb_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vpackeh
- __builtin_HEXAGON_V6_vpackhb_sat_128B(v32, v32);
- // CHECK: @llvm.hexagon.V6.vpackhb.sat.128B
- __builtin_HEXAGON_V6_vpackhb_sat(v16, v16);
+ __builtin_HEXAGON_V6_vpackeh(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vpackeh.128B
+ __builtin_HEXAGON_V6_vpackeh_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vpackhb.sat
- __builtin_HEXAGON_V6_vpackhub_sat_128B(v32, v32);
- // CHECK: @llvm.hexagon.V6.vpackhub.sat.128B
- __builtin_HEXAGON_V6_vpackhub_sat(v16, v16);
+ __builtin_HEXAGON_V6_vpackhb_sat(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vpackhb.sat.128B
+ __builtin_HEXAGON_V6_vpackhb_sat_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vpackhub.sat
- __builtin_HEXAGON_V6_vpackob_128B(v32, v32);
- // CHECK: @llvm.hexagon.V6.vpackob.128B
- __builtin_HEXAGON_V6_vpackob(v16, v16);
+ __builtin_HEXAGON_V6_vpackhub_sat(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vpackhub.sat.128B
+ __builtin_HEXAGON_V6_vpackhub_sat_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vpackob
- __builtin_HEXAGON_V6_vpackoh_128B(v32, v32);
- // CHECK: @llvm.hexagon.V6.vpackoh.128B
- __builtin_HEXAGON_V6_vpackoh(v16, v16);
+ __builtin_HEXAGON_V6_vpackob(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vpackob.128B
+ __builtin_HEXAGON_V6_vpackob_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vpackoh
- __builtin_HEXAGON_V6_vpackwh_sat_128B(v32, v32);
- // CHECK: @llvm.hexagon.V6.vpackwh.sat.128B
- __builtin_HEXAGON_V6_vpackwh_sat(v16, v16);
+ __builtin_HEXAGON_V6_vpackoh(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vpackoh.128B
+ __builtin_HEXAGON_V6_vpackoh_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vpackwh.sat
- __builtin_HEXAGON_V6_vpackwuh_sat_128B(v32, v32);
- // CHECK: @llvm.hexagon.V6.vpackwuh.sat.128B
- __builtin_HEXAGON_V6_vpackwuh_sat(v16, v16);
+ __builtin_HEXAGON_V6_vpackwh_sat(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vpackwh.sat.128B
+ __builtin_HEXAGON_V6_vpackwh_sat_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vpackwuh.sat
- __builtin_HEXAGON_V6_vpopcounth_128B(v32);
- // CHECK: @llvm.hexagon.V6.vpopcounth.128B
- __builtin_HEXAGON_V6_vpopcounth(v16);
+ __builtin_HEXAGON_V6_vpackwuh_sat(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vpackwuh.sat.128B
+ __builtin_HEXAGON_V6_vpackwuh_sat_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vpopcounth
- __builtin_HEXAGON_V6_vrdelta_128B(v32, v32);
- // CHECK: @llvm.hexagon.V6.vrdelta.128B
- __builtin_HEXAGON_V6_vrdelta(v16, v16);
+ __builtin_HEXAGON_V6_vpopcounth(v64);
+ // CHECK: @llvm.hexagon.V6.vpopcounth.128B
+ __builtin_HEXAGON_V6_vpopcounth_128B(v128);
+ // CHECK: @llvm.hexagon.V6.vprefixqb
+ __builtin_HEXAGON_V6_vprefixqb(v64);
+ // CHECK: @llvm.hexagon.V6.vprefixqb.128B
+ __builtin_HEXAGON_V6_vprefixqb_128B(v128);
+ // CHECK: @llvm.hexagon.V6.vprefixqh
+ __builtin_HEXAGON_V6_vprefixqh(v64);
+ // CHECK: @llvm.hexagon.V6.vprefixqh.128B
+ __builtin_HEXAGON_V6_vprefixqh_128B(v128);
+ // CHECK: @llvm.hexagon.V6.vprefixqw
+ __builtin_HEXAGON_V6_vprefixqw(v64);
+ // CHECK: @llvm.hexagon.V6.vprefixqw.128B
+ __builtin_HEXAGON_V6_vprefixqw_128B(v128);
// CHECK: @llvm.hexagon.V6.vrdelta
- __builtin_HEXAGON_V6_vrmpybus_128B(v32, 0);
+ __builtin_HEXAGON_V6_vrdelta(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vrdelta.128B
+ __builtin_HEXAGON_V6_vrdelta_128B(v128, v128);
+ // CHECK: @llvm.hexagon.V6.vrmpybub.rtt
+ __builtin_HEXAGON_V6_vrmpybub_rtt(v64, 0);
+ // CHECK: @llvm.hexagon.V6.vrmpybub.rtt.128B
+ __builtin_HEXAGON_V6_vrmpybub_rtt_128B(v128, 0);
+ // CHECK: @llvm.hexagon.V6.vrmpybub.rtt.acc
+ __builtin_HEXAGON_V6_vrmpybub_rtt_acc(v128, v64, 0);
+ // CHECK: @llvm.hexagon.V6.vrmpybub.rtt.acc.128B
+ __builtin_HEXAGON_V6_vrmpybub_rtt_acc_128B(v256, v128, 0);
+ // CHECK: @llvm.hexagon.V6.vrmpybus
+ __builtin_HEXAGON_V6_vrmpybus(v64, 0);
// CHECK: @llvm.hexagon.V6.vrmpybus.128B
- __builtin_HEXAGON_V6_vrmpybus_acc_128B(v32, v32, 0);
- // CHECK: @llvm.hexagon.V6.vrmpybus.acc.128B
- __builtin_HEXAGON_V6_vrmpybus_acc(v16, v16, 0);
+ __builtin_HEXAGON_V6_vrmpybus_128B(v128, 0);
// CHECK: @llvm.hexagon.V6.vrmpybus.acc
- __builtin_HEXAGON_V6_vrmpybusi_128B(v64, 0, 0);
+ __builtin_HEXAGON_V6_vrmpybus_acc(v64, v64, 0);
+ // CHECK: @llvm.hexagon.V6.vrmpybus.acc.128B
+ __builtin_HEXAGON_V6_vrmpybus_acc_128B(v128, v128, 0);
+ // CHECK: @llvm.hexagon.V6.vrmpybusi
+ __builtin_HEXAGON_V6_vrmpybusi(v128, 0, 0);
// CHECK: @llvm.hexagon.V6.vrmpybusi.128B
- __builtin_HEXAGON_V6_vrmpybusi_acc_128B(v64, v64, 0, 0);
- // CHECK: @llvm.hexagon.V6.vrmpybusi.acc.128B
- __builtin_HEXAGON_V6_vrmpybusi_acc(v32, v32, 0, 0);
+ __builtin_HEXAGON_V6_vrmpybusi_128B(v256, 0, 0);
// CHECK: @llvm.hexagon.V6.vrmpybusi.acc
- __builtin_HEXAGON_V6_vrmpybusi(v32, 0, 0);
- // CHECK: @llvm.hexagon.V6.vrmpybusi
- __builtin_HEXAGON_V6_vrmpybusv_128B(v32, v32);
+ __builtin_HEXAGON_V6_vrmpybusi_acc(v128, v128, 0, 0);
+ // CHECK: @llvm.hexagon.V6.vrmpybusi.acc.128B
+ __builtin_HEXAGON_V6_vrmpybusi_acc_128B(v256, v256, 0, 0);
+ // CHECK: @llvm.hexagon.V6.vrmpybusv
+ __builtin_HEXAGON_V6_vrmpybusv(v64, v64);
// CHECK: @llvm.hexagon.V6.vrmpybusv.128B
- __builtin_HEXAGON_V6_vrmpybus(v16, 0);
- // CHECK: @llvm.hexagon.V6.vrmpybus
- __builtin_HEXAGON_V6_vrmpybusv_acc_128B(v32, v32, v32);
- // CHECK: @llvm.hexagon.V6.vrmpybusv.acc.128B
- __builtin_HEXAGON_V6_vrmpybusv_acc(v16, v16, v16);
+ __builtin_HEXAGON_V6_vrmpybusv_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vrmpybusv.acc
- __builtin_HEXAGON_V6_vrmpybusv(v16, v16);
- // CHECK: @llvm.hexagon.V6.vrmpybusv
- __builtin_HEXAGON_V6_vrmpybv_128B(v32, v32);
+ __builtin_HEXAGON_V6_vrmpybusv_acc(v64, v64, v64);
+ // CHECK: @llvm.hexagon.V6.vrmpybusv.acc.128B
+ __builtin_HEXAGON_V6_vrmpybusv_acc_128B(v128, v128, v128);
+ // CHECK: @llvm.hexagon.V6.vrmpybv
+ __builtin_HEXAGON_V6_vrmpybv(v64, v64);
// CHECK: @llvm.hexagon.V6.vrmpybv.128B
- __builtin_HEXAGON_V6_vrmpybv_acc_128B(v32, v32, v32);
- // CHECK: @llvm.hexagon.V6.vrmpybv.acc.128B
- __builtin_HEXAGON_V6_vrmpybv_acc(v16, v16, v16);
+ __builtin_HEXAGON_V6_vrmpybv_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vrmpybv.acc
- __builtin_HEXAGON_V6_vrmpybv(v16, v16);
- // CHECK: @llvm.hexagon.V6.vrmpybv
- __builtin_HEXAGON_V6_vrmpyub_128B(v32, 0);
+ __builtin_HEXAGON_V6_vrmpybv_acc(v64, v64, v64);
+ // CHECK: @llvm.hexagon.V6.vrmpybv.acc.128B
+ __builtin_HEXAGON_V6_vrmpybv_acc_128B(v128, v128, v128);
+ // CHECK: @llvm.hexagon.V6.vrmpyub
+ __builtin_HEXAGON_V6_vrmpyub(v64, 0);
// CHECK: @llvm.hexagon.V6.vrmpyub.128B
- __builtin_HEXAGON_V6_vrmpyub_acc_128B(v32, v32, 0);
- // CHECK: @llvm.hexagon.V6.vrmpyub.acc.128B
- __builtin_HEXAGON_V6_vrmpyub_acc(v16, v16, 0);
+ __builtin_HEXAGON_V6_vrmpyub_128B(v128, 0);
// CHECK: @llvm.hexagon.V6.vrmpyub.acc
- __builtin_HEXAGON_V6_vrmpyubi_128B(v64, 0, 0);
+ __builtin_HEXAGON_V6_vrmpyub_acc(v64, v64, 0);
+ // CHECK: @llvm.hexagon.V6.vrmpyub.acc.128B
+ __builtin_HEXAGON_V6_vrmpyub_acc_128B(v128, v128, 0);
+ // CHECK: @llvm.hexagon.V6.vrmpyub.rtt
+ __builtin_HEXAGON_V6_vrmpyub_rtt(v64, 0);
+ // CHECK: @llvm.hexagon.V6.vrmpyub.rtt.128B
+ __builtin_HEXAGON_V6_vrmpyub_rtt_128B(v128, 0);
+ // CHECK: @llvm.hexagon.V6.vrmpyub.rtt.acc
+ __builtin_HEXAGON_V6_vrmpyub_rtt_acc(v128, v64, 0);
+ // CHECK: @llvm.hexagon.V6.vrmpyub.rtt.acc.128B
+ __builtin_HEXAGON_V6_vrmpyub_rtt_acc_128B(v256, v128, 0);
+ // CHECK: @llvm.hexagon.V6.vrmpyubi
+ __builtin_HEXAGON_V6_vrmpyubi(v128, 0, 0);
// CHECK: @llvm.hexagon.V6.vrmpyubi.128B
- __builtin_HEXAGON_V6_vrmpyubi_acc_128B(v64, v64, 0, 0);
- // CHECK: @llvm.hexagon.V6.vrmpyubi.acc.128B
- __builtin_HEXAGON_V6_vrmpyubi_acc(v32, v32, 0, 0);
+ __builtin_HEXAGON_V6_vrmpyubi_128B(v256, 0, 0);
// CHECK: @llvm.hexagon.V6.vrmpyubi.acc
- __builtin_HEXAGON_V6_vrmpyubi(v32, 0, 0);
- // CHECK: @llvm.hexagon.V6.vrmpyubi
- __builtin_HEXAGON_V6_vrmpyubv_128B(v32, v32);
+ __builtin_HEXAGON_V6_vrmpyubi_acc(v128, v128, 0, 0);
+ // CHECK: @llvm.hexagon.V6.vrmpyubi.acc.128B
+ __builtin_HEXAGON_V6_vrmpyubi_acc_128B(v256, v256, 0, 0);
+ // CHECK: @llvm.hexagon.V6.vrmpyubv
+ __builtin_HEXAGON_V6_vrmpyubv(v64, v64);
// CHECK: @llvm.hexagon.V6.vrmpyubv.128B
- __builtin_HEXAGON_V6_vrmpyub(v16, 0);
- // CHECK: @llvm.hexagon.V6.vrmpyub
- __builtin_HEXAGON_V6_vrmpyubv_acc_128B(v32, v32, v32);
- // CHECK: @llvm.hexagon.V6.vrmpyubv.acc.128B
- __builtin_HEXAGON_V6_vrmpyubv_acc(v16, v16, v16);
+ __builtin_HEXAGON_V6_vrmpyubv_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vrmpyubv.acc
- __builtin_HEXAGON_V6_vrmpyubv(v16, v16);
- // CHECK: @llvm.hexagon.V6.vrmpyubv
- __builtin_HEXAGON_V6_vror_128B(v32, 0);
- // CHECK: @llvm.hexagon.V6.vror.128B
- __builtin_HEXAGON_V6_vror(v16, 0);
+ __builtin_HEXAGON_V6_vrmpyubv_acc(v64, v64, v64);
+ // CHECK: @llvm.hexagon.V6.vrmpyubv.acc.128B
+ __builtin_HEXAGON_V6_vrmpyubv_acc_128B(v128, v128, v128);
// CHECK: @llvm.hexagon.V6.vror
- __builtin_HEXAGON_V6_vroundhb_128B(v32, v32);
- // CHECK: @llvm.hexagon.V6.vroundhb.128B
- __builtin_HEXAGON_V6_vroundhb(v16, v16);
+ __builtin_HEXAGON_V6_vror(v64, 0);
+ // CHECK: @llvm.hexagon.V6.vror.128B
+ __builtin_HEXAGON_V6_vror_128B(v128, 0);
// CHECK: @llvm.hexagon.V6.vroundhb
- __builtin_HEXAGON_V6_vroundhub_128B(v32, v32);
- // CHECK: @llvm.hexagon.V6.vroundhub.128B
- __builtin_HEXAGON_V6_vroundhub(v16, v16);
+ __builtin_HEXAGON_V6_vroundhb(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vroundhb.128B
+ __builtin_HEXAGON_V6_vroundhb_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vroundhub
- __builtin_HEXAGON_V6_vroundwh_128B(v32, v32);
- // CHECK: @llvm.hexagon.V6.vroundwh.128B
- __builtin_HEXAGON_V6_vroundwh(v16, v16);
+ __builtin_HEXAGON_V6_vroundhub(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vroundhub.128B
+ __builtin_HEXAGON_V6_vroundhub_128B(v128, v128);
+ // CHECK: @llvm.hexagon.V6.vrounduhub
+ __builtin_HEXAGON_V6_vrounduhub(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vrounduhub.128B
+ __builtin_HEXAGON_V6_vrounduhub_128B(v128, v128);
+ // CHECK: @llvm.hexagon.V6.vrounduwuh
+ __builtin_HEXAGON_V6_vrounduwuh(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vrounduwuh.128B
+ __builtin_HEXAGON_V6_vrounduwuh_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vroundwh
- __builtin_HEXAGON_V6_vroundwuh_128B(v32, v32);
- // CHECK: @llvm.hexagon.V6.vroundwuh.128B
- __builtin_HEXAGON_V6_vroundwuh(v16, v16);
+ __builtin_HEXAGON_V6_vroundwh(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vroundwh.128B
+ __builtin_HEXAGON_V6_vroundwh_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vroundwuh
- __builtin_HEXAGON_V6_vrsadubi_128B(v64, 0, 0);
+ __builtin_HEXAGON_V6_vroundwuh(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vroundwuh.128B
+ __builtin_HEXAGON_V6_vroundwuh_128B(v128, v128);
+ // CHECK: @llvm.hexagon.V6.vrsadubi
+ __builtin_HEXAGON_V6_vrsadubi(v128, 0, 0);
// CHECK: @llvm.hexagon.V6.vrsadubi.128B
- __builtin_HEXAGON_V6_vrsadubi_acc_128B(v64, v64, 0, 0);
- // CHECK: @llvm.hexagon.V6.vrsadubi.acc.128B
- __builtin_HEXAGON_V6_vrsadubi_acc(v32, v32, 0, 0);
+ __builtin_HEXAGON_V6_vrsadubi_128B(v256, 0, 0);
// CHECK: @llvm.hexagon.V6.vrsadubi.acc
- __builtin_HEXAGON_V6_vrsadubi(v32, 0, 0);
- // CHECK: @llvm.hexagon.V6.vrsadubi
- __builtin_HEXAGON_V6_vsathub_128B(v32, v32);
- // CHECK: @llvm.hexagon.V6.vsathub.128B
- __builtin_HEXAGON_V6_vsathub(v16, v16);
+ __builtin_HEXAGON_V6_vrsadubi_acc(v128, v128, 0, 0);
+ // CHECK: @llvm.hexagon.V6.vrsadubi.acc.128B
+ __builtin_HEXAGON_V6_vrsadubi_acc_128B(v256, v256, 0, 0);
// CHECK: @llvm.hexagon.V6.vsathub
- __builtin_HEXAGON_V6_vsatwh_128B(v32, v32);
- // CHECK: @llvm.hexagon.V6.vsatwh.128B
- __builtin_HEXAGON_V6_vsatwh(v16, v16);
+ __builtin_HEXAGON_V6_vsathub(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vsathub.128B
+ __builtin_HEXAGON_V6_vsathub_128B(v128, v128);
+ // CHECK: @llvm.hexagon.V6.vsatuwuh
+ __builtin_HEXAGON_V6_vsatuwuh(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vsatuwuh.128B
+ __builtin_HEXAGON_V6_vsatuwuh_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vsatwh
- __builtin_HEXAGON_V6_vsb_128B(v32);
- // CHECK: @llvm.hexagon.V6.vsb.128B
- __builtin_HEXAGON_V6_vsb(v16);
+ __builtin_HEXAGON_V6_vsatwh(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vsatwh.128B
+ __builtin_HEXAGON_V6_vsatwh_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vsb
- __builtin_HEXAGON_V6_vsh_128B(v32);
+ __builtin_HEXAGON_V6_vsb(v64);
+ // CHECK: @llvm.hexagon.V6.vsb.128B
+ __builtin_HEXAGON_V6_vsb_128B(v128);
+ // CHECK: @llvm.hexagon.V6.vscattermh
+ __builtin_HEXAGON_V6_vscattermh(0, 0, v64, v64);
+ // CHECK: @llvm.hexagon.V6.vscattermh.128B
+ __builtin_HEXAGON_V6_vscattermh_128B(0, 0, v128, v128);
+ // CHECK: @llvm.hexagon.V6.vscattermh.add
+ __builtin_HEXAGON_V6_vscattermh_add(0, 0, v64, v64);
+ // CHECK: @llvm.hexagon.V6.vscattermh.add.128B
+ __builtin_HEXAGON_V6_vscattermh_add_128B(0, 0, v128, v128);
+ // CHECK: @llvm.hexagon.V6.vscattermhq
+ __builtin_HEXAGON_V6_vscattermhq(v64, 0, 0, v64, v64);
+ // CHECK: @llvm.hexagon.V6.vscattermhq.128B
+ __builtin_HEXAGON_V6_vscattermhq_128B(v128, 0, 0, v128, v128);
+ // CHECK: @llvm.hexagon.V6.vscattermhw
+ __builtin_HEXAGON_V6_vscattermhw(0, 0, v128, v64);
+ // CHECK: @llvm.hexagon.V6.vscattermhw.128B
+ __builtin_HEXAGON_V6_vscattermhw_128B(0, 0, v256, v128);
+ // CHECK: @llvm.hexagon.V6.vscattermhw.add
+ __builtin_HEXAGON_V6_vscattermhw_add(0, 0, v128, v64);
+ // CHECK: @llvm.hexagon.V6.vscattermhw.add.128B
+ __builtin_HEXAGON_V6_vscattermhw_add_128B(0, 0, v256, v128);
+ // CHECK: @llvm.hexagon.V6.vscattermhwq
+ __builtin_HEXAGON_V6_vscattermhwq(v64, 0, 0, v128, v64);
+ // CHECK: @llvm.hexagon.V6.vscattermhwq.128B
+ __builtin_HEXAGON_V6_vscattermhwq_128B(v128, 0, 0, v256, v128);
+ // CHECK: @llvm.hexagon.V6.vscattermw
+ __builtin_HEXAGON_V6_vscattermw(0, 0, v64, v64);
+ // CHECK: @llvm.hexagon.V6.vscattermw.128B
+ __builtin_HEXAGON_V6_vscattermw_128B(0, 0, v128, v128);
+ // CHECK: @llvm.hexagon.V6.vscattermw.add
+ __builtin_HEXAGON_V6_vscattermw_add(0, 0, v64, v64);
+ // CHECK: @llvm.hexagon.V6.vscattermw.add.128B
+ __builtin_HEXAGON_V6_vscattermw_add_128B(0, 0, v128, v128);
+ // CHECK: @llvm.hexagon.V6.vscattermwq
+ __builtin_HEXAGON_V6_vscattermwq(v64, 0, 0, v64, v64);
+ // CHECK: @llvm.hexagon.V6.vscattermwq.128B
+ __builtin_HEXAGON_V6_vscattermwq_128B(v128, 0, 0, v128, v128);
+ // CHECK: @llvm.hexagon.V6.vsh
+ __builtin_HEXAGON_V6_vsh(v64);
// CHECK: @llvm.hexagon.V6.vsh.128B
- __builtin_HEXAGON_V6_vshufeh_128B(v32, v32);
- // CHECK: @llvm.hexagon.V6.vshufeh.128B
- __builtin_HEXAGON_V6_vshufeh(v16, v16);
+ __builtin_HEXAGON_V6_vsh_128B(v128);
// CHECK: @llvm.hexagon.V6.vshufeh
- __builtin_HEXAGON_V6_vshuffb_128B(v32);
- // CHECK: @llvm.hexagon.V6.vshuffb.128B
- __builtin_HEXAGON_V6_vshuffb(v16);
+ __builtin_HEXAGON_V6_vshufeh(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vshufeh.128B
+ __builtin_HEXAGON_V6_vshufeh_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vshuffb
- __builtin_HEXAGON_V6_vshuffeb_128B(v32, v32);
- // CHECK: @llvm.hexagon.V6.vshuffeb.128B
- __builtin_HEXAGON_V6_vshuffeb(v16, v16);
+ __builtin_HEXAGON_V6_vshuffb(v64);
+ // CHECK: @llvm.hexagon.V6.vshuffb.128B
+ __builtin_HEXAGON_V6_vshuffb_128B(v128);
// CHECK: @llvm.hexagon.V6.vshuffeb
- __builtin_HEXAGON_V6_vshuffh_128B(v32);
- // CHECK: @llvm.hexagon.V6.vshuffh.128B
- __builtin_HEXAGON_V6_vshuffh(v16);
+ __builtin_HEXAGON_V6_vshuffeb(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vshuffeb.128B
+ __builtin_HEXAGON_V6_vshuffeb_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vshuffh
- __builtin_HEXAGON_V6_vshuffob_128B(v32, v32);
- // CHECK: @llvm.hexagon.V6.vshuffob.128B
- __builtin_HEXAGON_V6_vshuffob(v16, v16);
+ __builtin_HEXAGON_V6_vshuffh(v64);
+ // CHECK: @llvm.hexagon.V6.vshuffh.128B
+ __builtin_HEXAGON_V6_vshuffh_128B(v128);
// CHECK: @llvm.hexagon.V6.vshuffob
- __builtin_HEXAGON_V6_vshuffvdd_128B(v32, v32, 0);
- // CHECK: @llvm.hexagon.V6.vshuffvdd.128B
- __builtin_HEXAGON_V6_vshuffvdd(v16, v16, 0);
+ __builtin_HEXAGON_V6_vshuffob(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vshuffob.128B
+ __builtin_HEXAGON_V6_vshuffob_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vshuffvdd
- __builtin_HEXAGON_V6_vshufoeb_128B(v32, v32);
- // CHECK: @llvm.hexagon.V6.vshufoeb.128B
- __builtin_HEXAGON_V6_vshufoeb(v16, v16);
+ __builtin_HEXAGON_V6_vshuffvdd(v64, v64, 0);
+ // CHECK: @llvm.hexagon.V6.vshuffvdd.128B
+ __builtin_HEXAGON_V6_vshuffvdd_128B(v128, v128, 0);
// CHECK: @llvm.hexagon.V6.vshufoeb
- __builtin_HEXAGON_V6_vshufoeh_128B(v32, v32);
- // CHECK: @llvm.hexagon.V6.vshufoeh.128B
- __builtin_HEXAGON_V6_vshufoeh(v16, v16);
+ __builtin_HEXAGON_V6_vshufoeb(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vshufoeb.128B
+ __builtin_HEXAGON_V6_vshufoeb_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vshufoeh
- __builtin_HEXAGON_V6_vshufoh_128B(v32, v32);
- // CHECK: @llvm.hexagon.V6.vshufoh.128B
- __builtin_HEXAGON_V6_vshufoh(v16, v16);
+ __builtin_HEXAGON_V6_vshufoeh(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vshufoeh.128B
+ __builtin_HEXAGON_V6_vshufoeh_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vshufoh
- __builtin_HEXAGON_V6_vsh(v16);
- // CHECK: @llvm.hexagon.V6.vsh
- __builtin_HEXAGON_V6_vsubb_128B(v32, v32);
+ __builtin_HEXAGON_V6_vshufoh(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vshufoh.128B
+ __builtin_HEXAGON_V6_vshufoh_128B(v128, v128);
+ // CHECK: @llvm.hexagon.V6.vsubb
+ __builtin_HEXAGON_V6_vsubb(v64, v64);
// CHECK: @llvm.hexagon.V6.vsubb.128B
- __builtin_HEXAGON_V6_vsubb_dv_128B(v64, v64);
- // CHECK: @llvm.hexagon.V6.vsubb.dv.128B
- __builtin_HEXAGON_V6_vsubb_dv(v32, v32);
+ __builtin_HEXAGON_V6_vsubb_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vsubb.dv
- __builtin_HEXAGON_V6_vsubbnq_128B(v32, v32, v32);
- // CHECK: @llvm.hexagon.V6.vsubbnq.128B
- __builtin_HEXAGON_V6_vsubbnq(v16, v16, v16);
+ __builtin_HEXAGON_V6_vsubb_dv(v128, v128);
+ // CHECK: @llvm.hexagon.V6.vsubb.dv.128B
+ __builtin_HEXAGON_V6_vsubb_dv_128B(v256, v256);
// CHECK: @llvm.hexagon.V6.vsubbnq
- __builtin_HEXAGON_V6_vsubbq_128B(v32, v32, v32);
- // CHECK: @llvm.hexagon.V6.vsubbq.128B
- __builtin_HEXAGON_V6_vsubbq(v16, v16, v16);
+ __builtin_HEXAGON_V6_vsubbnq(v64, v64, v64);
+ // CHECK: @llvm.hexagon.V6.vsubbnq.128B
+ __builtin_HEXAGON_V6_vsubbnq_128B(v128, v128, v128);
// CHECK: @llvm.hexagon.V6.vsubbq
- __builtin_HEXAGON_V6_vsubb(v16, v16);
- // CHECK: @llvm.hexagon.V6.vsubb
- __builtin_HEXAGON_V6_vsubh_128B(v32, v32);
+ __builtin_HEXAGON_V6_vsubbq(v64, v64, v64);
+ // CHECK: @llvm.hexagon.V6.vsubbq.128B
+ __builtin_HEXAGON_V6_vsubbq_128B(v128, v128, v128);
+ // CHECK: @llvm.hexagon.V6.vsubbsat
+ __builtin_HEXAGON_V6_vsubbsat(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vsubbsat.128B
+ __builtin_HEXAGON_V6_vsubbsat_128B(v128, v128);
+ // CHECK: @llvm.hexagon.V6.vsubbsat.dv
+ __builtin_HEXAGON_V6_vsubbsat_dv(v128, v128);
+ // CHECK: @llvm.hexagon.V6.vsubbsat.dv.128B
+ __builtin_HEXAGON_V6_vsubbsat_dv_128B(v256, v256);
+ // CHECK: @llvm.hexagon.V6.vsubcarry
+ __builtin_HEXAGON_V6_vsubcarry(v64, v64, 0);
+ // CHECK: @llvm.hexagon.V6.vsubcarry.128B
+ __builtin_HEXAGON_V6_vsubcarry_128B(v128, v128, 0);
+ // CHECK: @llvm.hexagon.V6.vsubh
+ __builtin_HEXAGON_V6_vsubh(v64, v64);
// CHECK: @llvm.hexagon.V6.vsubh.128B
- __builtin_HEXAGON_V6_vsubh_dv_128B(v64, v64);
- // CHECK: @llvm.hexagon.V6.vsubh.dv.128B
- __builtin_HEXAGON_V6_vsubh_dv(v32, v32);
+ __builtin_HEXAGON_V6_vsubh_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vsubh.dv
- __builtin_HEXAGON_V6_vsubhnq_128B(v32, v32, v32);
- // CHECK: @llvm.hexagon.V6.vsubhnq.128B
- __builtin_HEXAGON_V6_vsubhnq(v16, v16, v16);
+ __builtin_HEXAGON_V6_vsubh_dv(v128, v128);
+ // CHECK: @llvm.hexagon.V6.vsubh.dv.128B
+ __builtin_HEXAGON_V6_vsubh_dv_128B(v256, v256);
// CHECK: @llvm.hexagon.V6.vsubhnq
- __builtin_HEXAGON_V6_vsubhq_128B(v32, v32, v32);
- // CHECK: @llvm.hexagon.V6.vsubhq.128B
- __builtin_HEXAGON_V6_vsubhq(v16, v16, v16);
+ __builtin_HEXAGON_V6_vsubhnq(v64, v64, v64);
+ // CHECK: @llvm.hexagon.V6.vsubhnq.128B
+ __builtin_HEXAGON_V6_vsubhnq_128B(v128, v128, v128);
// CHECK: @llvm.hexagon.V6.vsubhq
- __builtin_HEXAGON_V6_vsubhsat_128B(v32, v32);
+ __builtin_HEXAGON_V6_vsubhq(v64, v64, v64);
+ // CHECK: @llvm.hexagon.V6.vsubhq.128B
+ __builtin_HEXAGON_V6_vsubhq_128B(v128, v128, v128);
+ // CHECK: @llvm.hexagon.V6.vsubhsat
+ __builtin_HEXAGON_V6_vsubhsat(v64, v64);
// CHECK: @llvm.hexagon.V6.vsubhsat.128B
- __builtin_HEXAGON_V6_vsubhsat_dv_128B(v64, v64);
- // CHECK: @llvm.hexagon.V6.vsubhsat.dv.128B
- __builtin_HEXAGON_V6_vsubhsat_dv(v32, v32);
+ __builtin_HEXAGON_V6_vsubhsat_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vsubhsat.dv
- __builtin_HEXAGON_V6_vsubhsat(v16, v16);
- // CHECK: @llvm.hexagon.V6.vsubhsat
- __builtin_HEXAGON_V6_vsubh(v16, v16);
- // CHECK: @llvm.hexagon.V6.vsubh
- __builtin_HEXAGON_V6_vsubhw_128B(v32, v32);
- // CHECK: @llvm.hexagon.V6.vsubhw.128B
- __builtin_HEXAGON_V6_vsubhw(v16, v16);
+ __builtin_HEXAGON_V6_vsubhsat_dv(v128, v128);
+ // CHECK: @llvm.hexagon.V6.vsubhsat.dv.128B
+ __builtin_HEXAGON_V6_vsubhsat_dv_128B(v256, v256);
// CHECK: @llvm.hexagon.V6.vsubhw
- __builtin_HEXAGON_V6_vsububh_128B(v32, v32);
- // CHECK: @llvm.hexagon.V6.vsububh.128B
- __builtin_HEXAGON_V6_vsububh(v16, v16);
+ __builtin_HEXAGON_V6_vsubhw(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vsubhw.128B
+ __builtin_HEXAGON_V6_vsubhw_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vsububh
- __builtin_HEXAGON_V6_vsububsat_128B(v32, v32);
+ __builtin_HEXAGON_V6_vsububh(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vsububh.128B
+ __builtin_HEXAGON_V6_vsububh_128B(v128, v128);
+ // CHECK: @llvm.hexagon.V6.vsububsat
+ __builtin_HEXAGON_V6_vsububsat(v64, v64);
// CHECK: @llvm.hexagon.V6.vsububsat.128B
- __builtin_HEXAGON_V6_vsububsat_dv_128B(v64, v64);
- // CHECK: @llvm.hexagon.V6.vsububsat.dv.128B
- __builtin_HEXAGON_V6_vsububsat_dv(v32, v32);
+ __builtin_HEXAGON_V6_vsububsat_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vsububsat.dv
- __builtin_HEXAGON_V6_vsububsat(v16, v16);
- // CHECK: @llvm.hexagon.V6.vsububsat
- __builtin_HEXAGON_V6_vsubuhsat_128B(v32, v32);
+ __builtin_HEXAGON_V6_vsububsat_dv(v128, v128);
+ // CHECK: @llvm.hexagon.V6.vsububsat.dv.128B
+ __builtin_HEXAGON_V6_vsububsat_dv_128B(v256, v256);
+ // CHECK: @llvm.hexagon.V6.vsubububb.sat
+ __builtin_HEXAGON_V6_vsubububb_sat(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vsubububb.sat.128B
+ __builtin_HEXAGON_V6_vsubububb_sat_128B(v128, v128);
+ // CHECK: @llvm.hexagon.V6.vsubuhsat
+ __builtin_HEXAGON_V6_vsubuhsat(v64, v64);
// CHECK: @llvm.hexagon.V6.vsubuhsat.128B
- __builtin_HEXAGON_V6_vsubuhsat_dv_128B(v64, v64);
- // CHECK: @llvm.hexagon.V6.vsubuhsat.dv.128B
- __builtin_HEXAGON_V6_vsubuhsat_dv(v32, v32);
+ __builtin_HEXAGON_V6_vsubuhsat_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vsubuhsat.dv
- __builtin_HEXAGON_V6_vsubuhsat(v16, v16);
- // CHECK: @llvm.hexagon.V6.vsubuhsat
- __builtin_HEXAGON_V6_vsubuhw_128B(v32, v32);
- // CHECK: @llvm.hexagon.V6.vsubuhw.128B
- __builtin_HEXAGON_V6_vsubuhw(v16, v16);
+ __builtin_HEXAGON_V6_vsubuhsat_dv(v128, v128);
+ // CHECK: @llvm.hexagon.V6.vsubuhsat.dv.128B
+ __builtin_HEXAGON_V6_vsubuhsat_dv_128B(v256, v256);
// CHECK: @llvm.hexagon.V6.vsubuhw
- __builtin_HEXAGON_V6_vsubw_128B(v32, v32);
+ __builtin_HEXAGON_V6_vsubuhw(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vsubuhw.128B
+ __builtin_HEXAGON_V6_vsubuhw_128B(v128, v128);
+ // CHECK: @llvm.hexagon.V6.vsubuwsat
+ __builtin_HEXAGON_V6_vsubuwsat(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vsubuwsat.128B
+ __builtin_HEXAGON_V6_vsubuwsat_128B(v128, v128);
+ // CHECK: @llvm.hexagon.V6.vsubuwsat.dv
+ __builtin_HEXAGON_V6_vsubuwsat_dv(v128, v128);
+ // CHECK: @llvm.hexagon.V6.vsubuwsat.dv.128B
+ __builtin_HEXAGON_V6_vsubuwsat_dv_128B(v256, v256);
+ // CHECK: @llvm.hexagon.V6.vsubw
+ __builtin_HEXAGON_V6_vsubw(v64, v64);
// CHECK: @llvm.hexagon.V6.vsubw.128B
- __builtin_HEXAGON_V6_vsubw_dv_128B(v64, v64);
- // CHECK: @llvm.hexagon.V6.vsubw.dv.128B
- __builtin_HEXAGON_V6_vsubw_dv(v32, v32);
+ __builtin_HEXAGON_V6_vsubw_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vsubw.dv
- __builtin_HEXAGON_V6_vsubwnq_128B(v32, v32, v32);
- // CHECK: @llvm.hexagon.V6.vsubwnq.128B
- __builtin_HEXAGON_V6_vsubwnq(v16, v16, v16);
+ __builtin_HEXAGON_V6_vsubw_dv(v128, v128);
+ // CHECK: @llvm.hexagon.V6.vsubw.dv.128B
+ __builtin_HEXAGON_V6_vsubw_dv_128B(v256, v256);
// CHECK: @llvm.hexagon.V6.vsubwnq
- __builtin_HEXAGON_V6_vsubwq_128B(v32, v32, v32);
- // CHECK: @llvm.hexagon.V6.vsubwq.128B
- __builtin_HEXAGON_V6_vsubwq(v16, v16, v16);
+ __builtin_HEXAGON_V6_vsubwnq(v64, v64, v64);
+ // CHECK: @llvm.hexagon.V6.vsubwnq.128B
+ __builtin_HEXAGON_V6_vsubwnq_128B(v128, v128, v128);
// CHECK: @llvm.hexagon.V6.vsubwq
- __builtin_HEXAGON_V6_vsubwsat_128B(v32, v32);
+ __builtin_HEXAGON_V6_vsubwq(v64, v64, v64);
+ // CHECK: @llvm.hexagon.V6.vsubwq.128B
+ __builtin_HEXAGON_V6_vsubwq_128B(v128, v128, v128);
+ // CHECK: @llvm.hexagon.V6.vsubwsat
+ __builtin_HEXAGON_V6_vsubwsat(v64, v64);
// CHECK: @llvm.hexagon.V6.vsubwsat.128B
- __builtin_HEXAGON_V6_vsubwsat_dv_128B(v64, v64);
- // CHECK: @llvm.hexagon.V6.vsubwsat.dv.128B
- __builtin_HEXAGON_V6_vsubwsat_dv(v32, v32);
+ __builtin_HEXAGON_V6_vsubwsat_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vsubwsat.dv
- __builtin_HEXAGON_V6_vsubwsat(v16, v16);
- // CHECK: @llvm.hexagon.V6.vsubwsat
- __builtin_HEXAGON_V6_vsubw(v16, v16);
- // CHECK: @llvm.hexagon.V6.vsubw
- __builtin_HEXAGON_V6_vswap_128B(v32, v32, v32);
- // CHECK: @llvm.hexagon.V6.vswap.128B
- __builtin_HEXAGON_V6_vswap(v16, v16, v16);
+ __builtin_HEXAGON_V6_vsubwsat_dv(v128, v128);
+ // CHECK: @llvm.hexagon.V6.vsubwsat.dv.128B
+ __builtin_HEXAGON_V6_vsubwsat_dv_128B(v256, v256);
// CHECK: @llvm.hexagon.V6.vswap
- __builtin_HEXAGON_V6_vtmpyb_128B(v64, 0);
+ __builtin_HEXAGON_V6_vswap(v64, v64, v64);
+ // CHECK: @llvm.hexagon.V6.vswap.128B
+ __builtin_HEXAGON_V6_vswap_128B(v128, v128, v128);
+ // CHECK: @llvm.hexagon.V6.vtmpyb
+ __builtin_HEXAGON_V6_vtmpyb(v128, 0);
// CHECK: @llvm.hexagon.V6.vtmpyb.128B
- __builtin_HEXAGON_V6_vtmpyb_acc_128B(v64, v64, 0);
- // CHECK: @llvm.hexagon.V6.vtmpyb.acc.128B
- __builtin_HEXAGON_V6_vtmpyb_acc(v32, v32, 0);
+ __builtin_HEXAGON_V6_vtmpyb_128B(v256, 0);
// CHECK: @llvm.hexagon.V6.vtmpyb.acc
- __builtin_HEXAGON_V6_vtmpybus_128B(v64, 0);
+ __builtin_HEXAGON_V6_vtmpyb_acc(v128, v128, 0);
+ // CHECK: @llvm.hexagon.V6.vtmpyb.acc.128B
+ __builtin_HEXAGON_V6_vtmpyb_acc_128B(v256, v256, 0);
+ // CHECK: @llvm.hexagon.V6.vtmpybus
+ __builtin_HEXAGON_V6_vtmpybus(v128, 0);
// CHECK: @llvm.hexagon.V6.vtmpybus.128B
- __builtin_HEXAGON_V6_vtmpybus_acc_128B(v64, v64, 0);
- // CHECK: @llvm.hexagon.V6.vtmpybus.acc.128B
- __builtin_HEXAGON_V6_vtmpybus_acc(v32, v32, 0);
+ __builtin_HEXAGON_V6_vtmpybus_128B(v256, 0);
// CHECK: @llvm.hexagon.V6.vtmpybus.acc
- __builtin_HEXAGON_V6_vtmpybus(v32, 0);
- // CHECK: @llvm.hexagon.V6.vtmpybus
- __builtin_HEXAGON_V6_vtmpyb(v32, 0);
- // CHECK: @llvm.hexagon.V6.vtmpyb
- __builtin_HEXAGON_V6_vtmpyhb_128B(v64, 0);
+ __builtin_HEXAGON_V6_vtmpybus_acc(v128, v128, 0);
+ // CHECK: @llvm.hexagon.V6.vtmpybus.acc.128B
+ __builtin_HEXAGON_V6_vtmpybus_acc_128B(v256, v256, 0);
+ // CHECK: @llvm.hexagon.V6.vtmpyhb
+ __builtin_HEXAGON_V6_vtmpyhb(v128, 0);
// CHECK: @llvm.hexagon.V6.vtmpyhb.128B
- __builtin_HEXAGON_V6_vtmpyhb_acc_128B(v64, v64, 0);
- // CHECK: @llvm.hexagon.V6.vtmpyhb.acc.128B
- __builtin_HEXAGON_V6_vtmpyhb_acc(v32, v32, 0);
+ __builtin_HEXAGON_V6_vtmpyhb_128B(v256, 0);
// CHECK: @llvm.hexagon.V6.vtmpyhb.acc
- __builtin_HEXAGON_V6_vtmpyhb(v32, 0);
- // CHECK: @llvm.hexagon.V6.vtmpyhb
- __builtin_HEXAGON_V6_vunpackb_128B(v32);
- // CHECK: @llvm.hexagon.V6.vunpackb.128B
- __builtin_HEXAGON_V6_vunpackb(v16);
+ __builtin_HEXAGON_V6_vtmpyhb_acc(v128, v128, 0);
+ // CHECK: @llvm.hexagon.V6.vtmpyhb.acc.128B
+ __builtin_HEXAGON_V6_vtmpyhb_acc_128B(v256, v256, 0);
// CHECK: @llvm.hexagon.V6.vunpackb
- __builtin_HEXAGON_V6_vunpackh_128B(v32);
- // CHECK: @llvm.hexagon.V6.vunpackh.128B
- __builtin_HEXAGON_V6_vunpackh(v16);
+ __builtin_HEXAGON_V6_vunpackb(v64);
+ // CHECK: @llvm.hexagon.V6.vunpackb.128B
+ __builtin_HEXAGON_V6_vunpackb_128B(v128);
// CHECK: @llvm.hexagon.V6.vunpackh
- __builtin_HEXAGON_V6_vunpackob_128B(v64, v32);
- // CHECK: @llvm.hexagon.V6.vunpackob.128B
- __builtin_HEXAGON_V6_vunpackob(v32, v16);
+ __builtin_HEXAGON_V6_vunpackh(v64);
+ // CHECK: @llvm.hexagon.V6.vunpackh.128B
+ __builtin_HEXAGON_V6_vunpackh_128B(v128);
// CHECK: @llvm.hexagon.V6.vunpackob
- __builtin_HEXAGON_V6_vunpackoh_128B(v64, v32);
- // CHECK: @llvm.hexagon.V6.vunpackoh.128B
- __builtin_HEXAGON_V6_vunpackoh(v32, v16);
+ __builtin_HEXAGON_V6_vunpackob(v128, v64);
+ // CHECK: @llvm.hexagon.V6.vunpackob.128B
+ __builtin_HEXAGON_V6_vunpackob_128B(v256, v128);
// CHECK: @llvm.hexagon.V6.vunpackoh
- __builtin_HEXAGON_V6_vunpackub_128B(v32);
- // CHECK: @llvm.hexagon.V6.vunpackub.128B
- __builtin_HEXAGON_V6_vunpackub(v16);
+ __builtin_HEXAGON_V6_vunpackoh(v128, v64);
+ // CHECK: @llvm.hexagon.V6.vunpackoh.128B
+ __builtin_HEXAGON_V6_vunpackoh_128B(v256, v128);
// CHECK: @llvm.hexagon.V6.vunpackub
- __builtin_HEXAGON_V6_vunpackuh_128B(v32);
- // CHECK: @llvm.hexagon.V6.vunpackuh.128B
- __builtin_HEXAGON_V6_vunpackuh(v16);
+ __builtin_HEXAGON_V6_vunpackub(v64);
+ // CHECK: @llvm.hexagon.V6.vunpackub.128B
+ __builtin_HEXAGON_V6_vunpackub_128B(v128);
// CHECK: @llvm.hexagon.V6.vunpackuh
- __builtin_HEXAGON_V6_vxor_128B(v32, v32);
- // CHECK: @llvm.hexagon.V6.vxor.128B
- __builtin_HEXAGON_V6_vxor(v16, v16);
+ __builtin_HEXAGON_V6_vunpackuh(v64);
+ // CHECK: @llvm.hexagon.V6.vunpackuh.128B
+ __builtin_HEXAGON_V6_vunpackuh_128B(v128);
// CHECK: @llvm.hexagon.V6.vxor
- __builtin_HEXAGON_V6_vzb_128B(v32);
- // CHECK: @llvm.hexagon.V6.vzb.128B
- __builtin_HEXAGON_V6_vzb(v16);
+ __builtin_HEXAGON_V6_vxor(v64, v64);
+ // CHECK: @llvm.hexagon.V6.vxor.128B
+ __builtin_HEXAGON_V6_vxor_128B(v128, v128);
// CHECK: @llvm.hexagon.V6.vzb
- __builtin_HEXAGON_V6_vzh_128B(v32);
- // CHECK: @llvm.hexagon.V6.vzh.128B
- __builtin_HEXAGON_V6_vzh(v16);
+ __builtin_HEXAGON_V6_vzb(v64);
+ // CHECK: @llvm.hexagon.V6.vzb.128B
+ __builtin_HEXAGON_V6_vzb_128B(v128);
// CHECK: @llvm.hexagon.V6.vzh
- __builtin_HEXAGON_Y2_dccleana(0);
+ __builtin_HEXAGON_V6_vzh(v64);
+ // CHECK: @llvm.hexagon.V6.vzh.128B
+ __builtin_HEXAGON_V6_vzh_128B(v128);
// CHECK: @llvm.hexagon.Y2.dccleana
- __builtin_HEXAGON_Y2_dccleaninva(0);
+ __builtin_HEXAGON_Y2_dccleana(0);
// CHECK: @llvm.hexagon.Y2.dccleaninva
- __builtin_HEXAGON_Y2_dcinva(0);
+ __builtin_HEXAGON_Y2_dccleaninva(0);
// CHECK: @llvm.hexagon.Y2.dcinva
- __builtin_HEXAGON_Y2_dczeroa(0);
+ __builtin_HEXAGON_Y2_dcinva(0);
// CHECK: @llvm.hexagon.Y2.dczeroa
- __builtin_HEXAGON_Y4_l2fetch(0, 0);
+ __builtin_HEXAGON_Y2_dczeroa(0);
// CHECK: @llvm.hexagon.Y4.l2fetch
- __builtin_HEXAGON_Y5_l2fetch(0, 0);
+ __builtin_HEXAGON_Y4_l2fetch(0, 0);
// CHECK: @llvm.hexagon.Y5.l2fetch
+ __builtin_HEXAGON_Y5_l2fetch(0, 0);
+ // CHECK: @llvm.hexagon.brev.ldb
+ __builtin_brev_ldb(0, 0, 0);
+ // CHECK: @llvm.hexagon.brev.ldd
+ __builtin_brev_ldd(0, 0, 0);
+ // CHECK: @llvm.hexagon.brev.ldh
+ __builtin_brev_ldh(0, 0, 0);
+ // CHECK: @llvm.hexagon.brev.ldub
+ __builtin_brev_ldub(0, 0, 0);
+ // CHECK: @llvm.hexagon.brev.lduh
+ __builtin_brev_lduh(0, 0, 0);
+ // CHECK: @llvm.hexagon.brev.ldw
+ __builtin_brev_ldw(0, 0, 0);
+ // CHECK: @llvm.hexagon.brev.stb
+ __builtin_brev_stb(0, 0, 0);
+ // CHECK: @llvm.hexagon.brev.std
+ __builtin_brev_std(0, 0, 0);
+ // CHECK: @llvm.hexagon.brev.sth
+ __builtin_brev_sth(0, 0, 0);
+ // CHECK: @llvm.hexagon.brev.sthhi
+ __builtin_brev_sthhi(0, 0, 0);
+ // CHECK: @llvm.hexagon.brev.stw
+ __builtin_brev_stw(0, 0, 0);
+ // CHECK: @llvm.hexagon.circ.ldb
+ __builtin_circ_ldb(0, 0, 0, 0);
+ // CHECK: @llvm.hexagon.circ.ldd
+ __builtin_circ_ldd(0, 0, 0, 0);
+ // CHECK: @llvm.hexagon.circ.ldh
+ __builtin_circ_ldh(0, 0, 0, 0);
+ // CHECK: @llvm.hexagon.circ.ldub
+ __builtin_circ_ldub(0, 0, 0, 0);
+ // CHECK: @llvm.hexagon.circ.lduh
+ __builtin_circ_lduh(0, 0, 0, 0);
+ // CHECK: @llvm.hexagon.circ.ldw
+ __builtin_circ_ldw(0, 0, 0, 0);
+ // CHECK: @llvm.hexagon.circ.stb
+ __builtin_circ_stb(0, 0, 0, 0);
+ // CHECK: @llvm.hexagon.circ.std
+ __builtin_circ_std(0, 0, 0, 0);
+ // CHECK: @llvm.hexagon.circ.sth
+ __builtin_circ_sth(0, 0, 0, 0);
+ // CHECK: @llvm.hexagon.circ.sthhi
+ __builtin_circ_sthhi(0, 0, 0, 0);
+ // CHECK: @llvm.hexagon.circ.stw
+ __builtin_circ_stw(0, 0, 0, 0);
+ // CHECK: @llvm.hexagon.prefetch
+ __builtin_HEXAGON_prefetch(0);
}
diff --git a/test/CodeGen/builtins-nvptx-ptx50.cu b/test/CodeGen/builtins-nvptx-ptx50.cu
new file mode 100644
index 000000000000..e85be442eb47
--- /dev/null
+++ b/test/CodeGen/builtins-nvptx-ptx50.cu
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -triple nvptx64-unknown-unknown -target-cpu sm_60 \
+// RUN: -fcuda-is-device -S -emit-llvm -o - -x cuda %s \
+// RUN: | FileCheck -check-prefix=CHECK %s
+//
+// RUN: %clang_cc1 -triple nvptx-unknown-unknown -target-cpu sm_50 \
+// RUN: -fcuda-is-device -S -o /dev/null -x cuda -verify %s
+
+#define __device__ __attribute__((device))
+#define __global__ __attribute__((global))
+#define __shared__ __attribute__((shared))
+#define __constant__ __attribute__((constant))
+
+// We have to keep all builtins that depend on particular target feature in the
+// same function, because the codegen will stop after the very first function
+// that encounters an error, so -verify will not be able to find errors in
+// subsequent functions.
+
+// CHECK-LABEL: test_fn
+__device__ void test_fn(double d, double* double_ptr) {
+ // CHECK: call double @llvm.nvvm.atomic.load.add.f64.p0f64
+ // expected-error@+1 {{'__nvvm_atom_add_gen_d' needs target feature satom}}
+ __nvvm_atom_add_gen_d(double_ptr, d);
+}
diff --git a/test/CodeGen/builtins-nvptx-ptx60.cu b/test/CodeGen/builtins-nvptx-ptx60.cu
new file mode 100644
index 000000000000..11db9ac46ea5
--- /dev/null
+++ b/test/CodeGen/builtins-nvptx-ptx60.cu
@@ -0,0 +1,97 @@
+// RUN: %clang_cc1 -triple nvptx64-unknown-unknown -target-cpu sm_60 \
+// RUN: -fcuda-is-device -target-feature +ptx60 \
+// RUN: -S -emit-llvm -o - -x cuda %s \
+// RUN: | FileCheck -check-prefix=CHECK %s
+// RUN: %clang_cc1 -triple nvptx-unknown-unknown -target-cpu sm_60 \
+// RUN: -fcuda-is-device -S -o /dev/null -x cuda -verify %s
+
+#define __device__ __attribute__((device))
+#define __global__ __attribute__((global))
+#define __shared__ __attribute__((shared))
+#define __constant__ __attribute__((constant))
+
+typedef unsigned long long uint64_t;
+
+// We have to keep all builtins that depend on particular target feature in the
+// same function, because the codegen will stop after the very first function
+// that encounters an error, so -verify will not be able to find errors in
+// subsequent functions.
+
+// CHECK-LABEL: nvvm_sync
+__device__ void nvvm_sync(unsigned mask, int i, float f, int a, int b,
+ bool pred, uint64_t i64) {
+
+ // CHECK: call void @llvm.nvvm.bar.warp.sync(i32
+ // expected-error@+1 {{'__nvvm_bar_warp_sync' needs target feature ptx60}}
+ __nvvm_bar_warp_sync(mask);
+ // CHECK: call void @llvm.nvvm.barrier.sync(i32
+ // expected-error@+1 {{'__nvvm_barrier_sync' needs target feature ptx60}}
+ __nvvm_barrier_sync(mask);
+ // CHECK: call void @llvm.nvvm.barrier.sync.cnt(i32
+ // expected-error@+1 {{'__nvvm_barrier_sync_cnt' needs target feature ptx60}}
+ __nvvm_barrier_sync_cnt(mask, i);
+
+ //
+ // SHFL.SYNC
+ //
+ // CHECK: call i32 @llvm.nvvm.shfl.sync.down.i32(i32 {{%[0-9]+}}, i32
+ // expected-error@+1 {{'__nvvm_shfl_sync_down_i32' needs target feature ptx60}}
+ __nvvm_shfl_sync_down_i32(mask, i, a, b);
+ // CHECK: call float @llvm.nvvm.shfl.sync.down.f32(i32 {{%[0-9]+}}, float
+ // expected-error@+1 {{'__nvvm_shfl_sync_down_f32' needs target feature ptx60}}
+ __nvvm_shfl_sync_down_f32(mask, f, a, b);
+ // CHECK: call i32 @llvm.nvvm.shfl.sync.up.i32(i32 {{%[0-9]+}}, i32
+ // expected-error@+1 {{'__nvvm_shfl_sync_up_i32' needs target feature ptx60}}
+ __nvvm_shfl_sync_up_i32(mask, i, a, b);
+ // CHECK: call float @llvm.nvvm.shfl.sync.up.f32(i32 {{%[0-9]+}}, float
+ // expected-error@+1 {{'__nvvm_shfl_sync_up_f32' needs target feature ptx60}}
+ __nvvm_shfl_sync_up_f32(mask, f, a, b);
+ // CHECK: call i32 @llvm.nvvm.shfl.sync.bfly.i32(i32 {{%[0-9]+}}, i32
+ // expected-error@+1 {{'__nvvm_shfl_sync_bfly_i32' needs target feature ptx60}}
+ __nvvm_shfl_sync_bfly_i32(mask, i, a, b);
+ // CHECK: call float @llvm.nvvm.shfl.sync.bfly.f32(i32 {{%[0-9]+}}, float
+ // expected-error@+1 {{'__nvvm_shfl_sync_bfly_f32' needs target feature ptx60}}
+ __nvvm_shfl_sync_bfly_f32(mask, f, a, b);
+ // CHECK: call i32 @llvm.nvvm.shfl.sync.idx.i32(i32 {{%[0-9]+}}, i32
+ // expected-error@+1 {{'__nvvm_shfl_sync_idx_i32' needs target feature ptx60}}
+ __nvvm_shfl_sync_idx_i32(mask, i, a, b);
+ // CHECK: call float @llvm.nvvm.shfl.sync.idx.f32(i32 {{%[0-9]+}}, float
+ // expected-error@+1 {{'__nvvm_shfl_sync_idx_f32' needs target feature ptx60}}
+ __nvvm_shfl_sync_idx_f32(mask, f, a, b);
+
+ //
+ // VOTE.SYNC
+ //
+
+ // CHECK: call i1 @llvm.nvvm.vote.all.sync(i32
+ // expected-error@+1 {{'__nvvm_vote_all_sync' needs target feature ptx60}}
+ __nvvm_vote_all_sync(mask, pred);
+ // CHECK: call i1 @llvm.nvvm.vote.any.sync(i32
+ // expected-error@+1 {{'__nvvm_vote_any_sync' needs target feature ptx60}}
+ __nvvm_vote_any_sync(mask, pred);
+ // CHECK: call i1 @llvm.nvvm.vote.uni.sync(i32
+ // expected-error@+1 {{'__nvvm_vote_uni_sync' needs target feature ptx60}}
+ __nvvm_vote_uni_sync(mask, pred);
+ // CHECK: call i32 @llvm.nvvm.vote.ballot.sync(i32
+ // expected-error@+1 {{'__nvvm_vote_ballot_sync' needs target feature ptx60}}
+ __nvvm_vote_ballot_sync(mask, pred);
+
+ //
+ // MATCH.{ALL,ANY}.SYNC
+ //
+
+ // CHECK: call i32 @llvm.nvvm.match.any.sync.i32(i32
+ // expected-error@+1 {{'__nvvm_match_any_sync_i32' needs target feature ptx60}}
+ __nvvm_match_any_sync_i32(mask, i);
+ // CHECK: call i64 @llvm.nvvm.match.any.sync.i64(i32
+ // expected-error@+1 {{'__nvvm_match_any_sync_i64' needs target feature ptx60}}
+ __nvvm_match_any_sync_i64(mask, i64);
+ // CHECK: call { i32, i1 } @llvm.nvvm.match.all.sync.i32p(i32
+ // expected-error@+1 {{'__nvvm_match_all_sync_i32p' needs target feature ptx60}}
+ __nvvm_match_all_sync_i32p(mask, i, &i);
+ // CHECK: call { i64, i1 } @llvm.nvvm.match.all.sync.i64p(i32
+ // expected-error@+1 {{'__nvvm_match_all_sync_i64p' needs target feature ptx60}}
+ __nvvm_match_all_sync_i64p(mask, i64, &i);
+
+ // CHECK: ret void
+}
diff --git a/test/CodeGen/builtins-nvptx-sm_70.cu b/test/CodeGen/builtins-nvptx-sm_70.cu
new file mode 100644
index 000000000000..09e5b6ba7a7d
--- /dev/null
+++ b/test/CodeGen/builtins-nvptx-sm_70.cu
@@ -0,0 +1,166 @@
+// RUN: %clang_cc1 -triple nvptx64-unknown-unknown -target-cpu sm_70 \
+// RUN: -fcuda-is-device -target-feature +ptx60 \
+// RUN: -S -emit-llvm -o - -x cuda %s \
+// RUN: | FileCheck -check-prefix=CHECK %s
+// RUN: %clang_cc1 -triple nvptx-unknown-unknown -target-cpu sm_60 \
+// RUN: -fcuda-is-device -S -o /dev/null -x cuda -verify %s
+
+#if !defined(CUDA_VERSION)
+#define __device__ __attribute__((device))
+#define __global__ __attribute__((global))
+#define __shared__ __attribute__((shared))
+#define __constant__ __attribute__((constant))
+
+typedef unsigned long long uint64_t;
+#endif
+// We have to keep all builtins that depend on particular target feature in the
+// same function, because the codegen will stop after the very first function
+// that encounters an error, so -verify will not be able to find errors in
+// subsequent functions.
+
+// CHECK-LABEL: nvvm_wmma
+__device__ void nvvm_wmma(int *src, int *dst,
+ float *fsrc, float *fdst,
+ int ldm) {
+ // CHECK: call {{.*}} @llvm.nvvm.wmma.load.a.sync.row.m16n16k16.stride.f16
+ // expected-error@+1 {{'__hmma_m16n16k16_ld_a' needs target feature ptx60}}
+ __hmma_m16n16k16_ld_a(dst, src, ldm, 0);
+ // CHECK: call {{.*}} @llvm.nvvm.wmma.load.a.sync.col.m16n16k16.stride.f16
+ // expected-error@+1 {{'__hmma_m16n16k16_ld_a' needs target feature ptx60}}
+ __hmma_m16n16k16_ld_a(dst, src+1, ldm, 1);
+
+ // CHECK: call {{.*}} @llvm.nvvm.wmma.load.b.sync.row.m16n16k16.stride.f16
+ // expected-error@+1 {{'__hmma_m16n16k16_ld_b' needs target feature ptx60}}
+ __hmma_m16n16k16_ld_b(dst, src, ldm, 0);
+ // CHECK: call {{.*}} @llvm.nvvm.wmma.load.b.sync.col.m16n16k16.stride.f16
+ // expected-error@+1 {{'__hmma_m16n16k16_ld_b' needs target feature ptx60}}
+ __hmma_m16n16k16_ld_b(dst, src+2, ldm, 1);
+
+ // CHECK: call {{.*}} @llvm.nvvm.wmma.load.c.sync.row.m16n16k16.stride.f16
+ // expected-error@+1 {{'__hmma_m16n16k16_ld_c_f16' needs target feature ptx60}}
+ __hmma_m16n16k16_ld_c_f16(dst, src, ldm, 0);
+ // CHECK: call {{.*}} @llvm.nvvm.wmma.load.c.sync.col.m16n16k16.stride.f16
+ // expected-error@+1 {{'__hmma_m16n16k16_ld_c_f16' needs target feature ptx60}}
+ __hmma_m16n16k16_ld_c_f16(dst, src, ldm, 1);
+
+ // CHECK: call {{.*}} @llvm.nvvm.wmma.load.c.sync.row.m16n16k16.stride.f32
+ // expected-error@+1 {{'__hmma_m16n16k16_ld_c_f32' needs target feature ptx60}}
+ __hmma_m16n16k16_ld_c_f32(fdst, fsrc, ldm, 0);
+ // CHECK: call {{.*}} @llvm.nvvm.wmma.load.c.sync.col.m16n16k16.stride.f32
+ // expected-error@+1 {{'__hmma_m16n16k16_ld_c_f32' needs target feature ptx60}}
+ __hmma_m16n16k16_ld_c_f32(fdst, fsrc, ldm, 1);
+
+ // CHECK: call {{.*}} @llvm.nvvm.wmma.store.d.sync.row.m16n16k16.stride.f16
+ // expected-error@+1 {{'__hmma_m16n16k16_st_c_f16' needs target feature ptx60}}
+ __hmma_m16n16k16_st_c_f16(dst, src, ldm, 0);
+ // CHECK: call {{.*}} @llvm.nvvm.wmma.store.d.sync.col.m16n16k16.stride.f16
+ // expected-error@+1 {{'__hmma_m16n16k16_st_c_f16' needs target feature ptx60}}
+ __hmma_m16n16k16_st_c_f16(dst, src, ldm, 1);
+
+ // CHECK: call {{.*}} @llvm.nvvm.wmma.store.d.sync.row.m16n16k16.stride.f32
+ // expected-error@+1 {{'__hmma_m16n16k16_st_c_f32' needs target feature ptx60}}
+ __hmma_m16n16k16_st_c_f32(fdst, fsrc, ldm, 0);
+ // CHECK: call {{.*}} @llvm.nvvm.wmma.store.d.sync.col.m16n16k16.stride.f32
+ // expected-error@+1 {{'__hmma_m16n16k16_st_c_f32' needs target feature ptx60}}
+ __hmma_m16n16k16_st_c_f32(fdst, fsrc, ldm, 1);
+
+ // CHECK: call {{.*}} @llvm.nvvm.wmma.mma.sync.row.row.m16n16k16.f16.f16
+ // expected-error@+1 {{'__hmma_m16n16k16_mma_f16f16' needs target feature ptx60}}
+ __hmma_m16n16k16_mma_f16f16(dst, src, src, src, 0, 0);
+ // CHECK: call {{.*}} @llvm.nvvm.wmma.mma.sync.row.row.m16n16k16.f16.f16.satfinite
+ // expected-error@+1 {{'__hmma_m16n16k16_mma_f16f16' needs target feature ptx60}}
+ __hmma_m16n16k16_mma_f16f16(dst, src, src, src, 0, 1);
+ // CHECK: call {{.*}} @llvm.nvvm.wmma.mma.sync.row.col.m16n16k16.f16.f16
+ // expected-error@+1 {{'__hmma_m16n16k16_mma_f16f16' needs target feature ptx60}}
+ __hmma_m16n16k16_mma_f16f16(dst, src, src, src, 1, 0);
+ // CHECK: call {{.*}} @llvm.nvvm.wmma.mma.sync.row.col.m16n16k16.f16.f16.satfinite
+ // expected-error@+1 {{'__hmma_m16n16k16_mma_f16f16' needs target feature ptx60}}
+ __hmma_m16n16k16_mma_f16f16(dst, src, src, src, 1, 1);
+ // CHECK: call {{.*}} @llvm.nvvm.wmma.mma.sync.col.row.m16n16k16.f16.f16
+ // expected-error@+1 {{'__hmma_m16n16k16_mma_f16f16' needs target feature ptx60}}
+ __hmma_m16n16k16_mma_f16f16(dst, src, src, src, 2, 0);
+ // CHECK: call {{.*}} @llvm.nvvm.wmma.mma.sync.col.row.m16n16k16.f16.f16.satfinite
+ // expected-error@+1 {{'__hmma_m16n16k16_mma_f16f16' needs target feature ptx60}}
+ __hmma_m16n16k16_mma_f16f16(dst, src, src, src, 2, 1);
+ // CHECK: call {{.*}} @llvm.nvvm.wmma.mma.sync.col.col.m16n16k16.f16.f16
+ // expected-error@+1 {{'__hmma_m16n16k16_mma_f16f16' needs target feature ptx60}}
+ __hmma_m16n16k16_mma_f16f16(dst, src, src, src, 3, 0);
+ // CHECK: call {{.*}} @llvm.nvvm.wmma.mma.sync.col.col.m16n16k16.f16.f16.satfinite
+ // expected-error@+1 {{'__hmma_m16n16k16_mma_f16f16' needs target feature ptx60}}
+ __hmma_m16n16k16_mma_f16f16(dst, src, src, src, 3, 1);
+
+ // CHECK: call {{.*}} @llvm.nvvm.wmma.mma.sync.row.row.m16n16k16.f16.f32
+ // expected-error@+1 {{'__hmma_m16n16k16_mma_f16f32' needs target feature ptx60}}
+ __hmma_m16n16k16_mma_f16f32(dst, src, src, fsrc, 0, 0);
+ // CHECK: call {{.*}} @llvm.nvvm.wmma.mma.sync.row.row.m16n16k16.f16.f32.satfinite
+ // expected-error@+1 {{'__hmma_m16n16k16_mma_f16f32' needs target feature ptx60}}
+ __hmma_m16n16k16_mma_f16f32(dst, src, src, fsrc, 0, 1);
+ // CHECK: call {{.*}} @llvm.nvvm.wmma.mma.sync.row.col.m16n16k16.f16.f32
+ // expected-error@+1 {{'__hmma_m16n16k16_mma_f16f32' needs target feature ptx60}}
+ __hmma_m16n16k16_mma_f16f32(dst, src, src, fsrc, 1, 0);
+ // CHECK: call {{.*}} @llvm.nvvm.wmma.mma.sync.row.col.m16n16k16.f16.f32.satfinite
+ // expected-error@+1 {{'__hmma_m16n16k16_mma_f16f32' needs target feature ptx60}}
+ __hmma_m16n16k16_mma_f16f32(dst, src, src, fsrc, 1, 1);
+ // CHECK: call {{.*}} @llvm.nvvm.wmma.mma.sync.col.row.m16n16k16.f16.f32
+ // expected-error@+1 {{'__hmma_m16n16k16_mma_f16f32' needs target feature ptx60}}
+ __hmma_m16n16k16_mma_f16f32(dst, src, src, fsrc, 2, 0);
+ // CHECK: call {{.*}} @llvm.nvvm.wmma.mma.sync.col.row.m16n16k16.f16.f32.satfinite
+ // expected-error@+1 {{'__hmma_m16n16k16_mma_f16f32' needs target feature ptx60}}
+ __hmma_m16n16k16_mma_f16f32(dst, src, src, fsrc, 2, 1);
+ // CHECK: call {{.*}} @llvm.nvvm.wmma.mma.sync.col.col.m16n16k16.f16.f32
+ // expected-error@+1 {{'__hmma_m16n16k16_mma_f16f32' needs target feature ptx60}}
+ __hmma_m16n16k16_mma_f16f32(dst, src, src, fsrc, 3, 0);
+ // CHECK: call {{.*}} @llvm.nvvm.wmma.mma.sync.col.col.m16n16k16.f16.f32.satfinite
+ // expected-error@+1 {{'__hmma_m16n16k16_mma_f16f32' needs target feature ptx60}}
+ __hmma_m16n16k16_mma_f16f32(dst, src, src, fsrc, 3, 1);
+
+ // CHECK: call {{.*}} @llvm.nvvm.wmma.mma.sync.row.row.m16n16k16.f32.f16
+ // expected-error@+1 {{'__hmma_m16n16k16_mma_f32f16' needs target feature ptx60}}
+ __hmma_m16n16k16_mma_f32f16(fdst, src, src, src, 0, 0);
+ // CHECK: call {{.*}} @llvm.nvvm.wmma.mma.sync.row.row.m16n16k16.f32.f16.satfinite
+ // expected-error@+1 {{'__hmma_m16n16k16_mma_f32f16' needs target feature ptx60}}
+ __hmma_m16n16k16_mma_f32f16(fdst, src, src, src, 0, 1);
+ // CHECK: call {{.*}} @llvm.nvvm.wmma.mma.sync.row.col.m16n16k16.f32.f16
+ // expected-error@+1 {{'__hmma_m16n16k16_mma_f32f16' needs target feature ptx60}}
+ __hmma_m16n16k16_mma_f32f16(fdst, src, src, src, 1, 0);
+ // CHECK: call {{.*}} @llvm.nvvm.wmma.mma.sync.row.col.m16n16k16.f32.f16.satfinite
+ // expected-error@+1 {{'__hmma_m16n16k16_mma_f32f16' needs target feature ptx60}}
+ __hmma_m16n16k16_mma_f32f16(fdst, src, src, src, 1, 1);
+ // CHECK: call {{.*}} @llvm.nvvm.wmma.mma.sync.col.row.m16n16k16.f32.f16
+ // expected-error@+1 {{'__hmma_m16n16k16_mma_f32f16' needs target feature ptx60}}
+ __hmma_m16n16k16_mma_f32f16(fdst, src, src, src, 2, 0);
+ // CHECK: call {{.*}} @llvm.nvvm.wmma.mma.sync.col.row.m16n16k16.f32.f16.satfinite
+ // expected-error@+1 {{'__hmma_m16n16k16_mma_f32f16' needs target feature ptx60}}
+ __hmma_m16n16k16_mma_f32f16(fdst, src, src, src, 2, 1);
+ // CHECK: call {{.*}} @llvm.nvvm.wmma.mma.sync.col.col.m16n16k16.f32.f16
+ // expected-error@+1 {{'__hmma_m16n16k16_mma_f32f16' needs target feature ptx60}}
+ __hmma_m16n16k16_mma_f32f16(fdst, src, src, src, 3, 0);
+ // CHECK: call {{.*}} @llvm.nvvm.wmma.mma.sync.col.col.m16n16k16.f32.f16.satfinite
+ // expected-error@+1 {{'__hmma_m16n16k16_mma_f32f16' needs target feature ptx60}}
+ __hmma_m16n16k16_mma_f32f16(fdst, src, src, src, 3, 1);
+
+ // CHECK: call {{.*}} @llvm.nvvm.wmma.mma.sync.row.row.m16n16k16.f32.f32
+ // expected-error@+1 {{'__hmma_m16n16k16_mma_f32f32' needs target feature ptx60}}
+ __hmma_m16n16k16_mma_f32f32(fdst, src, src, fsrc, 0, 0);
+ // CHECK: call {{.*}} @llvm.nvvm.wmma.mma.sync.row.row.m16n16k16.f32.f32.satfinite
+ // expected-error@+1 {{'__hmma_m16n16k16_mma_f32f32' needs target feature ptx60}}
+ __hmma_m16n16k16_mma_f32f32(fdst, src, src, fsrc, 0, 1);
+ // CHECK: call {{.*}} @llvm.nvvm.wmma.mma.sync.row.col.m16n16k16.f32.f32
+ // expected-error@+1 {{'__hmma_m16n16k16_mma_f32f32' needs target feature ptx60}}
+ __hmma_m16n16k16_mma_f32f32(fdst, src, src, fsrc, 1, 0);
+ // CHECK: call {{.*}} @llvm.nvvm.wmma.mma.sync.row.col.m16n16k16.f32.f32.satfinite
+ // expected-error@+1 {{'__hmma_m16n16k16_mma_f32f32' needs target feature ptx60}}
+ __hmma_m16n16k16_mma_f32f32(fdst, src, src, fsrc, 1, 1);
+ // CHECK: call {{.*}} @llvm.nvvm.wmma.mma.sync.col.row.m16n16k16.f32.f32
+ // expected-error@+1 {{'__hmma_m16n16k16_mma_f32f32' needs target feature ptx60}}
+ __hmma_m16n16k16_mma_f32f32(fdst, src, src, fsrc, 2, 0);
+ // CHECK: call {{.*}} @llvm.nvvm.wmma.mma.sync.col.row.m16n16k16.f32.f32.satfinite
+ // expected-error@+1 {{'__hmma_m16n16k16_mma_f32f32' needs target feature ptx60}}
+ __hmma_m16n16k16_mma_f32f32(fdst, src, src, fsrc, 2, 1);
+ // CHECK: call {{.*}} @llvm.nvvm.wmma.mma.sync.col.col.m16n16k16.f32.f32
+ // expected-error@+1 {{'__hmma_m16n16k16_mma_f32f32' needs target feature ptx60}}
+ __hmma_m16n16k16_mma_f32f32(fdst, src, src, fsrc, 3, 0);
+ // CHECK: call {{.*}} @llvm.nvvm.wmma.mma.sync.col.col.m16n16k16.f32.f32.satfinite
+ // expected-error@+1 {{'__hmma_m16n16k16_mma_f32f32' needs target feature ptx60}}
+ __hmma_m16n16k16_mma_f32f32(fdst, src, src, fsrc, 3, 1);
+}
diff --git a/test/CodeGen/builtins-nvptx.c b/test/CodeGen/builtins-nvptx.c
index b0d646a51fec..89a982377ad4 100644
--- a/test/CodeGen/builtins-nvptx.c
+++ b/test/CodeGen/builtins-nvptx.c
@@ -636,3 +636,36 @@ __device__ void nvvm_ldg(const void *p) {
typedef double double2 __attribute__((ext_vector_type(2)));
__nvvm_ldg_d2((const double2 *)p);
}
+
+// CHECK-LABEL: nvvm_shfl
+__device__ void nvvm_shfl(int i, float f, int a, int b) {
+ // CHECK: call i32 @llvm.nvvm.shfl.down.i32(i32
+ __nvvm_shfl_down_i32(i, a, b);
+ // CHECK: call float @llvm.nvvm.shfl.down.f32(float
+ __nvvm_shfl_down_f32(f, a, b);
+ // CHECK: call i32 @llvm.nvvm.shfl.up.i32(i32
+ __nvvm_shfl_up_i32(i, a, b);
+ // CHECK: call float @llvm.nvvm.shfl.up.f32(float
+ __nvvm_shfl_up_f32(f, a, b);
+ // CHECK: call i32 @llvm.nvvm.shfl.bfly.i32(i32
+ __nvvm_shfl_bfly_i32(i, a, b);
+ // CHECK: call float @llvm.nvvm.shfl.bfly.f32(float
+ __nvvm_shfl_bfly_f32(f, a, b);
+ // CHECK: call i32 @llvm.nvvm.shfl.idx.i32(i32
+ __nvvm_shfl_idx_i32(i, a, b);
+ // CHECK: call float @llvm.nvvm.shfl.idx.f32(float
+ __nvvm_shfl_idx_f32(f, a, b);
+ // CHECK: ret void
+}
+
+__device__ void nvvm_vote(int pred) {
+ // CHECK: call i1 @llvm.nvvm.vote.all(i1
+ __nvvm_vote_all(pred);
+ // CHECK: call i1 @llvm.nvvm.vote.any(i1
+ __nvvm_vote_any(pred);
+ // CHECK: call i1 @llvm.nvvm.vote.uni(i1
+ __nvvm_vote_uni(pred);
+ // CHECK: call i32 @llvm.nvvm.vote.ballot(i1
+ __nvvm_vote_ballot(pred);
+ // CHECK: ret void
+}
diff --git a/test/CodeGen/builtins-overflow.c b/test/CodeGen/builtins-overflow.c
index c8d828dd33e7..7a30cfbd46ee 100644
--- a/test/CodeGen/builtins-overflow.c
+++ b/test/CodeGen/builtins-overflow.c
@@ -338,3 +338,122 @@ long long test_smulll_overflow(long long x, long long y) {
return LongLongErrorCode;
return result;
}
+
+int test_mixed_sign_mull_overflow(int x, unsigned y) {
+// CHECK: @test_mixed_sign_mull_overflow
+// CHECK: [[IsNeg:%.*]] = icmp slt i32 [[Op1:%.*]], 0
+// CHECK-NEXT: [[Signed:%.*]] = sub i32 0, [[Op1]]
+// CHECK-NEXT: [[AbsSigned:%.*]] = select i1 [[IsNeg]], i32 [[Signed]], i32 [[Op1]]
+// CHECK-NEXT: call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[AbsSigned]], i32 %{{.*}})
+// CHECK-NEXT: [[UnsignedOFlow:%.*]] = extractvalue { i32, i1 } %{{.*}}, 1
+// CHECK-NEXT: [[UnsignedResult:%.*]] = extractvalue { i32, i1 } %{{.*}}, 0
+// CHECK-NEXT: [[IsNegZext:%.*]] = zext i1 [[IsNeg]] to i32
+// CHECK-NEXT: [[MaxResult:%.*]] = add i32 2147483647, [[IsNegZext]]
+// CHECK-NEXT: [[SignedOFlow:%.*]] = icmp ugt i32 [[UnsignedResult]], [[MaxResult]]
+// CHECK-NEXT: [[OFlow:%.*]] = or i1 [[UnsignedOFlow]], [[SignedOFlow]]
+// CHECK-NEXT: [[NegativeResult:%.*]] = sub i32 0, [[UnsignedResult]]
+// CHECK-NEXT: [[Result:%.*]] = select i1 [[IsNeg]], i32 [[NegativeResult]], i32 [[UnsignedResult]]
+// CHECK-NEXT: store i32 [[Result]], i32* %{{.*}}, align 4
+// CHECK: br i1 [[OFlow]]
+
+ int result;
+ if (__builtin_mul_overflow(x, y, &result))
+ return LongErrorCode;
+ return result;
+}
+
+int test_mixed_sign_mull_overflow_unsigned(int x, unsigned y) {
+// CHECK: @test_mixed_sign_mull_overflow_unsigned
+// CHECK: [[IsNeg:%.*]] = icmp slt i32 [[Op1:%.*]], 0
+// CHECK-NEXT: [[Signed:%.*]] = sub i32 0, [[Op1]]
+// CHECK-NEXT: [[AbsSigned:%.*]] = select i1 [[IsNeg]], i32 [[Signed]], i32 [[Op1]]
+// CHECK-NEXT: call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[AbsSigned]], i32 %{{.*}})
+// CHECK-NEXT: [[UnsignedOFlow:%.*]] = extractvalue { i32, i1 } %{{.*}}, 1
+// CHECK-NEXT: [[UnsignedResult:%.*]] = extractvalue { i32, i1 } %{{.*}}, 0
+// CHECK-NEXT: [[NotNull:%.*]] = icmp ne i32 [[UnsignedResult]], 0
+// CHECK-NEXT: [[Underflow:%.*]] = and i1 [[IsNeg]], [[NotNull]]
+// CHECK-NEXT: [[OFlow:%.*]] = or i1 [[UnsignedOFlow]], [[Underflow]]
+// CHECK-NEXT: store i32 [[UnsignedResult]], i32* %{{.*}}, align 4
+// CHECK: br i1 [[OFlow]]
+
+ unsigned result;
+ if (__builtin_mul_overflow(x, y, &result))
+ return LongErrorCode;
+ return result;
+}
+
+int test_mixed_sign_mull_overflow_swapped(int x, unsigned y) {
+// CHECK: @test_mixed_sign_mull_overflow_swapped
+// CHECK: call { i32, i1 } @llvm.umul.with.overflow.i32
+// CHECK: add i32 2147483647
+ int result;
+ if (__builtin_mul_overflow(y, x, &result))
+ return LongErrorCode;
+ return result;
+}
+
+long long test_mixed_sign_mulll_overflow(long long x, unsigned long long y) {
+// CHECK: @test_mixed_sign_mulll_overflow
+// CHECK: call { i64, i1 } @llvm.umul.with.overflow.i64
+// CHECK: add i64 92233720368547
+ long long result;
+ if (__builtin_mul_overflow(x, y, &result))
+ return LongLongErrorCode;
+ return result;
+}
+
+long long test_mixed_sign_mulll_overflow_swapped(long long x, unsigned long long y) {
+// CHECK: @test_mixed_sign_mulll_overflow_swapped
+// CHECK: call { i64, i1 } @llvm.umul.with.overflow.i64
+// CHECK: add i64 92233720368547
+ long long result;
+ if (__builtin_mul_overflow(y, x, &result))
+ return LongLongErrorCode;
+ return result;
+}
+
+long long test_mixed_sign_mulll_overflow_trunc_signed(long long x, unsigned long long y) {
+// CHECK: @test_mixed_sign_mulll_overflow_trunc_signed
+// CHECK: call { i64, i1 } @llvm.umul.with.overflow.i64
+// CHECK: add i64 2147483647
+// CHECK: trunc
+// CHECK: store
+ int result;
+ if (__builtin_mul_overflow(y, x, &result))
+ return LongLongErrorCode;
+ return result;
+}
+
+long long test_mixed_sign_mulll_overflow_trunc_unsigned(long long x, unsigned long long y) {
+// CHECK: @test_mixed_sign_mulll_overflow_trunc_unsigned
+// CHECK: call { i64, i1 } @llvm.umul.with.overflow.i64
+// CHECK: [[NON_ZERO:%.*]] = icmp ne i64 [[UNSIGNED_RESULT:%.*]], 0
+// CHECK-NEXT: [[UNDERFLOW:%.*]] = and i1 {{.*}}, [[NON_ZERO]]
+// CHECK-NEXT: [[OVERFLOW_PRE_TRUNC:%.*]] = or i1 {{.*}}, [[UNDERFLOW]]
+// CHECK-NEXT: [[TRUNC_OVERFLOW:%.*]] = icmp ugt i64 [[UNSIGNED_RESULT]], 4294967295
+// CHECK-NEXT: [[OVERFLOW:%.*]] = or i1 [[OVERFLOW_PRE_TRUNC]], [[TRUNC_OVERFLOW]]
+// CHECK-NEXT: trunc i64 [[UNSIGNED_RESULT]] to i32
+// CHECK-NEXT: store
+ unsigned result;
+ if (__builtin_mul_overflow(y, x, &result))
+ return LongLongErrorCode;
+ return result;
+}
+
+long long test_mixed_sign_mul_overflow_extend_signed(int x, unsigned y) {
+// CHECK: @test_mixed_sign_mul_overflow_extend_signed
+// CHECK: call { i64, i1 } @llvm.smul.with.overflow.i64
+ long long result;
+ if (__builtin_mul_overflow(y, x, &result))
+ return LongLongErrorCode;
+ return result;
+}
+
+long long test_mixed_sign_mul_overflow_extend_unsigned(int x, unsigned y) {
+// CHECK: @test_mixed_sign_mul_overflow_extend_unsigned
+// CHECK: call { i65, i1 } @llvm.smul.with.overflow.i65
+ unsigned long long result;
+ if (__builtin_mul_overflow(y, x, &result))
+ return LongLongErrorCode;
+ return result;
+}
diff --git a/test/CodeGen/builtins-x86.c b/test/CodeGen/builtins-x86.c
index 0086f7079dd9..fc3cc448cf3c 100644
--- a/test/CodeGen/builtins-x86.c
+++ b/test/CodeGen/builtins-x86.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -DUSE_64 -triple x86_64-unknown-unknown -target-feature +fxsr -target-feature +avx -target-feature +xsaveopt -target-feature +xsaves -target-feature +xsavec -target-feature +mwaitx -target-feature +clzero -emit-llvm -o %t %s
-// RUN: %clang_cc1 -DUSE_ALL -triple x86_64-unknown-unknown -target-feature +fxsr -target-feature +avx -target-feature +xsaveopt -target-feature +xsaves -target-feature +xsavec -target-feature +mwaitx -target-feature +clzero -fsyntax-only -o %t %s
+// RUN: %clang_cc1 -DUSE_64 -triple x86_64-unknown-unknown -target-feature +fxsr -target-feature +avx -target-feature +xsaveopt -target-feature +xsaves -target-feature +xsavec -target-feature +mwaitx -target-feature +clzero -target-feature +ibt -target-feature +shstk -emit-llvm -o %t %s
+// RUN: %clang_cc1 -DUSE_ALL -triple x86_64-unknown-unknown -target-feature +fxsr -target-feature +avx -target-feature +xsaveopt -target-feature +xsaves -target-feature +xsavec -target-feature +mwaitx -target-feature +ibt -target-feature +shstk -target-feature +clzero -fsyntax-only -o %t %s
#ifdef USE_ALL
#define USE_3DNOW
@@ -160,8 +160,6 @@ void f0() {
tmp_V4s = __builtin_ia32_psubusw(tmp_V4s, tmp_V4s);
tmp_V4s = __builtin_ia32_pmulhw(tmp_V4s, tmp_V4s);
tmp_V4s = __builtin_ia32_pmulhuw(tmp_V4s, tmp_V4s);
- tmp_V8c = __builtin_ia32_pavgb(tmp_V8c, tmp_V8c);
- tmp_V4s = __builtin_ia32_pavgw(tmp_V4s, tmp_V4s);
tmp_V8c = __builtin_ia32_pcmpeqb(tmp_V8c, tmp_V8c);
tmp_V4s = __builtin_ia32_pcmpeqw(tmp_V4s, tmp_V4s);
tmp_V2i = __builtin_ia32_pcmpeqd(tmp_V2i, tmp_V2i);
@@ -201,8 +199,6 @@ void f0() {
tmp_V16c = __builtin_ia32_psubusb128(tmp_V16c, tmp_V16c);
tmp_V8s = __builtin_ia32_psubusw128(tmp_V8s, tmp_V8s);
tmp_V8s = __builtin_ia32_pmulhw128(tmp_V8s, tmp_V8s);
- tmp_V16c = __builtin_ia32_pavgb128(tmp_V16c, tmp_V16c);
- tmp_V8s = __builtin_ia32_pavgw128(tmp_V8s, tmp_V8s);
tmp_V16c = __builtin_ia32_pmaxub128(tmp_V16c, tmp_V16c);
tmp_V8s = __builtin_ia32_pmaxsw128(tmp_V8s, tmp_V8s);
tmp_V16c = __builtin_ia32_pminub128(tmp_V16c, tmp_V16c);
@@ -261,6 +257,19 @@ void f0() {
tmp_V8c = __builtin_ia32_packuswb(tmp_V4s, tmp_V4s);
tmp_i = __builtin_ia32_vec_ext_v2si(tmp_V2i, 0);
+ __builtin_ia32_incsspd(tmp_Ui);
+ __builtin_ia32_incsspq(tmp_ULLi);
+ tmp_Ui = __builtin_ia32_rdsspd(tmp_Ui);
+ tmp_ULLi = __builtin_ia32_rdsspq(tmp_ULLi);
+ __builtin_ia32_saveprevssp();
+ __builtin_ia32_rstorssp(tmp_vp);
+ __builtin_ia32_wrssd(tmp_Ui, tmp_vp);
+ __builtin_ia32_wrssq(tmp_ULLi, tmp_vp);
+ __builtin_ia32_wrussd(tmp_Ui, tmp_vp);
+ __builtin_ia32_wrussq(tmp_ULLi, tmp_vp);
+ __builtin_ia32_setssbsy();
+ __builtin_ia32_clrssbsy(tmp_vp);
+
(void) __builtin_ia32_ldmxcsr(tmp_Ui);
(void) _mm_setcsr(tmp_Ui);
tmp_Ui = __builtin_ia32_stmxcsr();
diff --git a/test/CodeGen/builtins.c b/test/CodeGen/builtins.c
index 390c2e35bf9d..4f84db00cbd7 100644
--- a/test/CodeGen/builtins.c
+++ b/test/CodeGen/builtins.c
@@ -176,6 +176,19 @@ void bar() {
}
// CHECK: }
+// CHECK-LABEL: define void @test_conditional_bzero
+void test_conditional_bzero() {
+ char dst[20];
+ int _sz = 20, len = 20;
+ return (_sz
+ ? ((_sz >= len)
+ ? __builtin_bzero(dst, len)
+ : foo())
+ : __builtin_bzero(dst, len));
+ // CHECK: call void @llvm.memset
+ // CHECK: call void @llvm.memset
+ // CHECK-NOT: phi
+}
// CHECK-LABEL: define void @test_float_builtins
void test_float_builtins(float F, double D, long double LD) {
@@ -317,6 +330,15 @@ void test_float_builtin_ops(float F, double D, long double LD) {
resld = __builtin_floorl(LD);
// CHECK: call x86_fp80 @llvm.floor.f80
+ resf = __builtin_sqrtf(F);
+ // CHECK: call float @llvm.sqrt.f32(
+
+ resd = __builtin_sqrt(D);
+ // CHECK: call double @llvm.sqrt.f64(
+
+ resld = __builtin_sqrtl(LD);
+ // CHECK: call x86_fp80 @llvm.sqrt.f80
+
resf = __builtin_truncf(F);
// CHECK: call float @llvm.trunc.f32
@@ -378,229 +400,385 @@ long long test_builtin_readcyclecounter() {
#ifdef __x86_64__
// CHECK-LABEL: define void @test_builtin_os_log
-// CHECK: (i8* [[BUF:%.*]], i32 [[I:%.*]], i8* [[DATA:%.*]])
+// CHECK: (i8* %[[BUF:.*]], i32 %[[I:.*]], i8* %[[DATA:.*]])
void test_builtin_os_log(void *buf, int i, const char *data) {
volatile int len;
- // CHECK: store i8* [[BUF]], i8** [[BUF_ADDR:%.*]], align 8
- // CHECK: store i32 [[I]], i32* [[I_ADDR:%.*]], align 4
- // CHECK: store i8* [[DATA]], i8** [[DATA_ADDR:%.*]], align 8
-
- // CHECK: store volatile i32 34
+ // CHECK: %[[BUF_ADDR:.*]] = alloca i8*, align 8
+ // CHECK: %[[I_ADDR:.*]] = alloca i32, align 4
+ // CHECK: %[[DATA_ADDR:.*]] = alloca i8*, align 8
+ // CHECK: %[[LEN:.*]] = alloca i32, align 4
+ // CHECK: store i8* %[[BUF]], i8** %[[BUF_ADDR]], align 8
+ // CHECK: store i32 %[[I]], i32* %[[I_ADDR]], align 4
+ // CHECK: store i8* %[[DATA]], i8** %[[DATA_ADDR]], align 8
+
+ // CHECK: store volatile i32 34, i32* %[[LEN]]
len = __builtin_os_log_format_buffer_size("%d %{public}s %{private}.16P", i, data, data);
- // CHECK: [[BUF2:%.*]] = load i8*, i8** [[BUF_ADDR]]
- // CHECK: [[SUMMARY:%.*]] = getelementptr i8, i8* [[BUF2]], i64 0
- // CHECK: store i8 3, i8* [[SUMMARY]]
- // CHECK: [[NUM_ARGS:%.*]] = getelementptr i8, i8* [[BUF2]], i64 1
- // CHECK: store i8 4, i8* [[NUM_ARGS]]
- //
- // CHECK: [[ARG1_DESC:%.*]] = getelementptr i8, i8* [[BUF2]], i64 2
- // CHECK: store i8 0, i8* [[ARG1_DESC]]
- // CHECK: [[ARG1_SIZE:%.*]] = getelementptr i8, i8* [[BUF2]], i64 3
- // CHECK: store i8 4, i8* [[ARG1_SIZE]]
- // CHECK: [[ARG1:%.*]] = getelementptr i8, i8* [[BUF2]], i64 4
- // CHECK: [[ARG1_INT:%.*]] = bitcast i8* [[ARG1]] to i32*
- // CHECK: [[I2:%.*]] = load i32, i32* [[I_ADDR]]
- // CHECK: store i32 [[I2]], i32* [[ARG1_INT]]
-
- // CHECK: [[ARG2_DESC:%.*]] = getelementptr i8, i8* [[BUF2]], i64 8
- // CHECK: store i8 34, i8* [[ARG2_DESC]]
- // CHECK: [[ARG2_SIZE:%.*]] = getelementptr i8, i8* [[BUF2]], i64 9
- // CHECK: store i8 8, i8* [[ARG2_SIZE]]
- // CHECK: [[ARG2:%.*]] = getelementptr i8, i8* [[BUF2]], i64 10
- // CHECK: [[ARG2_PTR:%.*]] = bitcast i8* [[ARG2]] to i8**
- // CHECK: [[DATA2:%.*]] = load i8*, i8** [[DATA_ADDR]]
- // CHECK: store i8* [[DATA2]], i8** [[ARG2_PTR]]
-
- // CHECK: [[ARG3_DESC:%.*]] = getelementptr i8, i8* [[BUF2]], i64 18
- // CHECK: store i8 17, i8* [[ARG3_DESC]]
- // CHECK: [[ARG3_SIZE:%.*]] = getelementptr i8, i8* [[BUF2]], i64 19
- // CHECK: store i8 4, i8* [[ARG3_SIZE]]
- // CHECK: [[ARG3:%.*]] = getelementptr i8, i8* [[BUF2]], i64 20
- // CHECK: [[ARG3_INT:%.*]] = bitcast i8* [[ARG3]] to i32*
- // CHECK: store i32 16, i32* [[ARG3_INT]]
-
- // CHECK: [[ARG4_DESC:%.*]] = getelementptr i8, i8* [[BUF2]], i64 24
- // CHECK: store i8 49, i8* [[ARG4_DESC]]
- // CHECK: [[ARG4_SIZE:%.*]] = getelementptr i8, i8* [[BUF2]], i64 25
- // CHECK: store i8 8, i8* [[ARG4_SIZE]]
- // CHECK: [[ARG4:%.*]] = getelementptr i8, i8* [[BUF2]], i64 26
- // CHECK: [[ARG4_PTR:%.*]] = bitcast i8* [[ARG4]] to i8**
- // CHECK: [[DATA3:%.*]] = load i8*, i8** [[DATA_ADDR]]
- // CHECK: store i8* [[DATA3]], i8** [[ARG4_PTR]]
-
+ // CHECK: %[[V1:.*]] = load i8*, i8** %[[BUF_ADDR]]
+ // CHECK: %[[V2:.*]] = load i32, i32* %[[I_ADDR]]
+ // CHECK: %[[V3:.*]] = load i8*, i8** %[[DATA_ADDR]]
+ // CHECK: %[[V4:.*]] = ptrtoint i8* %[[V3]] to i64
+ // CHECK: %[[V5:.*]] = load i8*, i8** %[[DATA_ADDR]]
+ // CHECK: %[[V6:.*]] = ptrtoint i8* %[[V5]] to i64
+ // CHECK: call void @__os_log_helper_1_3_4_4_0_8_34_4_17_8_49(i8* %[[V1]], i32 %[[V2]], i64 %[[V4]], i32 16, i64 %[[V6]])
__builtin_os_log_format(buf, "%d %{public}s %{private}.16P", i, data, data);
}
-// CHECK-LABEL: define void @test_builtin_os_log_errno
-// CHECK: (i8* [[BUF:%.*]], i8* [[DATA:%.*]])
-void test_builtin_os_log_errno(void *buf, const char *data) {
- volatile int len;
- // CHECK: store i8* [[BUF]], i8** [[BUF_ADDR:%.*]], align 8
- // CHECK: store i8* [[DATA]], i8** [[DATA_ADDR:%.*]], align 8
-
- // CHECK: store volatile i32 2
- len = __builtin_os_log_format_buffer_size("%S");
-
- // CHECK: [[BUF2:%.*]] = load i8*, i8** [[BUF_ADDR]]
- // CHECK: [[SUMMARY:%.*]] = getelementptr i8, i8* [[BUF2]], i64 0
- // CHECK: store i8 2, i8* [[SUMMARY]]
- // CHECK: [[NUM_ARGS:%.*]] = getelementptr i8, i8* [[BUF2]], i64 1
- // CHECK: store i8 1, i8* [[NUM_ARGS]]
-
- // CHECK: [[ARG1_DESC:%.*]] = getelementptr i8, i8* [[BUF2]], i64 2
- // CHECK: store i8 96, i8* [[ARG1_DESC]]
- // CHECK: [[ARG1_SIZE:%.*]] = getelementptr i8, i8* [[BUF2]], i64 3
- // CHECK: store i8 0, i8* [[ARG1_SIZE]]
- // CHECK: [[ARG1:%.*]] = getelementptr i8, i8* [[BUF2]], i64 4
- // CHECK: [[ARG1_INT:%.*]] = bitcast i8* [[ARG1]] to i32*
- // CHECK: store i32 0, i32* [[ARG1_INT]]
-
- __builtin_os_log_format(buf, "%m");
-}
+// CHECK-LABEL: define linkonce_odr hidden void @__os_log_helper_1_3_4_4_0_8_34_4_17_8_49
+// CHECK: (i8* %[[BUFFER:.*]], i32 %[[ARG0:.*]], i64 %[[ARG1:.*]], i32 %[[ARG2:.*]], i64 %[[ARG3:.*]])
+
+// CHECK: %[[BUFFER_ADDR:.*]] = alloca i8*, align 8
+// CHECK: %[[ARG0_ADDR:.*]] = alloca i32, align 4
+// CHECK: %[[ARG1_ADDR:.*]] = alloca i64, align 8
+// CHECK: %[[ARG2_ADDR:.*]] = alloca i32, align 4
+// CHECK: %[[ARG3_ADDR:.*]] = alloca i64, align 8
+// CHECK: store i8* %[[BUFFER]], i8** %[[BUFFER_ADDR]], align 8
+// CHECK: store i32 %[[ARG0]], i32* %[[ARG0_ADDR]], align 4
+// CHECK: store i64 %[[ARG1]], i64* %[[ARG1_ADDR]], align 8
+// CHECK: store i32 %[[ARG2]], i32* %[[ARG2_ADDR]], align 4
+// CHECK: store i64 %[[ARG3]], i64* %[[ARG3_ADDR]], align 8
+// CHECK: %[[BUF:.*]] = load i8*, i8** %[[BUFFER_ADDR]], align 8
+// CHECK: %[[SUMMARY:.*]] = getelementptr i8, i8* %[[BUF]], i64 0
+// CHECK: store i8 3, i8* %[[SUMMARY]], align 1
+// CHECK: %[[NUMARGS:.*]] = getelementptr i8, i8* %[[BUF]], i64 1
+// CHECK: store i8 4, i8* %[[NUMARGS]], align 1
+// CHECK: %[[ARGDESCRIPTOR:.*]] = getelementptr i8, i8* %[[BUF]], i64 2
+// CHECK: store i8 0, i8* %[[ARGDESCRIPTOR]], align 1
+// CHECK: %[[ARGSIZE:.*]] = getelementptr i8, i8* %[[BUF]], i64 3
+// CHECK: store i8 4, i8* %[[ARGSIZE]], align 1
+// CHECK: %[[ARGDATA:.*]] = getelementptr i8, i8* %[[BUF]], i64 4
+// CHECK: %[[ARGDATACAST:.*]] = bitcast i8* %[[ARGDATA]] to i32*
+// CHECK: %[[V0:.*]] = load i32, i32* %[[ARG0_ADDR]], align 4
+// CHECK: store i32 %[[V0]], i32* %[[ARGDATACAST]], align 1
+// CHECK: %[[ARGDESCRIPTOR1:.*]] = getelementptr i8, i8* %[[BUF]], i64 8
+// CHECK: store i8 34, i8* %[[ARGDESCRIPTOR1]], align 1
+// CHECK: %[[ARGSIZE2:.*]] = getelementptr i8, i8* %[[BUF]], i64 9
+// CHECK: store i8 8, i8* %[[ARGSIZE2]], align 1
+// CHECK: %[[ARGDATA3:.*]] = getelementptr i8, i8* %[[BUF]], i64 10
+// CHECK: %[[ARGDATACAST4:.*]] = bitcast i8* %[[ARGDATA3]] to i64*
+// CHECK: %[[V1:.*]] = load i64, i64* %[[ARG1_ADDR]], align 8
+// CHECK: store i64 %[[V1]], i64* %[[ARGDATACAST4]], align 1
+// CHECK: %[[ARGDESCRIPTOR5:.*]] = getelementptr i8, i8* %[[BUF]], i64 18
+// CHECK: store i8 17, i8* %[[ARGDESCRIPTOR5]], align 1
+// CHECK: %[[ARGSIZE6:.*]] = getelementptr i8, i8* %[[BUF]], i64 19
+// CHECK: store i8 4, i8* %[[ARGSIZE6]], align 1
+// CHECK: %[[ARGDATA7:.*]] = getelementptr i8, i8* %[[BUF]], i64 20
+// CHECK: %[[ARGDATACAST8:.*]] = bitcast i8* %[[ARGDATA7]] to i32*
+// CHECK: %[[V2:.*]] = load i32, i32* %[[ARG2_ADDR]], align 4
+// CHECK: store i32 %[[V2]], i32* %[[ARGDATACAST8]], align 1
+// CHECK: %[[ARGDESCRIPTOR9:.*]] = getelementptr i8, i8* %[[BUF]], i64 24
+// CHECK: store i8 49, i8* %[[ARGDESCRIPTOR9]], align 1
+// CHECK: %[[ARGSIZE10:.*]] = getelementptr i8, i8* %[[BUF]], i64 25
+// CHECK: store i8 8, i8* %[[ARGSIZE10]], align 1
+// CHECK: %[[ARGDATA11:.*]] = getelementptr i8, i8* %[[BUF]], i64 26
+// CHECK: %[[ARGDATACAST12:.*]] = bitcast i8* %[[ARGDATA11]] to i64*
+// CHECK: %[[V3:.*]] = load i64, i64* %[[ARG3_ADDR]], align 8
+// CHECK: store i64 %[[V3]], i64* %[[ARGDATACAST12]], align 1
// CHECK-LABEL: define void @test_builtin_os_log_wide
-// CHECK: (i8* [[BUF:%.*]], i8* [[DATA:%.*]], i32* [[STR:%.*]])
+// CHECK: (i8* %[[BUF:.*]], i8* %[[DATA:.*]], i32* %[[STR:.*]])
typedef int wchar_t;
void test_builtin_os_log_wide(void *buf, const char *data, wchar_t *str) {
volatile int len;
- // CHECK: store i8* [[BUF]], i8** [[BUF_ADDR:%.*]], align 8
- // CHECK: store i8* [[DATA]], i8** [[DATA_ADDR:%.*]], align 8
- // CHECK: store i32* [[STR]], i32** [[STR_ADDR:%.*]],
- // CHECK: store volatile i32 12
+ // CHECK: %[[BUF_ADDR:.*]] = alloca i8*, align 8
+ // CHECK: %[[DATA_ADDR:.*]] = alloca i8*, align 8
+ // CHECK: %[[STR_ADDR:.*]] = alloca i32*, align 8
+ // CHECK: %[[LEN:.*]] = alloca i32, align 4
+ // CHECK: store i8* %[[BUF]], i8** %[[BUF_ADDR]], align 8
+ // CHECK: store i8* %[[DATA]], i8** %[[DATA_ADDR]], align 8
+ // CHECK: store i32* %[[STR]], i32** %[[STR_ADDR]], align 8
+
+ // CHECK: store volatile i32 12, i32* %[[LEN]], align 4
len = __builtin_os_log_format_buffer_size("%S", str);
- // CHECK: [[BUF2:%.*]] = load i8*, i8** [[BUF_ADDR]]
- // CHECK: [[SUMMARY:%.*]] = getelementptr i8, i8* [[BUF2]], i64 0
- // CHECK: store i8 2, i8* [[SUMMARY]]
- // CHECK: [[NUM_ARGS:%.*]] = getelementptr i8, i8* [[BUF2]], i64 1
- // CHECK: store i8 1, i8* [[NUM_ARGS]]
-
- // CHECK: [[ARG1_DESC:%.*]] = getelementptr i8, i8* [[BUF2]], i64 2
- // CHECK: store i8 80, i8* [[ARG1_DESC]]
- // CHECK: [[ARG1_SIZE:%.*]] = getelementptr i8, i8* [[BUF2]], i64 3
- // CHECK: store i8 8, i8* [[ARG1_SIZE]]
- // CHECK: [[ARG1:%.*]] = getelementptr i8, i8* [[BUF2]], i64 4
- // CHECK: [[ARG1_PTR:%.*]] = bitcast i8* [[ARG1]] to i32**
- // CHECK: [[STR2:%.*]] = load i32*, i32** [[STR_ADDR]]
- // CHECK: store i32* [[STR2]], i32** [[ARG1_PTR]]
+ // CHECK: %[[V1:.*]] = load i8*, i8** %[[BUF_ADDR]], align 8
+ // CHECK: %[[V2:.*]] = load i32*, i32** %[[STR_ADDR]], align 8
+ // CHECK: %[[V3:.*]] = ptrtoint i32* %[[V2]] to i64
+ // CHECK: call void @__os_log_helper_1_2_1_8_80(i8* %[[V1]], i64 %[[V3]])
__builtin_os_log_format(buf, "%S", str);
}
+// CHECK-LABEL: define linkonce_odr hidden void @__os_log_helper_1_2_1_8_80
+// CHECK: (i8* %[[BUFFER:.*]], i64 %[[ARG0:.*]])
+
+// CHECK: %[[BUFFER_ADDR:.*]] = alloca i8*, align 8
+// CHECK: %[[ARG0_ADDR:.*]] = alloca i64, align 8
+// CHECK: store i8* %[[BUFFER]], i8** %[[BUFFER_ADDR]], align 8
+// CHECK: store i64 %[[ARG0]], i64* %[[ARG0_ADDR]], align 8
+// CHECK: %[[BUF:.*]] = load i8*, i8** %[[BUFFER_ADDR]], align 8
+// CHECK: %[[SUMMARY:.*]] = getelementptr i8, i8* %[[BUF]], i64 0
+// CHECK: store i8 2, i8* %[[SUMMARY]], align 1
+// CHECK: %[[NUMARGS:.*]] = getelementptr i8, i8* %[[BUF]], i64 1
+// CHECK: store i8 1, i8* %[[NUMARGS]], align 1
+// CHECK: %[[ARGDESCRIPTOR:.*]] = getelementptr i8, i8* %[[BUF]], i64 2
+// CHECK: store i8 80, i8* %[[ARGDESCRIPTOR]], align 1
+// CHECK: %[[ARGSIZE:.*]] = getelementptr i8, i8* %[[BUF]], i64 3
+// CHECK: store i8 8, i8* %[[ARGSIZE]], align 1
+// CHECK: %[[ARGDATA:.*]] = getelementptr i8, i8* %[[BUF]], i64 4
+// CHECK: %[[ARGDATACAST:.*]] = bitcast i8* %[[ARGDATA]] to i64*
+// CHECK: %[[V0:.*]] = load i64, i64* %[[ARG0_ADDR]], align 8
+// CHECK: store i64 %[[V0]], i64* %[[ARGDATACAST]], align 1
+
// CHECK-LABEL: define void @test_builtin_os_log_precision_width
-// CHECK: (i8* [[BUF:%.*]], i8* [[DATA:%.*]], i32 [[PRECISION:%.*]], i32 [[WIDTH:%.*]])
+// CHECK: (i8* %[[BUF:.*]], i8* %[[DATA:.*]], i32 %[[PRECISION:.*]], i32 %[[WIDTH:.*]])
void test_builtin_os_log_precision_width(void *buf, const char *data,
int precision, int width) {
volatile int len;
- // CHECK: store i8* [[BUF]], i8** [[BUF_ADDR:%.*]], align 8
- // CHECK: store i8* [[DATA]], i8** [[DATA_ADDR:%.*]], align 8
- // CHECK: store i32 [[PRECISION]], i32* [[PRECISION_ADDR:%.*]], align 4
- // CHECK: store i32 [[WIDTH]], i32* [[WIDTH_ADDR:%.*]], align 4
-
- // CHECK: store volatile i32 24,
+ // CHECK: %[[BUF_ADDR:.*]] = alloca i8*, align 8
+ // CHECK: %[[DATA_ADDR:.*]] = alloca i8*, align 8
+ // CHECK: %[[PRECISION_ADDR:.*]] = alloca i32, align 4
+ // CHECK: %[[WIDTH_ADDR:.*]] = alloca i32, align 4
+ // CHECK: %[[LEN:.*]] = alloca i32, align 4
+ // CHECK: store i8* %[[BUF]], i8** %[[BUF_ADDR]], align 8
+ // CHECK: store i8* %[[DATA]], i8** %[[DATA_ADDR]], align 8
+ // CHECK: store i32 %[[PRECISION]], i32* %[[PRECISION_ADDR]], align 4
+ // CHECK: store i32 %[[WIDTH]], i32* %[[WIDTH_ADDR]], align 4
+
+ // CHECK: store volatile i32 24, i32* %[[LEN]], align 4
len = __builtin_os_log_format_buffer_size("Hello %*.*s World", precision, width, data);
- // CHECK: [[BUF2:%.*]] = load i8*, i8** [[BUF_ADDR]]
- // CHECK: [[SUMMARY:%.*]] = getelementptr i8, i8* [[BUF2]], i64 0
- // CHECK: store i8 2, i8* [[SUMMARY]]
- // CHECK: [[NUM_ARGS:%.*]] = getelementptr i8, i8* [[BUF2]], i64 1
- // CHECK: store i8 3, i8* [[NUM_ARGS]]
-
- // CHECK: [[ARG1_DESC:%.*]] = getelementptr i8, i8* [[BUF2]], i64 2
- // CHECK: store i8 0, i8* [[ARG1_DESC]]
- // CHECK: [[ARG1_SIZE:%.*]] = getelementptr i8, i8* [[BUF2]], i64 3
- // CHECK: store i8 4, i8* [[ARG1_SIZE]]
- // CHECK: [[ARG1:%.*]] = getelementptr i8, i8* [[BUF2]], i64 4
- // CHECK: [[ARG1_INT:%.*]] = bitcast i8* [[ARG1]] to i32*
- // CHECK: [[ARG1_VAL:%.*]] = load i32, i32* [[PRECISION_ADDR]]
- // CHECK: store i32 [[ARG1_VAL]], i32* [[ARG1_INT]]
-
- // CHECK: [[ARG2_DESC:%.*]] = getelementptr i8, i8* [[BUF2]], i64 8
- // CHECK: store i8 16, i8* [[ARG2_DESC]]
- // CHECK: [[ARG2_SIZE:%.*]] = getelementptr i8, i8* [[BUF2]], i64 9
- // CHECK: store i8 4, i8* [[ARG2_SIZE]]
- // CHECK: [[ARG2:%.*]] = getelementptr i8, i8* [[BUF2]], i64 10
- // CHECK: [[ARG2_INT:%.*]] = bitcast i8* [[ARG2]] to i32*
- // CHECK: [[ARG2_VAL:%.*]] = load i32, i32* [[WIDTH_ADDR]]
- // CHECK: store i32 [[ARG2_VAL]], i32* [[ARG2_INT]]
-
- // CHECK: [[ARG3_DESC:%.*]] = getelementptr i8, i8* [[BUF2]], i64 14
- // CHECK: store i8 32, i8* [[ARG3_DESC]]
- // CHECK: [[ARG3_SIZE:%.*]] = getelementptr i8, i8* [[BUF2]], i64 15
- // CHECK: store i8 8, i8* [[ARG3_SIZE]]
- // CHECK: [[ARG3:%.*]] = getelementptr i8, i8* [[BUF2]], i64 16
- // CHECK: [[ARG3_PTR:%.*]] = bitcast i8* [[ARG3]] to i8**
- // CHECK: [[DATA2:%.*]] = load i8*, i8** [[DATA_ADDR]]
- // CHECK: store i8* [[DATA2]], i8** [[ARG3_PTR]]
-
+ // CHECK: %[[V1:.*]] = load i8*, i8** %[[BUF_ADDR]], align 8
+ // CHECK: %[[V2:.*]] = load i32, i32* %[[PRECISION_ADDR]], align 4
+ // CHECK: %[[V3:.*]] = load i32, i32* %[[WIDTH_ADDR]], align 4
+ // CHECK: %[[V4:.*]] = load i8*, i8** %[[DATA_ADDR]], align 8
+ // CHECK: %[[V5:.*]] = ptrtoint i8* %[[V4]] to i64
+ // CHECK: call void @__os_log_helper_1_2_3_4_0_4_16_8_32(i8* %[[V1]], i32 %[[V2]], i32 %[[V3]], i64 %[[V5]])
__builtin_os_log_format(buf, "Hello %*.*s World", precision, width, data);
}
+// CHECK-LABEL: define linkonce_odr hidden void @__os_log_helper_1_2_3_4_0_4_16_8_32
+// CHECK: (i8* %[[BUFFER:.*]], i32 %[[ARG0:.*]], i32 %[[ARG1:.*]], i64 %[[ARG2:.*]])
+
+// CHECK: %[[BUFFER_ADDR:.*]] = alloca i8*, align 8
+// CHECK: %[[ARG0_ADDR:.*]] = alloca i32, align 4
+// CHECK: %[[ARG1_ADDR:.*]] = alloca i32, align 4
+// CHECK: %[[ARG2_ADDR:.*]] = alloca i64, align 8
+// CHECK: store i8* %[[BUFFER]], i8** %[[BUFFER_ADDR]], align 8
+// CHECK: store i32 %[[ARG0]], i32* %[[ARG0_ADDR]], align 4
+// CHECK: store i32 %[[ARG1]], i32* %[[ARG1_ADDR]], align 4
+// CHECK: store i64 %[[ARG2]], i64* %[[ARG2_ADDR]], align 8
+// CHECK: %[[BUF:.*]] = load i8*, i8** %[[BUFFER_ADDR]], align 8
+// CHECK: %[[SUMMARY:.*]] = getelementptr i8, i8* %[[BUF]], i64 0
+// CHECK: store i8 2, i8* %[[SUMMARY]], align 1
+// CHECK: %[[NUMARGS:.*]] = getelementptr i8, i8* %[[BUF]], i64 1
+// CHECK: store i8 3, i8* %[[NUMARGS]], align 1
+// CHECK: %[[ARGDESCRIPTOR:.*]] = getelementptr i8, i8* %[[BUF]], i64 2
+// CHECK: store i8 0, i8* %[[ARGDESCRIPTOR]], align 1
+// CHECK: %[[ARGSIZE:.*]] = getelementptr i8, i8* %[[BUF]], i64 3
+// CHECK: store i8 4, i8* %[[ARGSIZE]], align 1
+// CHECK: %[[ARGDATA:.*]] = getelementptr i8, i8* %[[BUF]], i64 4
+// CHECK: %[[ARGDATACAST:.*]] = bitcast i8* %[[ARGDATA]] to i32*
+// CHECK: %[[V0:.*]] = load i32, i32* %[[ARG0_ADDR]], align 4
+// CHECK: store i32 %[[V0]], i32* %[[ARGDATACAST]], align 1
+// CHECK: %[[ARGDESCRIPTOR1:.*]] = getelementptr i8, i8* %[[BUF]], i64 8
+// CHECK: store i8 16, i8* %[[ARGDESCRIPTOR1]], align 1
+// CHECK: %[[ARGSIZE2:.*]] = getelementptr i8, i8* %[[BUF]], i64 9
+// CHECK: store i8 4, i8* %[[ARGSIZE2]], align 1
+// CHECK: %[[ARGDATA3:.*]] = getelementptr i8, i8* %[[BUF]], i64 10
+// CHECK: %[[ARGDATACAST4:.*]] = bitcast i8* %[[ARGDATA3]] to i32*
+// CHECK: %[[V1:.*]] = load i32, i32* %[[ARG1_ADDR]], align 4
+// CHECK: store i32 %[[V1]], i32* %[[ARGDATACAST4]], align 1
+// CHECK: %[[ARGDESCRIPTOR5:.*]] = getelementptr i8, i8* %[[BUF]], i64 14
+// CHECK: store i8 32, i8* %[[ARGDESCRIPTOR5]], align 1
+// CHECK: %[[ARGSIZE6:.*]] = getelementptr i8, i8* %[[BUF]], i64 15
+// CHECK: store i8 8, i8* %[[ARGSIZE6]], align 1
+// CHECK: %[[ARGDATA7:.*]] = getelementptr i8, i8* %[[BUF]], i64 16
+// CHECK: %[[ARGDATACAST8:.*]] = bitcast i8* %[[ARGDATA7]] to i64*
+// CHECK: %[[V2:.*]] = load i64, i64* %[[ARG2_ADDR]], align 8
+// CHECK: store i64 %[[V2]], i64* %[[ARGDATACAST8]], align 1
+
// CHECK-LABEL: define void @test_builtin_os_log_invalid
-// CHECK: (i8* [[BUF:%.*]], i32 [[DATA:%.*]])
+// CHECK: (i8* %[[BUF:.*]], i32 %[[DATA:.*]])
void test_builtin_os_log_invalid(void *buf, int data) {
volatile int len;
- // CHECK: store i8* [[BUF]], i8** [[BUF_ADDR:%.*]], align 8
- // CHECK: store i32 [[DATA]], i32* [[DATA_ADDR:%.*]]
+ // CHECK: %[[BUF_ADDR:.*]] = alloca i8*, align 8
+ // CHECK: %[[DATA_ADDR:.*]] = alloca i32, align 4
+ // CHECK: %[[LEN:.*]] = alloca i32, align 4
+ // CHECK: store i8* %[[BUF]], i8** %[[BUF_ADDR]], align 8
+ // CHECK: store i32 %[[DATA]], i32* %[[DATA_ADDR]], align 4
- // CHECK: store volatile i32 8,
+ // CHECK: store volatile i32 8, i32* %[[LEN]], align 4
len = __builtin_os_log_format_buffer_size("invalid specifier %: %d even a trailing one%", data);
- // CHECK: [[BUF2:%.*]] = load i8*, i8** [[BUF_ADDR]]
- // CHECK: [[SUMMARY:%.*]] = getelementptr i8, i8* [[BUF2]], i64 0
- // CHECK: store i8 0, i8* [[SUMMARY]]
- // CHECK: [[NUM_ARGS:%.*]] = getelementptr i8, i8* [[BUF2]], i64 1
- // CHECK: store i8 1, i8* [[NUM_ARGS]]
-
- // CHECK: [[ARG1_DESC:%.*]] = getelementptr i8, i8* [[BUF2]], i64 2
- // CHECK: store i8 0, i8* [[ARG1_DESC]]
- // CHECK: [[ARG1_SIZE:%.*]] = getelementptr i8, i8* [[BUF2]], i64 3
- // CHECK: store i8 4, i8* [[ARG1_SIZE]]
- // CHECK: [[ARG1:%.*]] = getelementptr i8, i8* [[BUF2]], i64 4
- // CHECK: [[ARG1_INT:%.*]] = bitcast i8* [[ARG1]] to i32*
- // CHECK: [[ARG1_VAL:%.*]] = load i32, i32* [[DATA_ADDR]]
- // CHECK: store i32 [[ARG1_VAL]], i32* [[ARG1_INT]]
+ // CHECK: %[[V1:.*]] = load i8*, i8** %[[BUF_ADDR]], align 8
+ // CHECK: %[[V2:.*]] = load i32, i32* %[[DATA_ADDR]], align 4
+ // CHECK: call void @__os_log_helper_1_0_1_4_0(i8* %[[V1]], i32 %[[V2]])
__builtin_os_log_format(buf, "invalid specifier %: %d even a trailing one%", data);
}
+// CHECK-LABEL: define linkonce_odr hidden void @__os_log_helper_1_0_1_4_0
+// CHECK: (i8* %[[BUFFER:.*]], i32 %[[ARG0:.*]])
+
+// CHECK: %[[BUFFER_ADDR:.*]] = alloca i8*, align 8
+// CHECK: %[[ARG0_ADDR:.*]] = alloca i32, align 4
+// CHECK: store i8* %[[BUFFER]], i8** %[[BUFFER_ADDR]], align 8
+// CHECK: store i32 %[[ARG0]], i32* %[[ARG0_ADDR]], align 4
+// CHECK: %[[BUF:.*]] = load i8*, i8** %[[BUFFER_ADDR]], align 8
+// CHECK: %[[SUMMARY:.*]] = getelementptr i8, i8* %[[BUF]], i64 0
+// CHECK: store i8 0, i8* %[[SUMMARY]], align 1
+// CHECK: %[[NUMARGS:.*]] = getelementptr i8, i8* %[[BUF]], i64 1
+// CHECK: store i8 1, i8* %[[NUMARGS]], align 1
+// CHECK: %[[ARGDESCRIPTOR:.*]] = getelementptr i8, i8* %[[BUF]], i64 2
+// CHECK: store i8 0, i8* %[[ARGDESCRIPTOR]], align 1
+// CHECK: %[[ARGSIZE:.*]] = getelementptr i8, i8* %[[BUF]], i64 3
+// CHECK: store i8 4, i8* %[[ARGSIZE]], align 1
+// CHECK: %[[ARGDATA:.*]] = getelementptr i8, i8* %[[BUF]], i64 4
+// CHECK: %[[ARGDATACAST:.*]] = bitcast i8* %[[ARGDATA]] to i32*
+// CHECK: %[[V0:.*]] = load i32, i32* %[[ARG0_ADDR]], align 4
+// CHECK: store i32 %[[V0]], i32* %[[ARGDATACAST]], align 1
+
// CHECK-LABEL: define void @test_builtin_os_log_percent
-// CHECK: (i8* [[BUF:%.*]], i8* [[DATA1:%.*]], i8* [[DATA2:%.*]])
+// CHECK: (i8* %[[BUF:.*]], i8* %[[DATA1:.*]], i8* %[[DATA2:.*]])
// Check that the %% which does not consume any argument is correctly handled
void test_builtin_os_log_percent(void *buf, const char *data1, const char *data2) {
volatile int len;
- // CHECK: store i8* [[BUF]], i8** [[BUF_ADDR:%.*]], align 8
- // CHECK: store i8* [[DATA1]], i8** [[DATA1_ADDR:%.*]], align 8
- // CHECK: store i8* [[DATA2]], i8** [[DATA2_ADDR:%.*]], align 8
- // CHECK: store volatile i32 22
+ // CHECK: %[[BUF_ADDR:.*]] = alloca i8*, align 8
+ // CHECK: %[[DATA1_ADDR:.*]] = alloca i8*, align 8
+ // CHECK: %[[DATA2_ADDR:.*]] = alloca i8*, align 8
+ // CHECK: %[[LEN:.*]] = alloca i32, align 4
+ // CHECK: store i8* %[[BUF]], i8** %[[BUF_ADDR]], align 8
+ // CHECK: store i8* %[[DATA1]], i8** %[[DATA1_ADDR]], align 8
+ // CHECK: store i8* %[[DATA2]], i8** %[[DATA2_ADDR]], align 8
+ // CHECK: store volatile i32 22, i32* %[[LEN]], align 4
+
len = __builtin_os_log_format_buffer_size("%s %% %s", data1, data2);
- // CHECK: [[BUF2:%.*]] = load i8*, i8** [[BUF_ADDR]]
- // CHECK: [[SUMMARY:%.*]] = getelementptr i8, i8* [[BUF2]], i64 0
- // CHECK: store i8 2, i8* [[SUMMARY]]
- // CHECK: [[NUM_ARGS:%.*]] = getelementptr i8, i8* [[BUF2]], i64 1
- // CHECK: store i8 2, i8* [[NUM_ARGS]]
- //
- // CHECK: [[ARG1_DESC:%.*]] = getelementptr i8, i8* [[BUF2]], i64 2
- // CHECK: store i8 32, i8* [[ARG1_DESC]]
- // CHECK: [[ARG1_SIZE:%.*]] = getelementptr i8, i8* [[BUF2]], i64 3
- // CHECK: store i8 8, i8* [[ARG1_SIZE]]
- // CHECK: [[ARG1:%.*]] = getelementptr i8, i8* [[BUF2]], i64 4
- // CHECK: [[ARG1_PTR:%.*]] = bitcast i8* [[ARG1]] to i8**
- // CHECK: [[DATA1:%.*]] = load i8*, i8** [[DATA1_ADDR]]
- // CHECK: store i8* [[DATA1]], i8** [[ARG1_PTR]]
- //
- // CHECK: [[ARG2_DESC:%.*]] = getelementptr i8, i8* [[BUF2]], i64 12
- // CHECK: store i8 32, i8* [[ARG2_DESC]]
- // CHECK: [[ARG2_SIZE:%.*]] = getelementptr i8, i8* [[BUF2]], i64 13
- // CHECK: store i8 8, i8* [[ARG2_SIZE]]
- // CHECK: [[ARG2:%.*]] = getelementptr i8, i8* [[BUF2]], i64 14
- // CHECK: [[ARG2_PTR:%.*]] = bitcast i8* [[ARG2]] to i8**
- // CHECK: [[DATA2:%.*]] = load i8*, i8** [[DATA2_ADDR]]
- // CHECK: store i8* [[DATA2]], i8** [[ARG2_PTR]]
+ // CHECK: %[[V1:.*]] = load i8*, i8** %[[BUF_ADDR]], align 8
+ // CHECK: %[[V2:.*]] = load i8*, i8** %[[DATA1_ADDR]], align 8
+ // CHECK: %[[V3:.*]] = ptrtoint i8* %[[V2]] to i64
+ // CHECK: %[[V4:.*]] = load i8*, i8** %[[DATA2_ADDR]], align 8
+ // CHECK: %[[V5:.*]] = ptrtoint i8* %[[V4]] to i64
+ // CHECK: call void @__os_log_helper_1_2_2_8_32_8_32(i8* %[[V1]], i64 %[[V3]], i64 %[[V5]])
+
__builtin_os_log_format(buf, "%s %% %s", data1, data2);
}
-#endif \ No newline at end of file
+// CHECK-LABEL: define linkonce_odr hidden void @__os_log_helper_1_2_2_8_32_8_32
+// CHECK: (i8* %[[BUFFER:.*]], i64 %[[ARG0:.*]], i64 %[[ARG1:.*]])
+
+// CHECK: %[[BUFFER_ADDR:.*]] = alloca i8*, align 8
+// CHECK: %[[ARG0_ADDR:.*]] = alloca i64, align 8
+// CHECK: %[[ARG1_ADDR:.*]] = alloca i64, align 8
+// CHECK: store i8* %[[BUFFER]], i8** %[[BUFFER_ADDR]], align 8
+// CHECK: store i64 %[[ARG0]], i64* %[[ARG0_ADDR]], align 8
+// CHECK: store i64 %[[ARG1]], i64* %[[ARG1_ADDR]], align 8
+// CHECK: %[[BUF:.*]] = load i8*, i8** %[[BUFFER_ADDR]], align 8
+// CHECK: %[[SUMMARY:.*]] = getelementptr i8, i8* %[[BUF]], i64 0
+// CHECK: store i8 2, i8* %[[SUMMARY]], align 1
+// CHECK: %[[NUMARGS:.*]] = getelementptr i8, i8* %[[BUF]], i64 1
+// CHECK: store i8 2, i8* %[[NUMARGS]], align 1
+// CHECK: %[[ARGDESCRIPTOR:.*]] = getelementptr i8, i8* %[[BUF]], i64 2
+// CHECK: store i8 32, i8* %[[ARGDESCRIPTOR]], align 1
+// CHECK: %[[ARGSIZE:.*]] = getelementptr i8, i8* %[[BUF]], i64 3
+// CHECK: store i8 8, i8* %[[ARGSIZE]], align 1
+// CHECK: %[[ARGDATA:.*]] = getelementptr i8, i8* %[[BUF]], i64 4
+// CHECK: %[[ARGDATACAST:.*]] = bitcast i8* %[[ARGDATA]] to i64*
+// CHECK: %[[V0:.*]] = load i64, i64* %[[ARG0_ADDR]], align 8
+// CHECK: store i64 %[[V0]], i64* %[[ARGDATACAST]], align 1
+// CHECK: %[[ARGDESCRIPTOR1:.*]] = getelementptr i8, i8* %[[BUF]], i64 12
+// CHECK: store i8 32, i8* %[[ARGDESCRIPTOR1]], align 1
+// CHECK: %[[ARGSIZE2:.*]] = getelementptr i8, i8* %[[BUF]], i64 13
+// CHECK: store i8 8, i8* %[[ARGSIZE2]], align 1
+// CHECK: %[[ARGDATA3:.*]] = getelementptr i8, i8* %[[BUF]], i64 14
+// CHECK: %[[ARGDATACAST4:.*]] = bitcast i8* %[[ARGDATA3]] to i64*
+// CHECK: %[[V1:.*]] = load i64, i64* %[[ARG1_ADDR]], align 8
+// CHECK: store i64 %[[V1]], i64* %[[ARGDATACAST4]], align 1
+
+// Check that the following two functions call the same helper function.
+
+// CHECK-LABEL: define void @test_builtin_os_log_merge_helper0
+// CHECK: call void @__os_log_helper_1_0_2_4_0_8_0(
+void test_builtin_os_log_merge_helper0(void *buf, int i, double d) {
+ __builtin_os_log_format(buf, "%d %f", i, d);
+}
+
+// CHECK-LABEL: define linkonce_odr hidden void @__os_log_helper_1_0_2_4_0_8_0(
+
+// CHECK-LABEL: define void @test_builtin_os_log_merge_helper1
+// CHECK: call void @__os_log_helper_1_0_2_4_0_8_0(
+void test_builtin_os_log_merge_helper1(void *buf, unsigned u, long long ll) {
+ __builtin_os_log_format(buf, "%u %lld", u, ll);
+}
+
+// Check that this function doesn't write past the end of array 'buf'.
+
+// CHECK-LABEL: define void @test_builtin_os_log_errno
+void test_builtin_os_log_errno() {
+ // CHECK: %[[VLA:.*]] = alloca i8, i64 4, align 16
+ // CHECK: call void @__os_log_helper_16_2_1_0_96(i8* %[[VLA]])
+
+ char buf[__builtin_os_log_format_buffer_size("%m")];
+ __builtin_os_log_format(buf, "%m");
+}
+
+// CHECK-LABEL: define linkonce_odr hidden void @__os_log_helper_16_2_1_0_96
+// CHECK: (i8* %[[BUFFER:.*]])
+
+// CHECK: %[[BUFFER_ADDR:.*]] = alloca i8*, align 8
+// CHECK: store i8* %[[BUFFER]], i8** %[[BUFFER_ADDR]], align 8
+// CHECK: %[[BUF:.*]] = load i8*, i8** %[[BUFFER_ADDR]], align 8
+// CHECK: %[[SUMMARY:.*]] = getelementptr i8, i8* %[[BUF]], i64 0
+// CHECK: store i8 2, i8* %[[SUMMARY]], align 16
+// CHECK: %[[NUMARGS:.*]] = getelementptr i8, i8* %[[BUF]], i64 1
+// CHECK: store i8 1, i8* %[[NUMARGS]], align 1
+// CHECK: %[[ARGDESCRIPTOR:.*]] = getelementptr i8, i8* %[[BUF]], i64 2
+// CHECK: store i8 96, i8* %[[ARGDESCRIPTOR]], align 2
+// CHECK: %[[ARGSIZE:.*]] = getelementptr i8, i8* %[[BUF]], i64 3
+// CHECK: store i8 0, i8* %[[ARGSIZE]], align 1
+// CHECK-NEXT: ret void
+
+// CHECK-LABEL: define void @test_builtin_os_log_long_double
+// CHECK: (i8* %[[BUF:.*]], x86_fp80 %[[LD:.*]])
+void test_builtin_os_log_long_double(void *buf, long double ld) {
+ // CHECK: %[[BUF_ADDR:.*]] = alloca i8*, align 8
+ // CHECK: %[[LD_ADDR:.*]] = alloca x86_fp80, align 16
+ // CHECK: %[[COERCE:.*]] = alloca i128, align 16
+ // CHECK: store i8* %[[BUF]], i8** %[[BUF_ADDR]], align 8
+ // CHECK: store x86_fp80 %[[LD]], x86_fp80* %[[LD_ADDR]], align 16
+ // CHECK: %[[V0:.*]] = load i8*, i8** %[[BUF_ADDR]], align 8
+ // CHECK: %[[V1:.*]] = load x86_fp80, x86_fp80* %[[LD_ADDR]], align 16
+ // CHECK: %[[V2:.*]] = bitcast x86_fp80 %[[V1]] to i80
+ // CHECK: %[[V3:.*]] = zext i80 %[[V2]] to i128
+ // CHECK: store i128 %[[V3]], i128* %[[COERCE]], align 16
+ // CHECK: %[[V4:.*]] = bitcast i128* %[[COERCE]] to { i64, i64 }*
+ // CHECK: %[[V5:.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* %[[V4]], i32 0, i32 0
+ // CHECK: %[[V6:.*]] = load i64, i64* %[[V5]], align 16
+ // CHECK: %[[V7:.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* %[[V4]], i32 0, i32 1
+ // CHECK: %[[V8:.*]] = load i64, i64* %[[V7]], align 8
+ // CHECK: call void @__os_log_helper_1_0_1_16_0(i8* %[[V0]], i64 %[[V6]], i64 %[[V8]])
+
+ __builtin_os_log_format(buf, "%Lf", ld);
+}
+
+// CHECK-LABEL: define linkonce_odr hidden void @__os_log_helper_1_0_1_16_0
+// CHECK: (i8* %[[BUFFER:.*]], i64 %[[ARG0_COERCE0:.*]], i64 %[[ARG0_COERCE1:.*]])
+
+// CHECK: %[[ARG0:.*]] = alloca i128, align 16
+// CHECK: %[[BUFFER_ADDR:.*]] = alloca i8*, align 8
+// CHECK: %[[ARG0_ADDR:.*]] = alloca i128, align 16
+// CHECK: %[[V0:.*]] = bitcast i128* %[[ARG0]] to { i64, i64 }*
+// CHECK: %[[V1:.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* %[[V0]], i32 0, i32 0
+// CHECK: store i64 %[[ARG0_COERCE0]], i64* %[[V1]], align 16
+// CHECK: %[[V2:.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* %[[V0]], i32 0, i32 1
+// CHECK: store i64 %[[ARG0_COERCE1]], i64* %[[V2]], align 8
+// CHECK: %[[ARG01:.*]] = load i128, i128* %[[ARG0]], align 16
+// CHECK: store i8* %[[BUFFER]], i8** %[[BUFFER_ADDR]], align 8
+// CHECK: store i128 %[[ARG01]], i128* %[[ARG0_ADDR]], align 16
+// CHECK: %[[BUF:.*]] = load i8*, i8** %[[BUFFER_ADDR]], align 8
+// CHECK: %[[SUMMARY:.*]] = getelementptr i8, i8* %[[BUF]], i64 0
+// CHECK: store i8 0, i8* %[[SUMMARY]], align 1
+// CHECK: %[[NUMARGS:.*]] = getelementptr i8, i8* %[[BUF]], i64 1
+// CHECK: store i8 1, i8* %[[NUMARGS]], align 1
+// CHECK: %[[ARGDESCRIPTOR:.*]] = getelementptr i8, i8* %[[BUF]], i64 2
+// CHECK: store i8 0, i8* %[[ARGDESCRIPTOR]], align 1
+// CHECK: %[[ARGSIZE:.*]] = getelementptr i8, i8* %[[BUF]], i64 3
+// CHECK: store i8 16, i8* %[[ARGSIZE]], align 1
+// CHECK: %[[ARGDATA:.*]] = getelementptr i8, i8* %[[BUF]], i64 4
+// CHECK: %[[ARGDATACAST:.*]] = bitcast i8* %[[ARGDATA]] to i128*
+// CHECK: %[[V3:.*]] = load i128, i128* %[[ARG0_ADDR]], align 16
+// CHECK: store i128 %[[V3]], i128* %[[ARGDATACAST]], align 1
+
+#endif
diff --git a/test/CodeGen/catch-undef-behavior.c b/test/CodeGen/catch-undef-behavior.c
index e67f0a1f8eec..7915ed9db1c1 100644
--- a/test/CodeGen/catch-undef-behavior.c
+++ b/test/CodeGen/catch-undef-behavior.c
@@ -59,8 +59,7 @@ int bar(int *a) {
// CHECK-COMMON-NEXT: %[[MISALIGN:.*]] = and i64 %[[PTRINT]], 3
// CHECK-COMMON-NEXT: icmp eq i64 %[[MISALIGN]], 0
- // CHECK-UBSAN: %[[ARG:.*]] = ptrtoint
- // CHECK-UBSAN-NEXT: call void @__ubsan_handle_type_mismatch_v1(i8* bitcast ({{.*}} @[[LINE_200]] to i8*), i64 %[[ARG]])
+ // CHECK-UBSAN: call void @__ubsan_handle_type_mismatch_v1(i8* bitcast ({{.*}} @[[LINE_200]] to i8*), i64 %[[PTRINT]])
// CHECK-TRAP: call void @llvm.trap() [[NR_NUW]]
// CHECK-TRAP-NEXT: unreachable
diff --git a/test/CodeGen/cetintrin.c b/test/CodeGen/cetintrin.c
new file mode 100644
index 000000000000..085462a6626d
--- /dev/null
+++ b/test/CodeGen/cetintrin.c
@@ -0,0 +1,84 @@
+// RUN: %clang_cc1 -ffreestanding %s -triple=i386-apple-darwin -target-feature +shstk -emit-llvm -o - -Wall -Werror | FileCheck %s
+// RUN: %clang_cc1 -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +shstk -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefix=X86_64
+
+#include <immintrin.h>
+
+void test_incsspd(int a) {
+ // CHECK-LABEL: @test_incsspd
+ // CHECK: call void @llvm.x86.incsspd(i32 %{{[0-9]+}})
+ _incsspd(a);
+}
+
+#ifdef __x86_64__
+void test_incsspq(int a) {
+ // X86_64-LABEL: @test_incsspq
+ // X86_64: call void @llvm.x86.incsspq(i64 %{{[a-z0-9.]+}})
+ _incsspq(a);
+}
+#endif
+
+unsigned int test_rdsspd(unsigned int a) {
+ // CHECK-LABEL: @test_rdsspd
+ // CHECK: call i32 @llvm.x86.rdsspd(i32 %{{[a-z0-9.]+}})
+ return _rdsspd(a);
+}
+
+#ifdef __x86_64__
+unsigned long long test_rdsspq(unsigned long long a) {
+ // X86_64-LABEL: @test_rdsspq
+ // X86_64: call i64 @llvm.x86.rdsspq(i64 %{{[a-z0-9.]+}})
+ return _rdsspq(a);
+}
+#endif
+
+void test_saveprevssp() {
+ // CHECK-LABEL: @test_saveprevssp
+ // CHECK: call void @llvm.x86.saveprevssp()
+ _saveprevssp();
+}
+
+void test_rstorssp(void * __p) {
+ // CHECK-LABEL: @test_rstorssp
+ // CHECK: call void @llvm.x86.rstorssp(i8* %{{[a-z0-9.]+}})
+ _rstorssp(__p);
+}
+
+void test_wrssd(unsigned int __a, void * __p) {
+ // CHECK-LABEL: @test_wrssd
+ // CHECK: call void @llvm.x86.wrssd(i32 %{{[a-z0-9.]+}}, i8* %{{[a-z0-9.]+}})
+ _wrssd(__a, __p);
+}
+
+#ifdef __x86_64__
+void test_wrssq(unsigned long long __a, void * __p) {
+ // X86_64-LABEL: @test_wrssq
+ // X86_64: call void @llvm.x86.wrssq(i64 %{{[a-z0-9.]+}}, i8* %{{[a-z0-9.]+}})
+ _wrssq(__a, __p);
+}
+#endif
+
+void test_wrussd(unsigned int __a, void * __p) {
+ // CHECK-LABEL: @test_wrussd
+ // CHECK: call void @llvm.x86.wrussd(i32 %{{[a-z0-9.]+}}, i8* %{{[a-z0-9.]+}})
+ _wrussd(__a, __p);
+}
+
+#ifdef __x86_64__
+void test_wrussq(unsigned long long __a, void * __p) {
+ // X86_64-LABEL: @test_wrussq
+ // X86_64: call void @llvm.x86.wrussq(i64 %{{[a-z0-9.]+}}, i8* %{{[a-z0-9.]+}})
+ _wrussq(__a, __p);
+}
+#endif
+
+void test_setssbsy() {
+ // CHECK-LABEL: @test_setssbsy
+ // CHECK: call void @llvm.x86.setssbsy()
+ _setssbsy();
+}
+
+void test_clrssbsy(void * __p) {
+ // CHECK-LABEL: @test_clrssbsy
+ // CHECK: call void @llvm.x86.clrssbsy(i8* %{{[a-z0-9.]+}})
+ _clrssbsy(__p);
+}
diff --git a/test/CodeGen/cfi-icall-cross-dso.c b/test/CodeGen/cfi-icall-cross-dso.c
index 636a9e4aedb4..43ab0e73b14a 100644
--- a/test/CodeGen/cfi-icall-cross-dso.c
+++ b/test/CodeGen/cfi-icall-cross-dso.c
@@ -46,7 +46,7 @@ void caller(void (*f)()) {
// Check that we emit both string and hash based type entries for static void g(),
// and don't emit them for the declaration of h().
-// CHECK: define internal void @g({{.*}} !type [[TVOID:![0-9]+]] !type [[TVOID_ID:![0-9]+]]
+// CHECK: define internal void @g({{.*}} !type [[TVOID:![0-9]+]] !type [[TVOID_GENERALIZED:![0-9]+]] !type [[TVOID_ID:![0-9]+]]
static void g(void) {}
// CHECK: declare void @h({{[^!]*$}}
@@ -60,9 +60,9 @@ Fn h1() {
return &h;
}
-// CHECK: define void @bar({{.*}} !type [[TNOPROTO:![0-9]+]] !type [[TNOPROTO_ID:![0-9]+]]
+// CHECK: define void @bar({{.*}} !type [[TNOPROTO:![0-9]+]] !type [[TNOPROTO_GENERALIZED:![0-9]+]] !type [[TNOPROTO_ID:![0-9]+]]
// ITANIUM: define available_externally void @foo({{[^!]*$}}
-// MS: define linkonce_odr void @foo({{.*}} !type [[TNOPROTO]] !type [[TNOPROTO_ID]]
+// MS: define linkonce_odr void @foo({{.*}} !type [[TNOPROTO]] !type [[TNOPROTO_GENERALIZED:![0-9]+]] !type [[TNOPROTO_ID]]
inline void foo() {}
void bar() { foo(); }
@@ -71,11 +71,15 @@ void bar() { foo(); }
// Check that the type entries are correct.
// ITANIUM: [[TVOID]] = !{i64 0, !"_ZTSFvvE"}
+// ITANIUM: [[TVOID_GENERALIZED]] = !{i64 0, !"_ZTSFvvE.generalized"}
// ITANIUM: [[TVOID_ID]] = !{i64 0, i64 9080559750644022485}
// ITANIUM: [[TNOPROTO]] = !{i64 0, !"_ZTSFvE"}
+// ITANIUM: [[TNOPROTO_GENERALIZED]] = !{i64 0, !"_ZTSFvE.generalized"}
// ITANIUM: [[TNOPROTO_ID]] = !{i64 0, i64 6588678392271548388}
// MS: [[TVOID]] = !{i64 0, !"?6AXXZ"}
+// MS: [[TVOID_GENERALIZED]] = !{i64 0, !"?6AXXZ.generalized"}
// MS: [[TVOID_ID]] = !{i64 0, i64 5113650790573562461}
// MS: [[TNOPROTO]] = !{i64 0, !"?6AX@Z"}
+// MS: [[TNOPROTO_GENERALIZED]] = !{i64 0, !"?6AX@Z.generalized"}
// MS: [[TNOPROTO_ID]] = !{i64 0, i64 4195979634929632483}
diff --git a/test/CodeGen/cfi-icall-generalize.c b/test/CodeGen/cfi-icall-generalize.c
new file mode 100644
index 000000000000..c7c7b30a7a21
--- /dev/null
+++ b/test/CodeGen/cfi-icall-generalize.c
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-icall -fsanitize-trap=cfi-icall -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=UNGENERALIZED %s
+// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-icall -fsanitize-trap=cfi-icall -fsanitize-cfi-icall-generalize-pointers -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=GENERALIZED %s
+
+// Test that const char* is generalized to const void* and that const char** is
+// generalized to void*
+
+// CHECK: define i32** @f({{.*}} !type [[TYPE:![0-9]+]] !type [[TYPE_GENERALIZED:![0-9]+]]
+int** f(const char *a, const char **b) {
+ return (int**)0;
+}
+
+void g(int** (*fp)(const char *, const char **)) {
+ // UNGENERALIZED: call i1 @llvm.type.test(i8* {{.*}}, metadata !"_ZTSFPPiPKcPS2_E")
+ // GENERALIZED: call i1 @llvm.type.test(i8* {{.*}}, metadata !"_ZTSFPvPKvS_E.generalized")
+ fp(0, 0);
+}
+
+// CHECK: [[TYPE]] = !{i64 0, !"_ZTSFPPiPKcPS2_E"}
+// CHECK: [[TYPE_GENERALIZED]] = !{i64 0, !"_ZTSFPvPKvS_E.generalized"}
diff --git a/test/CodeGen/cfi-icall.c b/test/CodeGen/cfi-icall.c
index ed34f4f44beb..5f346b66e81e 100644
--- a/test/CodeGen/cfi-icall.c
+++ b/test/CodeGen/cfi-icall.c
@@ -3,22 +3,26 @@
// Tests that we assign appropriate identifiers to unprototyped functions.
-// CHECK: define void @f({{.*}} !type [[TVOID:![0-9]+]]
+// CHECK: define void @f({{.*}} !type [[TVOID:![0-9]+]] !type [[TVOID_GENERALIZED:![0-9]+]]
void f() {
}
void xf();
-// CHECK: define void @g({{.*}} !type [[TINT:![0-9]+]]
+// CHECK: define void @g({{.*}} !type [[TINT:![0-9]+]] !type [[TINT_GENERALIZED:![0-9]+]]
void g(int b) {
void (*fp)() = b ? f : xf;
// ITANIUM: call i1 @llvm.type.test(i8* {{.*}}, metadata !"_ZTSFvE")
fp();
}
-// CHECK: declare !type [[TVOID:![0-9]+]] void @xf({{.*}}
+// CHECK: declare !type [[TVOID]] !type [[TVOID_GENERALIZED]] void @xf({{.*}}
// ITANIUM-DAG: [[TVOID]] = !{i64 0, !"_ZTSFvE"}
+// ITANIUM-DAG: [[TVOID_GENERALIZED]] = !{i64 0, !"_ZTSFvE.generalized"}
// ITANIUM-DAG: [[TINT]] = !{i64 0, !"_ZTSFviE"}
+// ITANIUM-DAG: [[TINT_GENERALIZED]] = !{i64 0, !"_ZTSFviE.generalized"}
// MS-DAG: [[TVOID]] = !{i64 0, !"?6AX@Z"}
+// MS-DAG: [[TVOID_GENERALIZED]] = !{i64 0, !"?6AX@Z.generalized"}
// MS-DAG: [[TINT]] = !{i64 0, !"?6AXH@Z"}
+// MS-DAG: [[TINT_GENERALIZED]] = !{i64 0, !"?6AXH@Z.generalized"}
diff --git a/test/CodeGen/cfi-unrelated-cast.cpp b/test/CodeGen/cfi-unrelated-cast.cpp
new file mode 100644
index 000000000000..d01cdf00b754
--- /dev/null
+++ b/test/CodeGen/cfi-unrelated-cast.cpp
@@ -0,0 +1,37 @@
+// STL allocators should not have unrelated-cast tests applied
+// RUN: %clang_cc1 -flto -triple x86_64-unknown-linux -fvisibility hidden -fsanitize=cfi-unrelated-cast -emit-llvm -o - %s | FileCheck %s
+
+#include <stddef.h>
+
+template<class T>
+class myalloc {
+ public:
+ // CHECK: define{{.*}}allocateE{{.}}
+ // CHECK-NOT: llvm.type.test
+ T *allocate(size_t sz) {
+ return (T*)::operator new(sz);
+ }
+
+ // CHECK: define{{.*}}allocateE{{.}}PKv
+ // CHECK-NOT: llvm.type.test
+ T *allocate(size_t sz, const void *ptr) {
+ return (T*)::operator new(sz);
+ }
+
+ // CHECK: define{{.*}}differentName
+ // CHECK: llvm.type.test
+ T *differentName(size_t sz, const void *ptr) {
+ return (T*)::operator new(sz);
+ }
+};
+
+class C1 {
+ virtual void f() {}
+};
+
+C1 *f1() {
+ myalloc<C1> allocator;
+ (void)allocator.allocate(16);
+ (void)allocator.allocate(16, 0);
+ (void)allocator.differentName(16, 0);
+}
diff --git a/test/CodeGen/complex-builtins.c b/test/CodeGen/complex-builtins.c
new file mode 100644
index 000000000000..dbf3b5901866
--- /dev/null
+++ b/test/CodeGen/complex-builtins.c
@@ -0,0 +1,206 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -w -S -o - -emit-llvm %s | FileCheck %s -check-prefix=NO__ERRNO
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -w -S -o - -emit-llvm -fmath-errno %s | FileCheck %s -check-prefix=HAS_ERRNO
+
+// Test attributes and codegen of complex builtins.
+
+void foo(float f) {
+ __builtin_cabs(f); __builtin_cabsf(f); __builtin_cabsl(f);
+
+// NO__ERRNO: declare double @cabs(double, double) [[READNONE:#[0-9]+]]
+// NO__ERRNO: declare float @cabsf(<2 x float>) [[READNONE]]
+// NO__ERRNO: declare x86_fp80 @cabsl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE:#[0-9]+]]
+// HAS_ERRNO: declare double @cabs(double, double) [[NOT_READNONE:#[0-9]+]]
+// HAS_ERRNO: declare float @cabsf(<2 x float>) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @cabsl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+
+ __builtin_cacos(f); __builtin_cacosf(f); __builtin_cacosl(f);
+
+// NO__ERRNO: declare { double, double } @cacos(double, double) [[READNONE]]
+// NO__ERRNO: declare <2 x float> @cacosf(<2 x float>) [[READNONE]]
+// NO__ERRNO: declare { x86_fp80, x86_fp80 } @cacosl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+// HAS_ERRNO: declare { double, double } @cacos(double, double) [[NOT_READNONE]]
+// HAS_ERRNO: declare <2 x float> @cacosf(<2 x float>) [[NOT_READNONE]]
+// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @cacosl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+
+ __builtin_cacosh(f); __builtin_cacoshf(f); __builtin_cacoshl(f);
+
+// NO__ERRNO: declare { double, double } @cacosh(double, double) [[READNONE]]
+// NO__ERRNO: declare <2 x float> @cacoshf(<2 x float>) [[READNONE]]
+// NO__ERRNO: declare { x86_fp80, x86_fp80 } @cacoshl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+// HAS_ERRNO: declare { double, double } @cacosh(double, double) [[NOT_READNONE]]
+// HAS_ERRNO: declare <2 x float> @cacoshf(<2 x float>) [[NOT_READNONE]]
+// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @cacoshl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+
+ __builtin_carg(f); __builtin_cargf(f); __builtin_cargl(f);
+
+// NO__ERRNO: declare double @carg(double, double) [[READNONE]]
+// NO__ERRNO: declare float @cargf(<2 x float>) [[READNONE]]
+// NO__ERRNO: declare x86_fp80 @cargl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+// HAS_ERRNO: declare double @carg(double, double) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @cargf(<2 x float>) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @cargl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+
+ __builtin_casin(f); __builtin_casinf(f); __builtin_casinl(f);
+
+// NO__ERRNO: declare { double, double } @casin(double, double) [[READNONE]]
+// NO__ERRNO: declare <2 x float> @casinf(<2 x float>) [[READNONE]]
+// NO__ERRNO: declare { x86_fp80, x86_fp80 } @casinl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+// HAS_ERRNO: declare { double, double } @casin(double, double) [[NOT_READNONE]]
+// HAS_ERRNO: declare <2 x float> @casinf(<2 x float>) [[NOT_READNONE]]
+// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @casinl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+
+ __builtin_casinh(f); __builtin_casinhf(f); __builtin_casinhl(f);
+
+// NO__ERRNO: declare { double, double } @casinh(double, double) [[READNONE]]
+// NO__ERRNO: declare <2 x float> @casinhf(<2 x float>) [[READNONE]]
+// NO__ERRNO: declare { x86_fp80, x86_fp80 } @casinhl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+// HAS_ERRNO: declare { double, double } @casinh(double, double) [[NOT_READNONE]]
+// HAS_ERRNO: declare <2 x float> @casinhf(<2 x float>) [[NOT_READNONE]]
+// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @casinhl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+
+ __builtin_catan(f); __builtin_catanf(f); __builtin_catanl(f);
+
+// NO__ERRNO: declare { double, double } @catan(double, double) [[READNONE]]
+// NO__ERRNO: declare <2 x float> @catanf(<2 x float>) [[READNONE]]
+// NO__ERRNO: declare { x86_fp80, x86_fp80 } @catanl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+// HAS_ERRNO: declare { double, double } @catan(double, double) [[NOT_READNONE]]
+// HAS_ERRNO: declare <2 x float> @catanf(<2 x float>) [[NOT_READNONE]]
+// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @catanl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+
+ __builtin_catanh(f); __builtin_catanhf(f); __builtin_catanhl(f);
+
+// NO__ERRNO: declare { double, double } @catanh(double, double) [[READNONE]]
+// NO__ERRNO: declare <2 x float> @catanhf(<2 x float>) [[READNONE]]
+// NO__ERRNO: declare { x86_fp80, x86_fp80 } @catanhl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+// HAS_ERRNO: declare { double, double } @catanh(double, double) [[NOT_READNONE]]
+// HAS_ERRNO: declare <2 x float> @catanhf(<2 x float>) [[NOT_READNONE]]
+// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @catanhl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+
+ __builtin_ccos(f); __builtin_ccosf(f); __builtin_ccosl(f);
+
+// NO__ERRNO: declare { double, double } @ccos(double, double) [[READNONE]]
+// NO__ERRNO: declare <2 x float> @ccosf(<2 x float>) [[READNONE]]
+// NO__ERRNO: declare { x86_fp80, x86_fp80 } @ccosl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+// HAS_ERRNO: declare { double, double } @ccos(double, double) [[NOT_READNONE]]
+// HAS_ERRNO: declare <2 x float> @ccosf(<2 x float>) [[NOT_READNONE]]
+// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @ccosl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+
+ __builtin_ccosh(f); __builtin_ccoshf(f); __builtin_ccoshl(f);
+
+// NO__ERRNO: declare { double, double } @ccosh(double, double) [[READNONE]]
+// NO__ERRNO: declare <2 x float> @ccoshf(<2 x float>) [[READNONE]]
+// NO__ERRNO: declare { x86_fp80, x86_fp80 } @ccoshl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+// HAS_ERRNO: declare { double, double } @ccosh(double, double) [[NOT_READNONE]]
+// HAS_ERRNO: declare <2 x float> @ccoshf(<2 x float>) [[NOT_READNONE]]
+// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @ccoshl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+
+ __builtin_cexp(f); __builtin_cexpf(f); __builtin_cexpl(f);
+
+// NO__ERRNO: declare { double, double } @cexp(double, double) [[READNONE]]
+// NO__ERRNO: declare <2 x float> @cexpf(<2 x float>) [[READNONE]]
+// NO__ERRNO: declare { x86_fp80, x86_fp80 } @cexpl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+// HAS_ERRNO: declare { double, double } @cexp(double, double) [[NOT_READNONE]]
+// HAS_ERRNO: declare <2 x float> @cexpf(<2 x float>) [[NOT_READNONE]]
+// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @cexpl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+
+ __builtin_cimag(f); __builtin_cimagf(f); __builtin_cimagl(f);
+
+// NO__ERRNO-NOT: .cimag
+// NO__ERRNO-NOT: @cimag
+// HAS_ERRNO-NOT: .cimag
+// HAS_ERRNO-NOT: @cimag
+
+ __builtin_conj(f); __builtin_conjf(f); __builtin_conjl(f);
+
+// NO__ERRNO-NOT: .conj
+// NO__ERRNO-NOT: @conj
+// HAS_ERRNO-NOT: .conj
+// HAS_ERRNO-NOT: @conj
+
+ __builtin_clog(f); __builtin_clogf(f); __builtin_clogl(f);
+
+// NO__ERRNO: declare { double, double } @clog(double, double) [[READNONE]]
+// NO__ERRNO: declare <2 x float> @clogf(<2 x float>) [[READNONE]]
+// NO__ERRNO: declare { x86_fp80, x86_fp80 } @clogl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+// HAS_ERRNO: declare { double, double } @clog(double, double) [[NOT_READNONE]]
+// HAS_ERRNO: declare <2 x float> @clogf(<2 x float>) [[NOT_READNONE]]
+// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @clogl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+
+ __builtin_cproj(f); __builtin_cprojf(f); __builtin_cprojl(f);
+
+// NO__ERRNO: declare { double, double } @cproj(double, double) [[READNONE]]
+// NO__ERRNO: declare <2 x float> @cprojf(<2 x float>) [[READNONE]]
+// NO__ERRNO: declare { x86_fp80, x86_fp80 } @cprojl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+// HAS_ERRNO: declare { double, double } @cproj(double, double) [[READNONE:#[0-9]+]]
+// HAS_ERRNO: declare <2 x float> @cprojf(<2 x float>) [[READNONE]]
+// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @cprojl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+
+ __builtin_cpow(f,f); __builtin_cpowf(f,f); __builtin_cpowl(f,f);
+
+// NO__ERRNO: declare { double, double } @cpow(double, double, double, double) [[READNONE]]
+// NO__ERRNO: declare <2 x float> @cpowf(<2 x float>, <2 x float>) [[READNONE]]
+// NO__ERRNO: declare { x86_fp80, x86_fp80 } @cpowl({ x86_fp80, x86_fp80 }* byval align 16, { x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+// HAS_ERRNO: declare { double, double } @cpow(double, double, double, double) [[NOT_READNONE]]
+// HAS_ERRNO: declare <2 x float> @cpowf(<2 x float>, <2 x float>) [[NOT_READNONE]]
+// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @cpowl({ x86_fp80, x86_fp80 }* byval align 16, { x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+
+ __builtin_creal(f); __builtin_crealf(f); __builtin_creall(f);
+
+// NO__ERRNO-NOT: .creal
+// NO__ERRNO-NOT: @creal
+// HAS_ERRNO-NOT: .creal
+// HAS_ERRNO-NOT: @creal
+
+ __builtin_csin(f); __builtin_csinf(f); __builtin_csinl(f);
+
+// NO__ERRNO: declare { double, double } @csin(double, double) [[READNONE]]
+// NO__ERRNO: declare <2 x float> @csinf(<2 x float>) [[READNONE]]
+// NO__ERRNO: declare { x86_fp80, x86_fp80 } @csinl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+// HAS_ERRNO: declare { double, double } @csin(double, double) [[NOT_READNONE]]
+// HAS_ERRNO: declare <2 x float> @csinf(<2 x float>) [[NOT_READNONE]]
+// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @csinl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+
+ __builtin_csinh(f); __builtin_csinhf(f); __builtin_csinhl(f);
+
+// NO__ERRNO: declare { double, double } @csinh(double, double) [[READNONE]]
+// NO__ERRNO: declare <2 x float> @csinhf(<2 x float>) [[READNONE]]
+// NO__ERRNO: declare { x86_fp80, x86_fp80 } @csinhl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+// HAS_ERRNO: declare { double, double } @csinh(double, double) [[NOT_READNONE]]
+// HAS_ERRNO: declare <2 x float> @csinhf(<2 x float>) [[NOT_READNONE]]
+// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @csinhl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+
+ __builtin_csqrt(f); __builtin_csqrtf(f); __builtin_csqrtl(f);
+
+// NO__ERRNO: declare { double, double } @csqrt(double, double) [[READNONE]]
+// NO__ERRNO: declare <2 x float> @csqrtf(<2 x float>) [[READNONE]]
+// NO__ERRNO: declare { x86_fp80, x86_fp80 } @csqrtl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+// HAS_ERRNO: declare { double, double } @csqrt(double, double) [[NOT_READNONE]]
+// HAS_ERRNO: declare <2 x float> @csqrtf(<2 x float>) [[NOT_READNONE]]
+// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @csqrtl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+
+ __builtin_ctan(f); __builtin_ctanf(f); __builtin_ctanl(f);
+
+// NO__ERRNO: declare { double, double } @ctan(double, double) [[READNONE]]
+// NO__ERRNO: declare <2 x float> @ctanf(<2 x float>) [[READNONE]]
+// NO__ERRNO: declare { x86_fp80, x86_fp80 } @ctanl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+// HAS_ERRNO: declare { double, double } @ctan(double, double) [[NOT_READNONE]]
+// HAS_ERRNO: declare <2 x float> @ctanf(<2 x float>) [[NOT_READNONE]]
+// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @ctanl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+
+ __builtin_ctanh(f); __builtin_ctanhf(f); __builtin_ctanhl(f);
+
+// NO__ERRNO: declare { double, double } @ctanh(double, double) [[READNONE]]
+// NO__ERRNO: declare <2 x float> @ctanhf(<2 x float>) [[READNONE]]
+// NO__ERRNO: declare { x86_fp80, x86_fp80 } @ctanhl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+// HAS_ERRNO: declare { double, double } @ctanh(double, double) [[NOT_READNONE]]
+// HAS_ERRNO: declare <2 x float> @ctanhf(<2 x float>) [[NOT_READNONE]]
+// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @ctanhl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+};
+
+
+// NO__ERRNO: attributes [[READNONE]] = { {{.*}}readnone{{.*}} }
+// NO__ERRNO: attributes [[NOT_READNONE]] = { nounwind "correctly{{.*}} }
+
+// HAS_ERRNO: attributes [[NOT_READNONE]] = { nounwind "correctly{{.*}} }
+// HAS_ERRNO: attributes [[READNONE]] = { {{.*}}readnone{{.*}} }
+
diff --git a/test/CodeGen/complex-libcalls.c b/test/CodeGen/complex-libcalls.c
new file mode 100644
index 000000000000..db56628835fd
--- /dev/null
+++ b/test/CodeGen/complex-libcalls.c
@@ -0,0 +1,208 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -w -S -o - -emit-llvm %s | FileCheck %s -check-prefix=NO__ERRNO
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -w -S -o - -emit-llvm -fmath-errno %s | FileCheck %s -check-prefix=HAS_ERRNO
+
+// Test attributes and builtin codegen of complex library calls.
+
+void foo(float f) {
+ cabs(f); cabsf(f); cabsl(f);
+
+// NO__ERRNO: declare double @cabs(double, double) [[READNONE:#[0-9]+]]
+// NO__ERRNO: declare float @cabsf(<2 x float>) [[READNONE]]
+// NO__ERRNO: declare x86_fp80 @cabsl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE:#[0-9]+]]
+// HAS_ERRNO: declare double @cabs(double, double) [[NOT_READNONE:#[0-9]+]]
+// HAS_ERRNO: declare float @cabsf(<2 x float>) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @cabsl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+
+ cacos(f); cacosf(f); cacosl(f);
+
+// NO__ERRNO: declare { double, double } @cacos(double, double) [[READNONE]]
+// NO__ERRNO: declare <2 x float> @cacosf(<2 x float>) [[READNONE]]
+// NO__ERRNO: declare { x86_fp80, x86_fp80 } @cacosl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+// HAS_ERRNO: declare { double, double } @cacos(double, double) [[NOT_READNONE]]
+// HAS_ERRNO: declare <2 x float> @cacosf(<2 x float>) [[NOT_READNONE]]
+// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @cacosl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+
+ cacosh(f); cacoshf(f); cacoshl(f);
+
+// NO__ERRNO: declare { double, double } @cacosh(double, double) [[READNONE]]
+// NO__ERRNO: declare <2 x float> @cacoshf(<2 x float>) [[READNONE]]
+// NO__ERRNO: declare { x86_fp80, x86_fp80 } @cacoshl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+// HAS_ERRNO: declare { double, double } @cacosh(double, double) [[NOT_READNONE]]
+// HAS_ERRNO: declare <2 x float> @cacoshf(<2 x float>) [[NOT_READNONE]]
+// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @cacoshl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+
+ carg(f); cargf(f); cargl(f);
+
+// NO__ERRNO: declare double @carg(double, double) [[READNONE]]
+// NO__ERRNO: declare float @cargf(<2 x float>) [[READNONE]]
+// NO__ERRNO: declare x86_fp80 @cargl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+// HAS_ERRNO: declare double @carg(double, double) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @cargf(<2 x float>) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @cargl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+
+ casin(f); casinf(f); casinl(f);
+
+// NO__ERRNO: declare { double, double } @casin(double, double) [[READNONE]]
+// NO__ERRNO: declare <2 x float> @casinf(<2 x float>) [[READNONE]]
+// NO__ERRNO: declare { x86_fp80, x86_fp80 } @casinl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+// HAS_ERRNO: declare { double, double } @casin(double, double) [[NOT_READNONE]]
+// HAS_ERRNO: declare <2 x float> @casinf(<2 x float>) [[NOT_READNONE]]
+// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @casinl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+
+ casinh(f); casinhf(f); casinhl(f);
+
+// NO__ERRNO: declare { double, double } @casinh(double, double) [[READNONE]]
+// NO__ERRNO: declare <2 x float> @casinhf(<2 x float>) [[READNONE]]
+// NO__ERRNO: declare { x86_fp80, x86_fp80 } @casinhl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+// HAS_ERRNO: declare { double, double } @casinh(double, double) [[NOT_READNONE]]
+// HAS_ERRNO: declare <2 x float> @casinhf(<2 x float>) [[NOT_READNONE]]
+// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @casinhl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+
+ catan(f); catanf(f); catanl(f);
+
+// NO__ERRNO: declare { double, double } @catan(double, double) [[READNONE]]
+// NO__ERRNO: declare <2 x float> @catanf(<2 x float>) [[READNONE]]
+// NO__ERRNO: declare { x86_fp80, x86_fp80 } @catanl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+// HAS_ERRNO: declare { double, double } @catan(double, double) [[NOT_READNONE]]
+// HAS_ERRNO: declare <2 x float> @catanf(<2 x float>) [[NOT_READNONE]]
+// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @catanl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+
+ catanh(f); catanhf(f); catanhl(f);
+
+// NO__ERRNO: declare { double, double } @catanh(double, double) [[READNONE]]
+// NO__ERRNO: declare <2 x float> @catanhf(<2 x float>) [[READNONE]]
+// NO__ERRNO: declare { x86_fp80, x86_fp80 } @catanhl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+// HAS_ERRNO: declare { double, double } @catanh(double, double) [[NOT_READNONE]]
+// HAS_ERRNO: declare <2 x float> @catanhf(<2 x float>) [[NOT_READNONE]]
+// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @catanhl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+
+ ccos(f); ccosf(f); ccosl(f);
+
+// NO__ERRNO: declare { double, double } @ccos(double, double) [[READNONE]]
+// NO__ERRNO: declare <2 x float> @ccosf(<2 x float>) [[READNONE]]
+// NO__ERRNO: declare { x86_fp80, x86_fp80 } @ccosl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+// HAS_ERRNO: declare { double, double } @ccos(double, double) [[NOT_READNONE]]
+// HAS_ERRNO: declare <2 x float> @ccosf(<2 x float>) [[NOT_READNONE]]
+// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @ccosl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+
+ ccosh(f); ccoshf(f); ccoshl(f);
+
+// NO__ERRNO: declare { double, double } @ccosh(double, double) [[READNONE]]
+// NO__ERRNO: declare <2 x float> @ccoshf(<2 x float>) [[READNONE]]
+// NO__ERRNO: declare { x86_fp80, x86_fp80 } @ccoshl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+// HAS_ERRNO: declare { double, double } @ccosh(double, double) [[NOT_READNONE]]
+// HAS_ERRNO: declare <2 x float> @ccoshf(<2 x float>) [[NOT_READNONE]]
+// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @ccoshl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+
+ cexp(f); cexpf(f); cexpl(f);
+
+// NO__ERRNO: declare { double, double } @cexp(double, double) [[READNONE]]
+// NO__ERRNO: declare <2 x float> @cexpf(<2 x float>) [[READNONE]]
+// NO__ERRNO: declare { x86_fp80, x86_fp80 } @cexpl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+// HAS_ERRNO: declare { double, double } @cexp(double, double) [[NOT_READNONE]]
+// HAS_ERRNO: declare <2 x float> @cexpf(<2 x float>) [[NOT_READNONE]]
+// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @cexpl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+
+ cimag(f); cimagf(f); cimagl(f);
+
+// NO__ERRNO-NOT: .cimag
+// NO__ERRNO-NOT: @cimag
+// HAS_ERRNO-NOT: .cimag
+// HAS_ERRNO-NOT: @cimag
+
+ conj(f); conjf(f); conjl(f);
+
+// NO__ERRNO: declare { double, double } @conj(double, double) [[READNONE:#[0-9]+]]
+// NO__ERRNO: declare <2 x float> @conjf(<2 x float>) [[READNONE]]
+// NO__ERRNO: declare { x86_fp80, x86_fp80 } @conjl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+// HAS_ERRNO: declare { double, double } @conj(double, double) [[READNONE:#[0-9]+]]
+// HAS_ERRNO: declare <2 x float> @conjf(<2 x float>) [[READNONE]]
+// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @conjl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+
+ clog(f); clogf(f); clogl(f);
+
+// NO__ERRNO: declare { double, double } @clog(double, double) [[READNONE]]
+// NO__ERRNO: declare <2 x float> @clogf(<2 x float>) [[READNONE]]
+// NO__ERRNO: declare { x86_fp80, x86_fp80 } @clogl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+// HAS_ERRNO: declare { double, double } @clog(double, double) [[NOT_READNONE]]
+// HAS_ERRNO: declare <2 x float> @clogf(<2 x float>) [[NOT_READNONE]]
+// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @clogl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+
+ cproj(f); cprojf(f); cprojl(f);
+
+// NO__ERRNO: declare { double, double } @cproj(double, double) [[READNONE]]
+// NO__ERRNO: declare <2 x float> @cprojf(<2 x float>) [[READNONE]]
+// NO__ERRNO: declare { x86_fp80, x86_fp80 } @cprojl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+// HAS_ERRNO: declare { double, double } @cproj(double, double) [[READNONE]]
+// HAS_ERRNO: declare <2 x float> @cprojf(<2 x float>) [[READNONE]]
+// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @cprojl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+
+ cpow(f,f); cpowf(f,f); cpowl(f,f);
+
+// NO__ERRNO: declare { double, double } @cpow(double, double, double, double) [[READNONE]]
+// NO__ERRNO: declare <2 x float> @cpowf(<2 x float>, <2 x float>) [[READNONE]]
+// NO__ERRNO: declare { x86_fp80, x86_fp80 } @cpowl({ x86_fp80, x86_fp80 }* byval align 16, { x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+// HAS_ERRNO: declare { double, double } @cpow(double, double, double, double) [[NOT_READNONE]]
+// HAS_ERRNO: declare <2 x float> @cpowf(<2 x float>, <2 x float>) [[NOT_READNONE]]
+// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @cpowl({ x86_fp80, x86_fp80 }* byval align 16, { x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+
+ creal(f); crealf(f); creall(f);
+
+// NO__ERRNO-NOT: .creal
+// NO__ERRNO-NOT: @creal
+// HAS_ERRNO-NOT: .creal
+// HAS_ERRNO-NOT: @creal
+
+ csin(f); csinf(f); csinl(f);
+
+// NO__ERRNO: declare { double, double } @csin(double, double) [[READNONE]]
+// NO__ERRNO: declare <2 x float> @csinf(<2 x float>) [[READNONE]]
+// NO__ERRNO: declare { x86_fp80, x86_fp80 } @csinl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+// HAS_ERRNO: declare { double, double } @csin(double, double) [[NOT_READNONE]]
+// HAS_ERRNO: declare <2 x float> @csinf(<2 x float>) [[NOT_READNONE]]
+// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @csinl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+
+ csinh(f); csinhf(f); csinhl(f);
+
+// NO__ERRNO: declare { double, double } @csinh(double, double) [[READNONE]]
+// NO__ERRNO: declare <2 x float> @csinhf(<2 x float>) [[READNONE]]
+// NO__ERRNO: declare { x86_fp80, x86_fp80 } @csinhl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+// HAS_ERRNO: declare { double, double } @csinh(double, double) [[NOT_READNONE]]
+// HAS_ERRNO: declare <2 x float> @csinhf(<2 x float>) [[NOT_READNONE]]
+// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @csinhl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+
+ csqrt(f); csqrtf(f); csqrtl(f);
+
+// NO__ERRNO: declare { double, double } @csqrt(double, double) [[READNONE]]
+// NO__ERRNO: declare <2 x float> @csqrtf(<2 x float>) [[READNONE]]
+// NO__ERRNO: declare { x86_fp80, x86_fp80 } @csqrtl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+// HAS_ERRNO: declare { double, double } @csqrt(double, double) [[NOT_READNONE]]
+// HAS_ERRNO: declare <2 x float> @csqrtf(<2 x float>) [[NOT_READNONE]]
+// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @csqrtl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+
+ ctan(f); ctanf(f); ctanl(f);
+
+// NO__ERRNO: declare { double, double } @ctan(double, double) [[READNONE]]
+// NO__ERRNO: declare <2 x float> @ctanf(<2 x float>) [[READNONE]]
+// NO__ERRNO: declare { x86_fp80, x86_fp80 } @ctanl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+// HAS_ERRNO: declare { double, double } @ctan(double, double) [[NOT_READNONE]]
+// HAS_ERRNO: declare <2 x float> @ctanf(<2 x float>) [[NOT_READNONE]]
+// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @ctanl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+
+ ctanh(f); ctanhf(f); ctanhl(f);
+
+// NO__ERRNO: declare { double, double } @ctanh(double, double) [[READNONE]]
+// NO__ERRNO: declare <2 x float> @ctanhf(<2 x float>) [[READNONE]]
+// NO__ERRNO: declare { x86_fp80, x86_fp80 } @ctanhl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+// HAS_ERRNO: declare { double, double } @ctanh(double, double) [[NOT_READNONE]]
+// HAS_ERRNO: declare <2 x float> @ctanhf(<2 x float>) [[NOT_READNONE]]
+// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @ctanhl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]]
+};
+
+
+// NO__ERRNO: attributes [[READNONE]] = { {{.*}}readnone{{.*}} }
+// NO__ERRNO: attributes [[NOT_READNONE]] = { nounwind "correctly{{.*}} }
+
+// HAS_ERRNO: attributes [[NOT_READNONE]] = { nounwind "correctly{{.*}} }
+// HAS_ERRNO: attributes [[READNONE]] = { {{.*}}readnone{{.*}} }
+
diff --git a/test/CodeGen/darwin-ppc-varargs.c b/test/CodeGen/darwin-ppc-varargs.c
new file mode 100644
index 000000000000..c2a0d192233c
--- /dev/null
+++ b/test/CodeGen/darwin-ppc-varargs.c
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -triple powerpc-apple-macosx10.5.0 -target-feature +altivec -Os -emit-llvm -o - %s | FileCheck %s
+
+int f(__builtin_va_list args) { return __builtin_va_arg(args, int); }
+
+// CHECK: @f(i8* {{.*}}[[PARAM:%[a-zA-Z0-9]+]])
+// CHECK: [[BITCAST:%[0-9]+]] = bitcast i8* [[PARAM]] to i32*
+// CHECK: [[VALUE:%[0-9]+]] = load i32, i32* [[BITCAST]], align 4
+// CHECK: ret i32 [[VALUE]]
+
+void h(vector int);
+int g(__builtin_va_list args) {
+ int i = __builtin_va_arg(args, int);
+ h(__builtin_va_arg(args, vector int));
+ int j = __builtin_va_arg(args, int);
+ return i + j;
+}
+
+// CHECK: @g(i8* {{.*}}[[PARAM:%[a-zA-Z0-9]+]])
+// CHECK: [[NEXT:%[-_.a-zA-Z0-9]+]] = getelementptr inbounds i8, i8* [[PARAM]], i32 4
+// CHECK: [[BITCAST:%[0-9]+]] = bitcast i8* [[PARAM]] to i32*
+// CHECK: [[LOAD:%[0-9]+]] = load i32, i32* [[BITCAST]], align 4
+// CHECK: [[PTRTOINT:%[0-9]+]] = ptrtoint i8* [[NEXT]] to i32
+// CHECK: [[ADD:%[0-9]+]] = add i32 [[PTRTOINT]], 15
+// CHECK: [[AND:%[0-9]+]] = and i32 [[ADD]], -16
+// CHECK: [[INTTOPTR:%[0-9]+]] = inttoptr i32 [[AND]] to <4 x i32>*
+// CHECK: [[ARG:%[0-9]]] = load <4 x i32>, <4 x i32>* [[INTTOPTR]], align 16
+// CHECK: call void @h(<4 x i32> [[ARG]]
+
diff --git a/test/CodeGen/debug-info-attributed-stmt.c b/test/CodeGen/debug-info-attributed-stmt.c
new file mode 100644
index 000000000000..b60aaf66ff88
--- /dev/null
+++ b/test/CodeGen/debug-info-attributed-stmt.c
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -triple x86_64-unk-unk -debug-info-kind=limited -emit-llvm %s -o - | FileCheck %s
+
+void f(_Bool b)
+{
+#pragma nounroll
+ while (b);
+}
+
+// CHECK: br label {{.*}}, !dbg ![[NUM:[0-9]+]]
+// CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !dbg ![[NUM]]
+// CHECK: br label {{.*}}, !dbg ![[NUM]], !llvm.loop
+// CHECK: ![[NUM]] = !DILocation(line: 6,
diff --git a/test/CodeGen/debug-info-block-vars.c b/test/CodeGen/debug-info-block-vars.c
new file mode 100644
index 000000000000..e0bb61e5e85f
--- /dev/null
+++ b/test/CodeGen/debug-info-block-vars.c
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -x c -fblocks -debug-info-kind=standalone -emit-llvm -O0 \
+// RUN: -triple x86_64-apple-darwin -o - %s | FileCheck %s
+// RUN: %clang_cc1 -x c -fblocks -debug-info-kind=standalone -emit-llvm -O1 \
+// RUN: -triple x86_64-apple-darwin -o - %s \
+// RUN: | FileCheck --check-prefix=CHECK-OPT %s
+
+// CHECK: define internal void @__f_block_invoke(i8* %.block_descriptor)
+// CHECK: %.block_descriptor.addr = alloca i8*, align 8
+// CHECK: %block.addr = alloca <{ i8*, i32, i32, i8*, %struct.__block_descriptor* }>*, align 8
+// CHECK: store i8* %.block_descriptor, i8** %.block_descriptor.addr, align 8
+// CHECK: call void @llvm.dbg.declare(metadata i8** %.block_descriptor.addr,
+// CHECK-SAME: metadata !DIExpression())
+// CHECK-OPT-NOT: alloca
+// CHECK-OPT: call void @llvm.dbg.value(metadata i8* %.block_descriptor,
+// CHECK-OPT-SAME: metadata !DIExpression())
+void f() {
+ a(^{
+ b();
+ });
+}
diff --git a/test/CodeGen/debug-info-global-constant.c b/test/CodeGen/debug-info-global-constant.c
index 4175f24675e5..8cb7f44ff3f0 100644
--- a/test/CodeGen/debug-info-global-constant.c
+++ b/test/CodeGen/debug-info-global-constant.c
@@ -5,11 +5,10 @@
// exactly once.
// CHECK: @i = internal constant i32 1, align 4, !dbg ![[I:[0-9]+]]
-// CHECK: ![[I]] = !DIGlobalVariableExpression(var: ![[VAR:.*]], expr: ![[EXPR:[0-9]+]])
+// CHECK: ![[I]] = !DIGlobalVariableExpression(var: ![[VAR:.*]], expr: !DIExpression(DW_OP_constu, 1, DW_OP_stack_value))
// CHECK: ![[VAR]] = distinct !DIGlobalVariable(name: "i",
// CHECK: !DICompileUnit({{.*}}globals: ![[GLOBALS:[0-9]+]])
// CHECK: ![[GLOBALS]] = !{![[I]]}
-// CHECK: ![[EXPR]] = !DIExpression(DW_OP_constu, 1, DW_OP_stack_value)
static const int i = 1;
void g(const int *, int);
diff --git a/test/CodeGen/debug-info-lto.c b/test/CodeGen/debug-info-lto.c
new file mode 100644
index 000000000000..5dab0a12641f
--- /dev/null
+++ b/test/CodeGen/debug-info-lto.c
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -flto -emit-llvm -debug-info-kind=standalone %s -o - | FileCheck %s
+// RUN: %clang_cc1 -flto=thin -emit-llvm -debug-info-kind=standalone %s -o - | FileCheck %s
+// The "o" in LTO stands for optimization!
+// CHECK: !DICompileUnit({{.*}} isOptimized: true
diff --git a/test/CodeGen/debug-info-preprocessed-file.i b/test/CodeGen/debug-info-preprocessed-file.i
new file mode 100644
index 000000000000..d231b45d67c2
--- /dev/null
+++ b/test/CodeGen/debug-info-preprocessed-file.i
@@ -0,0 +1,11 @@
+# 1 "/foo/bar/preprocessed-input.c"
+# 1 "<built-in>" 1
+# 1 "<built-in>" 3
+# 318 "<built-in>" 3
+# 1 "<command line>" 1
+# 1 "<built-in>" 2
+# 1 "preprocessed-input.c" 2
+
+// RUN: %clang -g -c -S -emit-llvm -o - %s | FileCheck %s
+// CHECK: !DICompileUnit(language: DW_LANG_C99, file: ![[FILE:[0-9]+]]
+// CHECK: ![[FILE]] = !DIFile(filename: "/foo/bar/preprocessed-input.c"
diff --git a/test/CodeGen/debug-info-static-const-fp.c b/test/CodeGen/debug-info-static-const-fp.c
index 4dfe057f2b6e..1b1da09f9e59 100644
--- a/test/CodeGen/debug-info-static-const-fp.c
+++ b/test/CodeGen/debug-info-static-const-fp.c
@@ -33,22 +33,19 @@ int main() {
return hVal + fVal + dVal + ldVal;
}
-// CHECK: !DIGlobalVariableExpression(var: [[HVAL:.*]], expr: [[HEXPR:.*]])
+// CHECK: !DIGlobalVariableExpression(var: [[HVAL:.*]], expr: !DIExpression(DW_OP_constu, 16502, DW_OP_stack_value))
// CHECK: [[HVAL]] = distinct !DIGlobalVariable(name: "hVal",
// CHECK-SAME: isLocal: true, isDefinition: true
-// CHECK: [[HEXPR]] = !DIExpression(DW_OP_constu, 16502, DW_OP_stack_value)
-// CHECK: !DIGlobalVariableExpression(var: [[FVAL:.*]], expr: [[FEXPR:.*]])
+// CHECK: !DIGlobalVariableExpression(var: [[FVAL:.*]], expr: !DIExpression(DW_OP_constu, 3238681178, DW_OP_stack_value))
// CHECK: [[FVAL]] = distinct !DIGlobalVariable(name: "fVal",
// CHECK-SAME: isLocal: true, isDefinition: true
-// CHECK: [[FEXPR]] = !DIExpression(DW_OP_constu, 3238681178, DW_OP_stack_value)
-// CHECK: !DIGlobalVariableExpression(var: [[DVAL:.*]], expr: [[DEXPR:.*]])
+// CHECK: !DIGlobalVariableExpression(var: [[DVAL:.*]], expr: !DIExpression(DW_OP_constu, 4658387303597904457, DW_OP_stack_value))
// CHECK: [[DVAL]] = distinct !DIGlobalVariable(name: "dVal",
// CHECK-SAME: isLocal: true, isDefinition: true
-// CHECK: [[DEXPR]] = !DIExpression(DW_OP_constu, 4658387303597904457, DW_OP_stack_value)
// CHECK-LDlg-DAG: [[LDVAL:.*]] = distinct !DIGlobalVariable(name: "ldVal", {{.*}}, isLocal: true, isDefinition: true)
-// CHECK-LDlg-DAG: !DIGlobalVariableExpression(var: [[LDVAL]])
+// CHECK-LDlg-DAG: !DIGlobalVariableExpression(var: [[LDVAL]], expr: !DIExpression())
// CHECK-LDsm-DAG: [[LDVAL:.*]] = distinct !DIGlobalVariable(name: "ldVal", {{.*}}, isLocal: true, isDefinition: true)
// CHECK-LDsm-DAG: !DIGlobalVariableExpression(var: [[LDVAL]], expr:
diff --git a/test/CodeGen/debug-info-static.c b/test/CodeGen/debug-info-static.c
index 016f1e6e6cc5..d6ade2aee56c 100644
--- a/test/CodeGen/debug-info-static.c
+++ b/test/CodeGen/debug-info-static.c
@@ -2,7 +2,7 @@
// CHECK: @f.xyzzy = internal global i32 0, align 4, !dbg [[XYZZY:![0-9]+]]
-// CHECK: [[XYZZY]] = !DIGlobalVariableExpression(var: [[VAR:.*]])
+// CHECK: [[XYZZY]] = !DIGlobalVariableExpression(var: [[VAR:.*]], expr: !DIExpression())
// CHECK: [[VAR]] = distinct !DIGlobalVariable
void f(void)
{
diff --git a/test/CodeGen/debug-info-vla.c b/test/CodeGen/debug-info-vla.c
index 3b69773207b2..7928ca761397 100644
--- a/test/CodeGen/debug-info-vla.c
+++ b/test/CodeGen/debug-info-vla.c
@@ -3,8 +3,7 @@
void testVLAwithSize(int s)
{
// CHECK: dbg.declare
-// CHECK: dbg.declare({{.*}}, metadata ![[VAR:.*]], metadata ![[EXPR:.*]])
-// CHECK: ![[EXPR]] = !DIExpression()
+// CHECK: dbg.declare({{.*}}, metadata ![[VAR:.*]], metadata !DIExpression())
// CHECK: ![[VAR]] = !DILocalVariable(name: "vla",{{.*}} line: [[@LINE+1]]
int vla[s];
int i;
diff --git a/test/CodeGen/finite-math.c b/test/CodeGen/finite-math.c
index 90a83fa30958..d1a2956b69fe 100644
--- a/test/CodeGen/finite-math.c
+++ b/test/CodeGen/finite-math.c
@@ -1,6 +1,7 @@
// RUN: %clang_cc1 -ffinite-math-only -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=FINITE
// RUN: %clang_cc1 -fno-signed-zeros -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=NSZ
// RUN: %clang_cc1 -freciprocal-math -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=RECIP
+// RUN: %clang_cc1 -mreassociate -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=REASSOC
float f0, f1, f2;
@@ -10,6 +11,7 @@ void foo(void) {
// FINITE: fadd nnan ninf
// NSZ: fadd nsz
// RECIP: fadd arcp
+ // REASSOC: fadd reassoc
f0 = f1 + f2;
// CHECK: ret
diff --git a/test/CodeGen/fma-builtins.c b/test/CodeGen/fma-builtins.c
index 91a2efe7637e..6f792a78d84c 100644
--- a/test/CodeGen/fma-builtins.c
+++ b/test/CodeGen/fma-builtins.c
@@ -4,161 +4,221 @@
#include <immintrin.h>
__m128 test_mm_fmadd_ps(__m128 a, __m128 b, __m128 c) {
+ // CHECK-LABEL: test_mm_fmadd_ps
// CHECK: @llvm.x86.fma.vfmadd.ps
return _mm_fmadd_ps(a, b, c);
}
__m128d test_mm_fmadd_pd(__m128d a, __m128d b, __m128d c) {
+ // CHECK-LABEL: test_mm_fmadd_pd
// CHECK: @llvm.x86.fma.vfmadd.pd
return _mm_fmadd_pd(a, b, c);
}
__m128 test_mm_fmadd_ss(__m128 a, __m128 b, __m128 c) {
+ // CHECK-LABEL: test_mm_fmadd_ss
// CHECK: @llvm.x86.fma.vfmadd.ss
return _mm_fmadd_ss(a, b, c);
}
__m128d test_mm_fmadd_sd(__m128d a, __m128d b, __m128d c) {
+ // CHECK-LABEL: test_mm_fmadd_sd
// CHECK: @llvm.x86.fma.vfmadd.sd
return _mm_fmadd_sd(a, b, c);
}
__m128 test_mm_fmsub_ps(__m128 a, __m128 b, __m128 c) {
- // CHECK: @llvm.x86.fma.vfmsub.ps
+ // CHECK-LABEL: test_mm_fmsub_ps
+ // CHECK: [[NEG:%.+]] = fsub <4 x float> <float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00>, %{{.+}}
+ // CHECK: @llvm.x86.fma.vfmadd.ps(<4 x float> %{{.+}}, <4 x float> %{{.+}}, <4 x float> [[NEG]])
return _mm_fmsub_ps(a, b, c);
}
__m128d test_mm_fmsub_pd(__m128d a, __m128d b, __m128d c) {
- // CHECK: @llvm.x86.fma.vfmsub.pd
+ // CHECK-LABEL: test_mm_fmsub_pd
+ // CHECK: [[NEG:%.+]] = fsub <2 x double> <double -0.000000e+00, double -0.000000e+00>, %{{.+}}
+ // CHECK: @llvm.x86.fma.vfmadd.pd(<2 x double> %{{.+}}, <2 x double> %{{.+}}, <2 x double> [[NEG]])
return _mm_fmsub_pd(a, b, c);
}
__m128 test_mm_fmsub_ss(__m128 a, __m128 b, __m128 c) {
- // CHECK: @llvm.x86.fma.vfmsub.ss
+ // CHECK-LABEL: test_mm_fmsub_ss
+ // CHECK: [[NEG:%.+]] = fsub <4 x float> <float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00>, %{{.+}}
+ // CHECK: @llvm.x86.fma.vfmadd.ss(<4 x float> %{{.+}}, <4 x float> %{{.+}}, <4 x float> [[NEG]])
return _mm_fmsub_ss(a, b, c);
}
__m128d test_mm_fmsub_sd(__m128d a, __m128d b, __m128d c) {
- // CHECK: @llvm.x86.fma.vfmsub.sd
+ // CHECK-LABEL: test_mm_fmsub_sd
+ // CHECK: [[NEG:%.+]] = fsub <2 x double> <double -0.000000e+00, double -0.000000e+00>, %{{.+}}
+ // CHECK: @llvm.x86.fma.vfmadd.sd(<2 x double> %{{.+}}, <2 x double> %{{.+}}, <2 x double> [[NEG]])
return _mm_fmsub_sd(a, b, c);
}
__m128 test_mm_fnmadd_ps(__m128 a, __m128 b, __m128 c) {
- // CHECK: @llvm.x86.fma.vfnmadd.ps
+ // CHECK-LABEL: test_mm_fnmadd_ps
+ // CHECK: [[NEG:%.+]] = fsub <4 x float> <float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00>, %{{.+}}
+ // CHECK: @llvm.x86.fma.vfmadd.ps(<4 x float> [[NEG]], <4 x float> %{{.+}}, <4 x float> %{{.+}})
return _mm_fnmadd_ps(a, b, c);
}
__m128d test_mm_fnmadd_pd(__m128d a, __m128d b, __m128d c) {
- // CHECK: @llvm.x86.fma.vfnmadd.pd
+ // CHECK-LABEL: test_mm_fnmadd_pd
+ // CHECK: [[NEG:%.+]] = fsub <2 x double> <double -0.000000e+00, double -0.000000e+00>, %{{.+}}
+ // CHECK: @llvm.x86.fma.vfmadd.pd(<2 x double> [[NEG]], <2 x double> %{{.+}}, <2 x double> %{{.+}})
return _mm_fnmadd_pd(a, b, c);
}
__m128 test_mm_fnmadd_ss(__m128 a, __m128 b, __m128 c) {
- // CHECK: @llvm.x86.fma.vfnmadd.ss
+ // CHECK-LABEL: test_mm_fnmadd_ss
+ // CHECK: [[NEG:%.+]] = fsub <4 x float> <float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00>, %{{.+}}
+ // CHECK: @llvm.x86.fma.vfmadd.ss(<4 x float> %{{.+}}, <4 x float> [[NEG]], <4 x float> %{{.+}})
return _mm_fnmadd_ss(a, b, c);
}
__m128d test_mm_fnmadd_sd(__m128d a, __m128d b, __m128d c) {
- // CHECK: @llvm.x86.fma.vfnmadd.sd
+ // CHECK-LABEL: test_mm_fnmadd_sd
+ // CHECK: [[NEG:%.+]] = fsub <2 x double> <double -0.000000e+00, double -0.000000e+00>, %{{.+}}
+ // CHECK: @llvm.x86.fma.vfmadd.sd(<2 x double> %{{.+}}, <2 x double> [[NEG]], <2 x double> %{{.+}})
return _mm_fnmadd_sd(a, b, c);
}
__m128 test_mm_fnmsub_ps(__m128 a, __m128 b, __m128 c) {
- // CHECK: @llvm.x86.fma.vfnmsub.ps
+ // CHECK-LABEL: test_mm_fnmsub_ps
+ // CHECK: [[NEG:%.+]] = fsub <4 x float> <float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00>, %{{.+}}
+ // CHECK: [[NEG2:%.+]] = fsub <4 x float> <float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00>, %{{.+}}
+ // CHECK: @llvm.x86.fma.vfmadd.ps(<4 x float> [[NEG]], <4 x float> %{{.+}}, <4 x float> [[NEG2]])
return _mm_fnmsub_ps(a, b, c);
}
__m128d test_mm_fnmsub_pd(__m128d a, __m128d b, __m128d c) {
- // CHECK: @llvm.x86.fma.vfnmsub.pd
+ // CHECK-LABEL: test_mm_fnmsub_pd
+ // CHECK: [[NEG:%.+]] = fsub <2 x double> <double -0.000000e+00, double -0.000000e+00>, %{{.+}}
+ // CHECK: [[NEG2:%.+]] = fsub <2 x double> <double -0.000000e+00, double -0.000000e+00>, %{{.+}}
+ // CHECK: @llvm.x86.fma.vfmadd.pd(<2 x double> [[NEG]], <2 x double> %{{.+}}, <2 x double> [[NEG2]])
return _mm_fnmsub_pd(a, b, c);
}
__m128 test_mm_fnmsub_ss(__m128 a, __m128 b, __m128 c) {
- // CHECK: @llvm.x86.fma.vfnmsub.ss
+ // CHECK-LABEL: test_mm_fnmsub_ss
+ // CHECK: [[NEG:%.+]] = fsub <4 x float> <float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00>, %{{.+}}
+ // CHECK: [[NEG2:%.+]] = fsub <4 x float> <float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00>, %{{.+}}
+ // CHECK: @llvm.x86.fma.vfmadd.ss(<4 x float> %{{.+}}, <4 x float> [[NEG]], <4 x float> [[NEG2]])
return _mm_fnmsub_ss(a, b, c);
}
__m128d test_mm_fnmsub_sd(__m128d a, __m128d b, __m128d c) {
- // CHECK: @llvm.x86.fma.vfnmsub.sd
+ // CHECK-LABEL: test_mm_fnmsub_sd
+ // CHECK: [[NEG:%.+]] = fsub <2 x double> <double -0.000000e+00, double -0.000000e+00>, %{{.+}}
+ // CHECK: [[NEG2:%.+]] = fsub <2 x double> <double -0.000000e+00, double -0.000000e+00>, %{{.+}}
+ // CHECK: @llvm.x86.fma.vfmadd.sd(<2 x double> %{{.+}}, <2 x double> [[NEG]], <2 x double> [[NEG2]])
return _mm_fnmsub_sd(a, b, c);
}
__m128 test_mm_fmaddsub_ps(__m128 a, __m128 b, __m128 c) {
+ // CHECK-LABEL: test_mm_fmaddsub_ps
// CHECK: @llvm.x86.fma.vfmaddsub.ps
return _mm_fmaddsub_ps(a, b, c);
}
__m128d test_mm_fmaddsub_pd(__m128d a, __m128d b, __m128d c) {
+ // CHECK-LABEL: test_mm_fmaddsub_pd
// CHECK: @llvm.x86.fma.vfmaddsub.pd
return _mm_fmaddsub_pd(a, b, c);
}
__m128 test_mm_fmsubadd_ps(__m128 a, __m128 b, __m128 c) {
- // CHECK: @llvm.x86.fma.vfmsubadd.ps
+ // CHECK-LABEL: test_mm_fmsubadd_ps
+ // CHECK: [[NEG:%.+]] = fsub <4 x float> <float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00>, %{{.+}}
+ // CHECK: @llvm.x86.fma.vfmaddsub.ps(<4 x float> %{{.+}}, <4 x float> %{{.+}}, <4 x float> [[NEG]])
return _mm_fmsubadd_ps(a, b, c);
}
__m128d test_mm_fmsubadd_pd(__m128d a, __m128d b, __m128d c) {
- // CHECK: @llvm.x86.fma.vfmsubadd.pd
+ // CHECK-LABEL: test_mm_fmsubadd_pd
+ // CHECK: [[NEG:%.+]] = fsub <2 x double> <double -0.000000e+00, double -0.000000e+00>, %{{.+}}
+ // CHECK: @llvm.x86.fma.vfmaddsub.pd(<2 x double> %{{.+}}, <2 x double> %{{.+}}, <2 x double> [[NEG]])
return _mm_fmsubadd_pd(a, b, c);
}
__m256 test_mm256_fmadd_ps(__m256 a, __m256 b, __m256 c) {
+ // CHECK-LABEL: test_mm256_fmadd_ps
// CHECK: @llvm.x86.fma.vfmadd.ps.256
return _mm256_fmadd_ps(a, b, c);
}
__m256d test_mm256_fmadd_pd(__m256d a, __m256d b, __m256d c) {
+ // CHECK-LABEL: test_mm256_fmadd_pd
// CHECK: @llvm.x86.fma.vfmadd.pd.256
return _mm256_fmadd_pd(a, b, c);
}
__m256 test_mm256_fmsub_ps(__m256 a, __m256 b, __m256 c) {
- // CHECK: @llvm.x86.fma.vfmsub.ps.256
+ // CHECK-LABEL: test_mm256_fmsub_ps
+ // CHECK: [[NEG:%.+]] = fsub <8 x float> <float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00>, %{{.*}}
+ // CHECK: @llvm.x86.fma.vfmadd.ps.256(<8 x float> %{{.+}}, <8 x float> %{{.+}}, <8 x float> [[NEG]])
return _mm256_fmsub_ps(a, b, c);
}
__m256d test_mm256_fmsub_pd(__m256d a, __m256d b, __m256d c) {
- // CHECK: @llvm.x86.fma.vfmsub.pd.256
+ // CHECK-LABEL: test_mm256_fmsub_pd
+ // CHECK: [[NEG:%.+]] = fsub <4 x double> <double -0.000000e+00, double -0.000000e+00, double -0.000000e+00, double -0.000000e+00>, %{{.+}}
+ // CHECK: @llvm.x86.fma.vfmadd.pd.256(<4 x double> %{{.+}}, <4 x double> %{{.+}}, <4 x double> [[NEG]])
return _mm256_fmsub_pd(a, b, c);
}
__m256 test_mm256_fnmadd_ps(__m256 a, __m256 b, __m256 c) {
- // CHECK: @llvm.x86.fma.vfnmadd.ps.256
+ // CHECK-LABEL: test_mm256_fnmadd_ps
+ // CHECK: [[NEG:%.+]] = fsub <8 x float> <float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00>, %{{.*}}
+ // CHECK: @llvm.x86.fma.vfmadd.ps.256(<8 x float> [[NEG]], <8 x float> %{{.+}}, <8 x float> %{{.+}})
return _mm256_fnmadd_ps(a, b, c);
}
__m256d test_mm256_fnmadd_pd(__m256d a, __m256d b, __m256d c) {
- // CHECK: @llvm.x86.fma.vfnmadd.pd.256
+ // CHECK-LABEL: test_mm256_fnmadd_pd
+ // CHECK: [[NEG:%.+]] = fsub <4 x double> <double -0.000000e+00, double -0.000000e+00, double -0.000000e+00, double -0.000000e+00>, %{{.+}}
+ // CHECK: @llvm.x86.fma.vfmadd.pd.256(<4 x double> [[NEG]], <4 x double> %{{.+}}, <4 x double> %{{.+}})
return _mm256_fnmadd_pd(a, b, c);
}
__m256 test_mm256_fnmsub_ps(__m256 a, __m256 b, __m256 c) {
- // CHECK: @llvm.x86.fma.vfnmsub.ps.256
+ // CHECK-LABEL: test_mm256_fnmsub_ps
+ // CHECK: [[NEG:%.+]] = fsub <8 x float> <float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00>, %{{.*}}
+ // CHECK: [[NEG2:%.+]] = fsub <8 x float> <float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00>, %{{.*}}
+ // CHECK: @llvm.x86.fma.vfmadd.ps.256(<8 x float> [[NEG]], <8 x float> %{{.+}}, <8 x float> [[NEG2]])
return _mm256_fnmsub_ps(a, b, c);
}
__m256d test_mm256_fnmsub_pd(__m256d a, __m256d b, __m256d c) {
- // CHECK: @llvm.x86.fma.vfnmsub.pd.256
+ // CHECK-LABEL: test_mm256_fnmsub_pd
+ // CHECK: [[NEG:%.+]] = fsub <4 x double> <double -0.000000e+00, double -0.000000e+00, double -0.000000e+00, double -0.000000e+00>, %{{.+}}
+ // CHECK: [[NEG2:%.+]] = fsub <4 x double> <double -0.000000e+00, double -0.000000e+00, double -0.000000e+00, double -0.000000e+00>, %{{.+}}
+ // CHECK: @llvm.x86.fma.vfmadd.pd.256(<4 x double> [[NEG]], <4 x double> %{{.+}}, <4 x double> [[NEG2]])
return _mm256_fnmsub_pd(a, b, c);
}
__m256 test_mm256_fmaddsub_ps(__m256 a, __m256 b, __m256 c) {
+ // CHECK-LABEL: test_mm256_fmaddsub_ps
// CHECK: @llvm.x86.fma.vfmaddsub.ps.256
return _mm256_fmaddsub_ps(a, b, c);
}
__m256d test_mm256_fmaddsub_pd(__m256d a, __m256d b, __m256d c) {
+ // CHECK-LABEL: test_mm256_fmaddsub_pd
// CHECK: @llvm.x86.fma.vfmaddsub.pd.256
return _mm256_fmaddsub_pd(a, b, c);
}
__m256 test_mm256_fmsubadd_ps(__m256 a, __m256 b, __m256 c) {
- // CHECK: @llvm.x86.fma.vfmsubadd.ps.256
+ // CHECK-LABEL: test_mm256_fmsubadd_ps
+ // CHECK: [[NEG:%.+]] = fsub <8 x float> <float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00>, %{{.*}}
+ // CHECK: @llvm.x86.fma.vfmaddsub.ps.256(<8 x float> %{{.*}}, <8 x float> %{{.+}}, <8 x float> [[NEG]])
return _mm256_fmsubadd_ps(a, b, c);
}
__m256d test_mm256_fmsubadd_pd(__m256d a, __m256d b, __m256d c) {
- // CHECK: @llvm.x86.fma.vfmsubadd.pd.256
+ // CHECK-LABEL: test_mm256_fmsubadd_pd
+ // CHECK: [[NEG:%.+]] = fsub <4 x double> <double -0.000000e+00, double -0.000000e+00, double -0.000000e+00, double -0.000000e+00>, %{{.+}}
+ // CHECK: @llvm.x86.fma.vfmaddsub.pd.256(<4 x double> %{{.+}}, <4 x double> %{{.+}}, <4 x double> [[NEG]])
return _mm256_fmsubadd_pd(a, b, c);
}
diff --git a/test/CodeGen/fma4-builtins.c b/test/CodeGen/fma4-builtins.c
index 3ca5fac68892..c848d4a751da 100644
--- a/test/CodeGen/fma4-builtins.c
+++ b/test/CodeGen/fma4-builtins.c
@@ -17,85 +17,101 @@ __m128d test_mm_macc_pd(__m128d a, __m128d b, __m128d c) {
__m128 test_mm_macc_ss(__m128 a, __m128 b, __m128 c) {
// CHECK-LABEL: test_mm_macc_ss
- // CHECK: @llvm.x86.fma.vfmadd.ss
+ // CHECK: @llvm.x86.fma4.vfmadd.ss
return _mm_macc_ss(a, b, c);
}
__m128d test_mm_macc_sd(__m128d a, __m128d b, __m128d c) {
// CHECK-LABEL: test_mm_macc_sd
- // CHECK: @llvm.x86.fma.vfmadd.sd
+ // CHECK: @llvm.x86.fma4.vfmadd.sd
return _mm_macc_sd(a, b, c);
}
__m128 test_mm_msub_ps(__m128 a, __m128 b, __m128 c) {
// CHECK-LABEL: test_mm_msub_ps
- // CHECK: @llvm.x86.fma.vfmsub.ps
+ // CHECK: [[NEG:%.+]] = fsub <4 x float> <float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00>, %{{.+}}
+ // CHECK: @llvm.x86.fma.vfmadd.ps(<4 x float> %{{.+}}, <4 x float> %{{.+}}, <4 x float> [[NEG]])
return _mm_msub_ps(a, b, c);
}
__m128d test_mm_msub_pd(__m128d a, __m128d b, __m128d c) {
// CHECK-LABEL: test_mm_msub_pd
- // CHECK: @llvm.x86.fma.vfmsub.pd
+ // CHECK: [[NEG:%.+]] = fsub <2 x double> <double -0.000000e+00, double -0.000000e+00>, %{{.+}}
+ // CHECK: @llvm.x86.fma.vfmadd.pd(<2 x double> %{{.+}}, <2 x double> %{{.+}}, <2 x double> [[NEG]])
return _mm_msub_pd(a, b, c);
}
__m128 test_mm_msub_ss(__m128 a, __m128 b, __m128 c) {
// CHECK-LABEL: test_mm_msub_ss
- // CHECK: @llvm.x86.fma.vfmsub.ss
+ // CHECK: [[NEG:%.+]] = fsub <4 x float> <float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00>, %{{.+}}
+ // CHECK: @llvm.x86.fma4.vfmadd.ss(<4 x float> %{{.+}}, <4 x float> %{{.+}}, <4 x float> [[NEG]])
return _mm_msub_ss(a, b, c);
}
__m128d test_mm_msub_sd(__m128d a, __m128d b, __m128d c) {
// CHECK-LABEL: test_mm_msub_sd
- // CHECK: @llvm.x86.fma.vfmsub.sd
+ // CHECK: [[NEG:%.+]] = fsub <2 x double> <double -0.000000e+00, double -0.000000e+00>, %{{.+}}
+ // CHECK: @llvm.x86.fma4.vfmadd.sd(<2 x double> %{{.+}}, <2 x double> %{{.+}}, <2 x double> [[NEG]])
return _mm_msub_sd(a, b, c);
}
__m128 test_mm_nmacc_ps(__m128 a, __m128 b, __m128 c) {
// CHECK-LABEL: test_mm_nmacc_ps
- // CHECK: @llvm.x86.fma.vfnmadd.ps
+ // CHECK: [[NEG:%.+]] = fsub <4 x float> <float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00>, %{{.+}}
+ // CHECK: @llvm.x86.fma.vfmadd.ps(<4 x float> [[NEG]], <4 x float> %{{.+}}, <4 x float> %{{.+}})
return _mm_nmacc_ps(a, b, c);
}
__m128d test_mm_nmacc_pd(__m128d a, __m128d b, __m128d c) {
// CHECK-LABEL: test_mm_nmacc_pd
- // CHECK: @llvm.x86.fma.vfnmadd.pd
+ // CHECK: [[NEG:%.+]] = fsub <2 x double> <double -0.000000e+00, double -0.000000e+00>, %{{.+}}
+ // CHECK: @llvm.x86.fma.vfmadd.pd(<2 x double> [[NEG]], <2 x double> %{{.+}}, <2 x double> %{{.+}})
return _mm_nmacc_pd(a, b, c);
}
__m128 test_mm_nmacc_ss(__m128 a, __m128 b, __m128 c) {
// CHECK-LABEL: test_mm_nmacc_ss
- // CHECK: @llvm.x86.fma.vfnmadd.ss
+ // CHECK: [[NEG:%.+]] = fsub <4 x float> <float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00>, %{{.+}}
+ // CHECK: @llvm.x86.fma4.vfmadd.ss(<4 x float> [[NEG]], <4 x float> %{{.+}}, <4 x float> %{{.+}})
return _mm_nmacc_ss(a, b, c);
}
__m128d test_mm_nmacc_sd(__m128d a, __m128d b, __m128d c) {
// CHECK-LABEL: test_mm_nmacc_sd
- // CHECK: @llvm.x86.fma.vfnmadd.sd
+ // CHECK: [[NEG:%.+]] = fsub <2 x double> <double -0.000000e+00, double -0.000000e+00>, %{{.+}}
+ // CHECK: @llvm.x86.fma4.vfmadd.sd(<2 x double> [[NEG]], <2 x double> %{{.+}}, <2 x double> %{{.+}})
return _mm_nmacc_sd(a, b, c);
}
__m128 test_mm_nmsub_ps(__m128 a, __m128 b, __m128 c) {
// CHECK-LABEL: test_mm_nmsub_ps
- // CHECK: @llvm.x86.fma.vfnmsub.ps
+ // CHECK: [[NEG:%.+]] = fsub <4 x float> <float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00>, %{{.+}}
+ // CHECK: [[NEG2:%.+]] = fsub <4 x float> <float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00>, %{{.+}}
+ // CHECK: @llvm.x86.fma.vfmadd.ps(<4 x float> [[NEG]], <4 x float> %{{.+}}, <4 x float> [[NEG2]])
return _mm_nmsub_ps(a, b, c);
}
__m128d test_mm_nmsub_pd(__m128d a, __m128d b, __m128d c) {
// CHECK-LABEL: test_mm_nmsub_pd
- // CHECK: @llvm.x86.fma.vfnmsub.pd
+ // CHECK: [[NEG:%.+]] = fsub <2 x double> <double -0.000000e+00, double -0.000000e+00>, %{{.+}}
+ // CHECK: [[NEG2:%.+]] = fsub <2 x double> <double -0.000000e+00, double -0.000000e+00>, %{{.+}}
+ // CHECK: @llvm.x86.fma.vfmadd.pd(<2 x double> [[NEG]], <2 x double> %{{.+}}, <2 x double> [[NEG2]])
return _mm_nmsub_pd(a, b, c);
}
__m128 test_mm_nmsub_ss(__m128 a, __m128 b, __m128 c) {
// CHECK-LABEL: test_mm_nmsub_ss
- // CHECK: @llvm.x86.fma.vfnmsub.ss
+ // CHECK: [[NEG:%.+]] = fsub <4 x float> <float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00>, %{{.+}}
+ // CHECK: [[NEG2:%.+]] = fsub <4 x float> <float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00>, %{{.+}}
+ // CHECK: @llvm.x86.fma4.vfmadd.ss(<4 x float> [[NEG]], <4 x float> %{{.+}}, <4 x float> [[NEG2]])
return _mm_nmsub_ss(a, b, c);
}
__m128d test_mm_nmsub_sd(__m128d a, __m128d b, __m128d c) {
// CHECK-LABEL: test_mm_nmsub_sd
- // CHECK: @llvm.x86.fma.vfnmsub.sd
+ // CHECK: [[NEG:%.+]] = fsub <2 x double> <double -0.000000e+00, double -0.000000e+00>, %{{.+}}
+ // CHECK: [[NEG2:%.+]] = fsub <2 x double> <double -0.000000e+00, double -0.000000e+00>, %{{.+}}
+ // CHECK: @llvm.x86.fma4.vfmadd.sd(<2 x double> [[NEG]], <2 x double> %{{.+}}, <2 x double> [[NEG2]])
return _mm_nmsub_sd(a, b, c);
}
@@ -113,13 +129,15 @@ __m128d test_mm_maddsub_pd(__m128d a, __m128d b, __m128d c) {
__m128 test_mm_msubadd_ps(__m128 a, __m128 b, __m128 c) {
// CHECK-LABEL: test_mm_msubadd_ps
- // CHECK: @llvm.x86.fma.vfmsubadd.ps
+ // CHECK: [[NEG:%.+]] = fsub <4 x float> <float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00>, %{{.+}}
+ // CHECK: @llvm.x86.fma.vfmaddsub.ps(<4 x float> %{{.+}}, <4 x float> %{{.+}}, <4 x float> [[NEG]])
return _mm_msubadd_ps(a, b, c);
}
__m128d test_mm_msubadd_pd(__m128d a, __m128d b, __m128d c) {
// CHECK-LABEL: test_mm_msubadd_pd
- // CHECK: @llvm.x86.fma.vfmsubadd.pd
+ // CHECK: [[NEG:%.+]] = fsub <2 x double> <double -0.000000e+00, double -0.000000e+00>, %{{.+}}
+ // CHECK: @llvm.x86.fma.vfmaddsub.pd(<2 x double> %{{.+}}, <2 x double> %{{.+}}, <2 x double> [[NEG]])
return _mm_msubadd_pd(a, b, c);
}
@@ -137,37 +155,45 @@ __m256d test_mm256_macc_pd(__m256d a, __m256d b, __m256d c) {
__m256 test_mm256_msub_ps(__m256 a, __m256 b, __m256 c) {
// CHECK-LABEL: test_mm256_msub_ps
- // CHECK: @llvm.x86.fma.vfmsub.ps.256
+ // CHECK: [[NEG:%.+]] = fsub <8 x float> <float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00>, %{{.*}}
+ // CHECK: @llvm.x86.fma.vfmadd.ps.256(<8 x float> %{{.+}}, <8 x float> %{{.+}}, <8 x float> [[NEG]])
return _mm256_msub_ps(a, b, c);
}
__m256d test_mm256_msub_pd(__m256d a, __m256d b, __m256d c) {
// CHECK-LABEL: test_mm256_msub_pd
- // CHECK: @llvm.x86.fma.vfmsub.pd.256
+ // CHECK: [[NEG:%.+]] = fsub <4 x double> <double -0.000000e+00, double -0.000000e+00, double -0.000000e+00, double -0.000000e+00>, %{{.+}}
+ // CHECK: @llvm.x86.fma.vfmadd.pd.256(<4 x double> %{{.+}}, <4 x double> %{{.+}}, <4 x double> [[NEG]])
return _mm256_msub_pd(a, b, c);
}
__m256 test_mm256_nmacc_ps(__m256 a, __m256 b, __m256 c) {
// CHECK-LABEL: test_mm256_nmacc_ps
- // CHECK: @llvm.x86.fma.vfnmadd.ps.256
+ // CHECK: [[NEG:%.+]] = fsub <8 x float> <float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00>, %{{.*}}
+ // CHECK: @llvm.x86.fma.vfmadd.ps.256(<8 x float> [[NEG]], <8 x float> %{{.+}}, <8 x float> %{{.+}})
return _mm256_nmacc_ps(a, b, c);
}
__m256d test_mm256_nmacc_pd(__m256d a, __m256d b, __m256d c) {
// CHECK-LABEL: test_mm256_nmacc_pd
- // CHECK: @llvm.x86.fma.vfnmadd.pd.256
+ // CHECK: [[NEG:%.+]] = fsub <4 x double> <double -0.000000e+00, double -0.000000e+00, double -0.000000e+00, double -0.000000e+00>, %{{.+}}
+ // CHECK: @llvm.x86.fma.vfmadd.pd.256(<4 x double> [[NEG]], <4 x double> %{{.+}}, <4 x double> %{{.+}})
return _mm256_nmacc_pd(a, b, c);
}
__m256 test_mm256_nmsub_ps(__m256 a, __m256 b, __m256 c) {
// CHECK-LABEL: test_mm256_nmsub_ps
- // CHECK: @llvm.x86.fma.vfnmsub.ps.256
+ // CHECK: [[NEG:%.+]] = fsub <8 x float> <float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00>, %{{.*}}
+ // CHECK: [[NEG2:%.+]] = fsub <8 x float> <float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00>, %{{.*}}
+ // CHECK: @llvm.x86.fma.vfmadd.ps.256(<8 x float> [[NEG]], <8 x float> %{{.+}}, <8 x float> [[NEG2]])
return _mm256_nmsub_ps(a, b, c);
}
__m256d test_mm256_nmsub_pd(__m256d a, __m256d b, __m256d c) {
// CHECK-LABEL: test_mm256_nmsub_pd
- // CHECK: @llvm.x86.fma.vfnmsub.pd.256
+ // CHECK: [[NEG:%.+]] = fsub <4 x double> <double -0.000000e+00, double -0.000000e+00, double -0.000000e+00, double -0.000000e+00>, %{{.+}}
+ // CHECK: [[NEG2:%.+]] = fsub <4 x double> <double -0.000000e+00, double -0.000000e+00, double -0.000000e+00, double -0.000000e+00>, %{{.+}}
+ // CHECK: @llvm.x86.fma.vfmadd.pd.256(<4 x double> [[NEG]], <4 x double> %{{.+}}, <4 x double> [[NEG2]])
return _mm256_nmsub_pd(a, b, c);
}
@@ -185,12 +211,14 @@ __m256d test_mm256_maddsub_pd(__m256d a, __m256d b, __m256d c) {
__m256 test_mm256_msubadd_ps(__m256 a, __m256 b, __m256 c) {
// CHECK-LABEL: test_mm256_msubadd_ps
- // CHECK: @llvm.x86.fma.vfmsubadd.ps.256
+ // CHECK: [[NEG:%.+]] = fsub <8 x float> <float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00>, %{{.*}}
+ // CHECK: @llvm.x86.fma.vfmaddsub.ps.256(<8 x float> %{{.*}}, <8 x float> %{{.+}}, <8 x float> [[NEG]])
return _mm256_msubadd_ps(a, b, c);
}
__m256d test_mm256_msubadd_pd(__m256d a, __m256d b, __m256d c) {
// CHECK-LABEL: test_mm256_msubadd_pd
- // CHECK: @llvm.x86.fma.vfmsubadd.pd.256
+ // CHECK: [[NEG:%.+]] = fsub <4 x double> <double -0.000000e+00, double -0.000000e+00, double -0.000000e+00, double -0.000000e+00>, %{{.+}}
+ // CHECK: @llvm.x86.fma.vfmaddsub.pd.256(<4 x double> %{{.+}}, <4 x double> %{{.+}}, <4 x double> [[NEG]])
return _mm256_msubadd_pd(a, b, c);
}
diff --git a/test/CodeGen/fp16-ops.c b/test/CodeGen/fp16-ops.c
index c96727f3d3fb..f2ed667341bb 100644
--- a/test/CodeGen/fp16-ops.c
+++ b/test/CodeGen/fp16-ops.c
@@ -1,8 +1,9 @@
// REQUIRES: arm-registered-target
-// RUN: %clang_cc1 -emit-llvm -o - -triple arm-none-linux-gnueabi %s | FileCheck %s --check-prefix=NOHALF --check-prefix=CHECK
-// RUN: %clang_cc1 -emit-llvm -o - -triple aarch64-none-linux-gnueabi %s | FileCheck %s --check-prefix=NOHALF --check-prefix=CHECK
-// RUN: %clang_cc1 -emit-llvm -o - -triple arm-none-linux-gnueabi -fallow-half-arguments-and-returns %s | FileCheck %s --check-prefix=HALF --check-prefix=CHECK
-// RUN: %clang_cc1 -emit-llvm -o - -triple aarch64-none-linux-gnueabi -fallow-half-arguments-and-returns %s | FileCheck %s --check-prefix=HALF --check-prefix=CHECK
+// RUN: %clang_cc1 -emit-llvm -o - -triple arm-none-linux-gnueabi %s | FileCheck %s --check-prefix=NOTNATIVE --check-prefix=CHECK
+// RUN: %clang_cc1 -emit-llvm -o - -triple aarch64-none-linux-gnueabi %s | FileCheck %s --check-prefix=NOTNATIVE --check-prefix=CHECK
+// RUN: %clang_cc1 -emit-llvm -o - -triple x86_64-linux-gnu %s | FileCheck %s --check-prefix=NOTNATIVE --check-prefix=CHECK
+// RUN: %clang_cc1 -emit-llvm -o - -triple arm-none-linux-gnueabi -fallow-half-arguments-and-returns %s | FileCheck %s --check-prefix=NOTNATIVE --check-prefix=CHECK
+// RUN: %clang_cc1 -emit-llvm -o - -triple aarch64-none-linux-gnueabi -fallow-half-arguments-and-returns %s | FileCheck %s --check-prefix=NOTNATIVE --check-prefix=CHECK
// RUN: %clang_cc1 -emit-llvm -o - -triple arm-none-linux-gnueabi -fnative-half-type %s \
// RUN: | FileCheck %s --check-prefix=NATIVE-HALF
// RUN: %clang_cc1 -emit-llvm -o - -triple aarch64-none-linux-gnueabi -fnative-half-type %s \
@@ -16,20 +17,19 @@ volatile int i0;
volatile __fp16 h0 = 0.0, h1 = 1.0, h2;
volatile float f0, f1, f2;
volatile double d0;
+short s0;
void foo(void) {
// CHECK-LABEL: define void @foo()
// Check unary ops
- // NOHALF: [[F16TOF32:call float @llvm.convert.from.fp16.f32]]
- // HALF: [[F16TOF32:fpext half]]
+ // NOTNATIVE: [[F16TOF32:fpext half]]
// CHECK: fptoui float
// NATIVE-HALF: fptoui half
test = (h0);
// CHECK: uitofp i32
- // NOHALF: [[F32TOF16:call i16 @llvm.convert.to.fp16.f32]]
- // HALF: [[F32TOF16:fptrunc float]]
+ // NOTNATIVE: [[F32TOF16:fptrunc float]]
// NATIVE-HALF: uitofp i32 {{.*}} to half
h0 = (test);
// CHECK: [[F16TOF32]]
@@ -38,8 +38,7 @@ void foo(void) {
test = (!h1);
// CHECK: [[F16TOF32]]
// CHECK: fsub float
- // NOHALF: [[F32TOF16]]
- // HALF: [[F32TOF16]]
+ // NOTNATIVE: [[F32TOF16]]
// NATIVE-HALF: fsub half
h1 = -h1;
// CHECK: [[F16TOF32]]
@@ -76,8 +75,6 @@ void foo(void) {
// NATIVE-HALF: fmul half
h1 = h0 * h2;
// CHECK: [[F16TOF32]]
- // NOHALF: [[F32TOF16]]
- // NOHALF: [[F16TOF32]]
// CHECK: fmul float
// CHECK: [[F32TOF16]]
// NATIVE-HALF: fmul half
@@ -107,7 +104,6 @@ void foo(void) {
// NATIVE-HALF: fdiv half
h1 = (h0 / h2);
// CHECK: [[F16TOF32]]
- // NOHALF: [[F16TOF32]]
// CHECK: fdiv float
// CHECK: [[F32TOF16]]
// NATIVE-HALF: fdiv half
@@ -137,7 +133,6 @@ void foo(void) {
// NATIVE-HALF: fadd half
h1 = (h2 + h0);
// CHECK: [[F16TOF32]]
- // NOHALF: [[F16TOF32]]
// CHECK: fadd float
// CHECK: [[F32TOF16]]
// NATIVE-HALF: fadd half
@@ -167,7 +162,6 @@ void foo(void) {
// NATIVE-HALF: fsub half
h1 = (h2 - h0);
// CHECK: [[F16TOF32]]
- // NOHALF: [[F16TOF32]]
// CHECK: fsub float
// CHECK: [[F32TOF16]]
// NATIVE-HALF: fsub half
@@ -196,7 +190,6 @@ void foo(void) {
// NATIVE-HALF: fcmp olt half
test = (h2 < h0);
// CHECK: [[F16TOF32]]
- // NOHALF: [[F16TOF32]]
// CHECK: fcmp olt float
// NATIVE-HALF: fcmp olt half
test = (h2 < (__fp16)42.0);
@@ -225,7 +218,6 @@ void foo(void) {
// NATIVE-HALF: fcmp ogt half
test = (h0 > h2);
// CHECK: [[F16TOF32]]
- // NOHALF: [[F16TOF32]]
// CHECK: fcmp ogt float
// NATIVE-HALF: fcmp ogt half
test = ((__fp16)42.0 > h2);
@@ -254,7 +246,6 @@ void foo(void) {
// NATIVE-HALF: fcmp ole half
test = (h2 <= h0);
// CHECK: [[F16TOF32]]
- // NOHALF: [[F16TOF32]]
// CHECK: fcmp ole float
// NATIVE-HALF: fcmp ole half
test = (h2 <= (__fp16)42.0);
@@ -284,7 +275,6 @@ void foo(void) {
// NATIVE-HALF: fcmp oge half
test = (h0 >= h2);
// CHECK: [[F16TOF32]]
- // NOHALF: [[F16TOF32]]
// CHECK: fcmp oge float
// NATIVE-HALF: fcmp oge half
test = (h0 >= (__fp16)-2.0);
@@ -313,7 +303,6 @@ void foo(void) {
// NATIVE-HALF: fcmp oeq half
test = (h1 == h2);
// CHECK: [[F16TOF32]]
- // NOHALF: [[F16TOF32]]
// CHECK: fcmp oeq float
// NATIVE-HALF: fcmp oeq half
test = (h1 == (__fp16)1.0);
@@ -342,7 +331,6 @@ void foo(void) {
// NATIVE-HALF: fcmp une half
test = (h1 != h2);
// CHECK: [[F16TOF32]]
- // NOHALF: [[F16TOF32]]
// CHECK: fcmp une float
// NATIVE-HALF: fcmp une half
test = (h1 != (__fp16)1.0);
@@ -374,8 +362,7 @@ void foo(void) {
h1 = (h1 ? h2 : h0);
// Check assignments (inc. compound)
h0 = h1;
- // NOHALF: [[F32TOF16]]
- // HALF: store {{.*}} half 0xHC000
+ // NOTNATIVE: store {{.*}} half 0xHC000
// NATIVE-HALF: store {{.*}} half 0xHC000
h0 = (__fp16)-2.0f;
// CHECK: [[F32TOF16]]
@@ -398,7 +385,6 @@ void foo(void) {
// NATIVE-HALF: fadd half
h0 += h1;
// CHECK: [[F16TOF32]]
- // NOHALF: [[F16TOF32]]
// CHECK: fadd float
// CHECK: [[F32TOF16]]
// NATIVE-HALF: fadd half
@@ -433,7 +419,6 @@ void foo(void) {
// NATIVE-HALF: fsub half
h0 -= h1;
// CHECK: [[F16TOF32]]
- // NOHALF: [[F16TOF32]]
// CHECK: fsub float
// CHECK: [[F32TOF16]]
// NATIVE-HALF: fsub half
@@ -468,7 +453,6 @@ void foo(void) {
// NATIVE-HALF: fmul half
h0 *= h1;
// CHECK: [[F16TOF32]]
- // NOHALF: [[F16TOF32]]
// CHECK: fmul float
// CHECK: [[F32TOF16]]
// NATIVE-HALF: fmul half
@@ -503,7 +487,6 @@ void foo(void) {
// NATIVE-HALF: fdiv half
h0 /= h1;
// CHECK: [[F16TOF32]]
- // NOHALF: [[F16TOF32]]
// CHECK: fdiv float
// CHECK: [[F32TOF16]]
// NATIVE-HALF: fdiv half
@@ -532,27 +515,29 @@ void foo(void) {
h0 /= i0;
// Check conversions to/from double
- // NOHALF: call i16 @llvm.convert.to.fp16.f64(
- // HALF: fptrunc double {{.*}} to half
+ // NOTNATIVE: fptrunc double {{.*}} to half
// NATIVE-HALF: fptrunc double {{.*}} to half
h0 = d0;
// CHECK: [[MID:%.*]] = fptrunc double {{%.*}} to float
- // NOHALF: call i16 @llvm.convert.to.fp16.f32(float [[MID]])
- // HALF: fptrunc float [[MID]] to half
+ // NOTNATIVE: fptrunc float [[MID]] to half
// NATIVE-HALF: [[MID:%.*]] = fptrunc double {{%.*}} to float
// NATIVE-HALF: fptrunc float {{.*}} to half
h0 = (float)d0;
- // NOHALF: call double @llvm.convert.from.fp16.f64(
- // HALF: fpext half {{.*}} to double
+ // NOTNATIVE: fpext half {{.*}} to double
// NATIVE-HALF: fpext half {{.*}} to double
d0 = h0;
- // NOHALF: [[MID:%.*]] = call float @llvm.convert.from.fp16.f32(
- // HALF: [[MID:%.*]] = fpext half {{.*}} to float
+ // NOTNATIVE: [[MID:%.*]] = fpext half {{.*}} to float
// CHECK: fpext float [[MID]] to double
// NATIVE-HALF: [[MID:%.*]] = fpext half {{.*}} to float
// NATIVE-HALF: fpext float [[MID]] to double
d0 = (float)h0;
+
+ // NOTNATIVE: [[V1:%.*]] = load i16, i16* @s0
+ // NOTNATIVE: [[CONV:%.*]] = sitofp i16 [[V1]] to float
+ // NOTNATIVE: [[TRUNC:%.*]] = fptrunc float [[CONV]] to half
+ // NOTNATIVE: store volatile half [[TRUNC]], half* @h0
+ h0 = s0;
}
diff --git a/test/CodeGen/fp16vec-ops.c b/test/CodeGen/fp16vec-ops.c
new file mode 100644
index 000000000000..2eb75a48e30a
--- /dev/null
+++ b/test/CodeGen/fp16vec-ops.c
@@ -0,0 +1,163 @@
+// REQUIRES: arm-registered-target
+// RUN: %clang_cc1 -triple arm64-apple-ios9 -emit-llvm -o - -fallow-half-arguments-and-returns %s | FileCheck %s --check-prefix=CHECK
+// RUN: %clang_cc1 -triple armv7-apple-ios9 -emit-llvm -o - -fallow-half-arguments-and-returns %s | FileCheck %s --check-prefix=CHECK
+// RUN: %clang_cc1 -triple x86_64-apple-macos10.13 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK
+
+typedef __fp16 half4 __attribute__ ((vector_size (8)));
+typedef short short4 __attribute__ ((vector_size (8)));
+
+half4 hv0, hv1;
+short4 sv0;
+
+// CHECK-LABEL: testFP16Vec0
+// CHECK: %[[V0:.*]] = load <4 x half>, <4 x half>* @hv0, align 8
+// CHECK: %[[CONV:.*]] = fpext <4 x half> %[[V0]] to <4 x float>
+// CHECK: %[[V1:.*]] = load <4 x half>, <4 x half>* @hv1, align 8
+// CHECK: %[[CONV1:.*]] = fpext <4 x half> %[[V1]] to <4 x float>
+// CHECK: %[[ADD:.*]] = fadd <4 x float> %[[CONV]], %[[CONV1]]
+// CHECK: %[[CONV2:.*]] = fptrunc <4 x float> %[[ADD]] to <4 x half>
+// CHECK: store <4 x half> %[[CONV2]], <4 x half>* @hv0, align 8
+// CHECK: %[[V2:.*]] = load <4 x half>, <4 x half>* @hv0, align 8
+// CHECK: %[[CONV3:.*]] = fpext <4 x half> %[[V2]] to <4 x float>
+// CHECK: %[[V3:.*]] = load <4 x half>, <4 x half>* @hv1, align 8
+// CHECK: %[[CONV4:.*]] = fpext <4 x half> %[[V3]] to <4 x float>
+// CHECK: %[[SUB:.*]] = fsub <4 x float> %[[CONV3]], %[[CONV4]]
+// CHECK: %[[CONV5:.*]] = fptrunc <4 x float> %[[SUB]] to <4 x half>
+// CHECK: store <4 x half> %[[CONV5]], <4 x half>* @hv0, align 8
+// CHECK: %[[V4:.*]] = load <4 x half>, <4 x half>* @hv0, align 8
+// CHECK: %[[CONV6:.*]] = fpext <4 x half> %[[V4]] to <4 x float>
+// CHECK: %[[V5:.*]] = load <4 x half>, <4 x half>* @hv1, align 8
+// CHECK: %[[CONV7:.*]] = fpext <4 x half> %[[V5]] to <4 x float>
+// CHECK: %[[MUL:.*]] = fmul <4 x float> %[[CONV6]], %[[CONV7]]
+// CHECK: %[[CONV8:.*]] = fptrunc <4 x float> %[[MUL]] to <4 x half>
+// CHECK: store <4 x half> %[[CONV8]], <4 x half>* @hv0, align 8
+// CHECK: %[[V6:.*]] = load <4 x half>, <4 x half>* @hv0, align 8
+// CHECK: %[[CONV9:.*]] = fpext <4 x half> %[[V6]] to <4 x float>
+// CHECK: %[[V7:.*]] = load <4 x half>, <4 x half>* @hv1, align 8
+// CHECK: %[[CONV10:.*]] = fpext <4 x half> %[[V7]] to <4 x float>
+// CHECK: %[[DIV:.*]] = fdiv <4 x float> %[[CONV9]], %[[CONV10]]
+// CHECK: %[[CONV11:.*]] = fptrunc <4 x float> %[[DIV]] to <4 x half>
+// CHECK: store <4 x half> %[[CONV11]], <4 x half>* @hv0, align 8
+
+void testFP16Vec0() {
+ hv0 = hv0 + hv1;
+ hv0 = hv0 - hv1;
+ hv0 = hv0 * hv1;
+ hv0 = hv0 / hv1;
+}
+
+// CHECK-LABEL: testFP16Vec1
+// CHECK: %[[V0:.*]] = load <4 x half>, <4 x half>* @hv1, align 8
+// CHECK: %[[CONV:.*]] = fpext <4 x half> %[[V0]] to <4 x float>
+// CHECK: %[[V1:.*]] = load <4 x half>, <4 x half>* @hv0, align 8
+// CHECK: %[[CONV1:.*]] = fpext <4 x half> %[[V1]] to <4 x float>
+// CHECK: %[[ADD:.*]] = fadd <4 x float> %[[CONV1]], %[[CONV]]
+// CHECK: %[[CONV2:.*]] = fptrunc <4 x float> %[[ADD]] to <4 x half>
+// CHECK: store <4 x half> %[[CONV2]], <4 x half>* @hv0, align 8
+// CHECK: %[[V2:.*]] = load <4 x half>, <4 x half>* @hv1, align 8
+// CHECK: %[[CONV3:.*]] = fpext <4 x half> %[[V2]] to <4 x float>
+// CHECK: %[[V3:.*]] = load <4 x half>, <4 x half>* @hv0, align 8
+// CHECK: %[[CONV4:.*]] = fpext <4 x half> %[[V3]] to <4 x float>
+// CHECK: %[[SUB:.*]] = fsub <4 x float> %[[CONV4]], %[[CONV3]]
+// CHECK: %[[CONV5:.*]] = fptrunc <4 x float> %[[SUB]] to <4 x half>
+// CHECK: store <4 x half> %[[CONV5]], <4 x half>* @hv0, align 8
+// CHECK: %[[V4:.*]] = load <4 x half>, <4 x half>* @hv1, align 8
+// CHECK: %[[CONV6:.*]] = fpext <4 x half> %[[V4]] to <4 x float>
+// CHECK: %[[V5:.*]] = load <4 x half>, <4 x half>* @hv0, align 8
+// CHECK: %[[CONV7:.*]] = fpext <4 x half> %[[V5]] to <4 x float>
+// CHECK: %[[MUL:.*]] = fmul <4 x float> %[[CONV7]], %[[CONV6]]
+// CHECK: %[[CONV8:.*]] = fptrunc <4 x float> %[[MUL]] to <4 x half>
+// CHECK: store <4 x half> %[[CONV8]], <4 x half>* @hv0, align 8
+// CHECK: %[[V6:.*]] = load <4 x half>, <4 x half>* @hv1, align 8
+// CHECK: %[[CONV9:.*]] = fpext <4 x half> %[[V6]] to <4 x float>
+// CHECK: %[[V7:.*]] = load <4 x half>, <4 x half>* @hv0, align 8
+// CHECK: %[[CONV10:.*]] = fpext <4 x half> %[[V7]] to <4 x float>
+// CHECK: %[[DIV:.*]] = fdiv <4 x float> %[[CONV10]], %[[CONV9]]
+// CHECK: %[[CONV11:.*]] = fptrunc <4 x float> %[[DIV]] to <4 x half>
+// CHECK: store <4 x half> %[[CONV11]], <4 x half>* @hv0, align 8
+
+void testFP16Vec1() {
+ hv0 += hv1;
+ hv0 -= hv1;
+ hv0 *= hv1;
+ hv0 /= hv1;
+}
+
+// CHECK-LABEL: testFP16Vec2
+// CHECK: %[[CADDR:.*]] = alloca i32, align 4
+// CHECK: store i32 %[[C:.*]], i32* %[[CADDR]], align 4
+// CHECK: %[[V0:.*]] = load i32, i32* %[[CADDR]], align 4
+// CHECK: %[[TOBOOL:.*]] = icmp ne i32 %[[V0]], 0
+// CHECK: br i1 %[[TOBOOL]], label %{{.*}}, label %{{.*}}
+//
+// CHECK: %[[V1:.*]] = load <4 x half>, <4 x half>* @hv0, align 8
+// CHECK: br label %{{.*}}
+//
+// CHECK: %[[V2:.*]] = load <4 x half>, <4 x half>* @hv1, align 8
+// CHECK: br label %{{.*}}
+//
+// CHECK: %[[COND:.*]] = phi <4 x half> [ %[[V1]], %{{.*}} ], [ %[[V2]], %{{.*}} ]
+// CHECK: store <4 x half> %[[COND]], <4 x half>* @hv0, align 8
+
+void testFP16Vec2(int c) {
+ hv0 = c ? hv0 : hv1;
+}
+
+// CHECK-LABEL: testFP16Vec3
+// CHECK: %[[V0:.*]] = load <4 x half>, <4 x half>* @hv0, align 8
+// CHECK: %[[CONV:.*]] = fpext <4 x half> %[[V0]] to <4 x float>
+// CHECK: %[[V1:.*]] = load <4 x half>, <4 x half>* @hv1, align 8
+// CHECK: %[[CONV1:.*]] = fpext <4 x half> %[[V1]] to <4 x float>
+// CHECK: %[[CMP:.*]] = fcmp oeq <4 x float> %[[CONV]], %[[CONV1]]
+// CHECK: %[[SEXT:.*]] = sext <4 x i1> %[[CMP]] to <4 x i32>
+// CHECK: %[[CONV2:.*]] = trunc <4 x i32> %[[SEXT]] to <4 x i16>
+// CHECK: store <4 x i16> %[[CONV2]], <4 x i16>* @sv0, align 8
+// CHECK: %[[V2:.*]] = load <4 x half>, <4 x half>* @hv0, align 8
+// CHECK: %[[CONV3:.*]] = fpext <4 x half> %[[V2]] to <4 x float>
+// CHECK: %[[V3:.*]] = load <4 x half>, <4 x half>* @hv1, align 8
+// CHECK: %[[CONV4:.*]] = fpext <4 x half> %[[V3]] to <4 x float>
+// CHECK: %[[CMP5:.*]] = fcmp une <4 x float> %[[CONV3]], %[[CONV4]]
+// CHECK: %[[SEXT6:.*]] = sext <4 x i1> %[[CMP5]] to <4 x i32>
+// CHECK: %[[CONV7:.*]] = trunc <4 x i32> %[[SEXT6]] to <4 x i16>
+// CHECK: store <4 x i16> %[[CONV7]], <4 x i16>* @sv0, align 8
+// CHECK: %[[V4:.*]] = load <4 x half>, <4 x half>* @hv0, align 8
+// CHECK: %[[CONV8:.*]] = fpext <4 x half> %[[V4]] to <4 x float>
+// CHECK: %[[V5:.*]] = load <4 x half>, <4 x half>* @hv1, align 8
+// CHECK: %[[CONV9:.*]] = fpext <4 x half> %[[V5]] to <4 x float>
+// CHECK: %[[CMP10:.*]] = fcmp olt <4 x float> %[[CONV8]], %[[CONV9]]
+// CHECK: %[[SEXT11:.*]] = sext <4 x i1> %[[CMP10]] to <4 x i32>
+// CHECK: %[[CONV12:.*]] = trunc <4 x i32> %[[SEXT11]] to <4 x i16>
+// CHECK: store <4 x i16> %[[CONV12]], <4 x i16>* @sv0, align 8
+// CHECK: %[[V6:.*]] = load <4 x half>, <4 x half>* @hv0, align 8
+// CHECK: %[[CONV13:.*]] = fpext <4 x half> %[[V6]] to <4 x float>
+// CHECK: %[[V7:.*]] = load <4 x half>, <4 x half>* @hv1, align 8
+// CHECK: %[[CONV14:.*]] = fpext <4 x half> %[[V7]] to <4 x float>
+// CHECK: %[[CMP15:.*]] = fcmp ogt <4 x float> %[[CONV13]], %[[CONV14]]
+// CHECK: %[[SEXT16:.*]] = sext <4 x i1> %[[CMP15]] to <4 x i32>
+// CHECK: %[[CONV17:.*]] = trunc <4 x i32> %[[SEXT16]] to <4 x i16>
+// CHECK: store <4 x i16> %[[CONV17]], <4 x i16>* @sv0, align 8
+// CHECK: %[[V8:.*]] = load <4 x half>, <4 x half>* @hv0, align 8
+// CHECK: %[[CONV18:.*]] = fpext <4 x half> %[[V8]] to <4 x float>
+// CHECK: %[[V9:.*]] = load <4 x half>, <4 x half>* @hv1, align 8
+// CHECK: %[[CONV19:.*]] = fpext <4 x half> %[[V9]] to <4 x float>
+// CHECK: %[[CMP20:.*]] = fcmp ole <4 x float> %[[CONV18]], %[[CONV19]]
+// CHECK: %[[SEXT21:.*]] = sext <4 x i1> %[[CMP20]] to <4 x i32>
+// CHECK: %[[CONV22:.*]] = trunc <4 x i32> %[[SEXT21]] to <4 x i16>
+// CHECK: store <4 x i16> %[[CONV22]], <4 x i16>* @sv0, align 8
+// CHECK: %[[V10:.*]] = load <4 x half>, <4 x half>* @hv0, align 8
+// CHECK: %[[CONV23:.*]] = fpext <4 x half> %[[V10]] to <4 x float>
+// CHECK: %[[V11:.*]] = load <4 x half>, <4 x half>* @hv1, align 8
+// CHECK: %[[CONV24:.*]] = fpext <4 x half> %[[V11]] to <4 x float>
+// CHECK: %[[CMP25:.*]] = fcmp oge <4 x float> %[[CONV23]], %[[CONV24]]
+// CHECK: %[[SEXT26:.*]] = sext <4 x i1> %[[CMP25]] to <4 x i32>
+// CHECK: %[[CONV27:.*]] = trunc <4 x i32> %[[SEXT26]] to <4 x i16>
+// CHECK: store <4 x i16> %[[CONV27]], <4 x i16>* @sv0, align 8
+
+void testFP16Vec3() {
+ sv0 = hv0 == hv1;
+ sv0 = hv0 != hv1;
+ sv0 = hv0 < hv1;
+ sv0 = hv0 > hv1;
+ sv0 = hv0 <= hv1;
+ sv0 = hv0 >= hv1;
+}
diff --git a/test/CodeGen/function-attributes.c b/test/CodeGen/function-attributes.c
index 2139f6fe6546..e14397440100 100644
--- a/test/CodeGen/function-attributes.c
+++ b/test/CodeGen/function-attributes.c
@@ -1,5 +1,6 @@
// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -disable-llvm-passes -Os -o - %s | FileCheck %s
// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -disable-llvm-passes -Os -std=c99 -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -disable-llvm-passes -Os -std=c99 -o - %s | FileCheck %s
// CHECK: define signext i8 @f0(i32 %x) [[NUW:#[0-9]+]]
// CHECK: define zeroext i8 @f1(i32 %x) [[NUW]]
// CHECK: define void @f2(i8 signext %x) [[NUW]]
diff --git a/test/CodeGen/hexagon-inline-asm.c b/test/CodeGen/hexagon-inline-asm.c
index cda3d0dcb6bd..3de3f58baf3b 100644
--- a/test/CodeGen/hexagon-inline-asm.c
+++ b/test/CodeGen/hexagon-inline-asm.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple hexagon-unknown-elf -target-feature +hvx -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple hexagon-unknown-elf -target-feature +hvx -target-feature +hvx-length64b -emit-llvm -o - %s | FileCheck %s
typedef int v64 __attribute__((__vector_size__(64)))
__attribute__((aligned(64)));
@@ -15,3 +15,9 @@ void foo(v64 v0, v64 v1, v64 *p) {
asm ("%0 = memw(##%1)" : "=r"(r) : "s"(&g));
// CHECK: call i32 asm "$0 = memw(##$1)", "=r,s"(i32* @g)
}
+
+void fred(unsigned *p, unsigned m, unsigned v) {
+ asm ("memw(%0++%1) = %2" : : "r"(p),"a"(m),"r"(v) : "memory");
+// CHECK: call void asm sideeffect "memw($0++$1) = $2", "r,a,r,~{memory}"(i32* %{{.*}}, i32 %{{.*}}, i32 %{{.*}})
+}
+
diff --git a/test/CodeGen/instrument-functions.c b/test/CodeGen/instrument-functions.c
index 454dc4de5220..c075c3972dd7 100644
--- a/test/CodeGen/instrument-functions.c
+++ b/test/CodeGen/instrument-functions.c
@@ -1,18 +1,34 @@
-// RUN: %clang_cc1 -S -debug-info-kind=standalone -emit-llvm -o - %s -finstrument-functions | FileCheck %s
+// RUN: %clang_cc1 -S -debug-info-kind=standalone -emit-llvm -o - %s -finstrument-functions -disable-llvm-passes | FileCheck %s
+// RUN: %clang_cc1 -S -debug-info-kind=standalone -emit-llvm -o - %s -finstrument-function-entry-bare -disable-llvm-passes | FileCheck -check-prefix=BARE %s
-// CHECK: @test1
int test1(int x) {
-// CHECK: call void @__cyg_profile_func_enter({{.*}}, !dbg
-// CHECK: call void @__cyg_profile_func_exit({{.*}}, !dbg
+// CHECK: @test1(i32 {{.*}}%x) #[[ATTR1:[0-9]+]]
// CHECK: ret
+
+// BARE: @test1(i32 {{.*}}%x) #[[ATTR1:[0-9]+]]
+// BARE: ret
return x;
}
-// CHECK: @test2
int test2(int) __attribute__((no_instrument_function));
int test2(int x) {
-// CHECK-NOT: __cyg_profile_func_enter
-// CHECK-NOT: __cyg_profile_func_exit
+// CHECK: @test2(i32 {{.*}}%x) #[[ATTR2:[0-9]+]]
// CHECK: ret
+
+// BARE: @test2(i32 {{.*}}%x) #[[ATTR2:[0-9]+]]
+// BARE: ret
return x;
}
+
+// CHECK: attributes #[[ATTR1]] =
+// CHECK-SAME: "instrument-function-entry"="__cyg_profile_func_enter"
+// CHECK-SAME: "instrument-function-exit"="__cyg_profile_func_exit"
+
+// BARE: attributes #[[ATTR1]] =
+// BARE-SAME: "instrument-function-entry-inlined"="__cyg_profile_func_enter_bare"
+
+// CHECK: attributes #[[ATTR2]] =
+// CHECK-NOT: "instrument-function-entry"
+
+// BARE: attributes #[[ATTR2]] =
+// BARE-NOT: "instrument-function-entry"
diff --git a/test/CodeGen/libcall-declarations.c b/test/CodeGen/libcall-declarations.c
index 5a0b2ba0e636..7492995be892 100644
--- a/test/CodeGen/libcall-declarations.c
+++ b/test/CodeGen/libcall-declarations.c
@@ -312,314 +312,310 @@ void *use[] = {
F(__cospif), F(__tanpi), F(__tanpif), F(__exp10), F(__exp10f)
};
-// CHECK-NOERRNO: declare double @atan2(double, double) [[NUW:#[0-9]+]]
-// CHECK-NOERRNO: declare float @atan2f(float, float) [[NUW]]
-// CHECK-NOERRNO: declare x86_fp80 @atan2l(x86_fp80, x86_fp80) [[NUW]]
-// CHECK-NOERRNO: declare i32 @abs(i32) [[NUW]]
-// CHECK-NOERRNO: declare i64 @labs(i64) [[NUW]]
-// CHECK-NOERRNO: declare i64 @llabs(i64) [[NUW]]
-// CHECK-NOERRNO: declare double @copysign(double, double) [[NUW]]
-// CHECK-NOERRNO: declare float @copysignf(float, float) [[NUW]]
-// CHECK-NOERRNO: declare x86_fp80 @copysignl(x86_fp80, x86_fp80) [[NUW]]
-// CHECK-NOERRNO: declare double @fabs(double) [[NUW]]
-// CHECK-NOERRNO: declare float @fabsf(float) [[NUW]]
-// CHECK-NOERRNO: declare x86_fp80 @fabsl(x86_fp80) [[NUW]]
-// CHECK-NOERRNO: declare double @fmod(double, double) [[NUW]]
-// CHECK-NOERRNO: declare float @fmodf(float, float) [[NUW]]
-// CHECK-NOERRNO: declare x86_fp80 @fmodl(x86_fp80, x86_fp80) [[NUW]]
-// CHECK-NOERRNO: declare double @ldexp(double, i32) [[NUW]]
-// CHECK-NOERRNO: declare float @ldexpf(float, i32) [[NUW]]
-// CHECK-NOERRNO: declare x86_fp80 @ldexpl(x86_fp80, i32) [[NUW]]
-// CHECK-NOERRNO: declare double @nan(i8*) [[NUW]]
-// CHECK-NOERRNO: declare float @nanf(i8*) [[NUW]]
-// CHECK-NOERRNO: declare x86_fp80 @nanl(i8*) [[NUW]]
-// CHECK-NOERRNO: declare double @pow(double, double) [[NUW]]
-// CHECK-NOERRNO: declare float @powf(float, float) [[NUW]]
-// CHECK-NOERRNO: declare x86_fp80 @powl(x86_fp80, x86_fp80) [[NUW]]
-// CHECK-NOERRNO: declare double @acos(double) [[NUW]]
-// CHECK-NOERRNO: declare float @acosf(float) [[NUW]]
-// CHECK-NOERRNO: declare x86_fp80 @acosl(x86_fp80) [[NUW]]
-// CHECK-NOERRNO: declare double @acosh(double) [[NUW]]
-// CHECK-NOERRNO: declare float @acoshf(float) [[NUW]]
-// CHECK-NOERRNO: declare x86_fp80 @acoshl(x86_fp80) [[NUW]]
-// CHECK-NOERRNO: declare double @asin(double) [[NUW]]
-// CHECK-NOERRNO: declare float @asinf(float) [[NUW]]
-// CHECK-NOERRNO: declare x86_fp80 @asinl(x86_fp80) [[NUW]]
-// CHECK-NOERRNO: declare double @asinh(double) [[NUW]]
-// CHECK-NOERRNO: declare float @asinhf(float) [[NUW]]
-// CHECK-NOERRNO: declare x86_fp80 @asinhl(x86_fp80) [[NUW]]
-// CHECK-NOERRNO: declare double @atan(double) [[NUW]]
-// CHECK-NOERRNO: declare float @atanf(float) [[NUW]]
-// CHECK-NOERRNO: declare x86_fp80 @atanl(x86_fp80) [[NUW]]
-// CHECK-NOERRNO: declare double @atanh(double) [[NUW]]
-// CHECK-NOERRNO: declare float @atanhf(float) [[NUW]]
-// CHECK-NOERRNO: declare x86_fp80 @atanhl(x86_fp80) [[NUW]]
-// CHECK-NOERRNO: declare double @cbrt(double) [[NUW]]
-// CHECK-NOERRNO: declare float @cbrtf(float) [[NUW]]
-// CHECK-NOERRNO: declare x86_fp80 @cbrtl(x86_fp80) [[NUW]]
-// CHECK-NOERRNO: declare double @ceil(double) [[NUW]]
-// CHECK-NOERRNO: declare float @ceilf(float) [[NUW]]
-// CHECK-NOERRNO: declare x86_fp80 @ceill(x86_fp80) [[NUW]]
-// CHECK-NOERRNO: declare double @cos(double) [[NUW]]
-// CHECK-NOERRNO: declare float @cosf(float) [[NUW]]
-// CHECK-NOERRNO: declare x86_fp80 @cosl(x86_fp80) [[NUW]]
-// CHECK-NOERRNO: declare double @cosh(double) [[NUW]]
-// CHECK-NOERRNO: declare float @coshf(float) [[NUW]]
-// CHECK-NOERRNO: declare x86_fp80 @coshl(x86_fp80) [[NUW]]
-// CHECK-NOERRNO: declare double @erf(double) [[NUW]]
-// CHECK-NOERRNO: declare float @erff(float) [[NUW]]
-// CHECK-NOERRNO: declare x86_fp80 @erfl(x86_fp80) [[NUW]]
-// CHECK-NOERRNO: declare double @erfc(double) [[NUW]]
-// CHECK-NOERRNO: declare float @erfcf(float) [[NUW]]
-// CHECK-NOERRNO: declare x86_fp80 @erfcl(x86_fp80) [[NUW]]
-// CHECK-NOERRNO: declare double @exp(double) [[NUW]]
-// CHECK-NOERRNO: declare float @expf(float) [[NUW]]
-// CHECK-NOERRNO: declare x86_fp80 @expl(x86_fp80) [[NUW]]
-// CHECK-NOERRNO: declare double @exp2(double) [[NUW]]
-// CHECK-NOERRNO: declare float @exp2f(float) [[NUW]]
-// CHECK-NOERRNO: declare x86_fp80 @exp2l(x86_fp80) [[NUW]]
-// CHECK-NOERRNO: declare double @expm1(double) [[NUW]]
-// CHECK-NOERRNO: declare float @expm1f(float) [[NUW]]
-// CHECK-NOERRNO: declare x86_fp80 @expm1l(x86_fp80) [[NUW]]
-// CHECK-NOERRNO: declare double @fdim(double, double) [[NUW]]
-// CHECK-NOERRNO: declare float @fdimf(float, float) [[NUW]]
-// CHECK-NOERRNO: declare x86_fp80 @fdiml(x86_fp80, x86_fp80) [[NUW]]
-// CHECK-NOERRNO: declare double @floor(double) [[NUW]]
-// CHECK-NOERRNO: declare float @floorf(float) [[NUW]]
-// CHECK-NOERRNO: declare x86_fp80 @floorl(x86_fp80) [[NUW]]
-// CHECK-NOERRNO: declare double @fma(double, double, double) [[NUW]]
-// CHECK-NOERRNO: declare float @fmaf(float, float, float) [[NUW]]
-// CHECK-NOERRNO: declare x86_fp80 @fmal(x86_fp80, x86_fp80, x86_fp80) [[NUW]]
-// CHECK-NOERRNO: declare double @fmax(double, double) [[NUW]]
-// CHECK-NOERRNO: declare float @fmaxf(float, float) [[NUW]]
-// CHECK-NOERRNO: declare x86_fp80 @fmaxl(x86_fp80, x86_fp80) [[NUW]]
-// CHECK-NOERRNO: declare double @fmin(double, double) [[NUW]]
-// CHECK-NOERRNO: declare float @fminf(float, float) [[NUW]]
-// CHECK-NOERRNO: declare x86_fp80 @fminl(x86_fp80, x86_fp80) [[NUW]]
-// CHECK-NOERRNO: declare double @hypot(double, double) [[NUW]]
-// CHECK-NOERRNO: declare float @hypotf(float, float) [[NUW]]
-// CHECK-NOERRNO: declare x86_fp80 @hypotl(x86_fp80, x86_fp80) [[NUW]]
-// CHECK-NOERRNO: declare i32 @ilogb(double) [[NUW]]
-// CHECK-NOERRNO: declare i32 @ilogbf(float) [[NUW]]
-// CHECK-NOERRNO: declare i32 @ilogbl(x86_fp80) [[NUW]]
+// CHECK-NOERRNO: declare double @atan2(double, double) [[NUWRN:#[0-9]+]]
+// CHECK-NOERRNO: declare float @atan2f(float, float) [[NUWRN]]
+// CHECK-NOERRNO: declare x86_fp80 @atan2l(x86_fp80, x86_fp80) [[NUWRN]]
+// CHECK-NOERRNO: declare i32 @abs(i32) [[NUWRN]]
+// CHECK-NOERRNO: declare i64 @labs(i64) [[NUWRN]]
+// CHECK-NOERRNO: declare i64 @llabs(i64) [[NUWRN]]
+// CHECK-NOERRNO: declare double @copysign(double, double) [[NUWRN]]
+// CHECK-NOERRNO: declare float @copysignf(float, float) [[NUWRN]]
+// CHECK-NOERRNO: declare x86_fp80 @copysignl(x86_fp80, x86_fp80) [[NUWRN]]
+// CHECK-NOERRNO: declare double @fabs(double) [[NUWRN]]
+// CHECK-NOERRNO: declare float @fabsf(float) [[NUWRN]]
+// CHECK-NOERRNO: declare x86_fp80 @fabsl(x86_fp80) [[NUWRN]]
+// CHECK-NOERRNO: declare double @fmod(double, double) [[NUWRN]]
+// CHECK-NOERRNO: declare float @fmodf(float, float) [[NUWRN]]
+// CHECK-NOERRNO: declare x86_fp80 @fmodl(x86_fp80, x86_fp80) [[NUWRN]]
+// CHECK-NOERRNO: declare double @ldexp(double, i32) [[NUWRN]]
+// CHECK-NOERRNO: declare float @ldexpf(float, i32) [[NUWRN]]
+// CHECK-NOERRNO: declare x86_fp80 @ldexpl(x86_fp80, i32) [[NUWRN]]
+// CHECK-NOERRNO: declare double @nan(i8*) [[NUWRO:#[0-9]+]]
+// CHECK-NOERRNO: declare float @nanf(i8*) [[NUWRO]]
+// CHECK-NOERRNO: declare x86_fp80 @nanl(i8*) [[NUWRO]]
+// CHECK-NOERRNO: declare double @pow(double, double) [[NUWRN]]
+// CHECK-NOERRNO: declare float @powf(float, float) [[NUWRN]]
+// CHECK-NOERRNO: declare x86_fp80 @powl(x86_fp80, x86_fp80) [[NUWRN]]
+// CHECK-NOERRNO: declare double @acos(double) [[NUWRN]]
+// CHECK-NOERRNO: declare float @acosf(float) [[NUWRN]]
+// CHECK-NOERRNO: declare x86_fp80 @acosl(x86_fp80) [[NUWRN]]
+// CHECK-NOERRNO: declare double @acosh(double) [[NUWRN]]
+// CHECK-NOERRNO: declare float @acoshf(float) [[NUWRN]]
+// CHECK-NOERRNO: declare x86_fp80 @acoshl(x86_fp80) [[NUWRN]]
+// CHECK-NOERRNO: declare double @asin(double) [[NUWRN]]
+// CHECK-NOERRNO: declare float @asinf(float) [[NUWRN]]
+// CHECK-NOERRNO: declare x86_fp80 @asinl(x86_fp80) [[NUWRN]]
+// CHECK-NOERRNO: declare double @asinh(double) [[NUWRN]]
+// CHECK-NOERRNO: declare float @asinhf(float) [[NUWRN]]
+// CHECK-NOERRNO: declare x86_fp80 @asinhl(x86_fp80) [[NUWRN]]
+// CHECK-NOERRNO: declare double @atan(double) [[NUWRN]]
+// CHECK-NOERRNO: declare float @atanf(float) [[NUWRN]]
+// CHECK-NOERRNO: declare x86_fp80 @atanl(x86_fp80) [[NUWRN]]
+// CHECK-NOERRNO: declare double @atanh(double) [[NUWRN]]
+// CHECK-NOERRNO: declare float @atanhf(float) [[NUWRN]]
+// CHECK-NOERRNO: declare x86_fp80 @atanhl(x86_fp80) [[NUWRN]]
+// CHECK-NOERRNO: declare double @cbrt(double) [[NUWRN]]
+// CHECK-NOERRNO: declare float @cbrtf(float) [[NUWRN]]
+// CHECK-NOERRNO: declare x86_fp80 @cbrtl(x86_fp80) [[NUWRN]]
+// CHECK-NOERRNO: declare double @ceil(double) [[NUWRN]]
+// CHECK-NOERRNO: declare float @ceilf(float) [[NUWRN]]
+// CHECK-NOERRNO: declare x86_fp80 @ceill(x86_fp80) [[NUWRN]]
+// CHECK-NOERRNO: declare double @cos(double) [[NUWRN]]
+// CHECK-NOERRNO: declare float @cosf(float) [[NUWRN]]
+// CHECK-NOERRNO: declare x86_fp80 @cosl(x86_fp80) [[NUWRN]]
+// CHECK-NOERRNO: declare double @cosh(double) [[NUWRN]]
+// CHECK-NOERRNO: declare float @coshf(float) [[NUWRN]]
+// CHECK-NOERRNO: declare x86_fp80 @coshl(x86_fp80) [[NUWRN]]
+// CHECK-NOERRNO: declare double @erf(double) [[NUWRN]]
+// CHECK-NOERRNO: declare float @erff(float) [[NUWRN]]
+// CHECK-NOERRNO: declare x86_fp80 @erfl(x86_fp80) [[NUWRN]]
+// CHECK-NOERRNO: declare double @erfc(double) [[NUWRN]]
+// CHECK-NOERRNO: declare float @erfcf(float) [[NUWRN]]
+// CHECK-NOERRNO: declare x86_fp80 @erfcl(x86_fp80) [[NUWRN]]
+// CHECK-NOERRNO: declare double @exp(double) [[NUWRN]]
+// CHECK-NOERRNO: declare float @expf(float) [[NUWRN]]
+// CHECK-NOERRNO: declare x86_fp80 @expl(x86_fp80) [[NUWRN]]
+// CHECK-NOERRNO: declare double @exp2(double) [[NUWRN]]
+// CHECK-NOERRNO: declare float @exp2f(float) [[NUWRN]]
+// CHECK-NOERRNO: declare x86_fp80 @exp2l(x86_fp80) [[NUWRN]]
+// CHECK-NOERRNO: declare double @expm1(double) [[NUWRN]]
+// CHECK-NOERRNO: declare float @expm1f(float) [[NUWRN]]
+// CHECK-NOERRNO: declare x86_fp80 @expm1l(x86_fp80) [[NUWRN]]
+// CHECK-NOERRNO: declare double @fdim(double, double) [[NUWRN]]
+// CHECK-NOERRNO: declare float @fdimf(float, float) [[NUWRN]]
+// CHECK-NOERRNO: declare x86_fp80 @fdiml(x86_fp80, x86_fp80) [[NUWRN]]
+// CHECK-NOERRNO: declare double @floor(double) [[NUWRN]]
+// CHECK-NOERRNO: declare float @floorf(float) [[NUWRN]]
+// CHECK-NOERRNO: declare x86_fp80 @floorl(x86_fp80) [[NUWRN]]
+// CHECK-NOERRNO: declare double @fma(double, double, double) [[NUWRN]]
+// CHECK-NOERRNO: declare float @fmaf(float, float, float) [[NUWRN]]
+// CHECK-NOERRNO: declare x86_fp80 @fmal(x86_fp80, x86_fp80, x86_fp80) [[NUWRN]]
+// CHECK-NOERRNO: declare double @fmax(double, double) [[NUWRN]]
+// CHECK-NOERRNO: declare float @fmaxf(float, float) [[NUWRN]]
+// CHECK-NOERRNO: declare x86_fp80 @fmaxl(x86_fp80, x86_fp80) [[NUWRN]]
+// CHECK-NOERRNO: declare double @fmin(double, double) [[NUWRN]]
+// CHECK-NOERRNO: declare float @fminf(float, float) [[NUWRN]]
+// CHECK-NOERRNO: declare x86_fp80 @fminl(x86_fp80, x86_fp80) [[NUWRN]]
+// CHECK-NOERRNO: declare double @hypot(double, double) [[NUWRN]]
+// CHECK-NOERRNO: declare float @hypotf(float, float) [[NUWRN]]
+// CHECK-NOERRNO: declare x86_fp80 @hypotl(x86_fp80, x86_fp80) [[NUWRN]]
+// CHECK-NOERRNO: declare i32 @ilogb(double) [[NUWRN]]
+// CHECK-NOERRNO: declare i32 @ilogbf(float) [[NUWRN]]
+// CHECK-NOERRNO: declare i32 @ilogbl(x86_fp80) [[NUWRN]]
// CHECK-NOERRNO: declare double @lgamma(double) [[NONCONST:#[0-9]+]]
// CHECK-NOERRNO: declare float @lgammaf(float) [[NONCONST]]
// CHECK-NOERRNO: declare x86_fp80 @lgammal(x86_fp80) [[NONCONST]]
-// CHECK-NOERRNO: declare i64 @llrint(double) [[NUW]]
-// CHECK-NOERRNO: declare i64 @llrintf(float) [[NUW]]
-// CHECK-NOERRNO: declare i64 @llrintl(x86_fp80) [[NUW]]
-// CHECK-NOERRNO: declare i64 @llround(double) [[NUW]]
-// CHECK-NOERRNO: declare i64 @llroundf(float) [[NUW]]
-// CHECK-NOERRNO: declare i64 @llroundl(x86_fp80) [[NUW]]
-// CHECK-NOERRNO: declare double @log(double) [[NUW]]
-// CHECK-NOERRNO: declare float @logf(float) [[NUW]]
-// CHECK-NOERRNO: declare x86_fp80 @logl(x86_fp80) [[NUW]]
-// CHECK-NOERRNO: declare double @log10(double) [[NUW]]
-// CHECK-NOERRNO: declare float @log10f(float) [[NUW]]
-// CHECK-NOERRNO: declare x86_fp80 @log10l(x86_fp80) [[NUW]]
-// CHECK-NOERRNO: declare double @log1p(double) [[NUW]]
-// CHECK-NOERRNO: declare float @log1pf(float) [[NUW]]
-// CHECK-NOERRNO: declare x86_fp80 @log1pl(x86_fp80) [[NUW]]
-// CHECK-NOERRNO: declare double @log2(double) [[NUW]]
-// CHECK-NOERRNO: declare float @log2f(float) [[NUW]]
-// CHECK-NOERRNO: declare x86_fp80 @log2l(x86_fp80) [[NUW]]
-// CHECK-NOERRNO: declare double @logb(double) [[NUW]]
-// CHECK-NOERRNO: declare float @logbf(float) [[NUW]]
-// CHECK-NOERRNO: declare x86_fp80 @logbl(x86_fp80) [[NUW]]
-// CHECK-NOERRNO: declare i64 @lrint(double) [[NUW]]
-// CHECK-NOERRNO: declare i64 @lrintf(float) [[NUW]]
-// CHECK-NOERRNO: declare i64 @lrintl(x86_fp80) [[NUW]]
-// CHECK-NOERRNO: declare i64 @lround(double) [[NUW]]
-// CHECK-NOERRNO: declare i64 @lroundf(float) [[NUW]]
-// CHECK-NOERRNO: declare i64 @lroundl(x86_fp80) [[NUW]]
-// CHECK-NOERRNO: declare double @nearbyint(double) [[NUW]]
-// CHECK-NOERRNO: declare float @nearbyintf(float) [[NUW]]
-// CHECK-NOERRNO: declare x86_fp80 @nearbyintl(x86_fp80) [[NUW]]
-// CHECK-NOERRNO: declare double @nextafter(double, double) [[NUW]]
-// CHECK-NOERRNO: declare float @nextafterf(float, float) [[NUW]]
-// CHECK-NOERRNO: declare x86_fp80 @nextafterl(x86_fp80, x86_fp80) [[NUW]]
-// CHECK-NOERRNO: declare double @nexttoward(double, x86_fp80) [[NUW]]
-// CHECK-NOERRNO: declare float @nexttowardf(float, x86_fp80) [[NUW]]
-// CHECK-NOERRNO: declare x86_fp80 @nexttowardl(x86_fp80, x86_fp80) [[NUW]]
-// CHECK-NOERRNO: declare double @remainder(double, double) [[NUW]]
-// CHECK-NOERRNO: declare float @remainderf(float, float) [[NUW]]
-// CHECK-NOERRNO: declare x86_fp80 @remainderl(x86_fp80, x86_fp80) [[NUW]]
-// CHECK-NOERRNO: declare double @rint(double) [[NUW]]
-// CHECK-NOERRNO: declare float @rintf(float) [[NUW]]
-// CHECK-NOERRNO: declare x86_fp80 @rintl(x86_fp80) [[NUW]]
-// CHECK-NOERRNO: declare double @round(double) [[NUW]]
-// CHECK-NOERRNO: declare float @roundf(float) [[NUW]]
-// CHECK-NOERRNO: declare x86_fp80 @roundl(x86_fp80) [[NUW]]
-// CHECK-NOERRNO: declare double @scalbln(double, i64) [[NUW]]
-// CHECK-NOERRNO: declare float @scalblnf(float, i64) [[NUW]]
-// CHECK-NOERRNO: declare x86_fp80 @scalblnl(x86_fp80, i64) [[NUW]]
-// CHECK-NOERRNO: declare double @scalbn(double, i32) [[NUW]]
-// CHECK-NOERRNO: declare float @scalbnf(float, i32) [[NUW]]
-// CHECK-NOERRNO: declare x86_fp80 @scalbnl(x86_fp80, i32) [[NUW]]
-// CHECK-NOERRNO: declare double @sin(double) [[NUW]]
-// CHECK-NOERRNO: declare float @sinf(float) [[NUW]]
-// CHECK-NOERRNO: declare x86_fp80 @sinl(x86_fp80) [[NUW]]
-// CHECK-NOERRNO: declare double @sinh(double) [[NUW]]
-// CHECK-NOERRNO: declare float @sinhf(float) [[NUW]]
-// CHECK-NOERRNO: declare x86_fp80 @sinhl(x86_fp80) [[NUW]]
-// CHECK-NOERRNO: declare double @sqrt(double) [[NUW]]
-// CHECK-NOERRNO: declare float @sqrtf(float) [[NUW]]
-// CHECK-NOERRNO: declare x86_fp80 @sqrtl(x86_fp80) [[NUW]]
-// CHECK-NOERRNO: declare double @tan(double) [[NUW]]
-// CHECK-NOERRNO: declare float @tanf(float) [[NUW]]
-// CHECK-NOERRNO: declare x86_fp80 @tanl(x86_fp80) [[NUW]]
-// CHECK-NOERRNO: declare double @tanh(double) [[NUW]]
-// CHECK-NOERRNO: declare float @tanhf(float) [[NUW]]
-// CHECK-NOERRNO: declare x86_fp80 @tanhl(x86_fp80) [[NUW]]
-// CHECK-NOERRNO: declare double @tgamma(double) [[NUW]]
-// CHECK-NOERRNO: declare float @tgammaf(float) [[NUW]]
-// CHECK-NOERRNO: declare x86_fp80 @tgammal(x86_fp80) [[NUW]]
-// CHECK-NOERRNO: declare double @trunc(double) [[NUW]]
-// CHECK-NOERRNO: declare float @truncf(float) [[NUW]]
-// CHECK-NOERRNO: declare x86_fp80 @truncl(x86_fp80) [[NUW]]
-// CHECK-NOERRNO: declare double @cabs(double, double) [[NUW]]
-// CHECK-NOERRNO: declare float @cabsf(<2 x float>) [[NUW]]
-// CHECK-NOERRNO: declare { double, double } @cacos(double, double) [[NUW]]
-// CHECK-NOERRNO: declare <2 x float> @cacosf(<2 x float>) [[NUW]]
-// CHECK-NOERRNO: declare { double, double } @cacosh(double, double) [[NUW]]
-// CHECK-NOERRNO: declare <2 x float> @cacoshf(<2 x float>) [[NUW]]
-// CHECK-NOERRNO: declare double @carg(double, double) [[NUW]]
-// CHECK-NOERRNO: declare float @cargf(<2 x float>) [[NUW]]
-// CHECK-NOERRNO: declare { double, double } @casin(double, double) [[NUW]]
-// CHECK-NOERRNO: declare <2 x float> @casinf(<2 x float>) [[NUW]]
-// CHECK-NOERRNO: declare { double, double } @casinh(double, double) [[NUW]]
-// CHECK-NOERRNO: declare <2 x float> @casinhf(<2 x float>) [[NUW]]
-// CHECK-NOERRNO: declare { double, double } @catan(double, double) [[NUW]]
-// CHECK-NOERRNO: declare <2 x float> @catanf(<2 x float>) [[NUW]]
-// CHECK-NOERRNO: declare { double, double } @catanh(double, double) [[NUW]]
-// CHECK-NOERRNO: declare <2 x float> @catanhf(<2 x float>) [[NUW]]
-// CHECK-NOERRNO: declare { double, double } @ccos(double, double) [[NUW]]
-// CHECK-NOERRNO: declare <2 x float> @ccosf(<2 x float>) [[NUW]]
-// CHECK-NOERRNO: declare { double, double } @ccosh(double, double) [[NUW]]
-// CHECK-NOERRNO: declare <2 x float> @ccoshf(<2 x float>) [[NUW]]
-// CHECK-NOERRNO: declare { double, double } @cexp(double, double) [[NUW]]
-// CHECK-NOERRNO: declare <2 x float> @cexpf(<2 x float>) [[NUW]]
-// CHECK-NOERRNO: declare double @cimag(double, double) [[NUW]]
-// CHECK-NOERRNO: declare float @cimagf(<2 x float>) [[NUW]]
-// CHECK-NOERRNO: declare { double, double } @conj(double, double) [[NUW]]
-// CHECK-NOERRNO: declare <2 x float> @conjf(<2 x float>) [[NUW]]
-// CHECK-NOERRNO: declare { double, double } @clog(double, double) [[NUW]]
-// CHECK-NOERRNO: declare <2 x float> @clogf(<2 x float>) [[NUW]]
-// CHECK-NOERRNO: declare { double, double } @cproj(double, double) [[NUW]]
-// CHECK-NOERRNO: declare <2 x float> @cprojf(<2 x float>) [[NUW]]
-// CHECK-NOERRNO: declare { double, double } @cpow(double, double, double, double) [[NUW]]
-// CHECK-NOERRNO: declare <2 x float> @cpowf(<2 x float>, <2 x float>) [[NUW]]
-// CHECK-NOERRNO: declare double @creal(double, double) [[NUW]]
-// CHECK-NOERRNO: declare float @crealf(<2 x float>) [[NUW]]
-// CHECK-NOERRNO: declare { double, double } @csin(double, double) [[NUW]]
-// CHECK-NOERRNO: declare <2 x float> @csinf(<2 x float>) [[NUW]]
-// CHECK-NOERRNO: declare { double, double } @csinh(double, double) [[NUW]]
-// CHECK-NOERRNO: declare <2 x float> @csinhf(<2 x float>) [[NUW]]
-// CHECK-NOERRNO: declare { double, double } @csqrt(double, double) [[NUW]]
-// CHECK-NOERRNO: declare <2 x float> @csqrtf(<2 x float>) [[NUW]]
-// CHECK-NOERRNO: declare { double, double } @ctan(double, double) [[NUW]]
-// CHECK-NOERRNO: declare <2 x float> @ctanf(<2 x float>) [[NUW]]
-// CHECK-NOERRNO: declare { double, double } @ctanh(double, double) [[NUW]]
-// CHECK-NOERRNO: declare <2 x float> @ctanhf(<2 x float>) [[NUW]]
-// CHECK-NOERRNO: declare double @__sinpi(double) [[NUW]]
-// CHECK-NOERRNO: declare float @__sinpif(float) [[NUW]]
-// CHECK-NOERRNO: declare double @__cospi(double) [[NUW]]
-// CHECK-NOERRNO: declare float @__cospif(float) [[NUW]]
-// CHECK-NOERRNO: declare double @__tanpi(double) [[NUW]]
-// CHECK-NOERRNO: declare float @__tanpif(float) [[NUW]]
-// CHECK-NOERRNO: declare double @__exp10(double) [[NUW]]
-// CHECK-NOERRNO: declare float @__exp10f(float) [[NUW]]
+// CHECK-NOERRNO: declare i64 @llrint(double) [[NUWRN]]
+// CHECK-NOERRNO: declare i64 @llrintf(float) [[NUWRN]]
+// CHECK-NOERRNO: declare i64 @llrintl(x86_fp80) [[NUWRN]]
+// CHECK-NOERRNO: declare i64 @llround(double) [[NUWRN]]
+// CHECK-NOERRNO: declare i64 @llroundf(float) [[NUWRN]]
+// CHECK-NOERRNO: declare i64 @llroundl(x86_fp80) [[NUWRN]]
+// CHECK-NOERRNO: declare double @log(double) [[NUWRN]]
+// CHECK-NOERRNO: declare float @logf(float) [[NUWRN]]
+// CHECK-NOERRNO: declare x86_fp80 @logl(x86_fp80) [[NUWRN]]
+// CHECK-NOERRNO: declare double @log10(double) [[NUWRN]]
+// CHECK-NOERRNO: declare float @log10f(float) [[NUWRN]]
+// CHECK-NOERRNO: declare x86_fp80 @log10l(x86_fp80) [[NUWRN]]
+// CHECK-NOERRNO: declare double @log1p(double) [[NUWRN]]
+// CHECK-NOERRNO: declare float @log1pf(float) [[NUWRN]]
+// CHECK-NOERRNO: declare x86_fp80 @log1pl(x86_fp80) [[NUWRN]]
+// CHECK-NOERRNO: declare double @log2(double) [[NUWRN]]
+// CHECK-NOERRNO: declare float @log2f(float) [[NUWRN]]
+// CHECK-NOERRNO: declare x86_fp80 @log2l(x86_fp80) [[NUWRN]]
+// CHECK-NOERRNO: declare double @logb(double) [[NUWRN]]
+// CHECK-NOERRNO: declare float @logbf(float) [[NUWRN]]
+// CHECK-NOERRNO: declare x86_fp80 @logbl(x86_fp80) [[NUWRN]]
+// CHECK-NOERRNO: declare i64 @lrint(double) [[NUWRN]]
+// CHECK-NOERRNO: declare i64 @lrintf(float) [[NUWRN]]
+// CHECK-NOERRNO: declare i64 @lrintl(x86_fp80) [[NUWRN]]
+// CHECK-NOERRNO: declare i64 @lround(double) [[NUWRN]]
+// CHECK-NOERRNO: declare i64 @lroundf(float) [[NUWRN]]
+// CHECK-NOERRNO: declare i64 @lroundl(x86_fp80) [[NUWRN]]
+// CHECK-NOERRNO: declare double @nearbyint(double) [[NUWRN]]
+// CHECK-NOERRNO: declare float @nearbyintf(float) [[NUWRN]]
+// CHECK-NOERRNO: declare x86_fp80 @nearbyintl(x86_fp80) [[NUWRN]]
+// CHECK-NOERRNO: declare double @nextafter(double, double) [[NUWRN]]
+// CHECK-NOERRNO: declare float @nextafterf(float, float) [[NUWRN]]
+// CHECK-NOERRNO: declare x86_fp80 @nextafterl(x86_fp80, x86_fp80) [[NUWRN]]
+// CHECK-NOERRNO: declare double @nexttoward(double, x86_fp80) [[NUWRN]]
+// CHECK-NOERRNO: declare float @nexttowardf(float, x86_fp80) [[NUWRN]]
+// CHECK-NOERRNO: declare x86_fp80 @nexttowardl(x86_fp80, x86_fp80) [[NUWRN]]
+// CHECK-NOERRNO: declare double @remainder(double, double) [[NUWRN]]
+// CHECK-NOERRNO: declare float @remainderf(float, float) [[NUWRN]]
+// CHECK-NOERRNO: declare x86_fp80 @remainderl(x86_fp80, x86_fp80) [[NUWRN]]
+// CHECK-NOERRNO: declare double @rint(double) [[NUWRN]]
+// CHECK-NOERRNO: declare float @rintf(float) [[NUWRN]]
+// CHECK-NOERRNO: declare x86_fp80 @rintl(x86_fp80) [[NUWRN]]
+// CHECK-NOERRNO: declare double @round(double) [[NUWRN]]
+// CHECK-NOERRNO: declare float @roundf(float) [[NUWRN]]
+// CHECK-NOERRNO: declare x86_fp80 @roundl(x86_fp80) [[NUWRN]]
+// CHECK-NOERRNO: declare double @scalbln(double, i64) [[NUWRN]]
+// CHECK-NOERRNO: declare float @scalblnf(float, i64) [[NUWRN]]
+// CHECK-NOERRNO: declare x86_fp80 @scalblnl(x86_fp80, i64) [[NUWRN]]
+// CHECK-NOERRNO: declare double @scalbn(double, i32) [[NUWRN]]
+// CHECK-NOERRNO: declare float @scalbnf(float, i32) [[NUWRN]]
+// CHECK-NOERRNO: declare x86_fp80 @scalbnl(x86_fp80, i32) [[NUWRN]]
+// CHECK-NOERRNO: declare double @sin(double) [[NUWRN]]
+// CHECK-NOERRNO: declare float @sinf(float) [[NUWRN]]
+// CHECK-NOERRNO: declare x86_fp80 @sinl(x86_fp80) [[NUWRN]]
+// CHECK-NOERRNO: declare double @sinh(double) [[NUWRN]]
+// CHECK-NOERRNO: declare float @sinhf(float) [[NUWRN]]
+// CHECK-NOERRNO: declare x86_fp80 @sinhl(x86_fp80) [[NUWRN]]
+// CHECK-NOERRNO: declare double @sqrt(double) [[NUWRN]]
+// CHECK-NOERRNO: declare float @sqrtf(float) [[NUWRN]]
+// CHECK-NOERRNO: declare x86_fp80 @sqrtl(x86_fp80) [[NUWRN]]
+// CHECK-NOERRNO: declare double @tan(double) [[NUWRN]]
+// CHECK-NOERRNO: declare float @tanf(float) [[NUWRN]]
+// CHECK-NOERRNO: declare x86_fp80 @tanl(x86_fp80) [[NUWRN]]
+// CHECK-NOERRNO: declare double @tanh(double) [[NUWRN]]
+// CHECK-NOERRNO: declare float @tanhf(float) [[NUWRN]]
+// CHECK-NOERRNO: declare x86_fp80 @tanhl(x86_fp80) [[NUWRN]]
+// CHECK-NOERRNO: declare double @tgamma(double) [[NUWRN]]
+// CHECK-NOERRNO: declare float @tgammaf(float) [[NUWRN]]
+// CHECK-NOERRNO: declare x86_fp80 @tgammal(x86_fp80) [[NUWRN]]
+// CHECK-NOERRNO: declare double @trunc(double) [[NUWRN]]
+// CHECK-NOERRNO: declare float @truncf(float) [[NUWRN]]
+// CHECK-NOERRNO: declare x86_fp80 @truncl(x86_fp80) [[NUWRN]]
+// CHECK-NOERRNO: declare double @cabs(double, double) [[NUWRN]]
+// CHECK-NOERRNO: declare float @cabsf(<2 x float>) [[NUWRN]]
+// CHECK-NOERRNO: declare { double, double } @cacos(double, double) [[NUWRN]]
+// CHECK-NOERRNO: declare <2 x float> @cacosf(<2 x float>) [[NUWRN]]
+// CHECK-NOERRNO: declare { double, double } @cacosh(double, double) [[NUWRN]]
+// CHECK-NOERRNO: declare <2 x float> @cacoshf(<2 x float>) [[NUWRN]]
+// CHECK-NOERRNO: declare double @carg(double, double) [[NUWRN]]
+// CHECK-NOERRNO: declare float @cargf(<2 x float>) [[NUWRN]]
+// CHECK-NOERRNO: declare { double, double } @casin(double, double) [[NUWRN]]
+// CHECK-NOERRNO: declare <2 x float> @casinf(<2 x float>) [[NUWRN]]
+// CHECK-NOERRNO: declare { double, double } @casinh(double, double) [[NUWRN]]
+// CHECK-NOERRNO: declare <2 x float> @casinhf(<2 x float>) [[NUWRN]]
+// CHECK-NOERRNO: declare { double, double } @catan(double, double) [[NUWRN]]
+// CHECK-NOERRNO: declare <2 x float> @catanf(<2 x float>) [[NUWRN]]
+// CHECK-NOERRNO: declare { double, double } @catanh(double, double) [[NUWRN]]
+// CHECK-NOERRNO: declare <2 x float> @catanhf(<2 x float>) [[NUWRN]]
+// CHECK-NOERRNO: declare { double, double } @ccos(double, double) [[NUWRN]]
+// CHECK-NOERRNO: declare <2 x float> @ccosf(<2 x float>) [[NUWRN]]
+// CHECK-NOERRNO: declare { double, double } @ccosh(double, double) [[NUWRN]]
+// CHECK-NOERRNO: declare <2 x float> @ccoshf(<2 x float>) [[NUWRN]]
+// CHECK-NOERRNO: declare { double, double } @cexp(double, double) [[NUWRN]]
+// CHECK-NOERRNO: declare <2 x float> @cexpf(<2 x float>) [[NUWRN]]
+// CHECK-NOERRNO: declare double @cimag(double, double) [[NUWRN]]
+// CHECK-NOERRNO: declare float @cimagf(<2 x float>) [[NUWRN]]
+// CHECK-NOERRNO: declare { double, double } @conj(double, double) [[NUWRN]]
+// CHECK-NOERRNO: declare <2 x float> @conjf(<2 x float>) [[NUWRN]]
+// CHECK-NOERRNO: declare { double, double } @clog(double, double) [[NUWRN]]
+// CHECK-NOERRNO: declare <2 x float> @clogf(<2 x float>) [[NUWRN]]
+// CHECK-NOERRNO: declare { double, double } @cproj(double, double) [[NUWRN]]
+// CHECK-NOERRNO: declare <2 x float> @cprojf(<2 x float>) [[NUWRN]]
+// CHECK-NOERRNO: declare { double, double } @cpow(double, double, double, double) [[NUWRN]]
+// CHECK-NOERRNO: declare <2 x float> @cpowf(<2 x float>, <2 x float>) [[NUWRN]]
+// CHECK-NOERRNO: declare double @creal(double, double) [[NUWRN]]
+// CHECK-NOERRNO: declare float @crealf(<2 x float>) [[NUWRN]]
+// CHECK-NOERRNO: declare { double, double } @csin(double, double) [[NUWRN]]
+// CHECK-NOERRNO: declare <2 x float> @csinf(<2 x float>) [[NUWRN]]
+// CHECK-NOERRNO: declare { double, double } @csinh(double, double) [[NUWRN]]
+// CHECK-NOERRNO: declare <2 x float> @csinhf(<2 x float>) [[NUWRN]]
+// CHECK-NOERRNO: declare { double, double } @csqrt(double, double) [[NUWRN]]
+// CHECK-NOERRNO: declare <2 x float> @csqrtf(<2 x float>) [[NUWRN]]
+// CHECK-NOERRNO: declare { double, double } @ctan(double, double) [[NUWRN]]
+// CHECK-NOERRNO: declare <2 x float> @ctanf(<2 x float>) [[NUWRN]]
+// CHECK-NOERRNO: declare { double, double } @ctanh(double, double) [[NUWRN]]
+// CHECK-NOERRNO: declare <2 x float> @ctanhf(<2 x float>) [[NUWRN]]
+// CHECK-NOERRNO: declare double @__sinpi(double) [[NUWRN]]
+// CHECK-NOERRNO: declare float @__sinpif(float) [[NUWRN]]
+// CHECK-NOERRNO: declare double @__cospi(double) [[NUWRN]]
+// CHECK-NOERRNO: declare float @__cospif(float) [[NUWRN]]
+// CHECK-NOERRNO: declare double @__tanpi(double) [[NUWRN]]
+// CHECK-NOERRNO: declare float @__tanpif(float) [[NUWRN]]
+// CHECK-NOERRNO: declare double @__exp10(double) [[NUWRN]]
+// CHECK-NOERRNO: declare float @__exp10f(float) [[NUWRN]]
-// CHECK-ERRNO: declare i32 @abs(i32) [[NUW:#[0-9]+]]
-// CHECK-ERRNO: declare i64 @labs(i64) [[NUW]]
-// CHECK-ERRNO: declare i64 @llabs(i64) [[NUW]]
-// CHECK-ERRNO: declare double @copysign(double, double) [[NUW]]
-// CHECK-ERRNO: declare float @copysignf(float, float) [[NUW]]
-// CHECK-ERRNO: declare x86_fp80 @copysignl(x86_fp80, x86_fp80) [[NUW]]
-// CHECK-ERRNO: declare double @fabs(double) [[NUW]]
-// CHECK-ERRNO: declare float @fabsf(float) [[NUW]]
-// CHECK-ERRNO: declare x86_fp80 @fabsl(x86_fp80) [[NUW]]
-// CHECK-ERRNO: declare double @nan(i8*) [[NUW]]
-// CHECK-ERRNO: declare float @nanf(i8*) [[NUW]]
-// CHECK-ERRNO: declare x86_fp80 @nanl(i8*) [[NUW]]
-// CHECK-ERRNO: declare double @ceil(double) [[NUW]]
-// CHECK-ERRNO: declare float @ceilf(float) [[NUW]]
-// CHECK-ERRNO: declare x86_fp80 @ceill(x86_fp80) [[NUW]]
-// CHECK-ERRNO: declare double @floor(double) [[NUW]]
-// CHECK-ERRNO: declare float @floorf(float) [[NUW]]
-// CHECK-ERRNO: declare x86_fp80 @floorl(x86_fp80) [[NUW]]
-// CHECK-ERRNO: declare double @fmax(double, double) [[NUW]]
-// CHECK-ERRNO: declare float @fmaxf(float, float) [[NUW]]
-// CHECK-ERRNO: declare x86_fp80 @fmaxl(x86_fp80, x86_fp80) [[NUW]]
-// CHECK-ERRNO: declare double @fmin(double, double) [[NUW]]
-// CHECK-ERRNO: declare float @fminf(float, float) [[NUW]]
-// CHECK-ERRNO: declare x86_fp80 @fminl(x86_fp80, x86_fp80) [[NUW]]
+// CHECK-ERRNO: declare i32 @abs(i32) [[NUWRN:#[0-9]+]]
+// CHECK-ERRNO: declare i64 @labs(i64) [[NUWRN]]
+// CHECK-ERRNO: declare i64 @llabs(i64) [[NUWRN]]
+// CHECK-ERRNO: declare double @copysign(double, double) [[NUWRN]]
+// CHECK-ERRNO: declare float @copysignf(float, float) [[NUWRN]]
+// CHECK-ERRNO: declare x86_fp80 @copysignl(x86_fp80, x86_fp80) [[NUWRN]]
+// CHECK-ERRNO: declare double @fabs(double) [[NUWRN]]
+// CHECK-ERRNO: declare float @fabsf(float) [[NUWRN]]
+// CHECK-ERRNO: declare x86_fp80 @fabsl(x86_fp80) [[NUWRN]]
+// CHECK-ERRNO: declare double @nan(i8*) [[NUWRO:#[0-9]+]]
+// CHECK-ERRNO: declare float @nanf(i8*) [[NUWRO]]
+// CHECK-ERRNO: declare x86_fp80 @nanl(i8*) [[NUWRO]]
+// CHECK-ERRNO: declare double @ceil(double) [[NUWRN]]
+// CHECK-ERRNO: declare float @ceilf(float) [[NUWRN]]
+// CHECK-ERRNO: declare x86_fp80 @ceill(x86_fp80) [[NUWRN]]
+// CHECK-ERRNO: declare double @floor(double) [[NUWRN]]
+// CHECK-ERRNO: declare float @floorf(float) [[NUWRN]]
+// CHECK-ERRNO: declare x86_fp80 @floorl(x86_fp80) [[NUWRN]]
+// CHECK-ERRNO: declare double @fmax(double, double) [[NUWRN]]
+// CHECK-ERRNO: declare float @fmaxf(float, float) [[NUWRN]]
+// CHECK-ERRNO: declare x86_fp80 @fmaxl(x86_fp80, x86_fp80) [[NUWRN]]
+// CHECK-ERRNO: declare double @fmin(double, double) [[NUWRN]]
+// CHECK-ERRNO: declare float @fminf(float, float) [[NUWRN]]
+// CHECK-ERRNO: declare x86_fp80 @fminl(x86_fp80, x86_fp80) [[NUWRN]]
// CHECK-ERRNO: declare double @lgamma(double) [[NONCONST:#[0-9]+]]
// CHECK-ERRNO: declare float @lgammaf(float) [[NONCONST]]
// CHECK-ERRNO: declare x86_fp80 @lgammal(x86_fp80) [[NONCONST]]
-// CHECK-ERRNO: declare double @nearbyint(double) [[NUW]]
-// CHECK-ERRNO: declare float @nearbyintf(float) [[NUW]]
-// CHECK-ERRNO: declare x86_fp80 @nearbyintl(x86_fp80) [[NUW]]
-// CHECK-ERRNO: declare double @rint(double) [[NUW]]
-// CHECK-ERRNO: declare float @rintf(float) [[NUW]]
-// CHECK-ERRNO: declare x86_fp80 @rintl(x86_fp80) [[NUW]]
-// CHECK-ERRNO: declare double @round(double) [[NUW]]
-// CHECK-ERRNO: declare float @roundf(float) [[NUW]]
-// CHECK-ERRNO: declare x86_fp80 @roundl(x86_fp80) [[NUW]]
-// CHECK-ERRNO: declare double @trunc(double) [[NUW]]
-// CHECK-ERRNO: declare float @truncf(float) [[NUW]]
-// CHECK-ERRNO: declare x86_fp80 @truncl(x86_fp80) [[NUW]]
-// CHECK-ERRNO: declare double @cabs(double, double) [[NUW]]
-// CHECK-ERRNO: declare float @cabsf(<2 x float>) [[NUW]]
-// CHECK-ERRNO: declare { double, double } @cacos(double, double) [[NUW]]
-// CHECK-ERRNO: declare <2 x float> @cacosf(<2 x float>) [[NUW]]
-// CHECK-ERRNO: declare { double, double } @cacosh(double, double) [[NUW]]
-// CHECK-ERRNO: declare <2 x float> @cacoshf(<2 x float>) [[NUW]]
-// CHECK-ERRNO: declare double @carg(double, double) [[NUW]]
-// CHECK-ERRNO: declare float @cargf(<2 x float>) [[NUW]]
-// CHECK-ERRNO: declare { double, double } @casin(double, double) [[NUW]]
-// CHECK-ERRNO: declare <2 x float> @casinf(<2 x float>) [[NUW]]
-// CHECK-ERRNO: declare { double, double } @casinh(double, double) [[NUW]]
-// CHECK-ERRNO: declare <2 x float> @casinhf(<2 x float>) [[NUW]]
-// CHECK-ERRNO: declare { double, double } @catan(double, double) [[NUW]]
-// CHECK-ERRNO: declare <2 x float> @catanf(<2 x float>) [[NUW]]
-// CHECK-ERRNO: declare { double, double } @catanh(double, double) [[NUW]]
-// CHECK-ERRNO: declare <2 x float> @catanhf(<2 x float>) [[NUW]]
-// CHECK-ERRNO: declare { double, double } @ccos(double, double) [[NUW]]
-// CHECK-ERRNO: declare <2 x float> @ccosf(<2 x float>) [[NUW]]
-// CHECK-ERRNO: declare { double, double } @ccosh(double, double) [[NUW]]
-// CHECK-ERRNO: declare <2 x float> @ccoshf(<2 x float>) [[NUW]]
-// CHECK-ERRNO: declare { double, double } @cexp(double, double) [[NUW]]
-// CHECK-ERRNO: declare <2 x float> @cexpf(<2 x float>) [[NUW]]
-// CHECK-ERRNO: declare double @cimag(double, double) [[NUW]]
-// CHECK-ERRNO: declare float @cimagf(<2 x float>) [[NUW]]
-// CHECK-ERRNO: declare { double, double } @conj(double, double) [[NUW]]
-// CHECK-ERRNO: declare <2 x float> @conjf(<2 x float>) [[NUW]]
-// CHECK-ERRNO: declare { double, double } @clog(double, double) [[NUW]]
-// CHECK-ERRNO: declare <2 x float> @clogf(<2 x float>) [[NUW]]
-// CHECK-ERRNO: declare { double, double } @cproj(double, double) [[NUW]]
-// CHECK-ERRNO: declare <2 x float> @cprojf(<2 x float>) [[NUW]]
-// CHECK-ERRNO: declare { double, double } @cpow(double, double, double, double) [[NUW]]
-// CHECK-ERRNO: declare <2 x float> @cpowf(<2 x float>, <2 x float>) [[NUW]]
-// CHECK-ERRNO: declare double @creal(double, double) [[NUW]]
-// CHECK-ERRNO: declare float @crealf(<2 x float>) [[NUW]]
-// CHECK-ERRNO: declare { double, double } @csin(double, double) [[NUW]]
-// CHECK-ERRNO: declare <2 x float> @csinf(<2 x float>) [[NUW]]
-// CHECK-ERRNO: declare { double, double } @csinh(double, double) [[NUW]]
-// CHECK-ERRNO: declare <2 x float> @csinhf(<2 x float>) [[NUW]]
-// CHECK-ERRNO: declare { double, double } @csqrt(double, double) [[NUW]]
-// CHECK-ERRNO: declare <2 x float> @csqrtf(<2 x float>) [[NUW]]
-// CHECK-ERRNO: declare { double, double } @ctan(double, double) [[NUW]]
-// CHECK-ERRNO: declare <2 x float> @ctanf(<2 x float>) [[NUW]]
-// CHECK-ERRNO: declare { double, double } @ctanh(double, double) [[NUW]]
-// CHECK-ERRNO: declare <2 x float> @ctanhf(<2 x float>) [[NUW]]
+// CHECK-ERRNO: declare double @nearbyint(double) [[NUWRN]]
+// CHECK-ERRNO: declare float @nearbyintf(float) [[NUWRN]]
+// CHECK-ERRNO: declare x86_fp80 @nearbyintl(x86_fp80) [[NUWRN]]
+// CHECK-ERRNO: declare double @rint(double) [[NUWRN]]
+// CHECK-ERRNO: declare float @rintf(float) [[NUWRN]]
+// CHECK-ERRNO: declare x86_fp80 @rintl(x86_fp80) [[NUWRN]]
+// CHECK-ERRNO: declare double @round(double) [[NUWRN]]
+// CHECK-ERRNO: declare float @roundf(float) [[NUWRN]]
+// CHECK-ERRNO: declare x86_fp80 @roundl(x86_fp80) [[NUWRN]]
+// CHECK-ERRNO: declare double @trunc(double) [[NUWRN]]
+// CHECK-ERRNO: declare float @truncf(float) [[NUWRN]]
+// CHECK-ERRNO: declare x86_fp80 @truncl(x86_fp80) [[NUWRN]]
+// CHECK-ERRNO: declare double @cabs(double, double) [[NONCONST]]
+// CHECK-ERRNO: declare float @cabsf(<2 x float>) [[NONCONST]]
+// CHECK-ERRNO: declare { double, double } @cacos(double, double) [[NONCONST]]
+// CHECK-ERRNO: declare <2 x float> @cacosf(<2 x float>) [[NONCONST]]
+// CHECK-ERRNO: declare { double, double } @cacosh(double, double) [[NONCONST]]
+// CHECK-ERRNO: declare <2 x float> @cacoshf(<2 x float>) [[NONCONST]]
+// CHECK-ERRNO: declare double @carg(double, double) [[NONCONST]]
+// CHECK-ERRNO: declare float @cargf(<2 x float>) [[NONCONST]]
+// CHECK-ERRNO: declare { double, double } @casin(double, double) [[NONCONST]]
+// CHECK-ERRNO: declare <2 x float> @casinf(<2 x float>) [[NONCONST]]
+// CHECK-ERRNO: declare { double, double } @casinh(double, double) [[NONCONST]]
+// CHECK-ERRNO: declare <2 x float> @casinhf(<2 x float>) [[NONCONST]]
+// CHECK-ERRNO: declare { double, double } @catan(double, double) [[NONCONST]]
+// CHECK-ERRNO: declare <2 x float> @catanf(<2 x float>) [[NONCONST]]
+// CHECK-ERRNO: declare { double, double } @catanh(double, double) [[NONCONST]]
+// CHECK-ERRNO: declare <2 x float> @catanhf(<2 x float>) [[NONCONST]]
+// CHECK-ERRNO: declare { double, double } @ccos(double, double) [[NONCONST]]
+// CHECK-ERRNO: declare <2 x float> @ccosf(<2 x float>) [[NONCONST]]
+// CHECK-ERRNO: declare { double, double } @ccosh(double, double) [[NONCONST]]
+// CHECK-ERRNO: declare <2 x float> @ccoshf(<2 x float>) [[NONCONST]]
+// CHECK-ERRNO: declare { double, double } @cexp(double, double) [[NONCONST]]
+// CHECK-ERRNO: declare <2 x float> @cexpf(<2 x float>) [[NONCONST]]
+// CHECK-ERRNO: declare double @cimag(double, double) [[NUWRN]]
+// CHECK-ERRNO: declare float @cimagf(<2 x float>) [[NUWRN]]
+// CHECK-ERRNO: declare { double, double } @conj(double, double) [[NUWRN]]
+// CHECK-ERRNO: declare <2 x float> @conjf(<2 x float>) [[NUWRN]]
+// CHECK-ERRNO: declare { double, double } @clog(double, double) [[NONCONST]]
+// CHECK-ERRNO: declare <2 x float> @clogf(<2 x float>) [[NONCONST]]
+// CHECK-ERRNO: declare { double, double } @cproj(double, double) [[NUWRN]]
+// CHECK-ERRNO: declare <2 x float> @cprojf(<2 x float>) [[NUWRN]]
+// CHECK-ERRNO: declare { double, double } @cpow(double, double, double, double) [[NONCONST]]
+// CHECK-ERRNO: declare <2 x float> @cpowf(<2 x float>, <2 x float>) [[NONCONST]]
+// CHECK-ERRNO: declare double @creal(double, double) [[NUWRN]]
+// CHECK-ERRNO: declare float @crealf(<2 x float>) [[NUWRN]]
+// CHECK-ERRNO: declare { double, double } @csin(double, double) [[NONCONST]]
+// CHECK-ERRNO: declare <2 x float> @csinf(<2 x float>) [[NONCONST]]
+// CHECK-ERRNO: declare { double, double } @csinh(double, double) [[NONCONST]]
+// CHECK-ERRNO: declare <2 x float> @csinhf(<2 x float>) [[NONCONST]]
+// CHECK-ERRNO: declare { double, double } @csqrt(double, double) [[NONCONST]]
+// CHECK-ERRNO: declare <2 x float> @csqrtf(<2 x float>) [[NONCONST]]
+// CHECK-ERRNO: declare { double, double } @ctan(double, double) [[NONCONST]]
+// CHECK-ERRNO: declare <2 x float> @ctanf(<2 x float>) [[NONCONST]]
+// CHECK-ERRNO: declare { double, double } @ctanh(double, double) [[NONCONST]]
+// CHECK-ERRNO: declare <2 x float> @ctanhf(<2 x float>) [[NONCONST]]
-// CHECK-NOERRNO: attributes [[NUW]] = { nounwind readnone{{.*}} }
-// CHECK-NOERRNO: attributes [[NONCONST]] = {
-// CHECK-NOERRNO-NOT: readnone
-// CHECK-NOERRNO-SAME: nounwind{{.*}} }
+// CHECK-NOERRNO: attributes [[NUWRN]] = { nounwind readnone{{.*}} }
+// CHECK-NOERRNO: attributes [[NUWRO]] = { nounwind readonly{{.*}} }
-// CHECK-ERRNO: attributes [[NONCONST]] = {
-// CHECK-ERRNO-NOT: readnone
-// CHECK-ERRNO-SAME: nounwind{{.*}} }
-// CHECK-ERRNO: attributes [[NUW]] = { nounwind readnone{{.*}} }
+// CHECK-ERRNO: attributes [[NUWRN]] = { nounwind readnone{{.*}} }
+// CHECK-ERRNO: attributes [[NUWRO]] = { nounwind readonly{{.*}} }
diff --git a/test/CodeGen/libcalls.c b/test/CodeGen/libcalls.c
index 3a8207b2bebc..1b314f777b4c 100644
--- a/test/CodeGen/libcalls.c
+++ b/test/CodeGen/libcalls.c
@@ -6,29 +6,28 @@
// CHECK-NO-LABEL: define void @test_sqrt
// CHECK-FAST-LABEL: define void @test_sqrt
void test_sqrt(float a0, double a1, long double a2) {
- // Following llvm-gcc's lead, we never emit these as intrinsics;
- // no-math-errno isn't good enough. We could probably use intrinsics
- // with appropriate guards if it proves worthwhile.
-
// CHECK-YES: call float @sqrtf
- // CHECK-NO: call float @sqrtf
+ // CHECK-NO: call float @llvm.sqrt.f32(float
+ // CHECK-FAST: call float @llvm.sqrt.f32(float
float l0 = sqrtf(a0);
// CHECK-YES: call double @sqrt
- // CHECK-NO: call double @sqrt
+ // CHECK-NO: call double @llvm.sqrt.f64(double
+ // CHECK-FAST: call double @llvm.sqrt.f64(double
double l1 = sqrt(a1);
// CHECK-YES: call x86_fp80 @sqrtl
- // CHECK-NO: call x86_fp80 @sqrtl
+ // CHECK-NO: call x86_fp80 @llvm.sqrt.f80(x86_fp80
+ // CHECK-FAST: call x86_fp80 @llvm.sqrt.f80(x86_fp80
long double l2 = sqrtl(a2);
}
// CHECK-YES: declare float @sqrtf(float)
// CHECK-YES: declare double @sqrt(double)
// CHECK-YES: declare x86_fp80 @sqrtl(x86_fp80)
-// CHECK-NO: declare float @sqrtf(float) [[NUW_RN:#[0-9]+]]
-// CHECK-NO: declare double @sqrt(double) [[NUW_RN]]
-// CHECK-NO: declare x86_fp80 @sqrtl(x86_fp80) [[NUW_RN]]
+// CHECK-NO: declare float @llvm.sqrt.f32(float)
+// CHECK-NO: declare double @llvm.sqrt.f64(double)
+// CHECK-NO: declare x86_fp80 @llvm.sqrt.f80(x86_fp80)
// CHECK-FAST: declare float @llvm.sqrt.f32(float)
// CHECK-FAST: declare double @llvm.sqrt.f64(double)
// CHECK-FAST: declare x86_fp80 @llvm.sqrt.f80(x86_fp80)
@@ -59,22 +58,22 @@ void test_pow(float a0, double a1, long double a2) {
// CHECK-YES-LABEL: define void @test_fma
// CHECK-NO-LABEL: define void @test_fma
void test_fma(float a0, double a1, long double a2) {
- // CHECK-YES: call float @llvm.fma.f32
+ // CHECK-YES: call float @fmaf
// CHECK-NO: call float @llvm.fma.f32
float l0 = fmaf(a0, a0, a0);
- // CHECK-YES: call double @llvm.fma.f64
+ // CHECK-YES: call double @fma
// CHECK-NO: call double @llvm.fma.f64
double l1 = fma(a1, a1, a1);
- // CHECK-YES: call x86_fp80 @llvm.fma.f80
+ // CHECK-YES: call x86_fp80 @fmal
// CHECK-NO: call x86_fp80 @llvm.fma.f80
long double l2 = fmal(a2, a2, a2);
}
-// CHECK-YES: declare float @llvm.fma.f32(float, float, float) [[NUW_RN:#[0-9]+]]
-// CHECK-YES: declare double @llvm.fma.f64(double, double, double) [[NUW_RN]]
-// CHECK-YES: declare x86_fp80 @llvm.fma.f80(x86_fp80, x86_fp80, x86_fp80) [[NUW_RN]]
+// CHECK-YES: declare float @fmaf(float, float, float)
+// CHECK-YES: declare double @fma(double, double, double)
+// CHECK-YES: declare x86_fp80 @fmal(x86_fp80, x86_fp80, x86_fp80)
// CHECK-NO: declare float @llvm.fma.f32(float, float, float) [[NUW_RN2:#[0-9]+]]
// CHECK-NO: declare double @llvm.fma.f64(double, double, double) [[NUW_RN2]]
// CHECK-NO: declare x86_fp80 @llvm.fma.f80(x86_fp80, x86_fp80, x86_fp80) [[NUW_RN2]]
@@ -86,7 +85,7 @@ void test_builtins(double d, float f, long double ld) {
double atan_ = atan(d);
long double atanl_ = atanl(ld);
float atanf_ = atanf(f);
-// CHECK-NO: declare double @atan(double) [[NUW_RN]]
+// CHECK-NO: declare double @atan(double) [[NUW_RN:#[0-9]+]]
// CHECK-NO: declare x86_fp80 @atanl(x86_fp80) [[NUW_RN]]
// CHECK-NO: declare float @atanf(float) [[NUW_RN]]
// CHECK-YES-NOT: declare double @atan(double) [[NUW_RN]]
@@ -106,9 +105,9 @@ void test_builtins(double d, float f, long double ld) {
double exp_ = exp(d);
long double expl_ = expl(ld);
float expf_ = expf(f);
-// CHECK-NO: declare double @exp(double) [[NUW_RN]]
-// CHECK-NO: declare x86_fp80 @expl(x86_fp80) [[NUW_RN]]
-// CHECK-NO: declare float @expf(float) [[NUW_RN]]
+// CHECK-NO: declare double @llvm.exp.f64(double) [[NUW_RNI]]
+// CHECK-NO: declare x86_fp80 @llvm.exp.f80(x86_fp80) [[NUW_RNI]]
+// CHECK-NO: declare float @llvm.exp.f32(float) [[NUW_RNI]]
// CHECK-YES-NOT: declare double @exp(double) [[NUW_RN]]
// CHECK-YES-NOT: declare x86_fp80 @expl(x86_fp80) [[NUW_RN]]
// CHECK-YES-NOT: declare float @expf(float) [[NUW_RN]]
@@ -116,15 +115,13 @@ void test_builtins(double d, float f, long double ld) {
double log_ = log(d);
long double logl_ = logl(ld);
float logf_ = logf(f);
-// CHECK-NO: declare double @log(double) [[NUW_RN]]
-// CHECK-NO: declare x86_fp80 @logl(x86_fp80) [[NUW_RN]]
-// CHECK-NO: declare float @logf(float) [[NUW_RN]]
+// CHECK-NO: declare double @llvm.log.f64(double) [[NUW_RNI]]
+// CHECK-NO: declare x86_fp80 @llvm.log.f80(x86_fp80) [[NUW_RNI]]
+// CHECK-NO: declare float @llvm.log.f32(float) [[NUW_RNI]]
// CHECK-YES-NOT: declare double @log(double) [[NUW_RN]]
// CHECK-YES-NOT: declare x86_fp80 @logl(x86_fp80) [[NUW_RN]]
// CHECK-YES-NOT: declare float @logf(float) [[NUW_RN]]
}
-// CHECK-YES: attributes [[NUW_RN]] = { nounwind readnone speculatable }
-
-// CHECK-NO: attributes [[NUW_RN]] = { nounwind readnone{{.*}} }
-// CHECK-NO: attributes [[NUW_RNI]] = { nounwind readnone speculatable }
+// CHECK-NO-DAG: attributes [[NUW_RN]] = { nounwind readnone{{.*}} }
+// CHECK-NO-DAG: attributes [[NUW_RNI]] = { nounwind readnone speculatable }
diff --git a/test/CodeGen/linux-arm-atomic.c b/test/CodeGen/linux-arm-atomic.c
index 116925a585b6..b8535f824827 100644
--- a/test/CodeGen/linux-arm-atomic.c
+++ b/test/CodeGen/linux-arm-atomic.c
@@ -2,7 +2,6 @@
// RUN: %clang_cc1 %s -emit-llvm -o - -triple=armv6-unknown-linux | FileCheck %s
// RUN: %clang_cc1 %s -emit-llvm -o - -triple=thumbv7-unknown-linux | FileCheck %s
// RUN: %clang_cc1 %s -emit-llvm -o - -triple=armv6-unknown-freebsd | FileCheck %s
-// RUN: %clang_cc1 %s -emit-llvm -o - -triple=armv6-unknown-bitrig | FileCheck %s
typedef int _Atomic_word;
_Atomic_word exchange_and_add(volatile _Atomic_word *__mem, int __val) {
diff --git a/test/CodeGen/long-call-attr.c b/test/CodeGen/long-call-attr.c
new file mode 100644
index 000000000000..82433caf76fd
--- /dev/null
+++ b/test/CodeGen/long-call-attr.c
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -triple mips-linux-gnu -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple mips64-linux-gnu -emit-llvm -o - %s | FileCheck %s
+
+void __attribute__((long_call)) foo1 (void);
+void __attribute__((short_call)) foo4 (void);
+
+void __attribute__((far)) foo2 (void) {}
+
+// CHECK: define void @foo2() [[FAR:#[0-9]+]]
+
+void __attribute__((near)) foo3 (void) { foo1(); foo4(); }
+
+// CHECK: define void @foo3() [[NEAR:#[0-9]+]]
+
+// CHECK: declare void @foo1() [[LONGDECL:#[0-9]+]]
+// CHECK: declare void @foo4() [[SHORTDECL:#[0-9]+]]
+
+// CHECK: attributes [[FAR]] = { {{.*}} "long-call" {{.*}} }
+// CHECK: attributes [[NEAR]] = { {{.*}} "short-call" {{.*}} }
+// CHECK: attributes [[LONGDECL]] = { {{.*}} "long-call" {{.*}} }
+// CHECK: attributes [[SHORTDECL]] = { {{.*}} "short-call" {{.*}} }
diff --git a/test/CodeGen/mangle-blocks.c b/test/CodeGen/mangle-blocks.c
index e8de92d8b400..4ea5a550c8bd 100644
--- a/test/CodeGen/mangle-blocks.c
+++ b/test/CodeGen/mangle-blocks.c
@@ -12,12 +12,12 @@ void (^mangle(void))(void) {
}
// CHECK: @__func__.__mangle_block_invoke_2 = private unnamed_addr constant [22 x i8] c"mangle_block_invoke_2\00", align 1
-// CHECK: @.str = private unnamed_addr constant {{.*}}, align 1
-// CHECK: @.str.1 = private unnamed_addr constant [7 x i8] c"mangle\00", align 1
+// CHECK: @.str{{.*}} = private unnamed_addr constant {{.*}}, align 1
+// CHECK: @.str[[STR1:.*]] = private unnamed_addr constant [7 x i8] c"mangle\00", align 1
// CHECK: define internal void @__mangle_block_invoke(i8* %.block_descriptor)
// CHECK: define internal void @__mangle_block_invoke_2(i8* %.block_descriptor){{.*}}{
-// CHECK: call void @__assert_rtn(i8* getelementptr inbounds ([22 x i8], [22 x i8]* @__func__.__mangle_block_invoke_2, i32 0, i32 0), i8* getelementptr inbounds {{.*}}, i32 9, i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str.1, i32 0, i32 0))
+// CHECK: call void @__assert_rtn(i8* getelementptr inbounds ([22 x i8], [22 x i8]* @__func__.__mangle_block_invoke_2, i32 0, i32 0), i8* getelementptr inbounds {{.*}}, i32 9, i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str[[STR1]], i32 0, i32 0))
// CHECK: }
diff --git a/test/CodeGen/math-builtins.c b/test/CodeGen/math-builtins.c
new file mode 100644
index 000000000000..799d91b4ec00
--- /dev/null
+++ b/test/CodeGen/math-builtins.c
@@ -0,0 +1,578 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -w -S -o - -emit-llvm %s | FileCheck %s -check-prefix=NO__ERRNO
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -w -S -o - -emit-llvm -fmath-errno %s | FileCheck %s -check-prefix=HAS_ERRNO
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown-gnu -w -S -o - -emit-llvm -fmath-errno %s | FileCheck %s --check-prefix=HAS_ERRNO_GNU
+// RUN: %clang_cc1 -triple x86_64-unknown-windows-msvc -w -S -o - -emit-llvm -fmath-errno %s | FileCheck %s --check-prefix=HAS_ERRNO_WIN
+
+// Test attributes and codegen of math builtins.
+
+void foo(double *d, float f, float *fp, long double *l, int *i, const char *c) {
+ f = __builtin_fmod(f,f); f = __builtin_fmodf(f,f); f = __builtin_fmodl(f,f);
+
+// NO__ERRNO: frem double
+// NO__ERRNO: frem float
+// NO__ERRNO: frem x86_fp80
+// HAS_ERRNO: declare double @fmod(double, double) [[NOT_READNONE:#[0-9]+]]
+// HAS_ERRNO: declare float @fmodf(float, float) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @fmodl(x86_fp80, x86_fp80) [[NOT_READNONE]]
+
+ __builtin_atan2(f,f); __builtin_atan2f(f,f) ; __builtin_atan2l(f, f);
+
+// NO__ERRNO: declare double @atan2(double, double) [[READNONE:#[0-9]+]]
+// NO__ERRNO: declare float @atan2f(float, float) [[READNONE]]
+// NO__ERRNO: declare x86_fp80 @atan2l(x86_fp80, x86_fp80) [[READNONE]]
+// HAS_ERRNO: declare double @atan2(double, double) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @atan2f(float, float) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @atan2l(x86_fp80, x86_fp80) [[NOT_READNONE]]
+
+ __builtin_copysign(f,f); __builtin_copysignf(f,f);__builtin_copysignl(f,f);
+
+// NO__ERRNO: declare double @llvm.copysign.f64(double, double) [[READNONE_INTRINSIC:#[0-9]+]]
+// NO__ERRNO: declare float @llvm.copysign.f32(float, float) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare x86_fp80 @llvm.copysign.f80(x86_fp80, x86_fp80) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare double @llvm.copysign.f64(double, double) [[READNONE_INTRINSIC:#[0-9]+]]
+// HAS_ERRNO: declare float @llvm.copysign.f32(float, float) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare x86_fp80 @llvm.copysign.f80(x86_fp80, x86_fp80) [[READNONE_INTRINSIC]]
+
+ __builtin_fabs(f); __builtin_fabsf(f); __builtin_fabsl(f);
+
+// NO__ERRNO: declare double @llvm.fabs.f64(double) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare float @llvm.fabs.f32(float) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare x86_fp80 @llvm.fabs.f80(x86_fp80) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare double @llvm.fabs.f64(double) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare float @llvm.fabs.f32(float) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare x86_fp80 @llvm.fabs.f80(x86_fp80) [[READNONE_INTRINSIC]]
+
+ __builtin_frexp(f,i); __builtin_frexpf(f,i); __builtin_frexpl(f,i);
+
+// NO__ERRNO: declare double @frexp(double, i32*) [[NOT_READNONE:#[0-9]+]]
+// NO__ERRNO: declare float @frexpf(float, i32*) [[NOT_READNONE]]
+// NO__ERRNO: declare x86_fp80 @frexpl(x86_fp80, i32*) [[NOT_READNONE]]
+// HAS_ERRNO: declare double @frexp(double, i32*) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @frexpf(float, i32*) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @frexpl(x86_fp80, i32*) [[NOT_READNONE]]
+
+ __builtin_huge_val(); __builtin_huge_valf(); __builtin_huge_vall();
+
+// NO__ERRNO-NOT: .huge
+// NO__ERRNO-NOT: @huge
+// HAS_ERRNO-NOT: .huge
+// HAS_ERRNO-NOT: @huge
+
+ __builtin_inf(); __builtin_inff(); __builtin_infl();
+
+// NO__ERRNO-NOT: .inf
+// NO__ERRNO-NOT: @inf
+// HAS_ERRNO-NOT: .inf
+// HAS_ERRNO-NOT: @inf
+
+ __builtin_ldexp(f,f); __builtin_ldexpf(f,f); __builtin_ldexpl(f,f);
+
+// NO__ERRNO: declare double @ldexp(double, i32) [[READNONE]]
+// NO__ERRNO: declare float @ldexpf(float, i32) [[READNONE]]
+// NO__ERRNO: declare x86_fp80 @ldexpl(x86_fp80, i32) [[READNONE]]
+// HAS_ERRNO: declare double @ldexp(double, i32) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @ldexpf(float, i32) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @ldexpl(x86_fp80, i32) [[NOT_READNONE]]
+
+ __builtin_modf(f,d); __builtin_modff(f,fp); __builtin_modfl(f,l);
+
+// NO__ERRNO: declare double @modf(double, double*) [[NOT_READNONE]]
+// NO__ERRNO: declare float @modff(float, float*) [[NOT_READNONE]]
+// NO__ERRNO: declare x86_fp80 @modfl(x86_fp80, x86_fp80*) [[NOT_READNONE]]
+// HAS_ERRNO: declare double @modf(double, double*) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @modff(float, float*) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @modfl(x86_fp80, x86_fp80*) [[NOT_READNONE]]
+
+ __builtin_nan(c); __builtin_nanf(c); __builtin_nanl(c);
+
+// NO__ERRNO: declare double @nan(i8*) [[READNONE]]
+// NO__ERRNO: declare float @nanf(i8*) [[READNONE]]
+// NO__ERRNO: declare x86_fp80 @nanl(i8*) [[READNONE]]
+// HAS_ERRNO: declare double @nan(i8*) [[READNONE:#[0-9]+]]
+// HAS_ERRNO: declare float @nanf(i8*) [[READNONE]]
+// HAS_ERRNO: declare x86_fp80 @nanl(i8*) [[READNONE]]
+
+ __builtin_nans(c); __builtin_nansf(c); __builtin_nansl(c);
+
+// NO__ERRNO: declare double @nans(i8*) [[READNONE]]
+// NO__ERRNO: declare float @nansf(i8*) [[READNONE]]
+// NO__ERRNO: declare x86_fp80 @nansl(i8*) [[READNONE]]
+// HAS_ERRNO: declare double @nans(i8*) [[READNONE]]
+// HAS_ERRNO: declare float @nansf(i8*) [[READNONE]]
+// HAS_ERRNO: declare x86_fp80 @nansl(i8*) [[READNONE]]
+
+ __builtin_pow(f,f); __builtin_powf(f,f); __builtin_powl(f,f);
+
+// NO__ERRNO: declare double @llvm.pow.f64(double, double) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare float @llvm.pow.f32(float, float) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare x86_fp80 @llvm.pow.f80(x86_fp80, x86_fp80) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare double @pow(double, double) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @powf(float, float) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @powl(x86_fp80, x86_fp80) [[NOT_READNONE]]
+
+ __builtin_powi(f,f); __builtin_powif(f,f); __builtin_powil(f,f);
+
+// NO__ERRNO: declare double @llvm.powi.f64(double, i32) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare float @llvm.powi.f32(float, i32) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare x86_fp80 @llvm.powi.f80(x86_fp80, i32) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare double @llvm.powi.f64(double, i32) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare float @llvm.powi.f32(float, i32) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare x86_fp80 @llvm.powi.f80(x86_fp80, i32) [[READNONE_INTRINSIC]]
+
+ /* math */
+ __builtin_acos(f); __builtin_acosf(f); __builtin_acosl(f);
+
+// NO__ERRNO: declare double @acos(double) [[READNONE]]
+// NO__ERRNO: declare float @acosf(float) [[READNONE]]
+// NO__ERRNO: declare x86_fp80 @acosl(x86_fp80) [[READNONE]]
+// HAS_ERRNO: declare double @acos(double) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @acosf(float) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @acosl(x86_fp80) [[NOT_READNONE]]
+
+ __builtin_acosh(f); __builtin_acoshf(f); __builtin_acoshl(f);
+
+// NO__ERRNO: declare double @acosh(double) [[READNONE]]
+// NO__ERRNO: declare float @acoshf(float) [[READNONE]]
+// NO__ERRNO: declare x86_fp80 @acoshl(x86_fp80) [[READNONE]]
+// HAS_ERRNO: declare double @acosh(double) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @acoshf(float) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @acoshl(x86_fp80) [[NOT_READNONE]]
+
+ __builtin_asin(f); __builtin_asinf(f); __builtin_asinl(f);
+
+// NO__ERRNO: declare double @asin(double) [[READNONE]]
+// NO__ERRNO: declare float @asinf(float) [[READNONE]]
+// NO__ERRNO: declare x86_fp80 @asinl(x86_fp80) [[READNONE]]
+// HAS_ERRNO: declare double @asin(double) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @asinf(float) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @asinl(x86_fp80) [[NOT_READNONE]]
+
+ __builtin_asinh(f); __builtin_asinhf(f); __builtin_asinhl(f);
+
+// NO__ERRNO: declare double @asinh(double) [[READNONE]]
+// NO__ERRNO: declare float @asinhf(float) [[READNONE]]
+// NO__ERRNO: declare x86_fp80 @asinhl(x86_fp80) [[READNONE]]
+// HAS_ERRNO: declare double @asinh(double) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @asinhf(float) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @asinhl(x86_fp80) [[NOT_READNONE]]
+
+ __builtin_atan(f); __builtin_atanf(f); __builtin_atanl(f);
+
+// NO__ERRNO: declare double @atan(double) [[READNONE]]
+// NO__ERRNO: declare float @atanf(float) [[READNONE]]
+// NO__ERRNO: declare x86_fp80 @atanl(x86_fp80) [[READNONE]]
+// HAS_ERRNO: declare double @atan(double) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @atanf(float) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @atanl(x86_fp80) [[NOT_READNONE]]
+
+ __builtin_atanh(f); __builtin_atanhf(f); __builtin_atanhl(f);
+
+// NO__ERRNO: declare double @atanh(double) [[READNONE]]
+// NO__ERRNO: declare float @atanhf(float) [[READNONE]]
+// NO__ERRNO: declare x86_fp80 @atanhl(x86_fp80) [[READNONE]]
+// HAS_ERRNO: declare double @atanh(double) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @atanhf(float) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @atanhl(x86_fp80) [[NOT_READNONE]]
+
+ __builtin_cbrt(f); __builtin_cbrtf(f); __builtin_cbrtl(f);
+
+// NO__ERRNO: declare double @cbrt(double) [[READNONE]]
+// NO__ERRNO: declare float @cbrtf(float) [[READNONE]]
+// NO__ERRNO: declare x86_fp80 @cbrtl(x86_fp80) [[READNONE]]
+// HAS_ERRNO: declare double @cbrt(double) [[READNONE]]
+// HAS_ERRNO: declare float @cbrtf(float) [[READNONE]]
+// HAS_ERRNO: declare x86_fp80 @cbrtl(x86_fp80) [[READNONE]]
+
+ __builtin_ceil(f); __builtin_ceilf(f); __builtin_ceill(f);
+
+// NO__ERRNO: declare double @llvm.ceil.f64(double) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare float @llvm.ceil.f32(float) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare x86_fp80 @llvm.ceil.f80(x86_fp80) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare double @llvm.ceil.f64(double) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare float @llvm.ceil.f32(float) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare x86_fp80 @llvm.ceil.f80(x86_fp80) [[READNONE_INTRINSIC]]
+
+ __builtin_cos(f); __builtin_cosf(f); __builtin_cosl(f);
+
+// NO__ERRNO: declare double @llvm.cos.f64(double) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare float @llvm.cos.f32(float) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare x86_fp80 @llvm.cos.f80(x86_fp80) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare double @cos(double) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @cosf(float) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @cosl(x86_fp80) [[NOT_READNONE]]
+
+ __builtin_cosh(f); __builtin_coshf(f); __builtin_coshl(f);
+
+// NO__ERRNO: declare double @cosh(double) [[READNONE]]
+// NO__ERRNO: declare float @coshf(float) [[READNONE]]
+// NO__ERRNO: declare x86_fp80 @coshl(x86_fp80) [[READNONE]]
+// HAS_ERRNO: declare double @cosh(double) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @coshf(float) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @coshl(x86_fp80) [[NOT_READNONE]]
+
+ __builtin_erf(f); __builtin_erff(f); __builtin_erfl(f);
+
+// NO__ERRNO: declare double @erf(double) [[READNONE]]
+// NO__ERRNO: declare float @erff(float) [[READNONE]]
+// NO__ERRNO: declare x86_fp80 @erfl(x86_fp80) [[READNONE]]
+// HAS_ERRNO: declare double @erf(double) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @erff(float) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @erfl(x86_fp80) [[NOT_READNONE]]
+
+ __builtin_erfc(f); __builtin_erfcf(f); __builtin_erfcl(f);
+
+// NO__ERRNO: declare double @erfc(double) [[READNONE]]
+// NO__ERRNO: declare float @erfcf(float) [[READNONE]]
+// NO__ERRNO: declare x86_fp80 @erfcl(x86_fp80) [[READNONE]]
+// HAS_ERRNO: declare double @erfc(double) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @erfcf(float) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @erfcl(x86_fp80) [[NOT_READNONE]]
+
+ __builtin_exp(f); __builtin_expf(f); __builtin_expl(f);
+
+// NO__ERRNO: declare double @llvm.exp.f64(double) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare float @llvm.exp.f32(float) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare x86_fp80 @llvm.exp.f80(x86_fp80) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare double @exp(double) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @expf(float) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @expl(x86_fp80) [[NOT_READNONE]]
+
+ __builtin_exp2(f); __builtin_exp2f(f); __builtin_exp2l(f);
+
+// NO__ERRNO: declare double @llvm.exp2.f64(double) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare float @llvm.exp2.f32(float) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare x86_fp80 @llvm.exp2.f80(x86_fp80) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare double @exp2(double) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @exp2f(float) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @exp2l(x86_fp80) [[NOT_READNONE]]
+
+ __builtin_expm1(f); __builtin_expm1f(f); __builtin_expm1l(f);
+
+// NO__ERRNO: declare double @expm1(double) [[READNONE]]
+// NO__ERRNO: declare float @expm1f(float) [[READNONE]]
+// NO__ERRNO: declare x86_fp80 @expm1l(x86_fp80) [[READNONE]]
+// HAS_ERRNO: declare double @expm1(double) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @expm1f(float) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @expm1l(x86_fp80) [[NOT_READNONE]]
+
+ __builtin_fdim(f,f); __builtin_fdimf(f,f); __builtin_fdiml(f,f);
+
+// NO__ERRNO: declare double @fdim(double, double) [[READNONE]]
+// NO__ERRNO: declare float @fdimf(float, float) [[READNONE]]
+// NO__ERRNO: declare x86_fp80 @fdiml(x86_fp80, x86_fp80) [[READNONE]]
+// HAS_ERRNO: declare double @fdim(double, double) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @fdimf(float, float) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @fdiml(x86_fp80, x86_fp80) [[NOT_READNONE]]
+
+ __builtin_floor(f); __builtin_floorf(f); __builtin_floorl(f);
+
+// NO__ERRNO: declare double @llvm.floor.f64(double) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare float @llvm.floor.f32(float) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare x86_fp80 @llvm.floor.f80(x86_fp80) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare double @llvm.floor.f64(double) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare float @llvm.floor.f32(float) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare x86_fp80 @llvm.floor.f80(x86_fp80) [[READNONE_INTRINSIC]]
+
+ __builtin_fma(f,f,f); __builtin_fmaf(f,f,f); __builtin_fmal(f,f,f);
+
+// NO__ERRNO: declare double @llvm.fma.f64(double, double, double) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare float @llvm.fma.f32(float, float, float) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare x86_fp80 @llvm.fma.f80(x86_fp80, x86_fp80, x86_fp80) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare double @fma(double, double, double) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @fmaf(float, float, float) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @fmal(x86_fp80, x86_fp80, x86_fp80) [[NOT_READNONE]]
+
+// On GNU or Win, fma never sets errno, so we can convert to the intrinsic.
+
+// HAS_ERRNO_GNU: declare double @llvm.fma.f64(double, double, double) [[READNONE_INTRINSIC:#[0-9]+]]
+// HAS_ERRNO_GNU: declare float @llvm.fma.f32(float, float, float) [[READNONE_INTRINSIC]]
+// HAS_ERRNO_GNU: declare x86_fp80 @llvm.fma.f80(x86_fp80, x86_fp80, x86_fp80) [[READNONE_INTRINSIC]]
+
+// HAS_ERRNO_WIN: declare double @llvm.fma.f64(double, double, double) [[READNONE_INTRINSIC:#[0-9]+]]
+// HAS_ERRNO_WIN: declare float @llvm.fma.f32(float, float, float) [[READNONE_INTRINSIC]]
+// Long double is just double on win, so no f80 use/declaration.
+// HAS_ERRNO_WIN-NOT: declare x86_fp80 @llvm.fma.f80(x86_fp80, x86_fp80, x86_fp80)
+
+ __builtin_fmax(f,f); __builtin_fmaxf(f,f); __builtin_fmaxl(f,f);
+
+// NO__ERRNO: declare double @llvm.maxnum.f64(double, double) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare float @llvm.maxnum.f32(float, float) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare x86_fp80 @llvm.maxnum.f80(x86_fp80, x86_fp80) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare double @llvm.maxnum.f64(double, double) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare float @llvm.maxnum.f32(float, float) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare x86_fp80 @llvm.maxnum.f80(x86_fp80, x86_fp80) [[READNONE_INTRINSIC]]
+
+ __builtin_fmin(f,f); __builtin_fminf(f,f); __builtin_fminl(f,f);
+
+// NO__ERRNO: declare double @llvm.minnum.f64(double, double) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare float @llvm.minnum.f32(float, float) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare x86_fp80 @llvm.minnum.f80(x86_fp80, x86_fp80) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare double @llvm.minnum.f64(double, double) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare float @llvm.minnum.f32(float, float) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare x86_fp80 @llvm.minnum.f80(x86_fp80, x86_fp80) [[READNONE_INTRINSIC]]
+
+ __builtin_hypot(f,f); __builtin_hypotf(f,f); __builtin_hypotl(f,f);
+
+// NO__ERRNO: declare double @hypot(double, double) [[READNONE]]
+// NO__ERRNO: declare float @hypotf(float, float) [[READNONE]]
+// NO__ERRNO: declare x86_fp80 @hypotl(x86_fp80, x86_fp80) [[READNONE]]
+// HAS_ERRNO: declare double @hypot(double, double) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @hypotf(float, float) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @hypotl(x86_fp80, x86_fp80) [[NOT_READNONE]]
+
+ __builtin_ilogb(f); __builtin_ilogbf(f); __builtin_ilogbl(f);
+
+// NO__ERRNO: declare i32 @ilogb(double) [[READNONE]]
+// NO__ERRNO: declare i32 @ilogbf(float) [[READNONE]]
+// NO__ERRNO: declare i32 @ilogbl(x86_fp80) [[READNONE]]
+// HAS_ERRNO: declare i32 @ilogb(double) [[NOT_READNONE]]
+// HAS_ERRNO: declare i32 @ilogbf(float) [[NOT_READNONE]]
+// HAS_ERRNO: declare i32 @ilogbl(x86_fp80) [[NOT_READNONE]]
+
+ __builtin_lgamma(f); __builtin_lgammaf(f); __builtin_lgammal(f);
+
+// NO__ERRNO: declare double @lgamma(double) [[NOT_READNONE]]
+// NO__ERRNO: declare float @lgammaf(float) [[NOT_READNONE]]
+// NO__ERRNO: declare x86_fp80 @lgammal(x86_fp80) [[NOT_READNONE]]
+// HAS_ERRNO: declare double @lgamma(double) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @lgammaf(float) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @lgammal(x86_fp80) [[NOT_READNONE]]
+
+ __builtin_llrint(f); __builtin_llrintf(f); __builtin_llrintl(f);
+
+// NO__ERRNO: declare i64 @llrint(double) [[READNONE]]
+// NO__ERRNO: declare i64 @llrintf(float) [[READNONE]]
+// NO__ERRNO: declare i64 @llrintl(x86_fp80) [[READNONE]]
+// HAS_ERRNO: declare i64 @llrint(double) [[NOT_READNONE]]
+// HAS_ERRNO: declare i64 @llrintf(float) [[NOT_READNONE]]
+// HAS_ERRNO: declare i64 @llrintl(x86_fp80) [[NOT_READNONE]]
+
+ __builtin_llround(f); __builtin_llroundf(f); __builtin_llroundl(f);
+
+// NO__ERRNO: declare i64 @llround(double) [[READNONE]]
+// NO__ERRNO: declare i64 @llroundf(float) [[READNONE]]
+// NO__ERRNO: declare i64 @llroundl(x86_fp80) [[READNONE]]
+// HAS_ERRNO: declare i64 @llround(double) [[NOT_READNONE]]
+// HAS_ERRNO: declare i64 @llroundf(float) [[NOT_READNONE]]
+// HAS_ERRNO: declare i64 @llroundl(x86_fp80) [[NOT_READNONE]]
+
+ __builtin_log(f); __builtin_logf(f); __builtin_logl(f);
+
+// NO__ERRNO: declare double @llvm.log.f64(double) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare float @llvm.log.f32(float) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare x86_fp80 @llvm.log.f80(x86_fp80) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare double @log(double) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @logf(float) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @logl(x86_fp80) [[NOT_READNONE]]
+
+ __builtin_log10(f); __builtin_log10f(f); __builtin_log10l(f);
+
+// NO__ERRNO: declare double @llvm.log10.f64(double) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare float @llvm.log10.f32(float) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare x86_fp80 @llvm.log10.f80(x86_fp80) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare double @log10(double) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @log10f(float) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @log10l(x86_fp80) [[NOT_READNONE]]
+
+ __builtin_log1p(f); __builtin_log1pf(f); __builtin_log1pl(f);
+
+// NO__ERRNO: declare double @log1p(double) [[READNONE]]
+// NO__ERRNO: declare float @log1pf(float) [[READNONE]]
+// NO__ERRNO: declare x86_fp80 @log1pl(x86_fp80) [[READNONE]]
+// HAS_ERRNO: declare double @log1p(double) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @log1pf(float) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @log1pl(x86_fp80) [[NOT_READNONE]]
+
+ __builtin_log2(f); __builtin_log2f(f); __builtin_log2l(f);
+
+// NO__ERRNO: declare double @llvm.log2.f64(double) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare float @llvm.log2.f32(float) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare x86_fp80 @llvm.log2.f80(x86_fp80) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare double @log2(double) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @log2f(float) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @log2l(x86_fp80) [[NOT_READNONE]]
+
+ __builtin_logb(f); __builtin_logbf(f); __builtin_logbl(f);
+
+// NO__ERRNO: declare double @logb(double) [[READNONE]]
+// NO__ERRNO: declare float @logbf(float) [[READNONE]]
+// NO__ERRNO: declare x86_fp80 @logbl(x86_fp80) [[READNONE]]
+// HAS_ERRNO: declare double @logb(double) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @logbf(float) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @logbl(x86_fp80) [[NOT_READNONE]]
+
+ __builtin_lrint(f); __builtin_lrintf(f); __builtin_lrintl(f);
+
+// NO__ERRNO: declare i64 @lrint(double) [[READNONE]]
+// NO__ERRNO: declare i64 @lrintf(float) [[READNONE]]
+// NO__ERRNO: declare i64 @lrintl(x86_fp80) [[READNONE]]
+// HAS_ERRNO: declare i64 @lrint(double) [[NOT_READNONE]]
+// HAS_ERRNO: declare i64 @lrintf(float) [[NOT_READNONE]]
+// HAS_ERRNO: declare i64 @lrintl(x86_fp80) [[NOT_READNONE]]
+
+ __builtin_lround(f); __builtin_lroundf(f); __builtin_lroundl(f);
+
+// NO__ERRNO: declare i64 @lround(double) [[READNONE]]
+// NO__ERRNO: declare i64 @lroundf(float) [[READNONE]]
+// NO__ERRNO: declare i64 @lroundl(x86_fp80) [[READNONE]]
+// HAS_ERRNO: declare i64 @lround(double) [[NOT_READNONE]]
+// HAS_ERRNO: declare i64 @lroundf(float) [[NOT_READNONE]]
+// HAS_ERRNO: declare i64 @lroundl(x86_fp80) [[NOT_READNONE]]
+
+ __builtin_nearbyint(f); __builtin_nearbyintf(f); __builtin_nearbyintl(f);
+
+// NO__ERRNO: declare double @llvm.nearbyint.f64(double) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare float @llvm.nearbyint.f32(float) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare x86_fp80 @llvm.nearbyint.f80(x86_fp80) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare double @llvm.nearbyint.f64(double) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare float @llvm.nearbyint.f32(float) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare x86_fp80 @llvm.nearbyint.f80(x86_fp80) [[READNONE_INTRINSIC]]
+
+ __builtin_nextafter(f,f); __builtin_nextafterf(f,f); __builtin_nextafterl(f,f);
+
+// NO__ERRNO: declare double @nextafter(double, double) [[READNONE]]
+// NO__ERRNO: declare float @nextafterf(float, float) [[READNONE]]
+// NO__ERRNO: declare x86_fp80 @nextafterl(x86_fp80, x86_fp80) [[READNONE]]
+// HAS_ERRNO: declare double @nextafter(double, double) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @nextafterf(float, float) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @nextafterl(x86_fp80, x86_fp80) [[NOT_READNONE]]
+
+ __builtin_nexttoward(f,f); __builtin_nexttowardf(f,f);__builtin_nexttowardl(f,f);
+
+// NO__ERRNO: declare double @nexttoward(double, x86_fp80) [[READNONE]]
+// NO__ERRNO: declare float @nexttowardf(float, x86_fp80) [[READNONE]]
+// NO__ERRNO: declare x86_fp80 @nexttowardl(x86_fp80, x86_fp80) [[READNONE]]
+// HAS_ERRNO: declare double @nexttoward(double, x86_fp80) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @nexttowardf(float, x86_fp80) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @nexttowardl(x86_fp80, x86_fp80) [[NOT_READNONE]]
+
+ __builtin_remainder(f,f); __builtin_remainderf(f,f); __builtin_remainderl(f,f);
+
+// NO__ERRNO: declare double @remainder(double, double) [[READNONE]]
+// NO__ERRNO: declare float @remainderf(float, float) [[READNONE]]
+// NO__ERRNO: declare x86_fp80 @remainderl(x86_fp80, x86_fp80) [[READNONE]]
+// HAS_ERRNO: declare double @remainder(double, double) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @remainderf(float, float) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @remainderl(x86_fp80, x86_fp80) [[NOT_READNONE]]
+
+ __builtin_remquo(f,f,i); __builtin_remquof(f,f,i); __builtin_remquol(f,f,i);
+
+// NO__ERRNO: declare double @remquo(double, double, i32*) [[NOT_READNONE]]
+// NO__ERRNO: declare float @remquof(float, float, i32*) [[NOT_READNONE]]
+// NO__ERRNO: declare x86_fp80 @remquol(x86_fp80, x86_fp80, i32*) [[NOT_READNONE]]
+// HAS_ERRNO: declare double @remquo(double, double, i32*) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @remquof(float, float, i32*) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @remquol(x86_fp80, x86_fp80, i32*) [[NOT_READNONE]]
+
+ __builtin_rint(f); __builtin_rintf(f); __builtin_rintl(f);
+
+// NO__ERRNO: declare double @llvm.rint.f64(double) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare float @llvm.rint.f32(float) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare x86_fp80 @llvm.rint.f80(x86_fp80) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare double @llvm.rint.f64(double) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare float @llvm.rint.f32(float) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare x86_fp80 @llvm.rint.f80(x86_fp80) [[READNONE_INTRINSIC]]
+
+ __builtin_round(f); __builtin_roundf(f); __builtin_roundl(f);
+
+// NO__ERRNO: declare double @llvm.round.f64(double) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare float @llvm.round.f32(float) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare x86_fp80 @llvm.round.f80(x86_fp80) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare double @llvm.round.f64(double) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare float @llvm.round.f32(float) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare x86_fp80 @llvm.round.f80(x86_fp80) [[READNONE_INTRINSIC]]
+
+ __builtin_scalbln(f,f); __builtin_scalblnf(f,f); __builtin_scalblnl(f,f);
+
+// NO__ERRNO: declare double @scalbln(double, i64) [[READNONE]]
+// NO__ERRNO: declare float @scalblnf(float, i64) [[READNONE]]
+// NO__ERRNO: declare x86_fp80 @scalblnl(x86_fp80, i64) [[READNONE]]
+// HAS_ERRNO: declare double @scalbln(double, i64) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @scalblnf(float, i64) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @scalblnl(x86_fp80, i64) [[NOT_READNONE]]
+
+ __builtin_scalbn(f,f); __builtin_scalbnf(f,f); __builtin_scalbnl(f,f);
+
+// NO__ERRNO: declare double @scalbn(double, i32) [[READNONE]]
+// NO__ERRNO: declare float @scalbnf(float, i32) [[READNONE]]
+// NO__ERRNO: declare x86_fp80 @scalbnl(x86_fp80, i32) [[READNONE]]
+// HAS_ERRNO: declare double @scalbn(double, i32) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @scalbnf(float, i32) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @scalbnl(x86_fp80, i32) [[NOT_READNONE]]
+
+ __builtin_sin(f); __builtin_sinf(f); __builtin_sinl(f);
+
+// NO__ERRNO: declare double @llvm.sin.f64(double) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare float @llvm.sin.f32(float) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare x86_fp80 @llvm.sin.f80(x86_fp80) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare double @sin(double) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @sinf(float) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @sinl(x86_fp80) [[NOT_READNONE]]
+
+ __builtin_sinh(f); __builtin_sinhf(f); __builtin_sinhl(f);
+
+// NO__ERRNO: declare double @sinh(double) [[READNONE]]
+// NO__ERRNO: declare float @sinhf(float) [[READNONE]]
+// NO__ERRNO: declare x86_fp80 @sinhl(x86_fp80) [[READNONE]]
+// HAS_ERRNO: declare double @sinh(double) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @sinhf(float) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @sinhl(x86_fp80) [[NOT_READNONE]]
+
+ __builtin_sqrt(f); __builtin_sqrtf(f); __builtin_sqrtl(f);
+
+// NO__ERRNO: declare double @llvm.sqrt.f64(double) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare float @llvm.sqrt.f32(float) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare x86_fp80 @llvm.sqrt.f80(x86_fp80) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare double @sqrt(double) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @sqrtf(float) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @sqrtl(x86_fp80) [[NOT_READNONE]]
+
+ __builtin_tan(f); __builtin_tanf(f); __builtin_tanl(f);
+
+// NO__ERRNO: declare double @tan(double) [[READNONE]]
+// NO__ERRNO: declare float @tanf(float) [[READNONE]]
+// NO__ERRNO: declare x86_fp80 @tanl(x86_fp80) [[READNONE]]
+// HAS_ERRNO: declare double @tan(double) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @tanf(float) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @tanl(x86_fp80) [[NOT_READNONE]]
+
+ __builtin_tanh(f); __builtin_tanhf(f); __builtin_tanhl(f);
+
+// NO__ERRNO: declare double @tanh(double) [[READNONE]]
+// NO__ERRNO: declare float @tanhf(float) [[READNONE]]
+// NO__ERRNO: declare x86_fp80 @tanhl(x86_fp80) [[READNONE]]
+// HAS_ERRNO: declare double @tanh(double) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @tanhf(float) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @tanhl(x86_fp80) [[NOT_READNONE]]
+
+ __builtin_tgamma(f); __builtin_tgammaf(f); __builtin_tgammal(f);
+
+// NO__ERRNO: declare double @tgamma(double) [[READNONE]]
+// NO__ERRNO: declare float @tgammaf(float) [[READNONE]]
+// NO__ERRNO: declare x86_fp80 @tgammal(x86_fp80) [[READNONE]]
+// HAS_ERRNO: declare double @tgamma(double) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @tgammaf(float) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @tgammal(x86_fp80) [[NOT_READNONE]]
+
+ __builtin_trunc(f); __builtin_truncf(f); __builtin_truncl(f);
+
+// NO__ERRNO: declare double @llvm.trunc.f64(double) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare float @llvm.trunc.f32(float) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare x86_fp80 @llvm.trunc.f80(x86_fp80) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare double @llvm.trunc.f64(double) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare float @llvm.trunc.f32(float) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare x86_fp80 @llvm.trunc.f80(x86_fp80) [[READNONE_INTRINSIC]]
+};
+
+
+// NO__ERRNO: attributes [[READNONE]] = { {{.*}}readnone{{.*}} }
+// NO__ERRNO: attributes [[READNONE_INTRINSIC]] = { {{.*}}readnone{{.*}} }
+// NO__ERRNO: attributes [[NOT_READNONE]] = { nounwind "correctly{{.*}} }
+
+// HAS_ERRNO: attributes [[NOT_READNONE]] = { nounwind "correctly{{.*}} }
+// HAS_ERRNO: attributes [[READNONE_INTRINSIC]] = { {{.*}}readnone{{.*}} }
+// HAS_ERRNO: attributes [[READNONE]] = { {{.*}}readnone{{.*}} }
+
+// HAS_ERRNO_GNU: attributes [[READNONE_INTRINSIC]] = { {{.*}}readnone{{.*}} }
+// HAS_ERRNO_WIN: attributes [[READNONE_INTRINSIC]] = { {{.*}}readnone{{.*}} }
+
diff --git a/test/CodeGen/math-libcalls.c b/test/CodeGen/math-libcalls.c
new file mode 100644
index 000000000000..39bcb4454d7c
--- /dev/null
+++ b/test/CodeGen/math-libcalls.c
@@ -0,0 +1,547 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -w -S -o - -emit-llvm %s | FileCheck %s --check-prefix=NO__ERRNO
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -w -S -o - -emit-llvm -fmath-errno %s | FileCheck %s --check-prefix=HAS_ERRNO
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown-gnu -w -S -o - -emit-llvm -fmath-errno %s | FileCheck %s --check-prefix=HAS_ERRNO_GNU
+// RUN: %clang_cc1 -triple x86_64-unknown-windows-msvc -w -S -o - -emit-llvm -fmath-errno %s | FileCheck %s --check-prefix=HAS_ERRNO_WIN
+
+// Test attributes and builtin codegen of math library calls.
+
+void foo(double *d, float f, float *fp, long double *l, int *i, const char *c) {
+ f = fmod(f,f); f = fmodf(f,f); f = fmodl(f,f);
+
+// NO__ERRNO: frem double
+// NO__ERRNO: frem float
+// NO__ERRNO: frem x86_fp80
+// HAS_ERRNO: declare double @fmod(double, double) [[NOT_READNONE:#[0-9]+]]
+// HAS_ERRNO: declare float @fmodf(float, float) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @fmodl(x86_fp80, x86_fp80) [[NOT_READNONE]]
+
+ atan2(f,f); atan2f(f,f) ; atan2l(f, f);
+
+// NO__ERRNO: declare double @atan2(double, double) [[READNONE:#[0-9]+]]
+// NO__ERRNO: declare float @atan2f(float, float) [[READNONE]]
+// NO__ERRNO: declare x86_fp80 @atan2l(x86_fp80, x86_fp80) [[READNONE]]
+// HAS_ERRNO: declare double @atan2(double, double) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @atan2f(float, float) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @atan2l(x86_fp80, x86_fp80) [[NOT_READNONE]]
+
+ copysign(f,f); copysignf(f,f);copysignl(f,f);
+
+// NO__ERRNO: declare double @llvm.copysign.f64(double, double) [[READNONE_INTRINSIC:#[0-9]+]]
+// NO__ERRNO: declare float @llvm.copysign.f32(float, float) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare x86_fp80 @llvm.copysign.f80(x86_fp80, x86_fp80) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare double @llvm.copysign.f64(double, double) [[READNONE_INTRINSIC:#[0-9]+]]
+// HAS_ERRNO: declare float @llvm.copysign.f32(float, float) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare x86_fp80 @llvm.copysign.f80(x86_fp80, x86_fp80) [[READNONE_INTRINSIC]]
+
+ fabs(f); fabsf(f); fabsl(f);
+
+// NO__ERRNO: declare double @llvm.fabs.f64(double) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare float @llvm.fabs.f32(float) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare x86_fp80 @llvm.fabs.f80(x86_fp80) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare double @llvm.fabs.f64(double) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare float @llvm.fabs.f32(float) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare x86_fp80 @llvm.fabs.f80(x86_fp80) [[READNONE_INTRINSIC]]
+
+ frexp(f,i); frexpf(f,i); frexpl(f,i);
+
+// NO__ERRNO: declare double @frexp(double, i32*) [[NOT_READNONE:#[0-9]+]]
+// NO__ERRNO: declare float @frexpf(float, i32*) [[NOT_READNONE]]
+// NO__ERRNO: declare x86_fp80 @frexpl(x86_fp80, i32*) [[NOT_READNONE]]
+// HAS_ERRNO: declare double @frexp(double, i32*) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @frexpf(float, i32*) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @frexpl(x86_fp80, i32*) [[NOT_READNONE]]
+
+ ldexp(f,f); ldexpf(f,f); ldexpl(f,f);
+
+// NO__ERRNO: declare double @ldexp(double, i32) [[READNONE]]
+// NO__ERRNO: declare float @ldexpf(float, i32) [[READNONE]]
+// NO__ERRNO: declare x86_fp80 @ldexpl(x86_fp80, i32) [[READNONE]]
+// HAS_ERRNO: declare double @ldexp(double, i32) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @ldexpf(float, i32) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @ldexpl(x86_fp80, i32) [[NOT_READNONE]]
+
+ modf(f,d); modff(f,fp); modfl(f,l);
+
+// NO__ERRNO: declare double @modf(double, double*) [[NOT_READNONE]]
+// NO__ERRNO: declare float @modff(float, float*) [[NOT_READNONE]]
+// NO__ERRNO: declare x86_fp80 @modfl(x86_fp80, x86_fp80*) [[NOT_READNONE]]
+// HAS_ERRNO: declare double @modf(double, double*) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @modff(float, float*) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @modfl(x86_fp80, x86_fp80*) [[NOT_READNONE]]
+
+ nan(c); nanf(c); nanl(c);
+
+// NO__ERRNO: declare double @nan(i8*) [[READONLY:#[0-9]+]]
+// NO__ERRNO: declare float @nanf(i8*) [[READONLY]]
+// NO__ERRNO: declare x86_fp80 @nanl(i8*) [[READONLY]]
+// HAS_ERRNO: declare double @nan(i8*) [[READONLY:#[0-9]+]]
+// HAS_ERRNO: declare float @nanf(i8*) [[READONLY]]
+// HAS_ERRNO: declare x86_fp80 @nanl(i8*) [[READONLY]]
+
+ pow(f,f); powf(f,f); powl(f,f);
+
+// NO__ERRNO: declare double @llvm.pow.f64(double, double) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare float @llvm.pow.f32(float, float) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare x86_fp80 @llvm.pow.f80(x86_fp80, x86_fp80) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare double @pow(double, double) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @powf(float, float) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @powl(x86_fp80, x86_fp80) [[NOT_READNONE]]
+
+ /* math */
+ acos(f); acosf(f); acosl(f);
+
+// NO__ERRNO: declare double @acos(double) [[READNONE]]
+// NO__ERRNO: declare float @acosf(float) [[READNONE]]
+// NO__ERRNO: declare x86_fp80 @acosl(x86_fp80) [[READNONE]]
+// HAS_ERRNO: declare double @acos(double) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @acosf(float) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @acosl(x86_fp80) [[NOT_READNONE]]
+
+ acosh(f); acoshf(f); acoshl(f);
+
+// NO__ERRNO: declare double @acosh(double) [[READNONE]]
+// NO__ERRNO: declare float @acoshf(float) [[READNONE]]
+// NO__ERRNO: declare x86_fp80 @acoshl(x86_fp80) [[READNONE]]
+// HAS_ERRNO: declare double @acosh(double) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @acoshf(float) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @acoshl(x86_fp80) [[NOT_READNONE]]
+
+ asin(f); asinf(f); asinl(f);
+
+// NO__ERRNO: declare double @asin(double) [[READNONE]]
+// NO__ERRNO: declare float @asinf(float) [[READNONE]]
+// NO__ERRNO: declare x86_fp80 @asinl(x86_fp80) [[READNONE]]
+// HAS_ERRNO: declare double @asin(double) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @asinf(float) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @asinl(x86_fp80) [[NOT_READNONE]]
+
+ asinh(f); asinhf(f); asinhl(f);
+
+// NO__ERRNO: declare double @asinh(double) [[READNONE]]
+// NO__ERRNO: declare float @asinhf(float) [[READNONE]]
+// NO__ERRNO: declare x86_fp80 @asinhl(x86_fp80) [[READNONE]]
+// HAS_ERRNO: declare double @asinh(double) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @asinhf(float) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @asinhl(x86_fp80) [[NOT_READNONE]]
+
+ atan(f); atanf(f); atanl(f);
+
+// NO__ERRNO: declare double @atan(double) [[READNONE]]
+// NO__ERRNO: declare float @atanf(float) [[READNONE]]
+// NO__ERRNO: declare x86_fp80 @atanl(x86_fp80) [[READNONE]]
+// HAS_ERRNO: declare double @atan(double) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @atanf(float) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @atanl(x86_fp80) [[NOT_READNONE]]
+
+ atanh(f); atanhf(f); atanhl(f);
+
+// NO__ERRNO: declare double @atanh(double) [[READNONE]]
+// NO__ERRNO: declare float @atanhf(float) [[READNONE]]
+// NO__ERRNO: declare x86_fp80 @atanhl(x86_fp80) [[READNONE]]
+// HAS_ERRNO: declare double @atanh(double) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @atanhf(float) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @atanhl(x86_fp80) [[NOT_READNONE]]
+
+ cbrt(f); cbrtf(f); cbrtl(f);
+
+// NO__ERRNO: declare double @cbrt(double) [[READNONE]]
+// NO__ERRNO: declare float @cbrtf(float) [[READNONE]]
+// NO__ERRNO: declare x86_fp80 @cbrtl(x86_fp80) [[READNONE]]
+// HAS_ERRNO: declare double @cbrt(double) [[READNONE:#[0-9]+]]
+// HAS_ERRNO: declare float @cbrtf(float) [[READNONE]]
+// HAS_ERRNO: declare x86_fp80 @cbrtl(x86_fp80) [[READNONE]]
+
+ ceil(f); ceilf(f); ceill(f);
+
+// NO__ERRNO: declare double @llvm.ceil.f64(double) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare float @llvm.ceil.f32(float) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare x86_fp80 @llvm.ceil.f80(x86_fp80) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare double @llvm.ceil.f64(double) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare float @llvm.ceil.f32(float) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare x86_fp80 @llvm.ceil.f80(x86_fp80) [[READNONE_INTRINSIC]]
+
+ cos(f); cosf(f); cosl(f);
+
+// NO__ERRNO: declare double @llvm.cos.f64(double) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare float @llvm.cos.f32(float) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare x86_fp80 @llvm.cos.f80(x86_fp80) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare double @cos(double) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @cosf(float) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @cosl(x86_fp80) [[NOT_READNONE]]
+
+ cosh(f); coshf(f); coshl(f);
+
+// NO__ERRNO: declare double @cosh(double) [[READNONE]]
+// NO__ERRNO: declare float @coshf(float) [[READNONE]]
+// NO__ERRNO: declare x86_fp80 @coshl(x86_fp80) [[READNONE]]
+// HAS_ERRNO: declare double @cosh(double) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @coshf(float) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @coshl(x86_fp80) [[NOT_READNONE]]
+
+ erf(f); erff(f); erfl(f);
+
+// NO__ERRNO: declare double @erf(double) [[READNONE]]
+// NO__ERRNO: declare float @erff(float) [[READNONE]]
+// NO__ERRNO: declare x86_fp80 @erfl(x86_fp80) [[READNONE]]
+// HAS_ERRNO: declare double @erf(double) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @erff(float) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @erfl(x86_fp80) [[NOT_READNONE]]
+
+ erfc(f); erfcf(f); erfcl(f);
+
+// NO__ERRNO: declare double @erfc(double) [[READNONE]]
+// NO__ERRNO: declare float @erfcf(float) [[READNONE]]
+// NO__ERRNO: declare x86_fp80 @erfcl(x86_fp80) [[READNONE]]
+// HAS_ERRNO: declare double @erfc(double) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @erfcf(float) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @erfcl(x86_fp80) [[NOT_READNONE]]
+
+ exp(f); expf(f); expl(f);
+
+// NO__ERRNO: declare double @llvm.exp.f64(double) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare float @llvm.exp.f32(float) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare x86_fp80 @llvm.exp.f80(x86_fp80) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare double @exp(double) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @expf(float) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @expl(x86_fp80) [[NOT_READNONE]]
+
+ exp2(f); exp2f(f); exp2l(f);
+
+// NO__ERRNO: declare double @llvm.exp2.f64(double) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare float @llvm.exp2.f32(float) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare x86_fp80 @llvm.exp2.f80(x86_fp80) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare double @exp2(double) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @exp2f(float) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @exp2l(x86_fp80) [[NOT_READNONE]]
+
+ expm1(f); expm1f(f); expm1l(f);
+
+// NO__ERRNO: declare double @expm1(double) [[READNONE]]
+// NO__ERRNO: declare float @expm1f(float) [[READNONE]]
+// NO__ERRNO: declare x86_fp80 @expm1l(x86_fp80) [[READNONE]]
+// HAS_ERRNO: declare double @expm1(double) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @expm1f(float) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @expm1l(x86_fp80) [[NOT_READNONE]]
+
+ fdim(f,f); fdimf(f,f); fdiml(f,f);
+
+// NO__ERRNO: declare double @fdim(double, double) [[READNONE]]
+// NO__ERRNO: declare float @fdimf(float, float) [[READNONE]]
+// NO__ERRNO: declare x86_fp80 @fdiml(x86_fp80, x86_fp80) [[READNONE]]
+// HAS_ERRNO: declare double @fdim(double, double) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @fdimf(float, float) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @fdiml(x86_fp80, x86_fp80) [[NOT_READNONE]]
+
+ floor(f); floorf(f); floorl(f);
+
+// NO__ERRNO: declare double @llvm.floor.f64(double) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare float @llvm.floor.f32(float) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare x86_fp80 @llvm.floor.f80(x86_fp80) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare double @llvm.floor.f64(double) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare float @llvm.floor.f32(float) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare x86_fp80 @llvm.floor.f80(x86_fp80) [[READNONE_INTRINSIC]]
+
+ fma(f,f,f); fmaf(f,f,f); fmal(f,f,f);
+
+// NO__ERRNO: declare double @llvm.fma.f64(double, double, double) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare float @llvm.fma.f32(float, float, float) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare x86_fp80 @llvm.fma.f80(x86_fp80, x86_fp80, x86_fp80) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare double @fma(double, double, double) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @fmaf(float, float, float) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @fmal(x86_fp80, x86_fp80, x86_fp80) [[NOT_READNONE]]
+
+// On GNU or Win, fma never sets errno, so we can convert to the intrinsic.
+
+// HAS_ERRNO_GNU: declare double @llvm.fma.f64(double, double, double) [[READNONE_INTRINSIC:#[0-9]+]]
+// HAS_ERRNO_GNU: declare float @llvm.fma.f32(float, float, float) [[READNONE_INTRINSIC]]
+// HAS_ERRNO_GNU: declare x86_fp80 @llvm.fma.f80(x86_fp80, x86_fp80, x86_fp80) [[READNONE_INTRINSIC]]
+
+// HAS_ERRNO_WIN: declare double @llvm.fma.f64(double, double, double) [[READNONE_INTRINSIC:#[0-9]+]]
+// HAS_ERRNO_WIN: declare float @llvm.fma.f32(float, float, float) [[READNONE_INTRINSIC]]
+// Long double is just double on win, so no f80 use/declaration.
+// HAS_ERRNO_WIN-NOT: declare x86_fp80 @llvm.fma.f80(x86_fp80, x86_fp80, x86_fp80)
+
+ fmax(f,f); fmaxf(f,f); fmaxl(f,f);
+
+// NO__ERRNO: declare double @llvm.maxnum.f64(double, double) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare float @llvm.maxnum.f32(float, float) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare x86_fp80 @llvm.maxnum.f80(x86_fp80, x86_fp80) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare double @llvm.maxnum.f64(double, double) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare float @llvm.maxnum.f32(float, float) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare x86_fp80 @llvm.maxnum.f80(x86_fp80, x86_fp80) [[READNONE_INTRINSIC]]
+
+ fmin(f,f); fminf(f,f); fminl(f,f);
+
+// NO__ERRNO: declare double @llvm.minnum.f64(double, double) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare float @llvm.minnum.f32(float, float) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare x86_fp80 @llvm.minnum.f80(x86_fp80, x86_fp80) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare double @llvm.minnum.f64(double, double) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare float @llvm.minnum.f32(float, float) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare x86_fp80 @llvm.minnum.f80(x86_fp80, x86_fp80) [[READNONE_INTRINSIC]]
+
+ hypot(f,f); hypotf(f,f); hypotl(f,f);
+
+// NO__ERRNO: declare double @hypot(double, double) [[READNONE]]
+// NO__ERRNO: declare float @hypotf(float, float) [[READNONE]]
+// NO__ERRNO: declare x86_fp80 @hypotl(x86_fp80, x86_fp80) [[READNONE]]
+// HAS_ERRNO: declare double @hypot(double, double) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @hypotf(float, float) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @hypotl(x86_fp80, x86_fp80) [[NOT_READNONE]]
+
+ ilogb(f); ilogbf(f); ilogbl(f);
+
+// NO__ERRNO: declare i32 @ilogb(double) [[READNONE]]
+// NO__ERRNO: declare i32 @ilogbf(float) [[READNONE]]
+// NO__ERRNO: declare i32 @ilogbl(x86_fp80) [[READNONE]]
+// HAS_ERRNO: declare i32 @ilogb(double) [[NOT_READNONE]]
+// HAS_ERRNO: declare i32 @ilogbf(float) [[NOT_READNONE]]
+// HAS_ERRNO: declare i32 @ilogbl(x86_fp80) [[NOT_READNONE]]
+
+ lgamma(f); lgammaf(f); lgammal(f);
+
+// NO__ERRNO: declare double @lgamma(double) [[NOT_READNONE]]
+// NO__ERRNO: declare float @lgammaf(float) [[NOT_READNONE]]
+// NO__ERRNO: declare x86_fp80 @lgammal(x86_fp80) [[NOT_READNONE]]
+// HAS_ERRNO: declare double @lgamma(double) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @lgammaf(float) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @lgammal(x86_fp80) [[NOT_READNONE]]
+
+ llrint(f); llrintf(f); llrintl(f);
+
+// NO__ERRNO: declare i64 @llrint(double) [[READNONE]]
+// NO__ERRNO: declare i64 @llrintf(float) [[READNONE]]
+// NO__ERRNO: declare i64 @llrintl(x86_fp80) [[READNONE]]
+// HAS_ERRNO: declare i64 @llrint(double) [[NOT_READNONE]]
+// HAS_ERRNO: declare i64 @llrintf(float) [[NOT_READNONE]]
+// HAS_ERRNO: declare i64 @llrintl(x86_fp80) [[NOT_READNONE]]
+
+ llround(f); llroundf(f); llroundl(f);
+
+// NO__ERRNO: declare i64 @llround(double) [[READNONE]]
+// NO__ERRNO: declare i64 @llroundf(float) [[READNONE]]
+// NO__ERRNO: declare i64 @llroundl(x86_fp80) [[READNONE]]
+// HAS_ERRNO: declare i64 @llround(double) [[NOT_READNONE]]
+// HAS_ERRNO: declare i64 @llroundf(float) [[NOT_READNONE]]
+// HAS_ERRNO: declare i64 @llroundl(x86_fp80) [[NOT_READNONE]]
+
+ log(f); logf(f); logl(f);
+
+// NO__ERRNO: declare double @llvm.log.f64(double) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare float @llvm.log.f32(float) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare x86_fp80 @llvm.log.f80(x86_fp80) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare double @log(double) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @logf(float) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @logl(x86_fp80) [[NOT_READNONE]]
+
+ log10(f); log10f(f); log10l(f);
+
+// NO__ERRNO: declare double @llvm.log10.f64(double) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare float @llvm.log10.f32(float) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare x86_fp80 @llvm.log10.f80(x86_fp80) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare double @log10(double) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @log10f(float) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @log10l(x86_fp80) [[NOT_READNONE]]
+
+ log1p(f); log1pf(f); log1pl(f);
+
+// NO__ERRNO: declare double @log1p(double) [[READNONE]]
+// NO__ERRNO: declare float @log1pf(float) [[READNONE]]
+// NO__ERRNO: declare x86_fp80 @log1pl(x86_fp80) [[READNONE]]
+// HAS_ERRNO: declare double @log1p(double) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @log1pf(float) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @log1pl(x86_fp80) [[NOT_READNONE]]
+
+ log2(f); log2f(f); log2l(f);
+
+// NO__ERRNO: declare double @llvm.log2.f64(double) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare float @llvm.log2.f32(float) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare x86_fp80 @llvm.log2.f80(x86_fp80) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare double @log2(double) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @log2f(float) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @log2l(x86_fp80) [[NOT_READNONE]]
+
+ logb(f); logbf(f); logbl(f);
+
+// NO__ERRNO: declare double @logb(double) [[READNONE]]
+// NO__ERRNO: declare float @logbf(float) [[READNONE]]
+// NO__ERRNO: declare x86_fp80 @logbl(x86_fp80) [[READNONE]]
+// HAS_ERRNO: declare double @logb(double) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @logbf(float) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @logbl(x86_fp80) [[NOT_READNONE]]
+
+ lrint(f); lrintf(f); lrintl(f);
+
+// NO__ERRNO: declare i64 @lrint(double) [[READNONE]]
+// NO__ERRNO: declare i64 @lrintf(float) [[READNONE]]
+// NO__ERRNO: declare i64 @lrintl(x86_fp80) [[READNONE]]
+// HAS_ERRNO: declare i64 @lrint(double) [[NOT_READNONE]]
+// HAS_ERRNO: declare i64 @lrintf(float) [[NOT_READNONE]]
+// HAS_ERRNO: declare i64 @lrintl(x86_fp80) [[NOT_READNONE]]
+
+ lround(f); lroundf(f); lroundl(f);
+
+// NO__ERRNO: declare i64 @lround(double) [[READNONE]]
+// NO__ERRNO: declare i64 @lroundf(float) [[READNONE]]
+// NO__ERRNO: declare i64 @lroundl(x86_fp80) [[READNONE]]
+// HAS_ERRNO: declare i64 @lround(double) [[NOT_READNONE]]
+// HAS_ERRNO: declare i64 @lroundf(float) [[NOT_READNONE]]
+// HAS_ERRNO: declare i64 @lroundl(x86_fp80) [[NOT_READNONE]]
+
+ nearbyint(f); nearbyintf(f); nearbyintl(f);
+
+// NO__ERRNO: declare double @llvm.nearbyint.f64(double) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare float @llvm.nearbyint.f32(float) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare x86_fp80 @llvm.nearbyint.f80(x86_fp80) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare double @llvm.nearbyint.f64(double) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare float @llvm.nearbyint.f32(float) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare x86_fp80 @llvm.nearbyint.f80(x86_fp80) [[READNONE_INTRINSIC]]
+
+ nextafter(f,f); nextafterf(f,f); nextafterl(f,f);
+
+// NO__ERRNO: declare double @nextafter(double, double) [[READNONE]]
+// NO__ERRNO: declare float @nextafterf(float, float) [[READNONE]]
+// NO__ERRNO: declare x86_fp80 @nextafterl(x86_fp80, x86_fp80) [[READNONE]]
+// HAS_ERRNO: declare double @nextafter(double, double) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @nextafterf(float, float) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @nextafterl(x86_fp80, x86_fp80) [[NOT_READNONE]]
+
+ nexttoward(f,f); nexttowardf(f,f);nexttowardl(f,f);
+
+// NO__ERRNO: declare double @nexttoward(double, x86_fp80) [[READNONE]]
+// NO__ERRNO: declare float @nexttowardf(float, x86_fp80) [[READNONE]]
+// NO__ERRNO: declare x86_fp80 @nexttowardl(x86_fp80, x86_fp80) [[READNONE]]
+// HAS_ERRNO: declare double @nexttoward(double, x86_fp80) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @nexttowardf(float, x86_fp80) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @nexttowardl(x86_fp80, x86_fp80) [[NOT_READNONE]]
+
+ remainder(f,f); remainderf(f,f); remainderl(f,f);
+
+// NO__ERRNO: declare double @remainder(double, double) [[READNONE]]
+// NO__ERRNO: declare float @remainderf(float, float) [[READNONE]]
+// NO__ERRNO: declare x86_fp80 @remainderl(x86_fp80, x86_fp80) [[READNONE]]
+// HAS_ERRNO: declare double @remainder(double, double) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @remainderf(float, float) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @remainderl(x86_fp80, x86_fp80) [[NOT_READNONE]]
+
+ remquo(f,f,i); remquof(f,f,i); remquol(f,f,i);
+
+// NO__ERRNO: declare double @remquo(double, double, i32*) [[NOT_READNONE]]
+// NO__ERRNO: declare float @remquof(float, float, i32*) [[NOT_READNONE]]
+// NO__ERRNO: declare x86_fp80 @remquol(x86_fp80, x86_fp80, i32*) [[NOT_READNONE]]
+// HAS_ERRNO: declare double @remquo(double, double, i32*) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @remquof(float, float, i32*) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @remquol(x86_fp80, x86_fp80, i32*) [[NOT_READNONE]]
+
+ rint(f); rintf(f); rintl(f);
+
+// NO__ERRNO: declare double @llvm.rint.f64(double) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare float @llvm.rint.f32(float) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare x86_fp80 @llvm.rint.f80(x86_fp80) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare double @llvm.rint.f64(double) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare float @llvm.rint.f32(float) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare x86_fp80 @llvm.rint.f80(x86_fp80) [[READNONE_INTRINSIC]]
+
+ round(f); roundf(f); roundl(f);
+
+// NO__ERRNO: declare double @llvm.round.f64(double) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare float @llvm.round.f32(float) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare x86_fp80 @llvm.round.f80(x86_fp80) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare double @llvm.round.f64(double) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare float @llvm.round.f32(float) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare x86_fp80 @llvm.round.f80(x86_fp80) [[READNONE_INTRINSIC]]
+
+ scalbln(f,f); scalblnf(f,f); scalblnl(f,f);
+
+// NO__ERRNO: declare double @scalbln(double, i64) [[READNONE]]
+// NO__ERRNO: declare float @scalblnf(float, i64) [[READNONE]]
+// NO__ERRNO: declare x86_fp80 @scalblnl(x86_fp80, i64) [[READNONE]]
+// HAS_ERRNO: declare double @scalbln(double, i64) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @scalblnf(float, i64) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @scalblnl(x86_fp80, i64) [[NOT_READNONE]]
+
+ scalbn(f,f); scalbnf(f,f); scalbnl(f,f);
+
+// NO__ERRNO: declare double @scalbn(double, i32) [[READNONE]]
+// NO__ERRNO: declare float @scalbnf(float, i32) [[READNONE]]
+// NO__ERRNO: declare x86_fp80 @scalbnl(x86_fp80, i32) [[READNONE]]
+// HAS_ERRNO: declare double @scalbn(double, i32) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @scalbnf(float, i32) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @scalbnl(x86_fp80, i32) [[NOT_READNONE]]
+
+ sin(f); sinf(f); sinl(f);
+
+// NO__ERRNO: declare double @llvm.sin.f64(double) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare float @llvm.sin.f32(float) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare x86_fp80 @llvm.sin.f80(x86_fp80) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare double @sin(double) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @sinf(float) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @sinl(x86_fp80) [[NOT_READNONE]]
+
+ sinh(f); sinhf(f); sinhl(f);
+
+// NO__ERRNO: declare double @sinh(double) [[READNONE]]
+// NO__ERRNO: declare float @sinhf(float) [[READNONE]]
+// NO__ERRNO: declare x86_fp80 @sinhl(x86_fp80) [[READNONE]]
+// HAS_ERRNO: declare double @sinh(double) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @sinhf(float) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @sinhl(x86_fp80) [[NOT_READNONE]]
+
+ sqrt(f); sqrtf(f); sqrtl(f);
+
+// NO__ERRNO: declare double @llvm.sqrt.f64(double) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare float @llvm.sqrt.f32(float) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare x86_fp80 @llvm.sqrt.f80(x86_fp80) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare double @sqrt(double) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @sqrtf(float) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @sqrtl(x86_fp80) [[NOT_READNONE]]
+
+ tan(f); tanf(f); tanl(f);
+
+// NO__ERRNO: declare double @tan(double) [[READNONE]]
+// NO__ERRNO: declare float @tanf(float) [[READNONE]]
+// NO__ERRNO: declare x86_fp80 @tanl(x86_fp80) [[READNONE]]
+// HAS_ERRNO: declare double @tan(double) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @tanf(float) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @tanl(x86_fp80) [[NOT_READNONE]]
+
+ tanh(f); tanhf(f); tanhl(f);
+
+// NO__ERRNO: declare double @tanh(double) [[READNONE]]
+// NO__ERRNO: declare float @tanhf(float) [[READNONE]]
+// NO__ERRNO: declare x86_fp80 @tanhl(x86_fp80) [[READNONE]]
+// HAS_ERRNO: declare double @tanh(double) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @tanhf(float) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @tanhl(x86_fp80) [[NOT_READNONE]]
+
+ tgamma(f); tgammaf(f); tgammal(f);
+
+// NO__ERRNO: declare double @tgamma(double) [[READNONE]]
+// NO__ERRNO: declare float @tgammaf(float) [[READNONE]]
+// NO__ERRNO: declare x86_fp80 @tgammal(x86_fp80) [[READNONE]]
+// HAS_ERRNO: declare double @tgamma(double) [[NOT_READNONE]]
+// HAS_ERRNO: declare float @tgammaf(float) [[NOT_READNONE]]
+// HAS_ERRNO: declare x86_fp80 @tgammal(x86_fp80) [[NOT_READNONE]]
+
+ trunc(f); truncf(f); truncl(f);
+
+// NO__ERRNO: declare double @llvm.trunc.f64(double) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare float @llvm.trunc.f32(float) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare x86_fp80 @llvm.trunc.f80(x86_fp80) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare double @llvm.trunc.f64(double) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare float @llvm.trunc.f32(float) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare x86_fp80 @llvm.trunc.f80(x86_fp80) [[READNONE_INTRINSIC]]
+};
+
+
+// NO__ERRNO: attributes [[READNONE]] = { {{.*}}readnone{{.*}} }
+// NO__ERRNO: attributes [[READNONE_INTRINSIC]] = { {{.*}}readnone{{.*}} }
+// NO__ERRNO: attributes [[NOT_READNONE]] = { nounwind "correctly{{.*}} }
+// NO__ERRNO: attributes [[READONLY]] = { {{.*}}readonly{{.*}} }
+
+// HAS_ERRNO: attributes [[NOT_READNONE]] = { nounwind "correctly{{.*}} }
+// HAS_ERRNO: attributes [[READNONE_INTRINSIC]] = { {{.*}}readnone{{.*}} }
+// HAS_ERRNO: attributes [[READONLY]] = { {{.*}}readonly{{.*}} }
+// HAS_ERRNO: attributes [[READNONE]] = { {{.*}}readnone{{.*}} }
+
+// HAS_ERRNO_GNU: attributes [[READNONE_INTRINSIC]] = { {{.*}}readnone{{.*}} }
+// HAS_ERRNO_WIN: attributes [[READNONE_INTRINSIC]] = { {{.*}}readnone{{.*}} }
diff --git a/test/CodeGen/mcount.c b/test/CodeGen/mcount.c
index 2284acac0f8e..98a2a6b39092 100644
--- a/test/CodeGen/mcount.c
+++ b/test/CodeGen/mcount.c
@@ -35,9 +35,9 @@ int main(void) {
return no_instrument();
}
-// CHECK: attributes #0 = { {{.*}}"counting-function"="mcount"{{.*}} }
+// CHECK: attributes #0 = { {{.*}}"instrument-function-entry-inlined"="mcount"{{.*}} }
// CHECK: attributes #1 = { {{.*}} }
-// CHECK-PREFIXED: attributes #0 = { {{.*}}"counting-function"="_mcount"{{.*}} }
+// CHECK-PREFIXED: attributes #0 = { {{.*}}"instrument-function-entry-inlined"="_mcount"{{.*}} }
// CHECK-PREFIXED: attributes #1 = { {{.*}} }
-// NO-MCOUNT-NOT: attributes #{{[0-9]}} = { {{.*}}"counting-function"={{.*}} }
-// NO-MCOUNT1-NOT: attributes #1 = { {{.*}}"counting-function"={{.*}} }
+// NO-MCOUNT-NOT: attributes #{{[0-9]}} = { {{.*}}"instrument-function-entry-inlined"={{.*}} }
+// NO-MCOUNT1-NOT: attributes #1 = { {{.*}}"instrument-function-entry-inlined"={{.*}} }
diff --git a/test/CodeGen/mozilla-ms-inline-asm.c b/test/CodeGen/mozilla-ms-inline-asm.c
index 26e8ebce1e28..0774c8cb3045 100644
--- a/test/CodeGen/mozilla-ms-inline-asm.c
+++ b/test/CodeGen/mozilla-ms-inline-asm.c
@@ -33,7 +33,7 @@ void invoke(void* that, unsigned methodIndex,
// CHECK-SAME: push ecx
// CHECK-SAME: mov edx,[ecx]
// CHECK-SAME: mov eax,$4
-// CHECK-SAME: call dword ptr[edx+eax*$$4]
+// CHECK-SAME: call dword ptr[edx + eax * $$4]
// CHECK-SAME: mov esp,ebp
// CHECK-SAME: pop ebp
// CHECK-SAME: ret
diff --git a/test/CodeGen/ms-annotation.c b/test/CodeGen/ms-annotation.c
new file mode 100644
index 000000000000..6f4a20c7b154
--- /dev/null
+++ b/test/CodeGen/ms-annotation.c
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -triple i686-windows %s -fms-extensions -emit-llvm -o - | FileCheck %s
+//
+// Test that LLVM optimizations leave these intrinsics alone, for the most part.
+// RUN: %clang_cc1 -O2 -triple i686-windows %s -fms-extensions -emit-llvm -o - | FileCheck %s
+
+void test1(void) {
+ __annotation(L"a1");
+ __annotation(L"a1", L"a2");
+ __annotation(L"a1", L"a2", L"a3");
+ __annotation(L"multi " L"part " L"string");
+ __annotation(L"unicode: \u0ca0_\u0ca0");
+}
+
+// CHECK-LABEL: define void @test1()
+// CHECK: call void @llvm.codeview.annotation(metadata ![[A1:[0-9]+]])
+// CHECK: call void @llvm.codeview.annotation(metadata ![[A2:[0-9]+]])
+// CHECK: call void @llvm.codeview.annotation(metadata ![[A3:[0-9]+]])
+// CHECK: call void @llvm.codeview.annotation(metadata ![[A4:[0-9]+]])
+// CHECK: call void @llvm.codeview.annotation(metadata ![[A5:[0-9]+]])
+// CHECK: ret void
+
+// CHECK: ![[A1]] = !{!"a1"}
+// CHECK: ![[A2]] = !{!"a1", !"a2"}
+// CHECK: ![[A3]] = !{!"a1", !"a2", !"a3"}
+// CHECK: ![[A4]] = !{!"multi part string"}
+// CHECK: ![[A5]] = !{!"unicode: \E0\B2\A0_\E0\B2\A0"}
diff --git a/test/CodeGen/ms-inline-asm-64.c b/test/CodeGen/ms-inline-asm-64.c
index 69828feb3623..5b144eb7bb68 100644
--- a/test/CodeGen/ms-inline-asm-64.c
+++ b/test/CodeGen/ms-inline-asm-64.c
@@ -34,8 +34,8 @@ int t3() {
// CHECK: t3
// CHECK: call void asm sideeffect inteldialect
// CHECK-SAME: lea ebx, $0
-// CHECK-SAME: mov eax, [ebx].0
-// CHECK-SAME: mov [ebx].4, ecx
+// CHECK-SAME: mov eax, [ebx]
+// CHECK-SAME: mov [ebx + $$4], ecx
// CHECK-SAME: "*m,~{eax},~{ebx},~{dirflag},~{fpsr},~{flags}"(%struct.t3_type* %{{.*}})
}
@@ -54,7 +54,7 @@ int t4() {
// CHECK: t4
// CHECK: call void asm sideeffect inteldialect
// CHECK-SAME: lea ebx, $0
-// CHECK-SAME: mov eax, [ebx].0
-// CHECK-SAME: mov [ebx].4, ecx
+// CHECK-SAME: mov eax, [ebx]
+// CHECK-SAME: mov [ebx + $$4], ecx
// CHECK-SAME: "*m,~{eax},~{ebx},~{dirflag},~{fpsr},~{flags}"(%struct.t3_type* %{{.*}})
}
diff --git a/test/CodeGen/ms-inline-asm-enums.cpp b/test/CodeGen/ms-inline-asm-enums.cpp
new file mode 100644
index 000000000000..4e9225ab4759
--- /dev/null
+++ b/test/CodeGen/ms-inline-asm-enums.cpp
@@ -0,0 +1,55 @@
+// REQUIRES: x86-registered-target
+// RUN: %clang_cc1 %s -fasm-blocks -triple i386-apple-darwin10 -emit-llvm -o - | FileCheck %s
+
+namespace x {
+ enum { A = 12 };
+ struct y_t {
+ enum { A = 17 };
+ int r;
+ } y;
+}
+
+// CHECK-LABEL: t1
+void t1() {
+ enum { A = 1 };
+ // CHECK: call void asm
+ // CHECK-SAME: mov eax, $$12
+ __asm mov eax, x::A
+ // CHECK-SAME: mov eax, $$17
+ __asm mov eax, x::y_t::A
+ // CHECK-NEXT: call void asm
+ // CHECK-SAME: mov eax, $$1
+ __asm {mov eax, A}
+}
+
+// CHECK-LABEL: t2
+void t2() {
+ enum { A = 1, B };
+ // CHECK: call void asm
+ // CHECK-SAME: mov eax, $$21
+ __asm mov eax, (A + 9) * 2 + A
+ // CHECK-SAME: mov eax, $$4
+ __asm mov eax, A << 2
+ // CHECK-SAME: mov eax, $$2
+ __asm mov eax, B & 3
+ // CHECK-SAME: mov eax, $$5
+ __asm mov eax, 3 + (B & 3)
+ // CHECK-SAME: mov eax, $$8
+ __asm mov eax, 2 << A * B
+}
+
+// CHECK-LABEL: t3
+void t3() {
+ int arr[4];
+ enum { A = 4, B };
+ // CHECK: call void asm
+ // CHECK-SAME: mov eax, [eax + $$47]
+ __asm { mov eax, [(x::A + 9) + A * B + 3 + 3 + eax] }
+ // CHECK-NEXT: call void asm
+ // CHECK-SAME: mov eax, dword ptr $0[$$4]
+ __asm { mov eax, dword ptr [arr + A] }
+ // CHECK-NEXT: call void asm
+ // CHECK-SAME: mov eax, dword ptr $0[$$8]
+ __asm { mov eax, dword ptr A[arr + A] }
+}
+
diff --git a/test/CodeGen/ms-inline-asm-variables.c b/test/CodeGen/ms-inline-asm-variables.c
new file mode 100644
index 000000000000..f8fd227610b6
--- /dev/null
+++ b/test/CodeGen/ms-inline-asm-variables.c
@@ -0,0 +1,35 @@
+// REQUIRES: x86-registered-target
+// RUN: %clang_cc1 %s -fasm-blocks -triple i386-apple-darwin10 -emit-llvm -o - | FileCheck %s
+
+int gVar;
+void t1() {
+ // CHECK: add eax, dword ptr gVar[eax]
+ __asm add eax, dword ptr gVar[eax]
+ // CHECK: add dword ptr gVar[eax], eax
+ __asm add dword ptr [eax+gVar], eax
+ // CHECK: add ebx, dword ptr gVar[ebx + $$270]
+ __asm add ebx, dword ptr gVar[271 - 82 + 81 + ebx]
+ // CHECK: add dword ptr gVar[ebx + $$828], ebx
+ __asm add dword ptr [ebx + gVar + 828], ebx
+ // CHECK: add ecx, dword ptr gVar[ecx + ecx * $$4 + $$4590]
+ __asm add ecx, dword ptr gVar[4590 + ecx + ecx*4]
+ // CHECK: add dword ptr gVar[ecx + ecx * $$8 + $$73], ecx
+ __asm add dword ptr [gVar + ecx + 45 + 23 - 53 + 60 - 2 + ecx*8], ecx
+ // CHECK: add gVar[ecx + ebx + $$7], eax
+ __asm add 1 + 1 + 2 + 3[gVar + ecx + ebx], eax
+}
+
+void t2() {
+ int lVar;
+ // CHECK: mov eax, dword ptr ${{[0-9]}}[eax]
+ __asm mov eax, dword ptr lVar[eax]
+ // CHECK: mov dword ptr ${{[0-9]}}[eax], eax
+ __asm mov dword ptr [eax+lVar], eax
+ // CHECK: mov ebx, dword ptr ${{[0-9]}}[ebx + $$270]
+ __asm mov ebx, dword ptr lVar[271 - 82 + 81 + ebx]
+ // CHECK: mov dword ptr ${{[0-9]}}[ebx + $$828], ebx
+ __asm mov dword ptr [ebx + lVar + 828], ebx
+ // CHECK: mov ${{[0-9]}}[ebx + $$47], eax
+ __asm mov 5 + 8 + 13 + 21[lVar + ebx], eax
+}
+
diff --git a/test/CodeGen/ms-inline-asm.c b/test/CodeGen/ms-inline-asm.c
index d26a660c9b0a..5c3e3ff2a843 100644
--- a/test/CodeGen/ms-inline-asm.c
+++ b/test/CodeGen/ms-inline-asm.c
@@ -42,7 +42,7 @@ void t5(void) {
void t6(void) {
__asm int 0x2c
// CHECK: t6
-// CHECK: call void asm sideeffect inteldialect "int $$0x2c", "~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "int $$44", "~{dirflag},~{fpsr},~{flags}"()
}
void t7() {
@@ -61,7 +61,7 @@ void t7() {
mov eax, ebx
}
// CHECK: t7
-// CHECK: call void asm sideeffect inteldialect "int $$0x2cU", "~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "int $$44", "~{dirflag},~{fpsr},~{flags}"()
// CHECK: call void asm sideeffect inteldialect "", "~{dirflag},~{fpsr},~{flags}"()
// CHECK: call void asm sideeffect inteldialect "mov eax, ebx", "~{eax},~{dirflag},~{fpsr},~{flags}"()
}
@@ -94,7 +94,7 @@ void t9() {
// CHECK: t9
// CHECK: call void asm sideeffect inteldialect
// CHECK-SAME: push ebx
-// CHECK-SAME: mov ebx, $$0x07
+// CHECK-SAME: mov ebx, $$7
// CHECK-SAME: pop ebx
// CHECK-SAME: "~{ebx},~{esp},~{dirflag},~{fpsr},~{flags}"()
}
@@ -229,7 +229,7 @@ void t20() {
__asm mov eax, LENGTH _bar
// CHECK: mov eax, $$2
__asm mov eax, [eax + LENGTH foo * 4]
-// CHECK: mov eax, [eax + $$1 * $$4]
+// CHECK: mov eax, [eax + $$4]
__asm mov eax, TYPE foo
// CHECK: mov eax, $$4
@@ -240,7 +240,7 @@ void t20() {
__asm mov eax, TYPE _bar
// CHECK: mov eax, $$1
__asm mov eax, [eax + TYPE foo * 4]
-// CHECK: mov eax, [eax + $$4 * $$4]
+// CHECK: mov eax, [eax + $$16]
__asm mov eax, SIZE foo
// CHECK: mov eax, $$4
@@ -249,7 +249,7 @@ void t20() {
__asm mov eax, SIZE _foo
// CHECK: mov eax, $$16
__asm mov eax, [eax + SIZE _foo * 4]
-// CHECK: mov eax, [eax + $$16 * $$4]
+// CHECK: mov eax, [eax + $$64]
__asm mov eax, SIZE _bar
// CHECK: mov eax, $$2
// CHECK: "~{eax},~{dirflag},~{fpsr},~{flags}"()
@@ -265,7 +265,7 @@ void t21() {
// CHECK: t21
// CHECK: call void asm sideeffect inteldialect
// CHECK-SAME: push ebx
-// CHECK-SAME: mov ebx, $$07H
+// CHECK-SAME: mov ebx, $$7
// CHECK-SAME: pop ebx
// CHECK-SAME: "~{ebx},~{esp},~{dirflag},~{fpsr},~{flags}"()
}
@@ -312,13 +312,13 @@ void t24() {
void t25() {
// CHECK: t25
__asm mov eax, 0ffffffffh
-// CHECK: mov eax, $$0ffffffffh
+// CHECK: mov eax, $$4294967295
__asm mov eax, 0fhU
// CHECK: mov eax, $$15
__asm mov eax, 0a2h
-// CHECK: mov eax, $$0a2h
+// CHECK: mov eax, $$162
__asm mov eax, 10100010b
-// CHECK: mov eax, $$10100010b
+// CHECK: mov eax, $$162
__asm mov eax, 10100010BU
// CHECK: mov eax, $$162
// CHECK: "~{eax},~{dirflag},~{fpsr},~{flags}"()
@@ -344,7 +344,7 @@ void t26() {
void t27() {
__asm mov eax, fs:[0h]
// CHECK: t27
-// CHECK: call void asm sideeffect inteldialect "mov eax, fs:[$$0h]", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "mov eax, fs:[$$0]", "~{eax},~{dirflag},~{fpsr},~{flags}"()
}
void t28() {
@@ -426,18 +426,18 @@ void t33() {
void t34() {
// CHECK: t34
__asm prefetchnta 64[eax]
-// CHECK: prefetchnta $$64[eax]
+// CHECK: prefetchnta [eax + $$64]
__asm mov eax, dword ptr 4[eax]
-// CHECK: mov eax, dword ptr $$4[eax]
+// CHECK: mov eax, dword ptr [eax + $$4]
// CHECK: "~{eax},~{dirflag},~{fpsr},~{flags}"()
}
void t35() {
// CHECK: t35
__asm prefetchnta [eax + (200*64)]
-// CHECK: prefetchnta [eax + ($$200*$$64)]
+// CHECK: prefetchnta [eax + $$12800]
__asm mov eax, dword ptr [eax + (200*64)]
-// CHECK: mov eax, dword ptr [eax + ($$200*$$64)]
+// CHECK: mov eax, dword ptr [eax + $$12800]
// CHECK: "~{eax},~{dirflag},~{fpsr},~{flags}"()
}
@@ -446,29 +446,29 @@ void t36() {
int arr[4];
// Work around PR20368: These should be single line blocks
__asm { mov eax, 4[arr] }
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$4$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$4]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
__asm { mov eax, 4[arr + 4] }
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$8$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$8]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
__asm { mov eax, 8[arr + 4 + 32*2 - 4] }
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$72$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$72]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
__asm { mov eax, 12[4 + arr] }
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$16$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$16]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
__asm { mov eax, 4[4 + arr + 4] }
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$12$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$12]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
__asm { mov eax, 4[64 + arr + (2*32)] }
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$132$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$132]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
__asm { mov eax, 4[64 + arr - 2*32] }
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$4$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$4]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
__asm { mov eax, [arr + 4] }
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$4$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$4]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
__asm { mov eax, [arr + 4 + 32*2 - 4] }
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$64$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$64]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
__asm { mov eax, [4 + arr] }
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$4$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$4]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
__asm { mov eax, [4 + arr + 4] }
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$8$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$8]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
__asm { mov eax, [64 + arr + (2*32)] }
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$128$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$128]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
__asm { mov eax, [64 + arr - 2*32] }
// CHECK: call void asm sideeffect inteldialect "mov eax, $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
}
@@ -484,13 +484,13 @@ void t37() {
__asm mov eax, (4 + 4) * 16
// CHECK: mov eax, $$128
__asm mov eax, 4 + 8 * -16
-// CHECK: mov eax, $$4294967172
+// CHECK: mov eax, $$-124
__asm mov eax, 4 + 16 / -8
// CHECK: mov eax, $$2
__asm mov eax, (16 + 16) / -8
-// CHECK: mov eax, $$4294967292
+// CHECK: mov eax, $$-4
__asm mov eax, ~15
-// CHECK: mov eax, $$4294967280
+// CHECK: mov eax, $$-16
__asm mov eax, 6 ^ 3
// CHECK: mov eax, $$5
// CHECK: "~{eax},~{dirflag},~{fpsr},~{flags}"()
@@ -501,21 +501,21 @@ void t38() {
int arr[4];
// Work around PR20368: These should be single line blocks
__asm { mov eax, 4+4[arr] }
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$8$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$8]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
__asm { mov eax, (4+4)[arr + 4] }
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$12$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$12]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
__asm { mov eax, 8*2[arr + 4 + 32*2 - 4] }
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$80$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$80]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
__asm { mov eax, 12+20[4 + arr] }
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$36$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$36]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
__asm { mov eax, 4*16+4[4 + arr + 4] }
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$76$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$76]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
__asm { mov eax, 4*4[64 + arr + (2*32)] }
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$144$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$144]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
__asm { mov eax, 4*(4-2)[64 + arr - 2*32] }
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$8$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$8]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
__asm { mov eax, 32*(4-2)[arr - 2*32] }
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$0$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
}
void cpuid() {
@@ -527,7 +527,7 @@ void cpuid() {
typedef struct {
int a;
int b;
-} A;
+} A, *pA;
typedef struct {
int b1;
@@ -539,24 +539,28 @@ typedef struct {
A c2;
int c3;
B c4;
-} C;
+} C, *pC;
void t39() {
// CHECK-LABEL: define void @t39
__asm mov eax, [eax].A.b
-// CHECK: mov eax, [eax].4
+// CHECK: mov eax, [eax + $$4]
__asm mov eax, [eax] A.b
-// CHECK: mov eax, [eax] .4
+// CHECK: mov eax, [eax + $$4]
+ __asm mov eax, [eax] pA.b
+// CHECK: mov eax, [eax + $$4]
__asm mov eax, fs:[0] A.b
-// CHECK: mov eax, fs:[$$0] .4
+// CHECK: mov eax, fs:[$$4]
__asm mov eax, [eax].B.b2.a
-// CHECK: mov eax, [eax].4
+// CHECK: mov eax, [eax + $$4]
__asm mov eax, [eax] B.b2.b
-// CHECK: mov eax, [eax] .8
+// CHECK: mov eax, [eax + $$8]
__asm mov eax, fs:[0] C.c2.b
-// CHECK: mov eax, fs:[$$0] .8
+// CHECK: mov eax, fs:[$$8]
__asm mov eax, [eax]C.c4.b2.b
-// CHECK: mov eax, [eax].24
+// CHECK: mov eax, [eax + $$24]
+ __asm mov eax, [eax]pC.c4.b2.b
+// CHECK: mov eax, [eax + $$24]
// CHECK: "~{eax},~{dirflag},~{fpsr},~{flags}"()
}
@@ -573,17 +577,17 @@ void t40(float a) {
void t41(unsigned short a) {
// CHECK-LABEL: define void @t41(i16 zeroext %a)
__asm mov cs, a;
-// CHECK: mov cs, word ptr $0
+// CHECK: mov cs, $0
__asm mov ds, a;
-// CHECK: mov ds, word ptr $1
+// CHECK: mov ds, $1
__asm mov es, a;
-// CHECK: mov es, word ptr $2
+// CHECK: mov es, $2
__asm mov fs, a;
-// CHECK: mov fs, word ptr $3
+// CHECK: mov fs, $3
__asm mov gs, a;
-// CHECK: mov gs, word ptr $4
+// CHECK: mov gs, $4
__asm mov ss, a;
-// CHECK: mov ss, word ptr $5
+// CHECK: mov ss, $5
// CHECK: "*m,*m,*m,*m,*m,*m,~{dirflag},~{fpsr},~{flags}"(i16* {{.*}}, i16* {{.*}}, i16* {{.*}}, i16* {{.*}}, i16* {{.*}}, i16* {{.*}})
}
@@ -600,37 +604,78 @@ void t43() {
C strct;
// Work around PR20368: These should be single line blocks
__asm { mov eax, 4[strct.c1] }
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$4$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$4]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
__asm { mov eax, 4[strct.c3 + 4] }
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$8$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$8]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
__asm { mov eax, 8[strct.c2.a + 4 + 32*2 - 4] }
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$72$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$72]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
__asm { mov eax, 12[4 + strct.c2.b] }
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$16$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$16]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
__asm { mov eax, 4[4 + strct.c4.b2.b + 4] }
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$12$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$12]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
__asm { mov eax, 4[64 + strct.c1 + (2*32)] }
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$132$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$132]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
__asm { mov eax, 4[64 + strct.c2.a - 2*32] }
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$4$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$4]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
__asm { mov eax, [strct.c4.b1 + 4] }
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$4$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$4]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
__asm { mov eax, [strct.c4.b2.a + 4 + 32*2 - 4] }
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$64$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$64]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
__asm { mov eax, [4 + strct.c1] }
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$4$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$4]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
__asm { mov eax, [4 + strct.c2.b + 4] }
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$8$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$8]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
__asm { mov eax, [64 + strct.c3 + (2*32)] }
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$128$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$128]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
__asm { mov eax, [64 + strct.c4.b2.b - 2*32] }
// CHECK: call void asm sideeffect inteldialect "mov eax, $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
}
+void t44() {
+ // CHECK-LABEL: define void @t44
+ __asm {
+ mov cr0, eax
+ mov cr2, ebx
+ mov cr3, ecx
+ mov cr4, edx
+ }
+ // CHECK: call void asm sideeffect inteldialect "mov cr0, eax\0A\09mov cr2, ebx\0A\09mov cr3, ecx\0A\09mov cr4, edx", "~{cr0},~{cr2},~{cr3},~{cr4},~{dirflag},~{fpsr},~{flags}"()
+}
+
+void t45() {
+ // CHECK-LABEL: define void @t45
+ __asm {
+ mov dr0, eax
+ mov dr1, ebx
+ mov dr2, ebx
+ mov dr3, ecx
+ mov dr6, edx
+ mov dr7, ecx
+ }
+ // CHECK: call void asm sideeffect inteldialect "mov dr0, eax\0A\09mov dr1, ebx\0A\09mov dr2, ebx\0A\09mov dr3, ecx\0A\09mov dr6, edx\0A\09mov dr7, ecx", "~{dr0},~{dr1},~{dr2},~{dr3},~{dr6},~{dr7},~{dirflag},~{fpsr},~{flags}"()
+}
+
+void t46() {
+ // CHECK-LABEL: define void @t46
+ __asm add eax, -128[eax]
+ // CHECK: call void asm sideeffect inteldialect "add eax, [eax + $$-128]", "~{eax},~{flags},~{dirflag},~{fpsr},~{flags}"()
+}
+
+void t47() {
+ // CHECK-LABEL: define void @t47
+ __asm {
+ bndmk bnd0, dword ptr [eax]
+ bndmk bnd1, dword ptr [ebx]
+ bndmk bnd2, dword ptr [ecx]
+ bndmk bnd3, dword ptr [edx]
+ }
+ // CHECK: call void asm sideeffect inteldialect "bndmk bnd0, dword ptr [eax]\0A\09bndmk bnd1, dword ptr [ebx]\0A\09bndmk bnd2, dword ptr [ecx]\0A\09bndmk bnd3, dword ptr [edx]", "~{bnd0},~{bnd1},~{bnd2},~{bnd3},~{dirflag},~{fpsr},~{flags}"()
+}
+
void dot_operator(){
-// CHECK-LABEL: define void @dot_operator
+ // CHECK-LABEL: define void @dot_operator
__asm { mov eax, 3[ebx]A.b}
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$3[ebx].4", "~{eax},~{dirflag},~{fpsr},~{flags}"
+ // CHECK: call void asm sideeffect inteldialect "mov eax, [ebx + $$7]", "~{eax},~{dirflag},~{fpsr},~{flags}"
}
void call_clobber() {
@@ -693,10 +738,12 @@ void label5() {
void label6(){
__asm {
jmp short label
+ jc short label
+ jz short label
label:
}
// CHECK-LABEL: define void @label6
- // CHECK: call void asm sideeffect inteldialect "jmp {{.*}}__MSASMLABEL_.${:uid}__label\0A\09{{.*}}__MSASMLABEL_.${:uid}__label:", "~{dirflag},~{fpsr},~{flags}"()
+ // CHECK: jmp {{.*}}__MSASMLABEL_.${:uid}__label\0A\09jc {{.*}}__MSASMLABEL_.${:uid}__label\0A\09jz {{.*}}__MSASMLABEL_.${:uid}__label\0A\09{{.*}}__MSASMLABEL_.${:uid}__label:"
}
// Don't include mxcsr in the clobber list.
diff --git a/test/CodeGen/ms-inline-asm.cpp b/test/CodeGen/ms-inline-asm.cpp
index a435e4b826d8..039cde9e10ed 100644
--- a/test/CodeGen/ms-inline-asm.cpp
+++ b/test/CodeGen/ms-inline-asm.cpp
@@ -130,7 +130,7 @@ void t7_struct() {
__asm mov eax, [eax].A.b
// CHECK-LABEL: define void @_Z9t7_structv
// CHECK: call void asm sideeffect inteldialect
- // CHECK-SAME: mov eax, [eax].4
+ // CHECK-SAME: mov eax, [eax + $$4]
// CHECK-SAME: "~{eax},~{dirflag},~{fpsr},~{flags}"()
}
@@ -142,7 +142,7 @@ void t7_typedef() {
__asm mov eax, [eax].A.b
// CHECK-LABEL: define void @_Z10t7_typedefv
// CHECK: call void asm sideeffect inteldialect
- // CHECK-SAME: mov eax, [eax].4
+ // CHECK-SAME: mov eax, [eax + $$4]
// CHECK-SAME: "~{eax},~{dirflag},~{fpsr},~{flags}"()
}
@@ -154,7 +154,7 @@ void t7_using() {
__asm mov eax, [eax].A.b
// CHECK-LABEL: define void @_Z8t7_usingv
// CHECK: call void asm sideeffect inteldialect
- // CHECK-SAME: mov eax, [eax].4
+ // CHECK-SAME: mov eax, [eax + $$4]
// CHECK-SAME: "~{eax},~{dirflag},~{fpsr},~{flags}"()
}
@@ -180,3 +180,19 @@ void t8() {
A::g();
}
+void t9() {
+ // CHECK-LABEL: define void @_Z2t9v()
+ struct A {
+ int a;
+ int b;
+ void g() {
+ __asm mov eax, dword ptr [eax]this.b
+ // CHECK: call void asm sideeffect inteldialect
+ // CHECK-SAME: mov eax, dword ptr [eax + $$4]
+ // CHECK-SAME: "~{eax},~{dirflag},~{fpsr},~{flags}"()
+ }
+ };
+ A AA;
+ AA.g();
+}
+
diff --git a/test/CodeGen/ms-intrinsics.c b/test/CodeGen/ms-intrinsics.c
index 818be7fd7ffd..38cda9785029 100644
--- a/test/CodeGen/ms-intrinsics.c
+++ b/test/CodeGen/ms-intrinsics.c
@@ -5,7 +5,7 @@
// RUN: -triple thumbv7--windows -Oz -emit-llvm %s -o - \
// RUN: | FileCheck %s --check-prefixes CHECK,CHECK-ARM,CHECK-ARM-X64
// RUN: %clang_cc1 -ffreestanding -fms-extensions -fms-compatibility -fms-compatibility-version=17.00 \
-// RUN: -triple x86_64--windows -Oz -emit-llvm %s -o - \
+// RUN: -triple x86_64--windows -Oz -emit-llvm -target-feature +cx16 %s -o - \
// RUN: | FileCheck %s --check-prefixes CHECK,CHECK-X64,CHECK-ARM-X64,CHECK-INTEL
// intrin.h needs size_t, but -ffreestanding prevents us from getting it from
@@ -329,6 +329,27 @@ __int64 test_InterlockedCompareExchange64(__int64 volatile *Destination, __int64
// CHECK: ret i64 [[RESULT]]
// CHECK: }
+#if defined(__x86_64__)
+unsigned char test_InterlockedCompareExchange128(__int64 volatile *Destination, __int64 ExchangeHigh, __int64 ExchangeLow, __int64* ComparandResult) {
+ return _InterlockedCompareExchange128(Destination, ExchangeHigh, ExchangeLow, ComparandResult);
+}
+// CHECK-X64: define{{.*}}i8 @test_InterlockedCompareExchange128(i64*{{[a-z_ ]*}}%Destination, i64{{[a-z_ ]*}}%ExchangeHigh, i64{{[a-z_ ]*}}%ExchangeLow, i64*{{[a-z_ ]*}}%ComparandResult){{.*}}{
+// CHECK-X64: [[DST:%[0-9]+]] = bitcast i64* %Destination to i128*
+// CHECK-X64: [[EH:%[0-9]+]] = zext i64 %ExchangeHigh to i128
+// CHECK-X64: [[EL:%[0-9]+]] = zext i64 %ExchangeLow to i128
+// CHECK-X64: [[CNR:%[0-9]+]] = bitcast i64* %ComparandResult to i128*
+// CHECK-X64: [[EHS:%[0-9]+]] = shl nuw i128 [[EH]], 64
+// CHECK-X64: [[EXP:%[0-9]+]] = or i128 [[EHS]], [[EL]]
+// CHECK-X64: [[ORG:%[0-9]+]] = load i128, i128* [[CNR]], align 16
+// CHECK-X64: [[RES:%[0-9]+]] = cmpxchg volatile i128* [[DST]], i128 [[ORG]], i128 [[EXP]] seq_cst seq_cst
+// CHECK-X64: [[OLD:%[0-9]+]] = extractvalue { i128, i1 } [[RES]], 0
+// CHECK-X64: store i128 [[OLD]], i128* [[CNR]], align 16
+// CHECK-X64: [[SUC1:%[0-9]+]] = extractvalue { i128, i1 } [[RES]], 1
+// CHECK-X64: [[SUC8:%[0-9]+]] = zext i1 [[SUC1]] to i8
+// CHECK-X64: ret i8 [[SUC8]]
+// CHECK-X64: }
+#endif
+
short test_InterlockedIncrement16(short volatile *Addend) {
return _InterlockedIncrement16(Addend);
}
diff --git a/test/CodeGen/nobuiltin.c b/test/CodeGen/nobuiltin.c
index f80c3c332ab4..543918f67491 100644
--- a/test/CodeGen/nobuiltin.c
+++ b/test/CodeGen/nobuiltin.c
@@ -4,6 +4,10 @@
// RUN: %clang_cc1 -triple x86_64-linux-gnu -fno-builtin -O1 -S -o - %s | FileCheck -check-prefix=NOSTRCPY -check-prefix=NOMEMSET %s
// RUN: %clang_cc1 -triple x86_64-linux-gnu -fno-builtin-memset -O1 -S -o - %s | FileCheck -check-prefix=STRCPY -check-prefix=NOMEMSET %s
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -O1 -fexperimental-new-pass-manager -S -o - %s | FileCheck -check-prefix=STRCPY -check-prefix=MEMSET %s
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -fno-builtin -O1 -fexperimental-new-pass-manager -S -o - %s | FileCheck -check-prefix=NOSTRCPY -check-prefix=NOMEMSET %s
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -fno-builtin-memset -O1 -fexperimental-new-pass-manager -S -o - %s | FileCheck -check-prefix=STRCPY -check-prefix=NOMEMSET %s
+
void PR13497() {
char content[2];
// make sure we don't optimize this call to strcpy()
diff --git a/test/CodeGen/noplt.c b/test/CodeGen/noplt.c
new file mode 100644
index 000000000000..f467199efab2
--- /dev/null
+++ b/test/CodeGen/noplt.c
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -emit-llvm -fno-plt %s -o - | FileCheck %s -check-prefix=CHECK-NOPLT
+
+// CHECK-NOPLT: Function Attrs: nonlazybind
+// CHECK-NOPLT-NEXT: declare {{.*}}i32 @foo
+int foo();
+
+int bar() {
+ return foo();
+}
diff --git a/test/CodeGen/nullptr-arithmetic.c b/test/CodeGen/nullptr-arithmetic.c
new file mode 100644
index 000000000000..ce9c9765b0f7
--- /dev/null
+++ b/test/CodeGen/nullptr-arithmetic.c
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 -S %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -S %s -emit-llvm -triple i686-unknown-unknown -o - | FileCheck %s
+// RUN: %clang_cc1 -S %s -emit-llvm -triple x86_64-unknown-unknown -o - | FileCheck %s
+
+#include <stdint.h>
+
+// This test is meant to verify code that handles the 'p = nullptr + n' idiom
+// used by some versions of glibc and gcc. This is undefined behavior but
+// it is intended there to act like a conversion from a pointer-sized integer
+// to a pointer, and we would like to tolerate that.
+
+#define NULLPTRI8 ((int8_t*)0)
+
+// This should get the inttoptr instruction.
+int8_t *test1(intptr_t n) {
+ return NULLPTRI8 + n;
+}
+// CHECK-LABEL: test1
+// CHECK: inttoptr
+// CHECK-NOT: getelementptr
+
+// This doesn't meet the idiom because the element type is larger than a byte.
+int16_t *test2(intptr_t n) {
+ return (int16_t*)0 + n;
+}
+// CHECK-LABEL: test2
+// CHECK: getelementptr
+// CHECK-NOT: inttoptr
+
+// This doesn't meet the idiom because the offset is subtracted.
+int8_t* test3(intptr_t n) {
+ return NULLPTRI8 - n;
+}
+// CHECK-LABEL: test3
+// CHECK: getelementptr
+// CHECK-NOT: inttoptr
+
+// This checks the case where the offset isn't pointer-sized.
+// The front end will implicitly cast the offset to an integer, so we need to
+// make sure that doesn't cause problems on targets where integers and pointers
+// are not the same size.
+int8_t *test4(int8_t b) {
+ return NULLPTRI8 + b;
+}
+// CHECK-LABEL: test4
+// CHECK: inttoptr
+// CHECK-NOT: getelementptr
diff --git a/test/CodeGen/pascal-wchar-string.c b/test/CodeGen/pascal-wchar-string.c
index 626fc99f15fb..ac36e4028f4c 100644
--- a/test/CodeGen/pascal-wchar-string.c
+++ b/test/CodeGen/pascal-wchar-string.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm -o - %s -fpascal-strings -fshort-wchar | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -o - %s -fpascal-strings -fwchar-type=short -fno-signed-wchar | FileCheck %s
// rdar://8020384
#include <stddef.h>
diff --git a/test/CodeGen/ppc-vector-compare.cc b/test/CodeGen/ppc-vector-compare.cc
new file mode 100644
index 000000000000..e1c92bb6bef3
--- /dev/null
+++ b/test/CodeGen/ppc-vector-compare.cc
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -target-feature +vsx -triple powerpc64-unknown-unknown -emit-llvm %s \
+// RUN: -o - | FileCheck %s
+
+#include <altivec.h>
+
+// CHECK-LABEL: @_Z5test1Dv8_tS_
+// CHECK: @llvm.ppc.altivec.vcmpequh.p
+bool test1(vector unsigned short v1, vector unsigned short v2) {
+ return v1 == v2;
+}
+
+// CHECK-LABEL: @_Z5test2Dv2_mS_Dv2_lS0_Dv2_yS1_Dv2_xS2_Dv2_dS3_
+bool test2(vector unsigned long v1, vector unsigned long v2,
+ vector long v3, vector long v4,
+ vector unsigned long long v5, vector unsigned long long v6,
+ vector long long v7, vector long long v8,
+ vector double v9, vector double v10) {
+ // CHECK: @llvm.ppc.altivec.vcmpequd.p
+ bool res = v1 == v2;
+
+ // CHECK: @llvm.ppc.altivec.vcmpequd.p
+ res |= v3 == v4;
+
+ // CHECK: @llvm.ppc.altivec.vcmpequd.p
+ res |= v5 == v6;
+
+ // CHECK: @llvm.ppc.altivec.vcmpequd.p
+ res |= v7 == v8;
+
+ // CHECK: @llvm.ppc.vsx.xvcmpeqdp.p
+ res |= v9 == v10;
+ return res;
+}
+
diff --git a/test/CodeGen/pr34021.c b/test/CodeGen/pr34021.c
new file mode 100644
index 000000000000..3c7a75a95aa9
--- /dev/null
+++ b/test/CodeGen/pr34021.c
@@ -0,0 +1,25 @@
+// REQUIRES: x86-registered-target
+// RUN: %clang_cc1 -fms-extensions %s -triple=i686-unknown-unknown -emit-llvm -o - | FileCheck %s --check-prefix=X86
+// RUN: %clang_cc1 -fms-extensions %s -triple=x86_64-unknown-unknown -emit-llvm -o - | FileCheck %s --check-prefix=X64
+
+typedef int v4si __attribute__ ((vector_size (16)));
+v4si rep() {
+// X86-LABEL: define <4 x i32> @rep
+// X86: %[[ALLOCA0:.*]] = alloca <4 x i32>, align 16
+// X86: %[[ALLOCA1:.*]] = alloca <4 x i32>, align 16
+// X86: %[[BITCAST:.*]] = bitcast <4 x i32>* %[[ALLOCA0]] to i128*
+// X86: %[[ASM:.*]] = call i64 asm sideeffect inteldialect "", "=A,~{dirflag},~{fpsr},~{flags}"()
+// X86: %[[ZEXT:.*]] = zext i64 %[[ASM]] to i128
+// X86: store i128 %[[ZEXT]], i128* %[[BITCAST]], align 16
+// X86: %[[LOAD:.*]] = load <4 x i32>, <4 x i32>* %[[ALLOCA1]], align 16
+// X86: ret <4 x i32> %[[LOAD]]
+//
+// X64-LABEL: define <4 x i32> @rep
+// X64: %[[ALLOCA:.*]] = alloca <4 x i32>, align 16
+// X64: call void asm sideeffect inteldialect "", "~{dirflag},~{fpsr},~{flags}"()
+// X64: %[[LOAD:.*]] = load <4 x i32>, <4 x i32>* %[[ALLOCA]], align 16
+// X64: ret <4 x i32> %[[LOAD]]
+ v4si res;
+ __asm {}
+ return res;
+}
diff --git a/test/CodeGen/pragma-comment.c b/test/CodeGen/pragma-comment.c
index e20efacdcb22..fae9b8fb9ed8 100644
--- a/test/CodeGen/pragma-comment.c
+++ b/test/CodeGen/pragma-comment.c
@@ -4,6 +4,7 @@
// RUN: %clang_cc1 %s -triple thumbv7-linux-gnueabihf -fms-extensions -emit-llvm -o - | FileCheck -check-prefix LINUX %s
// RUN: %clang_cc1 %s -triple i686-pc-linux -fms-extensions -emit-llvm -o - | FileCheck -check-prefix LINUX %s
// RUN: %clang_cc1 %s -triple x86_64-scei-ps4 -fms-extensions -emit-llvm -o - | FileCheck -check-prefix PS4 %s
+// RUN: %clang_cc1 %s -triple aarch64-windows-msvc -fms-extensions -emit-llvm -o - | FileCheck %s
#pragma comment(lib, "msvcrt.lib")
#pragma comment(lib, "kernel32")
diff --git a/test/CodeGen/preserve-call-conv.c b/test/CodeGen/preserve-call-conv.c
index 6e91a8489b40..b67e29f392a4 100644
--- a/test/CodeGen/preserve-call-conv.c
+++ b/test/CodeGen/preserve-call-conv.c
@@ -1,6 +1,9 @@
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm < %s | FileCheck %s
// RUN: %clang_cc1 -triple arm64-unknown-unknown -emit-llvm < %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-unknown-windows-msvc -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple aarch64-unknown-windows-msvc -emit-llvm %s -o - | FileCheck %s
+
// Check that the preserve_most calling convention attribute at the source level
// is lowered to the corresponding calling convention attrribute at the LLVM IR
// level.
diff --git a/test/CodeGen/profile-sample-accurate.c b/test/CodeGen/profile-sample-accurate.c
new file mode 100644
index 000000000000..556cad753c3c
--- /dev/null
+++ b/test/CodeGen/profile-sample-accurate.c
@@ -0,0 +1,7 @@
+// Test to ensure -emit-llvm profile-sample-accurate is honored by clang.
+// RUN: %clang -S -emit-llvm %s -fprofile-sample-accurate -o - | FileCheck %s
+
+// CHECK: define{{.*}} void @foo()
+// CHECK: attributes{{.*}} "profile-sample-accurate"
+void foo() {
+}
diff --git a/test/CodeGen/push-hidden-visibility-subclass.cpp b/test/CodeGen/push-hidden-visibility-subclass.cpp
new file mode 100644
index 000000000000..82bf65309abc
--- /dev/null
+++ b/test/CodeGen/push-hidden-visibility-subclass.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -triple x86_64-linux-unknown -emit-llvm %s -o - | FileCheck %s
+
+#pragma GCC visibility push(hidden)
+
+struct Base {
+ virtual ~Base() = default;
+ virtual void* Alloc() = 0;
+};
+
+class Child : public Base {
+public:
+ Child() = default;
+ void* Alloc();
+};
+
+void test() {
+ Child x;
+}
+
+// CHECK: @_ZTV5Child = external hidden unnamed_addr constant
diff --git a/test/CodeGen/sanitizer-special-case-list.c b/test/CodeGen/sanitizer-special-case-list.c
new file mode 100644
index 000000000000..45cfecd7efb0
--- /dev/null
+++ b/test/CodeGen/sanitizer-special-case-list.c
@@ -0,0 +1,26 @@
+// Verify that blacklist sections correctly select sanitizers to apply blacklist entries to.
+//
+// RUN: %clang_cc1 -fsanitize=unsigned-integer-overflow,cfi-icall -fsanitize-blacklist=%S/Inputs/sanitizer-special-case-list.unsanitized1.txt -emit-llvm %s -o - | FileCheck %s --check-prefix=UNSANITIZED
+// RUN: %clang_cc1 -fsanitize=unsigned-integer-overflow,cfi-icall -fsanitize-blacklist=%S/Inputs/sanitizer-special-case-list.unsanitized2.txt -emit-llvm %s -o - | FileCheck %s --check-prefix=UNSANITIZED
+// RUN: %clang_cc1 -fsanitize=unsigned-integer-overflow,cfi-icall -fsanitize-blacklist=%S/Inputs/sanitizer-special-case-list.unsanitized3.txt -emit-llvm %s -o - | FileCheck %s --check-prefix=UNSANITIZED
+// RUN: %clang_cc1 -fsanitize=unsigned-integer-overflow,cfi-icall -fsanitize-blacklist=%S/Inputs/sanitizer-special-case-list.unsanitized4.txt -emit-llvm %s -o - | FileCheck %s --check-prefix=UNSANITIZED
+//
+// RUN: %clang_cc1 -fsanitize=unsigned-integer-overflow,cfi-icall -fsanitize-blacklist=%S/Inputs/sanitizer-special-case-list.sanitized.txt -emit-llvm %s -o - | FileCheck %s --check-prefix=SANITIZED
+
+unsigned i;
+
+// SANITIZED: @overflow
+// UNSANITIZED: @overflow
+unsigned overflow() {
+ // SANITIZED: call {{.*}}void @__ubsan
+ // UNSANITIZED-NOT: call {{.*}}void @__ubsan
+ return i * 37;
+}
+
+// SANITIZED: @cfi
+// UNSANITIZED: @cfi
+void cfi(void (*fp)()) {
+ // SANITIZED: llvm.type.test
+ // UNSANITIZED-NOT: llvm.type.test
+ fp();
+}
diff --git a/test/CodeGen/sse2-builtins.c b/test/CodeGen/sse2-builtins.c
index ca51314d80b8..c2279cb88109 100644
--- a/test/CodeGen/sse2-builtins.c
+++ b/test/CodeGen/sse2-builtins.c
@@ -97,13 +97,25 @@ __m128i test_mm_andnot_si128(__m128i A, __m128i B) {
__m128i test_mm_avg_epu8(__m128i A, __m128i B) {
// CHECK-LABEL: test_mm_avg_epu8
- // CHECK: call <16 x i8> @llvm.x86.sse2.pavg.b(<16 x i8> %{{.*}}, <16 x i8> %{{.*}})
+ // CHECK-NOT: call <16 x i8> @llvm.x86.sse2.pavg.b(<16 x i8> %{{.*}}, <16 x i8> %{{.*}})
+ // CHECK: zext <16 x i8> %{{.*}} to <16 x i16>
+ // CHECK: zext <16 x i8> %{{.*}} to <16 x i16>
+ // CHECK: add <16 x i16> %{{.*}}, %{{.*}}
+ // CHECK: add <16 x i16> %{{.*}}, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
+ // CHECK: lshr <16 x i16> %{{.*}}, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
+ // CHECK:trunc <16 x i16> %{{.*}} to <16 x i8>
return _mm_avg_epu8(A, B);
}
__m128i test_mm_avg_epu16(__m128i A, __m128i B) {
// CHECK-LABEL: test_mm_avg_epu16
- // CHECK: call <8 x i16> @llvm.x86.sse2.pavg.w(<8 x i16> %{{.*}}, <8 x i16> %{{.*}})
+ // CHECK-NOT: call <8 x i16> @llvm.x86.sse2.pavg.w(<8 x i16> %{{.*}}, <8 x i16> %{{.*}})
+ // CHECK: zext <8 x i16> %{{.*}} to <8 x i32>
+ // CHECK: zext <8 x i16> %{{.*}} to <8 x i32>
+ // CHECK: add <8 x i32> %{{.*}}, %{{.*}}
+ // CHECK: add <8 x i32> %{{.*}}, <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1>
+ // CHECK: lshr <8 x i32> %{{.*}}, <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1>
+ // CHECK: trunc <8 x i32> %{{.*}} to <8 x i16>
return _mm_avg_epu16(A, B);
}
diff --git a/test/CodeGen/ssse3-builtins.c b/test/CodeGen/ssse3-builtins.c
index b2279e277cd2..4fd22aa79b46 100644
--- a/test/CodeGen/ssse3-builtins.c
+++ b/test/CodeGen/ssse3-builtins.c
@@ -7,19 +7,25 @@
__m128i test_mm_abs_epi8(__m128i a) {
// CHECK-LABEL: test_mm_abs_epi8
- // CHECK: call <16 x i8> @llvm.x86.ssse3.pabs.b.128(<16 x i8> %{{.*}})
+ // CHECK: [[SUB:%.+]] = sub <16 x i8> zeroinitializer, [[A:%.+]]
+ // CHECK: [[CMP:%.+]] = icmp sgt <16 x i8> [[A]], zeroinitializer
+ // CHECK: %{{.*}} = select <16 x i1> [[CMP]], <16 x i8> [[A]], <16 x i8> [[SUB]]
return _mm_abs_epi8(a);
}
__m128i test_mm_abs_epi16(__m128i a) {
// CHECK-LABEL: test_mm_abs_epi16
- // CHECK: call <8 x i16> @llvm.x86.ssse3.pabs.w.128(<8 x i16> %{{.*}})
+ // CHECK: [[SUB:%.+]] = sub <8 x i16> zeroinitializer, [[A:%.+]]
+ // CHECK: [[CMP:%.+]] = icmp sgt <8 x i16> [[A]], zeroinitializer
+ // CHECK: %{{.*}} = select <8 x i1> [[CMP]], <8 x i16> [[A]], <8 x i16> [[SUB]]
return _mm_abs_epi16(a);
}
__m128i test_mm_abs_epi32(__m128i a) {
// CHECK-LABEL: test_mm_abs_epi32
- // CHECK: call <4 x i32> @llvm.x86.ssse3.pabs.d.128(<4 x i32> %{{.*}})
+ // CHECK: [[SUB:%.+]] = sub <4 x i32> zeroinitializer, [[A:%.+]]
+ // CHECK: [[CMP:%.+]] = icmp sgt <4 x i32> [[A]], zeroinitializer
+ // CHECK: %{{.*}} = select <4 x i1> [[CMP]], <4 x i32> [[A]], <4 x i32> [[SUB]]
return _mm_abs_epi32(a);
}
diff --git a/test/CodeGen/string-literal-short-wstring.c b/test/CodeGen/string-literal-short-wstring.c
index 01de6a4d8027..fb1fe0cad0a8 100644
--- a/test/CodeGen/string-literal-short-wstring.c
+++ b/test/CodeGen/string-literal-short-wstring.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -x c++ -triple %itanium_abi_triple -emit-llvm -fshort-wchar %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=ITANIUM
-// RUN: %clang_cc1 -x c++ -triple %ms_abi_triple -emit-llvm -fshort-wchar %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=MSABI
+// RUN: %clang_cc1 -x c++ -triple %itanium_abi_triple -emit-llvm -fwchar-type=short -fno-signed-wchar %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=ITANIUM
+// RUN: %clang_cc1 -x c++ -triple %ms_abi_triple -emit-llvm -fwchar-type=short -fno-signed-wchar %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=MSABI
// Runs in c++ mode so that wchar_t is available.
// XFAIL: hexagon
diff --git a/test/CodeGen/string-literal-unicode-conversion.c b/test/CodeGen/string-literal-unicode-conversion.c
index 23205b80b027..71286b1fed23 100644
--- a/test/CodeGen/string-literal-unicode-conversion.c
+++ b/test/CodeGen/string-literal-unicode-conversion.c
@@ -1,6 +1,6 @@
// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck -check-prefix=CHECK-C %s
// RUN: %clang_cc1 -x c++ -std=c++0x -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck -check-prefix=CHECK-CPP0X %s
-// RUN: %clang_cc1 -x c++ -std=c++0x -fshort-wchar -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck -check-prefix=CHECK-SHORTWCHAR %s
+// RUN: %clang_cc1 -x c++ -std=c++0x -fwchar-type=short -fno-signed-wchar -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck -check-prefix=CHECK-SHORTWCHAR %s
// This file contains a mix of ISO-8859-1 and UTF-8 encoded data.
// the literal assigned to 'aa' should be the ISO-8859-1 encoding for the code
diff --git a/test/CodeGen/target-builtin-noerror.c b/test/CodeGen/target-builtin-noerror.c
index 2a7d69f1089f..37820b33bada 100644
--- a/test/CodeGen/target-builtin-noerror.c
+++ b/test/CodeGen/target-builtin-noerror.c
@@ -72,4 +72,42 @@ void verifyfeaturestrings() {
(void)__builtin_cpu_supports("avx512pf");
(void)__builtin_cpu_supports("avx512vbmi");
(void)__builtin_cpu_supports("avx512ifma");
+ (void)__builtin_cpu_supports("avx5124vnniw");
+ (void)__builtin_cpu_supports("avx5124fmaps");
+ (void)__builtin_cpu_supports("avx512vpopcntdq");
+}
+
+void verifycpustrings() {
+ (void)__builtin_cpu_is("amd");
+ (void)__builtin_cpu_is("amdfam10h");
+ (void)__builtin_cpu_is("amdfam15h");
+ (void)__builtin_cpu_is("amdfam17h");
+ (void)__builtin_cpu_is("atom");
+ (void)__builtin_cpu_is("barcelona");
+ (void)__builtin_cpu_is("bdver1");
+ (void)__builtin_cpu_is("bdver2");
+ (void)__builtin_cpu_is("bdver3");
+ (void)__builtin_cpu_is("bdver4");
+ (void)__builtin_cpu_is("bonnell");
+ (void)__builtin_cpu_is("broadwell");
+ (void)__builtin_cpu_is("btver1");
+ (void)__builtin_cpu_is("btver2");
+ (void)__builtin_cpu_is("cannonlake");
+ (void)__builtin_cpu_is("core2");
+ (void)__builtin_cpu_is("corei7");
+ (void)__builtin_cpu_is("haswell");
+ (void)__builtin_cpu_is("intel");
+ (void)__builtin_cpu_is("istanbul");
+ (void)__builtin_cpu_is("ivybridge");
+ (void)__builtin_cpu_is("knl");
+ (void)__builtin_cpu_is("knm");
+ (void)__builtin_cpu_is("nehalem");
+ (void)__builtin_cpu_is("sandybridge");
+ (void)__builtin_cpu_is("shanghai");
+ (void)__builtin_cpu_is("silvermont");
+ (void)__builtin_cpu_is("skylake");
+ (void)__builtin_cpu_is("skylake-avx512");
+ (void)__builtin_cpu_is("slm");
+ (void)__builtin_cpu_is("westmere");
+ (void)__builtin_cpu_is("znver1");
}
diff --git a/test/CodeGen/target-data.c b/test/CodeGen/target-data.c
index 851ce5831fa3..3869afec7858 100644
--- a/test/CodeGen/target-data.c
+++ b/test/CodeGen/target-data.c
@@ -116,11 +116,11 @@
// RUN: %clang_cc1 -triple nvptx-unknown -o - -emit-llvm %s | \
// RUN: FileCheck %s -check-prefix=NVPTX
-// NVPTX: target datalayout = "e-p:32:32-i64:64-v16:16-v32:32-n16:32:64"
+// NVPTX: target datalayout = "e-p:32:32-i64:64-i128:128-v16:16-v32:32-n16:32:64"
// RUN: %clang_cc1 -triple nvptx64-unknown -o - -emit-llvm %s | \
// RUN: FileCheck %s -check-prefix=NVPTX64
-// NVPTX64: target datalayout = "e-i64:64-v16:16-v32:32-n16:32:64"
+// NVPTX64: target datalayout = "e-i64:64-i128:128-v16:16-v32:32-n16:32:64"
// RUN: %clang_cc1 -triple r600-unknown -o - -emit-llvm %s | \
// RUN: FileCheck %s -check-prefix=R600
diff --git a/test/CodeGen/tbaa-array.cpp b/test/CodeGen/tbaa-array.cpp
new file mode 100644
index 000000000000..86ca5ccb40dc
--- /dev/null
+++ b/test/CodeGen/tbaa-array.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -triple x86_64-linux -O1 -disable-llvm-passes %s \
+// RUN: -emit-llvm -o - | FileCheck %s
+//
+// Check that we generate correct TBAA information for accesses to array
+// elements.
+
+struct A { int i; };
+struct B { A a[1]; };
+
+int foo(B *b) {
+// CHECK-LABEL: _Z3fooP1B
+// CHECK: load i32, {{.*}}, !tbaa [[TAG_A_i:!.*]]
+ return b->a->i;
+}
+
+// CHECK-DAG: [[TAG_A_i]] = !{[[TYPE_A:!.*]], [[TYPE_int:!.*]], i64 0}
+// CHECK-DAG: [[TYPE_A]] = !{!"_ZTS1A", !{{.*}}, i64 0}
+// CHECK-DAG: [[TYPE_int]] = !{!"int", !{{.*}}, i64 0}
diff --git a/test/CodeGen/tbaa-cast.cpp b/test/CodeGen/tbaa-cast.cpp
new file mode 100644
index 000000000000..2b9e31086664
--- /dev/null
+++ b/test/CodeGen/tbaa-cast.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -triple x86_64-linux -O1 -disable-llvm-passes %s \
+// RUN: -emit-llvm -o - | FileCheck %s
+//
+// Check that we generate correct TBAA information for lvalues constructed
+// with use of casts.
+
+struct V {
+ unsigned n;
+};
+
+struct S {
+ char bytes[4];
+};
+
+void foo(S *p) {
+// CHECK-LABEL: _Z3fooP1S
+// CHECK: store i32 5, {{.*}}, !tbaa [[TAG_V_n:!.*]]
+ ((V*)p->bytes)->n = 5;
+}
+
+// CHECK-DAG: [[TAG_V_n]] = !{[[TYPE_V:!.*]], [[TYPE_int:!.*]], i64 0}
+// CHECK-DAG: [[TYPE_V]] = !{!"_ZTS1V", !{{.*}}, i64 0}
+// CHECK-DAG: [[TYPE_int]] = !{!"int", !{{.*}}, i64 0}
diff --git a/test/CodeGen/tbaa-for-vptr.cpp b/test/CodeGen/tbaa-for-vptr.cpp
index 7b8ae2099e47..6136874cbfcb 100644
--- a/test/CodeGen/tbaa-for-vptr.cpp
+++ b/test/CodeGen/tbaa-for-vptr.cpp
@@ -23,12 +23,12 @@ void CallFoo(A *a, int (A::*fp)() const) {
}
// CHECK-LABEL: @_Z7CallFoo
-// CHECK: %{{.*}} = load {{.*}} !tbaa ![[NUM:[0-9]+]]
+// CHECK: %{{.*}} = load i32 (%struct.A*)**, {{.*}} !tbaa ![[NUM:[0-9]+]]
// CHECK: br i1
-// CHECK: load {{.*}}, !tbaa ![[NUM]]
+// CHECK: load i8*, {{.*}}, !tbaa ![[NUM]]
//
// CHECK-LABEL: @_ZN1AC2Ev
-// CHECK: store {{.*}} !tbaa ![[NUM]]
+// CHECK: store i32 (...)** {{.*}}, !tbaa ![[NUM]]
//
// CHECK: [[NUM]] = !{[[TYPE:!.*]], [[TYPE]], i64 0}
// CHECK: [[TYPE]] = !{!"vtable pointer", !{{.*}}
diff --git a/test/CodeGen/tbaa-reference.cpp b/test/CodeGen/tbaa-reference.cpp
new file mode 100644
index 000000000000..ecdbfbee7f14
--- /dev/null
+++ b/test/CodeGen/tbaa-reference.cpp
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1 -triple x86_64-linux -O1 -disable-llvm-passes %s -emit-llvm -o - | FileCheck %s
+//
+// Check that we generate correct TBAA information for reference accesses.
+
+struct S;
+
+struct B {
+ S &s;
+ B(S &s);
+ S &get();
+};
+
+B::B(S &s) : s(s) {
+// CHECK-LABEL: _ZN1BC2ER1S
+// Check initialization of the reference parameter.
+// CHECK: store %struct.S* {{.*}}, %struct.S** {{.*}}, !tbaa [[TAG_pointer:!.*]]
+
+// Check loading of the reference parameter.
+// CHECK: load %struct.S*, %struct.S** {{.*}}, !tbaa [[TAG_pointer]]
+
+// Check initialization of the reference member.
+// CHECK: store %struct.S* {{.*}}, %struct.S** {{.*}}, !tbaa [[TAG_pointer]]
+}
+
+S &B::get() {
+// CHECK-LABEL: _ZN1B3getEv
+// Check that we access the reference as a structure member.
+// CHECK: load %struct.S*, %struct.S** {{.*}}, !tbaa [[TAG_B_s:!.*]]
+ return s;
+}
+
+// CHECK-DAG: [[TAG_pointer]] = !{[[TYPE_pointer:!.*]], [[TYPE_pointer]], i64 0}
+// CHECK-DAG: [[TAG_B_s]] = !{[[TYPE_B:!.*]], [[TYPE_pointer]], i64 0}
+//
+// CHECK-DAG: [[TYPE_B]] = !{!"_ZTS1B", [[TYPE_pointer]], i64 0}
+// CHECK-DAG: [[TYPE_pointer]] = !{!"any pointer", [[TYPE_char:!.*]], i64 0}
+// CHECK-DAG: [[TYPE_char]] = !{!"omnipotent char", {{!.*}}, i64 0}
diff --git a/test/CodeGen/tbm-builtins.c b/test/CodeGen/tbm-builtins.c
index 8e031408a4b6..136a1d41c4ec 100644
--- a/test/CodeGen/tbm-builtins.c
+++ b/test/CodeGen/tbm-builtins.c
@@ -1,8 +1,4 @@
-// RUN: %clang_cc1 -ffreestanding %s -O3 -triple=x86_64-unknown-unknown -target-feature +tbm -emit-llvm -o - | FileCheck %s
-// FIXME: The code generation checks for add/sub and/or are depending on the optimizer.
-// The REQUIRES keyword will be removed when the FIXME is complete.
-// REQUIRES: x86-registered-target
-
+// RUN: %clang_cc1 -ffreestanding %s -triple=x86_64-unknown-unknown -target-feature +tbm -emit-llvm -o - | FileCheck %s
#include <x86intrin.h>
@@ -28,134 +24,136 @@ unsigned long long test__bextri_u64_bigint(unsigned long long a) {
unsigned int test__blcfill_u32(unsigned int a) {
// CHECK-LABEL: test__blcfill_u32
- // CHECK: [[TMP:%.*]] = add i32 [[SRC:%.*]], 1
- // CHECK-NEXT: %{{.*}} = and i32 [[TMP]], [[SRC]]
+ // CHECK: [[TMP:%.*]] = add i32 %{{.*}}, 1
+ // CHECK: %{{.*}} = and i32 %{{.*}}, [[TMP]]
return __blcfill_u32(a);
}
unsigned long long test__blcfill_u64(unsigned long long a) {
// CHECK-LABEL: test__blcfill_u64
- // CHECK: [[TMPT:%.*]] = add i64 [[SRC:%.*]], 1
- // CHECK-NEXT: %{{.*}} = and i64 [[TMP]], [[SRC]]
+ // CHECK: [[TMP:%.*]] = add i64 %{{.*}}, 1
+ // CHECK: %{{.*}} = and i64 %{{.*}}, [[TMP]]
return __blcfill_u64(a);
}
unsigned int test__blci_u32(unsigned int a) {
// CHECK-LABEL: test__blci_u32
- // CHECK: [[TMP:%.*]] = sub i32 -2, [[SRC:%.*]]
- // CHECK-NEXT: %{{.*}} = or i32 [[TMP]], [[SRC]]
+ // CHECK: [[TMP1:%.*]] = add i32 %{{.*}}, 1
+ // CHECK: [[TMP2:%.*]] = xor i32 [[TMP1]], -1
+ // CHECK: %{{.*}} = or i32 %{{.*}}, [[TMP2]]
return __blci_u32(a);
}
unsigned long long test__blci_u64(unsigned long long a) {
// CHECK-LABEL: test__blci_u64
- // CHECK: [[TMP:%.*]] = sub i64 -2, [[SRC:%.*]]
- // CHECK-NEXT: %{{.*}} = or i64 [[TMP]], [[SRC]]
+ // CHECK: [[TMP1:%.*]] = add i64 %{{.*}}, 1
+ // CHECK: [[TMP2:%.*]] = xor i64 [[TMP1]], -1
+ // CHECK: %{{.*}} = or i64 %{{.*}}, [[TMP2]]
return __blci_u64(a);
}
unsigned int test__blcic_u32(unsigned int a) {
// CHECK-LABEL: test__blcic_u32
- // CHECK: [[TMP1:%.*]] = xor i32 [[SRC:%.*]], -1
- // CHECK-NEXT: [[TMP2:%.*]] = add i32 [[SRC]], 1
- // CHECK-NEXT: {{.*}} = and i32 [[TMP2]], [[TMP1]]
+ // CHECK: [[TMP1:%.*]] = xor i32 %{{.*}}, -1
+ // CHECK: [[TMP2:%.*]] = add i32 %{{.*}}, 1
+ // CHECK-NEXT: {{.*}} = and i32 [[TMP1]], [[TMP2]]
return __blcic_u32(a);
}
unsigned long long test__blcic_u64(unsigned long long a) {
// CHECK-LABEL: test__blcic_u64
- // CHECK: [[TMP1:%.*]] = xor i64 [[SRC:%.*]], -1
- // CHECK-NEXT: [[TMP2:%.*]] = add i64 [[SRC]], 1
- // CHECK-NEXT: {{.*}} = and i64 [[TMP2]], [[TMP1]]
+ // CHECK: [[TMP1:%.*]] = xor i64 %{{.*}}, -1
+ // CHECK: [[TMP2:%.*]] = add i64 %{{.*}}, 1
+ // CHECK-NEXT: {{.*}} = and i64 [[TMP1]], [[TMP2]]
return __blcic_u64(a);
}
unsigned int test__blcmsk_u32(unsigned int a) {
// CHECK-LABEL: test__blcmsk_u32
- // CHECK: [[TMP:%.*]] = add i32 [[SRC:%.*]], 1
- // CHECK-NEXT: {{.*}} = xor i32 [[TMP]], [[SRC]]
+ // CHECK: [[TMP:%.*]] = add i32 %{{.*}}, 1
+ // CHECK-NEXT: {{.*}} = xor i32 %{{.*}}, [[TMP]]
return __blcmsk_u32(a);
}
unsigned long long test__blcmsk_u64(unsigned long long a) {
// CHECK-LABEL: test__blcmsk_u64
- // CHECK: [[TMP:%.*]] = add i64 [[SRC:%.*]], 1
- // CHECK-NEXT: {{.*}} = xor i64 [[TMP]], [[SRC]]
+ // CHECK: [[TMP:%.*]] = add i64 %{{.*}}, 1
+ // CHECK-NEXT: {{.*}} = xor i64 %{{.*}}, [[TMP]]
return __blcmsk_u64(a);
}
unsigned int test__blcs_u32(unsigned int a) {
// CHECK-LABEL: test__blcs_u32
- // CHECK: [[TMP:%.*]] = add i32 [[SRC:%.*]], 1
- // CHECK-NEXT: {{.*}} = or i32 [[TMP]], [[SRC]]
+ // CHECK: [[TMP:%.*]] = add i32 %{{.*}}, 1
+ // CHECK-NEXT: {{.*}} = or i32 %{{.*}}, [[TMP]]
return __blcs_u32(a);
}
unsigned long long test__blcs_u64(unsigned long long a) {
// CHECK-LABEL: test__blcs_u64
- // CHECK: [[TMP:%.*]] = add i64 [[SRC:%.*]], 1
- // CHECK-NEXT: {{.*}} = or i64 [[TMP]], [[SRC]]
+ // CHECK: [[TMP:%.*]] = add i64 %{{.*}}, 1
+ // CHECK-NEXT: {{.*}} = or i64 %{{.*}}, [[TMP]]
return __blcs_u64(a);
}
unsigned int test__blsfill_u32(unsigned int a) {
// CHECK-LABEL: test__blsfill_u32
- // CHECK: [[TMP:%.*]] = add i32 [[SRC:%.*]], -1
- // CHECK-NEXT: {{.*}} = or i32 [[TMP]], [[SRC]]
+ // CHECK: [[TMP:%.*]] = sub i32 %{{.*}}, 1
+ // CHECK-NEXT: {{.*}} = or i32 %{{.*}}, [[TMP]]
return __blsfill_u32(a);
}
unsigned long long test__blsfill_u64(unsigned long long a) {
// CHECK-LABEL: test__blsfill_u64
- // CHECK: [[TMP:%.*]] = add i64 [[SRC:%.*]], -1
- // CHECK-NEXT: {{.*}} = or i64 [[TMP]], [[SRC]]
+ // CHECK: [[TMP:%.*]] = sub i64 %{{.*}}, 1
+ // CHECK-NEXT: {{.*}} = or i64 %{{.*}}, [[TMP]]
return __blsfill_u64(a);
}
unsigned int test__blsic_u32(unsigned int a) {
// CHECK-LABEL: test__blsic_u32
- // CHECK: [[TMP1:%.*]] = xor i32 [[SRC:%.*]], -1
- // CHECK-NEXT: [[TMP2:%.*]] = add i32 [[SRC:%.*]], -1
- // CHECK-NEXT: {{.*}} = or i32 [[TMP2]], [[TMP1]]
+ // CHECK: [[TMP1:%.*]] = xor i32 %{{.*}}, -1
+ // CHECK: [[TMP2:%.*]] = sub i32 %{{.*}}, 1
+ // CHECK-NEXT: {{.*}} = or i32 [[TMP1]], [[TMP2]]
return __blsic_u32(a);
}
unsigned long long test__blsic_u64(unsigned long long a) {
// CHECK-LABEL: test__blsic_u64
- // CHECK: [[TMP1:%.*]] = xor i64 [[SRC:%.*]], -1
- // CHECK-NEXT: [[TMP2:%.*]] = add i64 [[SRC:%.*]], -1
- // CHECK-NEXT: {{.*}} = or i64 [[TMP2]], [[TMP1]]
+ // CHECK: [[TMP1:%.*]] = xor i64 %{{.*}}, -1
+ // CHECK: [[TMP2:%.*]] = sub i64 %{{.*}}, 1
+ // CHECK-NEXT: {{.*}} = or i64 [[TMP1]], [[TMP2]]
return __blsic_u64(a);
}
unsigned int test__t1mskc_u32(unsigned int a) {
// CHECK-LABEL: test__t1mskc_u32
- // CHECK: [[TMP1:%.*]] = xor i32 [[SRC:%.*]], -1
- // CHECK-NEXT: [[TMP2:%.*]] = add i32 [[SRC:%.*]], 1
- // CHECK-NEXT: {{.*}} = or i32 [[TMP2]], [[TMP1]]
+ // CHECK: [[TMP1:%.*]] = xor i32 %{{.*}}, -1
+ // CHECK: [[TMP2:%.*]] = add i32 %{{.*}}, 1
+ // CHECK-NEXT: {{.*}} = or i32 [[TMP1]], [[TMP2]]
return __t1mskc_u32(a);
}
unsigned long long test__t1mskc_u64(unsigned long long a) {
// CHECK-LABEL: test__t1mskc_u64
- // CHECK: [[TMP1:%.*]] = xor i64 [[SRC:%.*]], -1
- // CHECK-NEXT: [[TMP2:%.*]] = add i64 [[SRC:%.*]], 1
- // CHECK-NEXT: {{.*}} = or i64 [[TMP2]], [[TMP1]]
+ // CHECK: [[TMP1:%.*]] = xor i64 %{{.*}}, -1
+ // CHECK: [[TMP2:%.*]] = add i64 %{{.*}}, 1
+ // CHECK-NEXT: {{.*}} = or i64 [[TMP1]], [[TMP2]]
return __t1mskc_u64(a);
}
unsigned int test__tzmsk_u32(unsigned int a) {
// CHECK-LABEL: test__tzmsk_u32
- // CHECK: [[TMP1:%.*]] = xor i32 [[SRC:%.*]], -1
- // CHECK-NEXT: [[TMP2:%.*]] = add i32 [[SRC:%.*]], -1
- // CHECK-NEXT: {{.*}} = and i32 [[TMP2]], [[TMP1]]
+ // CHECK: [[TMP1:%.*]] = xor i32 %{{.*}}, -1
+ // CHECK: [[TMP2:%.*]] = sub i32 %{{.*}}, 1
+ // CHECK-NEXT: {{.*}} = and i32 [[TMP1]], [[TMP2]]
return __tzmsk_u32(a);
}
unsigned long long test__tzmsk_u64(unsigned long long a) {
// CHECK-LABEL: test__tzmsk_u64
- // CHECK: [[TMP1:%.*]] = xor i64 [[SRC:%.*]], -1
- // CHECK-NEXT: [[TMP2:%.*]] = add i64 [[SRC:%.*]], -1
- // CHECK-NEXT: {{.*}} = and i64 [[TMP2]], [[TMP1]]
+ // CHECK: [[TMP1:%.*]] = xor i64 %{{.*}}, -1
+ // CHECK: [[TMP2:%.*]] = sub i64 %{{.*}}, 1
+ // CHECK-NEXT: {{.*}} = and i64 [[TMP1]], [[TMP2]]
return __tzmsk_u64(a);
}
diff --git a/test/CodeGen/thinlto-debug-pm.c b/test/CodeGen/thinlto-debug-pm.c
new file mode 100644
index 000000000000..2accde1f3625
--- /dev/null
+++ b/test/CodeGen/thinlto-debug-pm.c
@@ -0,0 +1,10 @@
+// Test to ensure -fdebug-pass-manager works when invoking the
+// ThinLTO backend path with the new PM.
+// REQUIRES: x86-registered-target
+// RUN: %clang_cc1 -o %t.o -flto=thin -fexperimental-new-pass-manager -triple x86_64-unknown-linux-gnu -emit-llvm-bc %s
+// RUN: llvm-lto -thinlto -o %t %t.o
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-obj -O2 -o %t2.o -x ir %t.o -fthinlto-index=%t.thinlto.bc -fdebug-pass-manager -fexperimental-new-pass-manager 2>&1 | FileCheck %s
+// CHECK: Running pass:
+
+void foo() {
+}
diff --git a/test/CodeGen/thinlto-emit-llvm.c b/test/CodeGen/thinlto-emit-llvm.c
index f611162d1999..d6ef6650243e 100644
--- a/test/CodeGen/thinlto-emit-llvm.c
+++ b/test/CodeGen/thinlto-emit-llvm.c
@@ -5,6 +5,6 @@
// RUN: %clang_cc1 -O2 -x ir %t.o -fthinlto-index=%t.thinlto.bc -emit-llvm -o - | FileCheck %s
// RUN: %clang_cc1 -O2 -x ir %t.o -fthinlto-index=%t.thinlto.bc -emit-llvm-bc -o - | llvm-dis -o - | FileCheck %s
-// CHECK: define void @foo()
+// CHECK: define{{.*}} void @foo()
void foo() {
}
diff --git a/test/CodeGen/ubsan-builtin-checks.c b/test/CodeGen/ubsan-builtin-checks.c
new file mode 100644
index 000000000000..9733b0e04794
--- /dev/null
+++ b/test/CodeGen/ubsan-builtin-checks.c
@@ -0,0 +1,44 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -w -emit-llvm -o - %s -fsanitize=builtin | FileCheck %s
+// RUN: %clang_cc1 -triple arm64-none-linux-gnu -w -emit-llvm -o - %s -fsanitize=builtin | FileCheck %s --check-prefix=NOT-UB
+
+// NOT-UB-NOT: __ubsan_handle_invalid_builtin
+
+// CHECK: define void @check_ctz
+void check_ctz(int n) {
+ // CHECK: [[NOT_ZERO:%.*]] = icmp ne i32 [[N:%.*]], 0, !nosanitize
+ // CHECK-NEXT: br i1 [[NOT_ZERO]]
+ //
+ // Handler block:
+ // CHECK: call void @__ubsan_handle_invalid_builtin
+ // CHECK-NEXT: unreachable
+ //
+ // Continuation block:
+ // CHECK: call i32 @llvm.cttz.i32(i32 [[N]], i1 true)
+ __builtin_ctz(n);
+
+ // CHECK: call void @__ubsan_handle_invalid_builtin
+ __builtin_ctzl(n);
+
+ // CHECK: call void @__ubsan_handle_invalid_builtin
+ __builtin_ctzll(n);
+}
+
+// CHECK: define void @check_clz
+void check_clz(int n) {
+ // CHECK: [[NOT_ZERO:%.*]] = icmp ne i32 [[N:%.*]], 0, !nosanitize
+ // CHECK-NEXT: br i1 [[NOT_ZERO]]
+ //
+ // Handler block:
+ // CHECK: call void @__ubsan_handle_invalid_builtin
+ // CHECK-NEXT: unreachable
+ //
+ // Continuation block:
+ // CHECK: call i32 @llvm.ctlz.i32(i32 [[N]], i1 true)
+ __builtin_clz(n);
+
+ // CHECK: call void @__ubsan_handle_invalid_builtin
+ __builtin_clzl(n);
+
+ // CHECK: call void @__ubsan_handle_invalid_builtin
+ __builtin_clzll(n);
+}
diff --git a/test/CodeGen/ubsan-pass-object-size.c b/test/CodeGen/ubsan-pass-object-size.c
new file mode 100644
index 000000000000..d5d4f5a9e421
--- /dev/null
+++ b/test/CodeGen/ubsan-pass-object-size.c
@@ -0,0 +1,68 @@
+// RUN: %clang_cc1 %s -emit-llvm -w -triple x86_64-apple-darwin10 -fsanitize=array-bounds -o - | FileCheck %s
+
+// CHECK-LABEL: define i32 @foo(
+int foo(int *const p __attribute__((pass_object_size(0))), int n) {
+ int x = (p)[n];
+
+ // CHECK: [[SIZE_ALLOCA:%.*]] = alloca i64, align 8
+ // CHECK: store i64 %{{.*}}, i64* [[SIZE_ALLOCA]], align 8
+ // CHECK: [[LOAD_SIZE:%.*]] = load i64, i64* [[SIZE_ALLOCA]], align 8, !nosanitize
+ // CHECK-NEXT: [[SCALED_SIZE:%.*]] = udiv i64 [[LOAD_SIZE]], 4, !nosanitize
+ // CHECK-NEXT: [[SEXT_N:%.*]] = sext i32 %{{.*}} to i64, !nosanitize
+ // CHECK-NEXT: [[ICMP:%.*]] = icmp ult i64 [[SEXT_N]], [[SCALED_SIZE]], !nosanitize
+ // CHECK-NEXT: br i1 [[ICMP]], {{.*}} !nosanitize
+ // CHECK: __ubsan_handle_out_of_bounds
+
+ {
+ int **p = &p; // Shadow the parameter. The pass_object_size info is lost.
+ // CHECK-NOT: __ubsan_handle_out_of_bounds
+ x = *p[n];
+ }
+
+ // CHECK: ret i32
+ return x;
+}
+
+typedef struct {} ZeroSizedType;
+
+// CHECK-LABEL: define void @bar(
+ZeroSizedType bar(ZeroSizedType *const p __attribute__((pass_object_size(0))), int n) {
+ // CHECK-NOT: __ubsan_handle_out_of_bounds
+ // CHECK: ret void
+ return p[n];
+}
+
+// CHECK-LABEL: define i32 @baz(
+int baz(int *const p __attribute__((pass_object_size(1))), int n) {
+ // CHECK: __ubsan_handle_out_of_bounds
+ // CHECK: ret i32
+ return p[n];
+}
+
+// CHECK-LABEL: define i32 @mat(
+int mat(int *const p __attribute__((pass_object_size(2))), int n) {
+ // CHECK-NOT: __ubsan_handle_out_of_bounds
+ // CHECK: ret i32
+ return p[n];
+}
+
+// CHECK-LABEL: define i32 @pat(
+int pat(int *const p __attribute__((pass_object_size(3))), int n) {
+ // CHECK-NOT: __ubsan_handle_out_of_bounds
+ // CHECK: ret i32
+ return p[n];
+}
+
+// CHECK-LABEL: define i32 @cat(
+int cat(int p[static 10], int n) {
+ // CHECK-NOT: __ubsan_handle_out_of_bounds
+ // CHECK: ret i32
+ return p[n];
+}
+
+// CHECK-LABEL: define i32 @bat(
+int bat(int n, int p[n]) {
+ // CHECK-NOT: __ubsan_handle_out_of_bounds
+ // CHECK: ret i32
+ return p[n];
+}
diff --git a/test/CodeGen/unsigned-overflow-minimal.c b/test/CodeGen/unsigned-overflow-minimal.c
new file mode 100644
index 000000000000..d4b89664f840
--- /dev/null
+++ b/test/CodeGen/unsigned-overflow-minimal.c
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -fsanitize=unsigned-integer-overflow -fsanitize-minimal-runtime %s -emit-llvm -o - | FileCheck %s
+
+unsigned long li, lj, lk;
+
+// CHECK-LABEL: define void @testlongadd()
+void testlongadd() {
+ // CHECK: call void @__ubsan_handle_add_overflow_minimal_abort()
+ li = lj + lk;
+}
+
+// CHECK-LABEL: define void @testlongsub()
+void testlongsub() {
+ // CHECK: call void @__ubsan_handle_sub_overflow_minimal_abort()
+ li = lj - lk;
+}
+
+// CHECK-LABEL: define void @testlongmul()
+void testlongmul() {
+ // CHECK: call void @__ubsan_handle_mul_overflow_minimal_abort()
+ li = lj * lk;
+}
diff --git a/test/CodeGen/verify-debuginfo.ll b/test/CodeGen/verify-debuginfo.ll
new file mode 100644
index 000000000000..0a1858544f5c
--- /dev/null
+++ b/test/CodeGen/verify-debuginfo.ll
@@ -0,0 +1,17 @@
+; REQUIRES: x86-registered-target
+; RUN: %clang_cc1 -triple i386-apple-darwin -disable-llvm-optzns -S %s -o - 2>&1 \
+; RUN: | FileCheck %s
+; CHECK: invalid global variable ref
+; CHECK: warning: ignoring invalid debug info in {{.*}}.ll
+
+@global = common global i32 0, align 4, !dbg !2
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!5, !6}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "adrian", emissionKind: FullDebug, globals: !{!3})
+!1 = !DIFile(filename: "broken.c", directory: "/")
+!2 = !DIGlobalVariableExpression(var: !3, expr: !DIExpression())
+!3 = !DIGlobalVariable(name: "g", scope: !0, file: !1, line: 1, type: !1, isLocal: false, isDefinition: true)
+!5 = !{i32 2, !"Dwarf Version", i32 4}
+!6 = !{i32 1, !"Debug Info Version", i32 3}
diff --git a/test/CodeGen/wchar-size.c b/test/CodeGen/wchar-size.c
index 38da462d98cb..28cd5d14d77a 100644
--- a/test/CodeGen/wchar-size.c
+++ b/test/CodeGen/wchar-size.c
@@ -1,6 +1,6 @@
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s -check-prefix=LONG-WCHAR
// RUN: %clang_cc1 -triple x86_64-unknown-windows-msvc -emit-llvm -o - %s | FileCheck %s -check-prefix=SHORT-WCHAR
-// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -o - -fshort-wchar %s | FileCheck %s -check-prefix=SHORT-WCHAR
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -o - -fwchar-type=short -fno-signed-wchar %s | FileCheck %s -check-prefix=SHORT-WCHAR
// Note: -fno-short-wchar implies the target default is used; so there is no
// need to test this separately here.
diff --git a/test/CodeGen/x86-GCC-inline-asm-Y-constraints.c b/test/CodeGen/x86-GCC-inline-asm-Y-constraints.c
new file mode 100644
index 000000000000..0e1e69cd2459
--- /dev/null
+++ b/test/CodeGen/x86-GCC-inline-asm-Y-constraints.c
@@ -0,0 +1,68 @@
+// RUN: %clang_cc1 -ffreestanding -triple=x86_64-apple-darwin -target-cpu skx %s -emit-llvm -o - | FileCheck %s
+#include <xmmintrin.h>
+// This test is complimented by the .ll test under llvm/test/MC/X86/.
+// At this level we can only check if the constarints are passed correctly
+// from inline asm to llvm IR.
+
+// CHECK-LABEL: @f_Ym
+void f_Ym(__m64 m)
+ {
+ // CHECK: movq $0, %mm1
+ // CHECK-SAME: "=^Ym,~{dirflag},~{fpsr},~{flags}"
+ __asm__ volatile ("movq %0, %%mm1\n\t"
+ :"=Ym" (m));
+}
+
+// CHECK-LABEL: f_Yi
+void f_Yi(__m128 x, __m128 y, __m128 z)
+ {
+ // CHECK: vpaddq
+ // CHECK-SAME: "=^Yi,^Yi,^Yi,~{dirflag},~{fpsr},~{flags}"
+ __asm__ volatile ("vpaddq %0, %1, %2\n\t"
+ :"=Yi" (x)
+ :"Yi" (y),"Yi"(z));
+}
+
+// CHECK-LABEL: f_Yt
+void f_Yt(__m128 x, __m128 y, __m128 z)
+ {
+ // CHECK: vpaddq
+ // CHECK-SAME: "=^Yt,^Yt,^Yt,~{dirflag},~{fpsr},~{flags}"
+ __asm__ volatile ("vpaddq %0, %1, %2\n\t"
+ :"=Yt" (x)
+ :"Yt" (y),"Yt"(z));
+}
+
+// CHECK-LABEL: f_Y2
+void f_Y2(__m128 x, __m128 y, __m128 z)
+ {
+ // CHECK: vpaddq
+ // CHECK-SAME: "=^Y2,^Y2,^Y2,~{dirflag},~{fpsr},~{flags}"
+ __asm__ volatile ("vpaddq %0, %1, %2\n\t"
+ :"=Y2" (x)
+ :"Y2" (y),"Y2"(z));
+}
+
+// CHECK-LABEL: f_Yz
+void f_Yz(__m128 x, __m128 y, __m128 z)
+ {
+ // CHECK: vpaddq
+ // CHECK-SAME: vpaddq
+ // CHECK-SAME: "=^Yi,=^Yz,^Yi,0,~{dirflag},~{fpsr},~{flags}"
+ __asm__ volatile ("vpaddq %0,%2,%1\n\t"
+ "vpaddq %1,%0,%2\n\t"
+ :"+Yi"(z),"=Yz" (x)
+ :"Yi" (y) );
+}
+
+// CHECK-LABEL: f_Y0
+void f_Y0(__m128 x, __m128 y, __m128 z)
+ {
+ // CHECK: vpaddq
+ // CHECK-SAME: "=^Yi,=^Y0,^Yi,0,~{dirflag},~{fpsr},~{flags}"
+ __asm__ volatile ("vpaddq %0,%2,%1\n\t"
+ "vpaddq %1,%0,%2\n\t"
+ :"+Yi"(z),"=Y0" (x)
+ :"Yi" (y) );
+}
+
diff --git a/test/CodeGen/x86_32-xsave.c b/test/CodeGen/x86_32-xsave.c
index b475d63fb357..f5d84e2d920a 100644
--- a/test/CodeGen/x86_32-xsave.c
+++ b/test/CodeGen/x86_32-xsave.c
@@ -15,57 +15,57 @@ void test() {
void* tmp_vp = 0;
#ifdef TEST_XSAVE
-// XSAVE: [[tmp_vp_1:%[0-9a-zA-z]+]] = load i8*, i8** %tmp_vp, align 4
-// XSAVE: [[tmp_ULLi_1:%[0-9a-zA-z]+]] = load i64, i64* %tmp_ULLi, align 8
-// XSAVE: [[high64_1:%[0-9a-zA-z]+]] = lshr i64 [[tmp_ULLi_1]], 32
-// XSAVE: [[high32_1:%[0-9a-zA-z]+]] = trunc i64 [[high64_1]] to i32
-// XSAVE: [[low32_1:%[0-9a-zA-z]+]] = trunc i64 [[tmp_ULLi_1]] to i32
+// XSAVE: [[tmp_vp_1:%[0-9a-zA-Z]+]] = load i8*, i8** %tmp_vp, align 4
+// XSAVE: [[tmp_ULLi_1:%[0-9a-zA-Z]+]] = load i64, i64* %tmp_ULLi, align 8
+// XSAVE: [[high64_1:%[0-9a-zA-Z]+]] = lshr i64 [[tmp_ULLi_1]], 32
+// XSAVE: [[high32_1:%[0-9a-zA-Z]+]] = trunc i64 [[high64_1]] to i32
+// XSAVE: [[low32_1:%[0-9a-zA-Z]+]] = trunc i64 [[tmp_ULLi_1]] to i32
// XSAVE: call void @llvm.x86.xsave(i8* [[tmp_vp_1]], i32 [[high32_1]], i32 [[low32_1]])
(void)__builtin_ia32_xsave(tmp_vp, tmp_ULLi);
-// XSAVE: [[tmp_vp_3:%[0-9a-zA-z]+]] = load i8*, i8** %tmp_vp, align 4
-// XSAVE: [[tmp_ULLi_3:%[0-9a-zA-z]+]] = load i64, i64* %tmp_ULLi, align 8
-// XSAVE: [[high64_3:%[0-9a-zA-z]+]] = lshr i64 [[tmp_ULLi_3]], 32
-// XSAVE: [[high32_3:%[0-9a-zA-z]+]] = trunc i64 [[high64_3]] to i32
-// XSAVE: [[low32_3:%[0-9a-zA-z]+]] = trunc i64 [[tmp_ULLi_3]] to i32
+// XSAVE: [[tmp_vp_3:%[0-9a-zA-Z]+]] = load i8*, i8** %tmp_vp, align 4
+// XSAVE: [[tmp_ULLi_3:%[0-9a-zA-Z]+]] = load i64, i64* %tmp_ULLi, align 8
+// XSAVE: [[high64_3:%[0-9a-zA-Z]+]] = lshr i64 [[tmp_ULLi_3]], 32
+// XSAVE: [[high32_3:%[0-9a-zA-Z]+]] = trunc i64 [[high64_3]] to i32
+// XSAVE: [[low32_3:%[0-9a-zA-Z]+]] = trunc i64 [[tmp_ULLi_3]] to i32
// XSAVE: call void @llvm.x86.xrstor(i8* [[tmp_vp_3]], i32 [[high32_3]], i32 [[low32_3]])
(void)__builtin_ia32_xrstor(tmp_vp, tmp_ULLi);
#endif
#ifdef TEST_XSAVEOPT
-// XSAVEOPT: [[tmp_vp_1:%[0-9a-zA-z]+]] = load i8*, i8** %tmp_vp, align 4
-// XSAVEOPT: [[tmp_ULLi_1:%[0-9a-zA-z]+]] = load i64, i64* %tmp_ULLi, align 8
-// XSAVEOPT: [[high64_1:%[0-9a-zA-z]+]] = lshr i64 [[tmp_ULLi_1]], 32
-// XSAVEOPT: [[high32_1:%[0-9a-zA-z]+]] = trunc i64 [[high64_1]] to i32
-// XSAVEOPT: [[low32_1:%[0-9a-zA-z]+]] = trunc i64 [[tmp_ULLi_1]] to i32
+// XSAVEOPT: [[tmp_vp_1:%[0-9a-zA-Z]+]] = load i8*, i8** %tmp_vp, align 4
+// XSAVEOPT: [[tmp_ULLi_1:%[0-9a-zA-Z]+]] = load i64, i64* %tmp_ULLi, align 8
+// XSAVEOPT: [[high64_1:%[0-9a-zA-Z]+]] = lshr i64 [[tmp_ULLi_1]], 32
+// XSAVEOPT: [[high32_1:%[0-9a-zA-Z]+]] = trunc i64 [[high64_1]] to i32
+// XSAVEOPT: [[low32_1:%[0-9a-zA-Z]+]] = trunc i64 [[tmp_ULLi_1]] to i32
// XSAVEOPT: call void @llvm.x86.xsaveopt(i8* [[tmp_vp_1]], i32 [[high32_1]], i32 [[low32_1]])
(void)__builtin_ia32_xsaveopt(tmp_vp, tmp_ULLi);
#endif
#ifdef TEST_XSAVEC
-// XSAVEC: [[tmp_vp_1:%[0-9a-zA-z]+]] = load i8*, i8** %tmp_vp, align 4
-// XSAVEC: [[tmp_ULLi_1:%[0-9a-zA-z]+]] = load i64, i64* %tmp_ULLi, align 8
-// XSAVEC: [[high64_1:%[0-9a-zA-z]+]] = lshr i64 [[tmp_ULLi_1]], 32
-// XSAVEC: [[high32_1:%[0-9a-zA-z]+]] = trunc i64 [[high64_1]] to i32
-// XSAVEC: [[low32_1:%[0-9a-zA-z]+]] = trunc i64 [[tmp_ULLi_1]] to i32
+// XSAVEC: [[tmp_vp_1:%[0-9a-zA-Z]+]] = load i8*, i8** %tmp_vp, align 4
+// XSAVEC: [[tmp_ULLi_1:%[0-9a-zA-Z]+]] = load i64, i64* %tmp_ULLi, align 8
+// XSAVEC: [[high64_1:%[0-9a-zA-Z]+]] = lshr i64 [[tmp_ULLi_1]], 32
+// XSAVEC: [[high32_1:%[0-9a-zA-Z]+]] = trunc i64 [[high64_1]] to i32
+// XSAVEC: [[low32_1:%[0-9a-zA-Z]+]] = trunc i64 [[tmp_ULLi_1]] to i32
// XSAVEC: call void @llvm.x86.xsavec(i8* [[tmp_vp_1]], i32 [[high32_1]], i32 [[low32_1]])
(void)__builtin_ia32_xsavec(tmp_vp, tmp_ULLi);
#endif
#ifdef TEST_XSAVES
-// XSAVES: [[tmp_vp_1:%[0-9a-zA-z]+]] = load i8*, i8** %tmp_vp, align 4
-// XSAVES: [[tmp_ULLi_1:%[0-9a-zA-z]+]] = load i64, i64* %tmp_ULLi, align 8
-// XSAVES: [[high64_1:%[0-9a-zA-z]+]] = lshr i64 [[tmp_ULLi_1]], 32
-// XSAVES: [[high32_1:%[0-9a-zA-z]+]] = trunc i64 [[high64_1]] to i32
-// XSAVES: [[low32_1:%[0-9a-zA-z]+]] = trunc i64 [[tmp_ULLi_1]] to i32
+// XSAVES: [[tmp_vp_1:%[0-9a-zA-Z]+]] = load i8*, i8** %tmp_vp, align 4
+// XSAVES: [[tmp_ULLi_1:%[0-9a-zA-Z]+]] = load i64, i64* %tmp_ULLi, align 8
+// XSAVES: [[high64_1:%[0-9a-zA-Z]+]] = lshr i64 [[tmp_ULLi_1]], 32
+// XSAVES: [[high32_1:%[0-9a-zA-Z]+]] = trunc i64 [[high64_1]] to i32
+// XSAVES: [[low32_1:%[0-9a-zA-Z]+]] = trunc i64 [[tmp_ULLi_1]] to i32
// XSAVES: call void @llvm.x86.xsaves(i8* [[tmp_vp_1]], i32 [[high32_1]], i32 [[low32_1]])
(void)__builtin_ia32_xsaves(tmp_vp, tmp_ULLi);
-// XSAVES: [[tmp_vp_3:%[0-9a-zA-z]+]] = load i8*, i8** %tmp_vp, align 4
-// XSAVES: [[tmp_ULLi_3:%[0-9a-zA-z]+]] = load i64, i64* %tmp_ULLi, align 8
-// XSAVES: [[high64_3:%[0-9a-zA-z]+]] = lshr i64 [[tmp_ULLi_3]], 32
-// XSAVES: [[high32_3:%[0-9a-zA-z]+]] = trunc i64 [[high64_3]] to i32
-// XSAVES: [[low32_3:%[0-9a-zA-z]+]] = trunc i64 [[tmp_ULLi_3]] to i32
+// XSAVES: [[tmp_vp_3:%[0-9a-zA-Z]+]] = load i8*, i8** %tmp_vp, align 4
+// XSAVES: [[tmp_ULLi_3:%[0-9a-zA-Z]+]] = load i64, i64* %tmp_ULLi, align 8
+// XSAVES: [[high64_3:%[0-9a-zA-Z]+]] = lshr i64 [[tmp_ULLi_3]], 32
+// XSAVES: [[high32_3:%[0-9a-zA-Z]+]] = trunc i64 [[high64_3]] to i32
+// XSAVES: [[low32_3:%[0-9a-zA-Z]+]] = trunc i64 [[tmp_ULLi_3]] to i32
// XSAVES: call void @llvm.x86.xrstors(i8* [[tmp_vp_3]], i32 [[high32_3]], i32 [[low32_3]])
(void)__builtin_ia32_xrstors(tmp_vp, tmp_ULLi);
#endif
diff --git a/test/CodeGen/x86_64-instrument-functions.c b/test/CodeGen/x86_64-instrument-functions.c
new file mode 100644
index 000000000000..686d9aa14ca7
--- /dev/null
+++ b/test/CodeGen/x86_64-instrument-functions.c
@@ -0,0 +1,38 @@
+// REQUIRES: x86-registered-target
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -S -finstrument-functions -O2 -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -S -finstrument-functions-after-inlining -O2 -o - %s | FileCheck -check-prefix=NOINLINE %s
+
+// It's not so nice having asm tests in Clang, but we need to check that we set
+// up the pipeline correctly in order to have the instrumentation inserted.
+
+int leaf(int x) {
+ return x;
+// CHECK-LABEL: leaf:
+// CHECK: callq __cyg_profile_func_enter
+// CHECK-NOT: cyg_profile
+// CHECK: callq __cyg_profile_func_exit
+// CHECK-NOT: cyg_profile
+// CHECK: ret
+}
+
+int root(int x) {
+ return leaf(x);
+// CHECK-LABEL: root:
+// CHECK: callq __cyg_profile_func_enter
+// CHECK-NOT: cyg_profile
+
+// Inlined from leaf():
+// CHECK: callq __cyg_profile_func_enter
+// CHECK-NOT: cyg_profile
+// CHECK: callq __cyg_profile_func_exit
+
+// CHECK-NOT: cyg_profile
+// CHECK: callq __cyg_profile_func_exit
+// CHECK: ret
+
+// NOINLINE-LABEL: root:
+// NOINLINE: callq __cyg_profile_func_enter
+// NOINLINE-NOT: cyg_profile
+// NOINLINE: callq __cyg_profile_func_exit
+// NOINLINE: ret
+}
diff --git a/test/CodeGen/x86_64-xsave.c b/test/CodeGen/x86_64-xsave.c
index 496e982b99c5..beb775c0e47f 100644
--- a/test/CodeGen/x86_64-xsave.c
+++ b/test/CodeGen/x86_64-xsave.c
@@ -15,105 +15,105 @@ void test() {
void* tmp_vp = 0;
#ifdef TEST_XSAVE
-// XSAVE: [[tmp_vp_1:%[0-9a-zA-z]+]] = load i8*, i8** %tmp_vp, align 8
-// XSAVE: [[tmp_ULLi_1:%[0-9a-zA-z]+]] = load i64, i64* %tmp_ULLi, align 8
-// XSAVE: [[high64_1:%[0-9a-zA-z]+]] = lshr i64 [[tmp_ULLi_1]], 32
-// XSAVE: [[high32_1:%[0-9a-zA-z]+]] = trunc i64 [[high64_1]] to i32
-// XSAVE: [[low32_1:%[0-9a-zA-z]+]] = trunc i64 [[tmp_ULLi_1]] to i32
+// XSAVE: [[tmp_vp_1:%[0-9a-zA-Z]+]] = load i8*, i8** %tmp_vp, align 8
+// XSAVE: [[tmp_ULLi_1:%[0-9a-zA-Z]+]] = load i64, i64* %tmp_ULLi, align 8
+// XSAVE: [[high64_1:%[0-9a-zA-Z]+]] = lshr i64 [[tmp_ULLi_1]], 32
+// XSAVE: [[high32_1:%[0-9a-zA-Z]+]] = trunc i64 [[high64_1]] to i32
+// XSAVE: [[low32_1:%[0-9a-zA-Z]+]] = trunc i64 [[tmp_ULLi_1]] to i32
// XSAVE: call void @llvm.x86.xsave(i8* [[tmp_vp_1]], i32 [[high32_1]], i32 [[low32_1]])
(void)__builtin_ia32_xsave(tmp_vp, tmp_ULLi);
-// XSAVE: [[tmp_vp_2:%[0-9a-zA-z]+]] = load i8*, i8** %tmp_vp, align 8
-// XSAVE: [[tmp_ULLi_2:%[0-9a-zA-z]+]] = load i64, i64* %tmp_ULLi, align 8
-// XSAVE: [[high64_2:%[0-9a-zA-z]+]] = lshr i64 [[tmp_ULLi_2]], 32
-// XSAVE: [[high32_2:%[0-9a-zA-z]+]] = trunc i64 [[high64_2]] to i32
-// XSAVE: [[low32_2:%[0-9a-zA-z]+]] = trunc i64 [[tmp_ULLi_2]] to i32
+// XSAVE: [[tmp_vp_2:%[0-9a-zA-Z]+]] = load i8*, i8** %tmp_vp, align 8
+// XSAVE: [[tmp_ULLi_2:%[0-9a-zA-Z]+]] = load i64, i64* %tmp_ULLi, align 8
+// XSAVE: [[high64_2:%[0-9a-zA-Z]+]] = lshr i64 [[tmp_ULLi_2]], 32
+// XSAVE: [[high32_2:%[0-9a-zA-Z]+]] = trunc i64 [[high64_2]] to i32
+// XSAVE: [[low32_2:%[0-9a-zA-Z]+]] = trunc i64 [[tmp_ULLi_2]] to i32
// XSAVE: call void @llvm.x86.xsave64(i8* [[tmp_vp_2]], i32 [[high32_2]], i32 [[low32_2]])
(void)__builtin_ia32_xsave64(tmp_vp, tmp_ULLi);
-// XSAVE: [[tmp_vp_3:%[0-9a-zA-z]+]] = load i8*, i8** %tmp_vp, align 8
-// XSAVE: [[tmp_ULLi_3:%[0-9a-zA-z]+]] = load i64, i64* %tmp_ULLi, align 8
-// XSAVE: [[high64_3:%[0-9a-zA-z]+]] = lshr i64 [[tmp_ULLi_3]], 32
-// XSAVE: [[high32_3:%[0-9a-zA-z]+]] = trunc i64 [[high64_3]] to i32
-// XSAVE: [[low32_3:%[0-9a-zA-z]+]] = trunc i64 [[tmp_ULLi_3]] to i32
+// XSAVE: [[tmp_vp_3:%[0-9a-zA-Z]+]] = load i8*, i8** %tmp_vp, align 8
+// XSAVE: [[tmp_ULLi_3:%[0-9a-zA-Z]+]] = load i64, i64* %tmp_ULLi, align 8
+// XSAVE: [[high64_3:%[0-9a-zA-Z]+]] = lshr i64 [[tmp_ULLi_3]], 32
+// XSAVE: [[high32_3:%[0-9a-zA-Z]+]] = trunc i64 [[high64_3]] to i32
+// XSAVE: [[low32_3:%[0-9a-zA-Z]+]] = trunc i64 [[tmp_ULLi_3]] to i32
// XSAVE: call void @llvm.x86.xrstor(i8* [[tmp_vp_3]], i32 [[high32_3]], i32 [[low32_3]])
(void)__builtin_ia32_xrstor(tmp_vp, tmp_ULLi);
-// XSAVE: [[tmp_vp_4:%[0-9a-zA-z]+]] = load i8*, i8** %tmp_vp, align 8
-// XSAVE: [[tmp_ULLi_4:%[0-9a-zA-z]+]] = load i64, i64* %tmp_ULLi, align 8
-// XSAVE: [[high64_4:%[0-9a-zA-z]+]] = lshr i64 [[tmp_ULLi_4]], 32
-// XSAVE: [[high32_4:%[0-9a-zA-z]+]] = trunc i64 [[high64_4]] to i32
-// XSAVE: [[low32_4:%[0-9a-zA-z]+]] = trunc i64 [[tmp_ULLi_4]] to i32
+// XSAVE: [[tmp_vp_4:%[0-9a-zA-Z]+]] = load i8*, i8** %tmp_vp, align 8
+// XSAVE: [[tmp_ULLi_4:%[0-9a-zA-Z]+]] = load i64, i64* %tmp_ULLi, align 8
+// XSAVE: [[high64_4:%[0-9a-zA-Z]+]] = lshr i64 [[tmp_ULLi_4]], 32
+// XSAVE: [[high32_4:%[0-9a-zA-Z]+]] = trunc i64 [[high64_4]] to i32
+// XSAVE: [[low32_4:%[0-9a-zA-Z]+]] = trunc i64 [[tmp_ULLi_4]] to i32
// XSAVE: call void @llvm.x86.xrstor64(i8* [[tmp_vp_4]], i32 [[high32_4]], i32 [[low32_4]])
(void)__builtin_ia32_xrstor64(tmp_vp, tmp_ULLi);
#endif
#ifdef TEST_XSAVEOPT
-// XSAVEOPT: [[tmp_vp_1:%[0-9a-zA-z]+]] = load i8*, i8** %tmp_vp, align 8
-// XSAVEOPT: [[tmp_ULLi_1:%[0-9a-zA-z]+]] = load i64, i64* %tmp_ULLi, align 8
-// XSAVEOPT: [[high64_1:%[0-9a-zA-z]+]] = lshr i64 [[tmp_ULLi_1]], 32
-// XSAVEOPT: [[high32_1:%[0-9a-zA-z]+]] = trunc i64 [[high64_1]] to i32
-// XSAVEOPT: [[low32_1:%[0-9a-zA-z]+]] = trunc i64 [[tmp_ULLi_1]] to i32
+// XSAVEOPT: [[tmp_vp_1:%[0-9a-zA-Z]+]] = load i8*, i8** %tmp_vp, align 8
+// XSAVEOPT: [[tmp_ULLi_1:%[0-9a-zA-Z]+]] = load i64, i64* %tmp_ULLi, align 8
+// XSAVEOPT: [[high64_1:%[0-9a-zA-Z]+]] = lshr i64 [[tmp_ULLi_1]], 32
+// XSAVEOPT: [[high32_1:%[0-9a-zA-Z]+]] = trunc i64 [[high64_1]] to i32
+// XSAVEOPT: [[low32_1:%[0-9a-zA-Z]+]] = trunc i64 [[tmp_ULLi_1]] to i32
// XSAVEOPT: call void @llvm.x86.xsaveopt(i8* [[tmp_vp_1]], i32 [[high32_1]], i32 [[low32_1]])
(void)__builtin_ia32_xsaveopt(tmp_vp, tmp_ULLi);
-// XSAVEOPT: [[tmp_vp_2:%[0-9a-zA-z]+]] = load i8*, i8** %tmp_vp, align 8
-// XSAVEOPT: [[tmp_ULLi_2:%[0-9a-zA-z]+]] = load i64, i64* %tmp_ULLi, align 8
-// XSAVEOPT: [[high64_2:%[0-9a-zA-z]+]] = lshr i64 [[tmp_ULLi_2]], 32
-// XSAVEOPT: [[high32_2:%[0-9a-zA-z]+]] = trunc i64 [[high64_2]] to i32
-// XSAVEOPT: [[low32_2:%[0-9a-zA-z]+]] = trunc i64 [[tmp_ULLi_2]] to i32
+// XSAVEOPT: [[tmp_vp_2:%[0-9a-zA-Z]+]] = load i8*, i8** %tmp_vp, align 8
+// XSAVEOPT: [[tmp_ULLi_2:%[0-9a-zA-Z]+]] = load i64, i64* %tmp_ULLi, align 8
+// XSAVEOPT: [[high64_2:%[0-9a-zA-Z]+]] = lshr i64 [[tmp_ULLi_2]], 32
+// XSAVEOPT: [[high32_2:%[0-9a-zA-Z]+]] = trunc i64 [[high64_2]] to i32
+// XSAVEOPT: [[low32_2:%[0-9a-zA-Z]+]] = trunc i64 [[tmp_ULLi_2]] to i32
// XSAVEOPT: call void @llvm.x86.xsaveopt64(i8* [[tmp_vp_2]], i32 [[high32_2]], i32 [[low32_2]])
(void)__builtin_ia32_xsaveopt64(tmp_vp, tmp_ULLi);
#endif
#ifdef TEST_XSAVEC
-// XSAVEC: [[tmp_vp_1:%[0-9a-zA-z]+]] = load i8*, i8** %tmp_vp, align 8
-// XSAVEC: [[tmp_ULLi_1:%[0-9a-zA-z]+]] = load i64, i64* %tmp_ULLi, align 8
-// XSAVEC: [[high64_1:%[0-9a-zA-z]+]] = lshr i64 [[tmp_ULLi_1]], 32
-// XSAVEC: [[high32_1:%[0-9a-zA-z]+]] = trunc i64 [[high64_1]] to i32
-// XSAVEC: [[low32_1:%[0-9a-zA-z]+]] = trunc i64 [[tmp_ULLi_1]] to i32
+// XSAVEC: [[tmp_vp_1:%[0-9a-zA-Z]+]] = load i8*, i8** %tmp_vp, align 8
+// XSAVEC: [[tmp_ULLi_1:%[0-9a-zA-Z]+]] = load i64, i64* %tmp_ULLi, align 8
+// XSAVEC: [[high64_1:%[0-9a-zA-Z]+]] = lshr i64 [[tmp_ULLi_1]], 32
+// XSAVEC: [[high32_1:%[0-9a-zA-Z]+]] = trunc i64 [[high64_1]] to i32
+// XSAVEC: [[low32_1:%[0-9a-zA-Z]+]] = trunc i64 [[tmp_ULLi_1]] to i32
// XSAVEC: call void @llvm.x86.xsavec(i8* [[tmp_vp_1]], i32 [[high32_1]], i32 [[low32_1]])
(void)__builtin_ia32_xsavec(tmp_vp, tmp_ULLi);
-// XSAVEC: [[tmp_vp_2:%[0-9a-zA-z]+]] = load i8*, i8** %tmp_vp, align 8
-// XSAVEC: [[tmp_ULLi_2:%[0-9a-zA-z]+]] = load i64, i64* %tmp_ULLi, align 8
-// XSAVEC: [[high64_2:%[0-9a-zA-z]+]] = lshr i64 [[tmp_ULLi_2]], 32
-// XSAVEC: [[high32_2:%[0-9a-zA-z]+]] = trunc i64 [[high64_2]] to i32
-// XSAVEC: [[low32_2:%[0-9a-zA-z]+]] = trunc i64 [[tmp_ULLi_2]] to i32
+// XSAVEC: [[tmp_vp_2:%[0-9a-zA-Z]+]] = load i8*, i8** %tmp_vp, align 8
+// XSAVEC: [[tmp_ULLi_2:%[0-9a-zA-Z]+]] = load i64, i64* %tmp_ULLi, align 8
+// XSAVEC: [[high64_2:%[0-9a-zA-Z]+]] = lshr i64 [[tmp_ULLi_2]], 32
+// XSAVEC: [[high32_2:%[0-9a-zA-Z]+]] = trunc i64 [[high64_2]] to i32
+// XSAVEC: [[low32_2:%[0-9a-zA-Z]+]] = trunc i64 [[tmp_ULLi_2]] to i32
// XSAVEC: call void @llvm.x86.xsavec64(i8* [[tmp_vp_2]], i32 [[high32_2]], i32 [[low32_2]])
(void)__builtin_ia32_xsavec64(tmp_vp, tmp_ULLi);
#endif
#ifdef TEST_XSAVES
-// XSAVES: [[tmp_vp_1:%[0-9a-zA-z]+]] = load i8*, i8** %tmp_vp, align 8
-// XSAVES: [[tmp_ULLi_1:%[0-9a-zA-z]+]] = load i64, i64* %tmp_ULLi, align 8
-// XSAVES: [[high64_1:%[0-9a-zA-z]+]] = lshr i64 [[tmp_ULLi_1]], 32
-// XSAVES: [[high32_1:%[0-9a-zA-z]+]] = trunc i64 [[high64_1]] to i32
-// XSAVES: [[low32_1:%[0-9a-zA-z]+]] = trunc i64 [[tmp_ULLi_1]] to i32
+// XSAVES: [[tmp_vp_1:%[0-9a-zA-Z]+]] = load i8*, i8** %tmp_vp, align 8
+// XSAVES: [[tmp_ULLi_1:%[0-9a-zA-Z]+]] = load i64, i64* %tmp_ULLi, align 8
+// XSAVES: [[high64_1:%[0-9a-zA-Z]+]] = lshr i64 [[tmp_ULLi_1]], 32
+// XSAVES: [[high32_1:%[0-9a-zA-Z]+]] = trunc i64 [[high64_1]] to i32
+// XSAVES: [[low32_1:%[0-9a-zA-Z]+]] = trunc i64 [[tmp_ULLi_1]] to i32
// XSAVES: call void @llvm.x86.xsaves(i8* [[tmp_vp_1]], i32 [[high32_1]], i32 [[low32_1]])
(void)__builtin_ia32_xsaves(tmp_vp, tmp_ULLi);
-// XSAVES: [[tmp_vp_2:%[0-9a-zA-z]+]] = load i8*, i8** %tmp_vp, align 8
-// XSAVES: [[tmp_ULLi_2:%[0-9a-zA-z]+]] = load i64, i64* %tmp_ULLi, align 8
-// XSAVES: [[high64_2:%[0-9a-zA-z]+]] = lshr i64 [[tmp_ULLi_2]], 32
-// XSAVES: [[high32_2:%[0-9a-zA-z]+]] = trunc i64 [[high64_2]] to i32
-// XSAVES: [[low32_2:%[0-9a-zA-z]+]] = trunc i64 [[tmp_ULLi_2]] to i32
+// XSAVES: [[tmp_vp_2:%[0-9a-zA-Z]+]] = load i8*, i8** %tmp_vp, align 8
+// XSAVES: [[tmp_ULLi_2:%[0-9a-zA-Z]+]] = load i64, i64* %tmp_ULLi, align 8
+// XSAVES: [[high64_2:%[0-9a-zA-Z]+]] = lshr i64 [[tmp_ULLi_2]], 32
+// XSAVES: [[high32_2:%[0-9a-zA-Z]+]] = trunc i64 [[high64_2]] to i32
+// XSAVES: [[low32_2:%[0-9a-zA-Z]+]] = trunc i64 [[tmp_ULLi_2]] to i32
// XSAVES: call void @llvm.x86.xsaves64(i8* [[tmp_vp_2]], i32 [[high32_2]], i32 [[low32_2]])
(void)__builtin_ia32_xsaves64(tmp_vp, tmp_ULLi);
-// XSAVES: [[tmp_vp_3:%[0-9a-zA-z]+]] = load i8*, i8** %tmp_vp, align 8
-// XSAVES: [[tmp_ULLi_3:%[0-9a-zA-z]+]] = load i64, i64* %tmp_ULLi, align 8
-// XSAVES: [[high64_3:%[0-9a-zA-z]+]] = lshr i64 [[tmp_ULLi_3]], 32
-// XSAVES: [[high32_3:%[0-9a-zA-z]+]] = trunc i64 [[high64_3]] to i32
-// XSAVES: [[low32_3:%[0-9a-zA-z]+]] = trunc i64 [[tmp_ULLi_3]] to i32
+// XSAVES: [[tmp_vp_3:%[0-9a-zA-Z]+]] = load i8*, i8** %tmp_vp, align 8
+// XSAVES: [[tmp_ULLi_3:%[0-9a-zA-Z]+]] = load i64, i64* %tmp_ULLi, align 8
+// XSAVES: [[high64_3:%[0-9a-zA-Z]+]] = lshr i64 [[tmp_ULLi_3]], 32
+// XSAVES: [[high32_3:%[0-9a-zA-Z]+]] = trunc i64 [[high64_3]] to i32
+// XSAVES: [[low32_3:%[0-9a-zA-Z]+]] = trunc i64 [[tmp_ULLi_3]] to i32
// XSAVES: call void @llvm.x86.xrstors(i8* [[tmp_vp_3]], i32 [[high32_3]], i32 [[low32_3]])
(void)__builtin_ia32_xrstors(tmp_vp, tmp_ULLi);
-// XSAVES: [[tmp_vp_4:%[0-9a-zA-z]+]] = load i8*, i8** %tmp_vp, align 8
-// XSAVES: [[tmp_ULLi_4:%[0-9a-zA-z]+]] = load i64, i64* %tmp_ULLi, align 8
-// XSAVES: [[high64_4:%[0-9a-zA-z]+]] = lshr i64 [[tmp_ULLi_4]], 32
-// XSAVES: [[high32_4:%[0-9a-zA-z]+]] = trunc i64 [[high64_4]] to i32
-// XSAVES: [[low32_4:%[0-9a-zA-z]+]] = trunc i64 [[tmp_ULLi_4]] to i32
+// XSAVES: [[tmp_vp_4:%[0-9a-zA-Z]+]] = load i8*, i8** %tmp_vp, align 8
+// XSAVES: [[tmp_ULLi_4:%[0-9a-zA-Z]+]] = load i64, i64* %tmp_ULLi, align 8
+// XSAVES: [[high64_4:%[0-9a-zA-Z]+]] = lshr i64 [[tmp_ULLi_4]], 32
+// XSAVES: [[high32_4:%[0-9a-zA-Z]+]] = trunc i64 [[high64_4]] to i32
+// XSAVES: [[low32_4:%[0-9a-zA-Z]+]] = trunc i64 [[tmp_ULLi_4]] to i32
// XSAVES: call void @llvm.x86.xrstors64(i8* [[tmp_vp_4]], i32 [[high32_4]], i32 [[low32_4]])
(void)__builtin_ia32_xrstors64(tmp_vp, tmp_ULLi);
#endif
diff --git a/test/CodeGen/xray-always-emit-customevent.cpp b/test/CodeGen/xray-always-emit-customevent.cpp
new file mode 100644
index 000000000000..8ac22f2a1bca
--- /dev/null
+++ b/test/CodeGen/xray-always-emit-customevent.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fxray-instrument -fxray-always-emit-customevents -x c++ \
+// RUN: -std=c++11 -triple x86_64-unknown-unknown -emit-llvm -o - %s \
+// RUN: | FileCheck %s
+
+// CHECK-LABEL: @_Z15neverInstrumentv
+[[clang::xray_never_instrument]] void neverInstrument() {
+ static constexpr char kPhase[] = "never";
+ __xray_customevent(kPhase, 5);
+ // CHECK: call void @llvm.xray.customevent(i8*{{.*}}, i32 5)
+}
diff --git a/test/CodeGenCXX/anonymous-namespaces.cpp b/test/CodeGenCXX/anonymous-namespaces.cpp
index abc700fef6c2..b2857ff41714 100644
--- a/test/CodeGenCXX/anonymous-namespaces.cpp
+++ b/test/CodeGenCXX/anonymous-namespaces.cpp
@@ -6,7 +6,8 @@ int f();
namespace {
// CHECK-1: @_ZN12_GLOBAL__N_11bE = internal global i32 0
- // CHECK-1: @_ZN12_GLOBAL__N_1L1cE = internal global i32 0
+ // CHECK-1: @_ZN12_GLOBAL__N_11cE = internal global i32 0
+ // CHECK-1: @_ZN12_GLOBAL__N_12c2E = internal global i32 0
// CHECK-1: @_ZN12_GLOBAL__N_11D1dE = internal global i32 0
// CHECK-1: @_ZN12_GLOBAL__N_11aE = internal global i32 0
int a = 0;
@@ -15,6 +16,12 @@ namespace {
static int c = f();
+ // Note, we can't use an 'L' mangling for c or c2 (like GCC does) based on
+ // the 'static' specifier, because the variable can be redeclared without it.
+ extern int c2;
+ int g() { return c2; }
+ static int c2 = f();
+
class D {
static int d;
};
diff --git a/test/CodeGenCXX/anonymous-union-member-initializer.cpp b/test/CodeGenCXX/anonymous-union-member-initializer.cpp
index 69fa61c2155c..e8c4480b4906 100644
--- a/test/CodeGenCXX/anonymous-union-member-initializer.cpp
+++ b/test/CodeGenCXX/anonymous-union-member-initializer.cpp
@@ -80,37 +80,37 @@ namespace PR10512 {
};
// CHECK-LABEL: define void @_ZN7PR105121AC2Ev
- // CHECK: [[THISADDR:%[a-zA-z0-9.]+]] = alloca [[A:%"struct[A-Za-z0-9:.]+"]]
- // CHECK-NEXT: store [[A]]* [[THIS:%[a-zA-z0-9.]+]], [[A]]** [[THISADDR]]
- // CHECK-NEXT: [[THIS1:%[a-zA-z0-9.]+]] = load [[A]]*, [[A]]** [[THISADDR]]
+ // CHECK: [[THISADDR:%[a-zA-Z0-9.]+]] = alloca [[A:%"struct[A-Za-z0-9:.]+"]]
+ // CHECK-NEXT: store [[A]]* [[THIS:%[a-zA-Z0-9.]+]], [[A]]** [[THISADDR]]
+ // CHECK-NEXT: [[THIS1:%[a-zA-Z0-9.]+]] = load [[A]]*, [[A]]** [[THISADDR]]
// CHECK-NEXT: ret void
A::A() {}
// CHECK-LABEL: define void @_ZN7PR105121AC2Ei
- // CHECK: [[THISADDR:%[a-zA-z0-9.]+]] = alloca [[A:%"struct[A-Za-z0-9:.]+"]]
- // CHECK-NEXT: [[XADDR:%[a-zA-z0-9.]+]] = alloca i32
- // CHECK-NEXT: store [[A]]* [[THIS:%[a-zA-z0-9.]+]], [[A]]** [[THISADDR]]
- // CHECK-NEXT: store i32 [[X:%[a-zA-z0-9.]+]], i32* [[XADDR]]
- // CHECK-NEXT: [[THIS1:%[a-zA-z0-9.]+]] = load [[A]]*, [[A]]** [[THISADDR]]
+ // CHECK: [[THISADDR:%[a-zA-Z0-9.]+]] = alloca [[A:%"struct[A-Za-z0-9:.]+"]]
+ // CHECK-NEXT: [[XADDR:%[a-zA-Z0-9.]+]] = alloca i32
+ // CHECK-NEXT: store [[A]]* [[THIS:%[a-zA-Z0-9.]+]], [[A]]** [[THISADDR]]
+ // CHECK-NEXT: store i32 [[X:%[a-zA-Z0-9.]+]], i32* [[XADDR]]
+ // CHECK-NEXT: [[THIS1:%[a-zA-Z0-9.]+]] = load [[A]]*, [[A]]** [[THISADDR]]
// CHECK-NEXT: {{getelementptr inbounds.*i32 0, i32 0}}
// CHECK-NEXT: {{getelementptr inbounds.*i32 0, i32 0}}
// CHECK-NEXT: {{getelementptr inbounds.*i32 0, i32 0}}
- // CHECK-NEXT: [[TMP:%[a-zA-z0-9.]+]] = load i32, i32* [[XADDR]]
+ // CHECK-NEXT: [[TMP:%[a-zA-Z0-9.]+]] = load i32, i32* [[XADDR]]
// CHECK-NEXT: store i32 [[TMP]]
// CHECK-NEXT: ret void
A::A(int x) : x(x) { }
// CHECK-LABEL: define void @_ZN7PR105121AC2El
- // CHECK: [[THISADDR:%[a-zA-z0-9.]+]] = alloca [[A:%"struct[A-Za-z0-9:.]+"]]
- // CHECK-NEXT: [[XADDR:%[a-zA-z0-9.]+]] = alloca i64
- // CHECK-NEXT: store [[A]]* [[THIS:%[a-zA-z0-9.]+]], [[A]]** [[THISADDR]]
- // CHECK-NEXT: store i64 [[X:%[a-zA-z0-9.]+]], i64* [[XADDR]]
- // CHECK-NEXT: [[THIS1:%[a-zA-z0-9.]+]] = load [[A]]*, [[A]]** [[THISADDR]]
+ // CHECK: [[THISADDR:%[a-zA-Z0-9.]+]] = alloca [[A:%"struct[A-Za-z0-9:.]+"]]
+ // CHECK-NEXT: [[XADDR:%[a-zA-Z0-9.]+]] = alloca i64
+ // CHECK-NEXT: store [[A]]* [[THIS:%[a-zA-Z0-9.]+]], [[A]]** [[THISADDR]]
+ // CHECK-NEXT: store i64 [[X:%[a-zA-Z0-9.]+]], i64* [[XADDR]]
+ // CHECK-NEXT: [[THIS1:%[a-zA-Z0-9.]+]] = load [[A]]*, [[A]]** [[THISADDR]]
// CHECK-NEXT: {{getelementptr inbounds.*i32 0, i32 0}}
// CHECK-NEXT: {{getelementptr inbounds.*i32 0, i32 1}}
// CHECK-NEXT: {{getelementptr inbounds.*i32 0, i32 0}}
- // CHECK-NEXT: [[TMP:%[a-zA-z0-9.]+]] = load i64, i64* [[XADDR]]
- // CHECK-NEXT: [[CONV:%[a-zA-z0-9.]+]] = trunc i64 [[TMP]] to i32
+ // CHECK-NEXT: [[TMP:%[a-zA-Z0-9.]+]] = load i64, i64* [[XADDR]]
+ // CHECK-NEXT: [[CONV:%[a-zA-Z0-9.]+]] = trunc i64 [[TMP]] to i32
// CHECK-NEXT: store i32 [[CONV]]
// CHECK-NEXT: ret void
A::A(long y) : y(y) { }
diff --git a/test/CodeGenCXX/arm64-constructor-return.cpp b/test/CodeGenCXX/arm64-constructor-return.cpp
index 3adc1b7a280e..cbe66ab0e251 100644
--- a/test/CodeGenCXX/arm64-constructor-return.cpp
+++ b/test/CodeGenCXX/arm64-constructor-return.cpp
@@ -13,7 +13,7 @@ S::S() {
// CHECK: %struct.S* @_ZN1SC2Ev(%struct.S* returned %this)
// CHECK: %struct.S* @_ZN1SC1Ev(%struct.S* returned %this)
-// CHECK: [[THISADDR:%[a-zA-z0-9.]+]] = alloca %struct.S*
+// CHECK: [[THISADDR:%[a-zA-Z0-9.]+]] = alloca %struct.S*
// CHECK: store %struct.S* %this, %struct.S** [[THISADDR]]
// CHECK: [[THIS1:%.*]] = load %struct.S*, %struct.S** [[THISADDR]]
// CHECK: ret %struct.S* [[THIS1]]
diff --git a/test/CodeGenCXX/atomic-align.cpp b/test/CodeGenCXX/atomic-align.cpp
new file mode 100644
index 000000000000..9852ac38a6c8
--- /dev/null
+++ b/test/CodeGenCXX/atomic-align.cpp
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 %s -std=c++11 -emit-llvm -o - -triple=x86_64-linux-gnu | FileCheck %s
+
+struct AM {
+ int f1, f2;
+};
+alignas(8) AM m;
+AM load1() {
+ AM am;
+ // m is declared to align to 8bytes, so generate load atomic instead
+ // of libcall.
+ // CHECK-LABEL: @_Z5load1v
+ // CHECK: load atomic {{.*}} monotonic
+ __atomic_load(&m, &am, 0);
+ return am;
+}
+
+struct BM {
+ int f1;
+ alignas(8) AM f2;
+};
+BM bm;
+AM load2() {
+ AM am;
+ // BM::f2 is declared to align to 8bytes, so generate load atomic instead
+ // of libcall.
+ // CHECK-LABEL: @_Z5load2v
+ // CHECK: load atomic {{.*}} monotonic
+ __atomic_load(&bm.f2, &am, 0);
+ return am;
+}
diff --git a/test/CodeGenCXX/atomic-inline.cpp b/test/CodeGenCXX/atomic-inline.cpp
new file mode 100644
index 000000000000..fe727589d2e2
--- /dev/null
+++ b/test/CodeGenCXX/atomic-inline.cpp
@@ -0,0 +1,69 @@
+// RUN: %clang_cc1 %s -std=c++11 -emit-llvm -o - -triple=x86_64-linux-gnu | FileCheck %s
+// RUN: %clang_cc1 %s -std=c++11 -emit-llvm -o - -triple=x86_64-linux-gnu -target-cpu core2 | FileCheck %s --check-prefix=CORE2
+// Check the atomic code generation for cpu targets w/wo cx16 support.
+
+struct alignas(8) AM8 {
+ int f1, f2;
+};
+AM8 m8;
+AM8 load8() {
+ AM8 am;
+ // CHECK-LABEL: @_Z5load8v
+ // CHECK: load atomic i64, {{.*}} monotonic
+ // CORE2-LABEL: @_Z5load8v
+ // CORE2: load atomic i64, {{.*}} monotonic
+ __atomic_load(&m8, &am, 0);
+ return am;
+}
+
+AM8 s8;
+void store8() {
+ // CHECK-LABEL: @_Z6store8v
+ // CHECK: store atomic i64 {{.*}} monotonic
+ // CORE2-LABEL: @_Z6store8v
+ // CORE2: store atomic i64 {{.*}} monotonic
+ __atomic_store(&m8, &s8, 0);
+}
+
+bool cmpxchg8() {
+ AM8 am;
+ // CHECK-LABEL: @_Z8cmpxchg8v
+ // CHECK: cmpxchg i64* {{.*}} monotonic
+ // CORE2-LABEL: @_Z8cmpxchg8v
+ // CORE2: cmpxchg i64* {{.*}} monotonic
+ return __atomic_compare_exchange(&m8, &s8, &am, 0, 0, 0);
+}
+
+struct alignas(16) AM16 {
+ long f1, f2;
+};
+
+AM16 m16;
+AM16 load16() {
+ AM16 am;
+ // CHECK-LABEL: @_Z6load16v
+ // CHECK: call void @__atomic_load
+ // CORE2-LABEL: @_Z6load16v
+ // CORE2: load atomic i128, {{.*}} monotonic
+ __atomic_load(&m16, &am, 0);
+ return am;
+}
+
+AM16 s16;
+void store16() {
+ // CHECK-LABEL: @_Z7store16v
+ // CHECK: call void @__atomic_store
+ // CORE2-LABEL: @_Z7store16v
+ // CORE2: store atomic i128 {{.*}} monotonic
+ __atomic_store(&m16, &s16, 0);
+}
+
+bool cmpxchg16() {
+ AM16 am;
+ // CHECK-LABEL: @_Z9cmpxchg16v
+ // CHECK: call zeroext i1 @__atomic_compare_exchange
+ // CORE2-LABEL: @_Z9cmpxchg16v
+ // CORE2: cmpxchg i128* {{.*}} monotonic
+ return __atomic_compare_exchange(&m16, &s16, &am, 0, 0, 0);
+}
+
diff --git a/test/CodeGenCXX/blocks.cpp b/test/CodeGenCXX/blocks.cpp
index 5b7c7e6e46bb..37219d3f7abd 100644
--- a/test/CodeGenCXX/blocks.cpp
+++ b/test/CodeGenCXX/blocks.cpp
@@ -122,7 +122,6 @@ namespace test4 {
// CHECK-LABEL: define internal void @___ZN5test44testEv_block_invoke
// CHECK: [[TMP:%.*]] = alloca [[A:%.*]], align 1
// CHECK-NEXT: store i8* [[BLOCKDESC:%.*]], i8** {{.*}}, align 8
- // CHECK-NEXT: load i8*, i8**
// CHECK-NEXT: bitcast i8* [[BLOCKDESC]] to <{ i8*, i32, i32, i8*, %struct.__block_descriptor* }>*
// CHECK: call void @_ZN5test41AC1Ev([[A]]* [[TMP]])
// CHECK-NEXT: call void @_ZN5test43fooENS_1AE([[A]]* [[TMP]])
diff --git a/test/CodeGenCXX/catch-undef-behavior.cpp b/test/CodeGenCXX/catch-undef-behavior.cpp
index d58853c47f75..e8287538982b 100644
--- a/test/CodeGenCXX/catch-undef-behavior.cpp
+++ b/test/CodeGenCXX/catch-undef-behavior.cpp
@@ -16,6 +16,10 @@ struct S {
// Check that type mismatch handler is not modified by ASan.
// CHECK-ASAN: private unnamed_addr global { { [{{.*}} x i8]*, i32, i32 }, { i16, i16, [4 x i8] }*, i8*, i8 } { {{.*}}, { i16, i16, [4 x i8] }* [[TYPE_DESCR]], {{.*}} }
+// CHECK: [[IndirectRTTI_ZTIFvPFviEE:@.+]] = private constant i8* bitcast ({ i8*, i8* }* @_ZTIFvPFviEE to i8*)
+// CHECK-X86: [[IndirectRTTI_ZTIFvPFviEE:@.+]] = private constant i8* bitcast ({ i8*, i8* }* @_ZTIFvPFviEE to i8*)
+// CHECK-X32: [[IndirectRTTI_ZTIFvPFviEE:@.+]] = private constant i8* bitcast ({ i8*, i8* }* @_ZTIFvPFviEE to i8*)
+
struct T : S {};
// CHECK-LABEL: @_Z17reference_binding
@@ -395,26 +399,93 @@ void downcast_reference(B &b) {
// CHECK-NEXT: br i1 [[AND]]
}
-// CHECK-LABEL: @_Z22indirect_function_callPFviE({{.*}} prologue <{ i32, i8* }> <{ i32 1413876459, i8* bitcast ({ i8*, i8* }* @_ZTIFvPFviEE to i8*) }>
-// CHECK-X32: @_Z22indirect_function_callPFviE({{.*}} prologue <{ i32, i8* }> <{ i32 1413875435, i8* bitcast ({ i8*, i8* }* @_ZTIFvPFviEE to i8*) }>
-// CHECK-X86: @_Z22indirect_function_callPFviE({{.*}} prologue <{ i32, i8* }> <{ i32 1413875435, i8* bitcast ({ i8*, i8* }* @_ZTIFvPFviEE to i8*) }>
+//
+// CHECK-LABEL: @_Z22indirect_function_callPFviE({{.*}} prologue <{ i32, i32 }> <{ i32 846595819, i32 trunc (i64 sub (i64 ptrtoint (i8** {{.*}} to i64), i64 ptrtoint (void (void (i32)*)* @_Z22indirect_function_callPFviE to i64)) to i32) }>
+// CHECK-X32: @_Z22indirect_function_callPFviE({{.*}} prologue <{ i32, i32 }> <{ i32 846595819, i32 sub (i32 ptrtoint (i8** [[IndirectRTTI_ZTIFvPFviEE]] to i32), i32 ptrtoint (void (void (i32)*)* @_Z22indirect_function_callPFviE to i32)) }>
+// CHECK-X86: @_Z22indirect_function_callPFviE({{.*}} prologue <{ i32, i32 }> <{ i32 846595819, i32 sub (i32 ptrtoint (i8** [[IndirectRTTI_ZTIFvPFviEE]] to i32), i32 ptrtoint (void (void (i32)*)* @_Z22indirect_function_callPFviE to i32)) }>
void indirect_function_call(void (*p)(int)) {
- // CHECK: [[PTR:%.+]] = bitcast void (i32)* {{.*}} to <{ i32, i8* }>*
+ // CHECK: [[PTR:%.+]] = bitcast void (i32)* {{.*}} to <{ i32, i32 }>*
// Signature check
- // CHECK-NEXT: [[SIGPTR:%.+]] = getelementptr <{ i32, i8* }>, <{ i32, i8* }>* [[PTR]], i32 0, i32 0
+ // CHECK-NEXT: [[SIGPTR:%.+]] = getelementptr <{ i32, i32 }>, <{ i32, i32 }>* [[PTR]], i32 0, i32 0
// CHECK-NEXT: [[SIG:%.+]] = load i32, i32* [[SIGPTR]]
- // CHECK-NEXT: [[SIGCMP:%.+]] = icmp eq i32 [[SIG]], 1413876459
+ // CHECK-NEXT: [[SIGCMP:%.+]] = icmp eq i32 [[SIG]], 846595819
// CHECK-NEXT: br i1 [[SIGCMP]]
// RTTI pointer check
- // CHECK: [[RTTIPTR:%.+]] = getelementptr <{ i32, i8* }>, <{ i32, i8* }>* [[PTR]], i32 0, i32 1
- // CHECK-NEXT: [[RTTI:%.+]] = load i8*, i8** [[RTTIPTR]]
+ // CHECK: [[RTTIPTR:%.+]] = getelementptr <{ i32, i32 }>, <{ i32, i32 }>* [[PTR]], i32 0, i32 1
+ // CHECK-NEXT: [[RTTIEncIntTrunc:%.+]] = load i32, i32* [[RTTIPTR]]
+ // CHECK-NEXT: [[RTTIEncInt:%.+]] = sext i32 [[RTTIEncIntTrunc]] to i64
+ // CHECK-NEXT: [[FuncAddrInt:%.+]] = ptrtoint void (i32)* {{.*}} to i64
+ // CHECK-NEXT: [[IndirectGVInt:%.+]] = add i64 [[RTTIEncInt]], [[FuncAddrInt]]
+ // CHECK-NEXT: [[IndirectGV:%.+]] = inttoptr i64 [[IndirectGVInt]] to i8**
+ // CHECK-NEXT: [[RTTI:%.+]] = load i8*, i8** [[IndirectGV]], align 8
// CHECK-NEXT: [[RTTICMP:%.+]] = icmp eq i8* [[RTTI]], bitcast ({ i8*, i8* }* @_ZTIFviE to i8*)
// CHECK-NEXT: br i1 [[RTTICMP]]
+
p(42);
}
+namespace FunctionSanitizerVirtualCalls {
+struct A {
+ virtual void f() {}
+ virtual void g() {}
+ void h() {}
+};
+
+struct B : virtual A {
+ virtual void b() {}
+ virtual void f();
+ void g() final {}
+ static void q() {}
+};
+
+void B::f() {}
+
+void force_irgen() {
+ A a;
+ a.g();
+ a.h();
+
+ B b;
+ b.f();
+ b.b();
+ b.g();
+ B::q();
+}
+
+// CHECK-LABEL: define void @_ZN29FunctionSanitizerVirtualCalls1B1fEv
+// CHECK-NOT: prologue
+//
+// CHECK-LABEL: define void @_ZTv0_n24_N29FunctionSanitizerVirtualCalls1B1fEv
+// CHECK-NOT: prologue
+//
+// CHECK-LABEL: define void @_ZN29FunctionSanitizerVirtualCalls11force_irgenEv()
+// CHECK: prologue
+//
+// CHECK-LABEL: define linkonce_odr void @_ZN29FunctionSanitizerVirtualCalls1AC1Ev
+// CHECK-NOT: prologue
+//
+// CHECK-LABEL: define linkonce_odr void @_ZN29FunctionSanitizerVirtualCalls1A1gEv
+// CHECK-NOT: prologue
+//
+// CHECK-LABEL: define linkonce_odr void @_ZN29FunctionSanitizerVirtualCalls1A1hEv
+// CHECK-NOT: prologue
+//
+// CHECK-LABEL: define linkonce_odr void @_ZN29FunctionSanitizerVirtualCalls1BC1Ev
+// CHECK-NOT: prologue
+//
+// CHECK-LABEL: define linkonce_odr void @_ZN29FunctionSanitizerVirtualCalls1B1bEv
+// CHECK-NOT: prologue
+//
+// CHECK-LABEL: define linkonce_odr void @_ZN29FunctionSanitizerVirtualCalls1B1gEv
+// CHECK-NOT: prologue
+//
+// CHECK-LABEL: define linkonce_odr void @_ZN29FunctionSanitizerVirtualCalls1B1qEv
+// CHECK: prologue
+
+}
+
namespace UpcastPointerTest {
struct S {};
struct T : S { double d; };
@@ -454,7 +525,7 @@ struct ThisAlign {
void this_align_lambda_2();
};
void ThisAlign::this_align_lambda() {
- // CHECK-LABEL: define {{.*}}@"_ZZN9ThisAlign17this_align_lambdaEvENK3$_0clEv"
+ // CHECK-LABEL: define internal %struct.ThisAlign* @"_ZZN9ThisAlign17this_align_lambdaEvENK3$_0clEv"
// CHECK-SAME: (%{{.*}}* %[[this:[^)]*]])
// CHECK: %[[this_addr:.*]] = alloca
// CHECK: store %{{.*}}* %[[this]], %{{.*}}** %[[this_addr]],
@@ -555,7 +626,7 @@ namespace CopyValueRepresentation {
}
void ThisAlign::this_align_lambda_2() {
- // CHECK-LABEL: define {{.*}}@"_ZZN9ThisAlign19this_align_lambda_2EvENK3$_1clEv"
+ // CHECK-LABEL: define internal void @"_ZZN9ThisAlign19this_align_lambda_2EvENK3$_1clEv"
// CHECK-SAME: (%{{.*}}* %[[this:[^)]*]])
// CHECK: %[[this_addr:.*]] = alloca
// CHECK: store %{{.*}}* %[[this]], %{{.*}}** %[[this_addr]],
diff --git a/test/CodeGenCXX/cfi-blacklist.cpp b/test/CodeGenCXX/cfi-blacklist.cpp
index af8a10601d29..c01e5fcd9260 100644
--- a/test/CodeGenCXX/cfi-blacklist.cpp
+++ b/test/CodeGenCXX/cfi-blacklist.cpp
@@ -1,6 +1,18 @@
// RUN: %clang_cc1 -triple %itanium_abi_triple -fvisibility hidden -fms-extensions -fsanitize=cfi-vcall -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=NOBL %s
-// RUN: echo "type:std::*" > %t.txt
-// RUN: %clang_cc1 -triple %itanium_abi_triple -fvisibility hidden -fms-extensions -fsanitize=cfi-vcall -fsanitize-blacklist=%t.txt -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=NOSTD %s
+
+// Check that blacklisting cfi and cfi-vcall work correctly
+// RUN: echo "[cfi-vcall]" > %t.vcall.txt
+// RUN: echo "type:std::*" >> %t.vcall.txt
+// RUN: %clang_cc1 -triple %itanium_abi_triple -fvisibility hidden -fms-extensions -fsanitize=cfi-vcall -fsanitize-blacklist=%t.vcall.txt -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=NOSTD %s
+//
+// RUN: echo "[cfi]" > %t.cfi.txt
+// RUN: echo "type:std::*" >> %t.cfi.txt
+// RUN: %clang_cc1 -triple %itanium_abi_triple -fvisibility hidden -fms-extensions -fsanitize=cfi-vcall -fsanitize-blacklist=%t.cfi.txt -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=NOSTD %s
+
+// Check that blacklisting non-vcall modes does not affect vcalls
+// RUN: echo "[cfi-icall|cfi-nvcall|cfi-cast-strict|cfi-derived-cast|cfi-unrelated-cast]" > %t.other.txt
+// RUN: echo "type:std::*" >> %t.other.txt
+// RUN: %clang_cc1 -triple %itanium_abi_triple -fvisibility hidden -fms-extensions -fsanitize=cfi-vcall -fsanitize-blacklist=%t.other.txt -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=NOBL %s
struct S1 {
virtual void f();
diff --git a/test/CodeGenCXX/cfi-icall.cpp b/test/CodeGenCXX/cfi-icall.cpp
index c3c6ed309cc6..5f5778fc1f7c 100644
--- a/test/CodeGenCXX/cfi-icall.cpp
+++ b/test/CodeGenCXX/cfi-icall.cpp
@@ -8,19 +8,22 @@ namespace {
struct S {};
-void f(S *s) {
+void f(S s) {
}
}
void g() {
- void (*fp)(S *) = f;
- // CHECK: call i1 @llvm.type.test(i8* {{.*}}, metadata [[VOIDS:![0-9]+]])
- fp(0);
+ struct S s;
+ void (*fp)(S) = f;
+ // CHECK: call i1 @llvm.type.test(i8* {{.*}}, metadata [[VOIDS1:![0-9]+]])
+ fp(s);
}
-// ITANIUM: define internal void @_ZN12_GLOBAL__N_11fEPNS_1SE({{.*}} !type [[TS:![0-9]+]]
-// MS: define internal void @"\01?f@?A@@YAXPEAUS@?A@@@Z"({{.*}} !type [[TS:![0-9]+]]
+// ITANIUM: define internal void @_ZN12_GLOBAL__N_11fENS_1SE({{.*}} !type [[TS1:![0-9]+]] !type [[TS2:![0-9]+]]
+// MS: define internal void @"\01?f@?A@@YAXUS@?A@@@Z"({{.*}} !type [[TS1:![0-9]+]] !type [[TS2:![0-9]+]]
-// CHECK: [[VOIDS]] = distinct !{}
-// CHECK: [[TS]] = !{i64 0, [[VOIDS]]}
+// CHECK: [[VOIDS1]] = distinct !{}
+// CHECK: [[TS1]] = !{i64 0, [[VOIDS1]]}
+// CHECK: [[TS2]] = !{i64 0, [[VOIDS2:![0-9]+]]}
+// CHECK: [[VOIDS2]] = distinct !{}
diff --git a/test/CodeGenCXX/cfi-ms-vbase-derived-cast.cpp b/test/CodeGenCXX/cfi-ms-vbase-derived-cast.cpp
new file mode 100644
index 000000000000..3276d8f33edc
--- /dev/null
+++ b/test/CodeGenCXX/cfi-ms-vbase-derived-cast.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -flto -flto-unit -emit-llvm -o - -triple=x86_64-pc-win32 %s -fsanitize=cfi-derived-cast -fsanitize-trap=cfi-derived-cast | FileCheck %s
+
+struct foo {
+ virtual ~foo() {}
+ virtual void f() = 0;
+};
+
+template <typename T>
+struct bar : virtual public foo {
+ void f() {
+ // CHECK: define{{.*}}@"\01?f@?$bar@Ubaz@@@@UEAAXXZ"
+ // Load "this", vbtable, vbase offset and vtable.
+ // CHECK: load
+ // CHECK: load
+ // CHECK: load
+ // CHECK: load
+ // CHECK: @llvm.type.test{{.*}}!"?AUfoo@@"
+ static_cast<T&>(*this);
+ }
+};
+
+struct baz : public bar<baz> {
+ virtual ~baz() {}
+};
+
+int main() {
+ baz *z = new baz;
+ z->f();
+}
diff --git a/test/CodeGenCXX/cfi-ms-vbase-nvcall.cpp b/test/CodeGenCXX/cfi-ms-vbase-nvcall.cpp
new file mode 100644
index 000000000000..ab610628232e
--- /dev/null
+++ b/test/CodeGenCXX/cfi-ms-vbase-nvcall.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -flto -flto-unit -emit-llvm -o - -triple=x86_64-pc-win32 %s -fsanitize=cfi-nvcall -fsanitize-trap=cfi-nvcall | FileCheck %s
+
+struct foo {
+ virtual ~foo() {}
+ virtual void f() = 0;
+};
+
+template <typename T>
+struct bar : virtual public foo {
+ void f() {}
+};
+
+struct baz : public bar<baz> {
+ virtual ~baz() {}
+ void g() {}
+};
+
+void f(baz *z) {
+ // CHECK: define{{.*}}@"\01?f@@YAXPEAUbaz@@@Z"
+ // Load z, vbtable, vbase offset and vtable.
+ // CHECK: load
+ // CHECK: load
+ // CHECK: load
+ // CHECK: load
+ // CHECK: @llvm.type.test{{.*}}!"?AUfoo@@"
+ z->g();
+}
diff --git a/test/CodeGenCXX/cfi-vcall-no-trap.cpp b/test/CodeGenCXX/cfi-vcall-no-trap.cpp
new file mode 100644
index 000000000000..b7ef1426a91d
--- /dev/null
+++ b/test/CodeGenCXX/cfi-vcall-no-trap.cpp
@@ -0,0 +1,15 @@
+// Only output llvm.assume(llvm.type.test()) if cfi-vcall is disabled and whole-program-vtables is enabled
+// RUN: %clang_cc1 -flto -fvisibility hidden -fsanitize=cfi-vcall -fwhole-program-vtables -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=CFI %s
+// RUN: %clang_cc1 -flto -fvisibility hidden -fwhole-program-vtables -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=NOCFI %s
+
+struct S1 {
+ virtual void f();
+};
+
+// CHECK: define{{.*}}s1f
+// CHECK: llvm.type.test
+// CFI-NOT: llvm.assume
+// NOCFI: llvm.assume
+void s1f(S1 *s1) {
+ s1->f();
+}
diff --git a/test/CodeGenCXX/cxx11-extern-constexpr.cpp b/test/CodeGenCXX/cxx11-extern-constexpr.cpp
new file mode 100644
index 000000000000..6c520038e941
--- /dev/null
+++ b/test/CodeGenCXX/cxx11-extern-constexpr.cpp
@@ -0,0 +1,68 @@
+// RUN: %clang_cc1 -std=c++11 %s -emit-llvm -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefix=CHECK --check-prefix=CXX11
+// RUN: %clang_cc1 -std=c++1z %s -emit-llvm -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefix=CHECK --check-prefix=CXX17
+
+struct A {
+ static const int Foo = 123;
+};
+// CHECK: @_ZN1A3FooE = constant i32 123, align 4
+const int *p = &A::Foo; // emit available_externally
+const int A::Foo; // convert to full definition
+
+struct PODWithInit {
+ int g = 42;
+ char h = 43;
+};
+struct CreatePOD {
+ // Deferred initialization of the structure here requires changing
+ // the type of the global variable: the initializer list does not include
+ // the tail padding.
+ // CXX11: @_ZN9CreatePOD3podE = available_externally constant { i32, i8 } { i32 42, i8 43 },
+ static constexpr PODWithInit pod{};
+};
+const int *p_pod = &CreatePOD::pod.g;
+
+struct Bar {
+ int b;
+};
+
+struct MutableBar {
+ mutable int b;
+};
+
+struct Foo {
+ // CXX11: @_ZN3Foo21ConstexprStaticMemberE = available_externally constant i32 42,
+ // CXX17: @_ZN3Foo21ConstexprStaticMemberE = linkonce_odr constant i32 42,
+ static constexpr int ConstexprStaticMember = 42;
+ // CHECK: @_ZN3Foo17ConstStaticMemberE = available_externally constant i32 43,
+ static const int ConstStaticMember = 43;
+
+ // CXX11: @_ZN3Foo23ConstStaticStructMemberE = available_externally constant %struct.Bar { i32 44 },
+ // CXX17: @_ZN3Foo23ConstStaticStructMemberE = linkonce_odr constant %struct.Bar { i32 44 },
+ static constexpr Bar ConstStaticStructMember = {44};
+
+ // CXX11: @_ZN3Foo34ConstexprStaticMutableStructMemberE = external global %struct.MutableBar,
+ // CXX17: @_ZN3Foo34ConstexprStaticMutableStructMemberE = linkonce_odr global %struct.MutableBar { i32 45 },
+ static constexpr MutableBar ConstexprStaticMutableStructMember = {45};
+};
+// CHECK: @_ZL15ConstStaticexpr = internal constant i32 46,
+static constexpr int ConstStaticexpr = 46;
+// CHECK: @_ZL9ConstExpr = internal constant i32 46, align 4
+static const int ConstExpr = 46;
+
+// CHECK: @_ZL21ConstexprStaticStruct = internal constant %struct.Bar { i32 47 },
+static constexpr Bar ConstexprStaticStruct = {47};
+
+// CHECK: @_ZL28ConstexprStaticMutableStruct = internal global %struct.MutableBar { i32 48 },
+static constexpr MutableBar ConstexprStaticMutableStruct = {48};
+
+void use(const int &);
+void foo() {
+ use(Foo::ConstexprStaticMember);
+ use(Foo::ConstStaticMember);
+ use(Foo::ConstStaticStructMember.b);
+ use(Foo::ConstexprStaticMutableStructMember.b);
+ use(ConstStaticexpr);
+ use(ConstExpr);
+ use(ConstexprStaticStruct.b);
+ use(ConstexprStaticMutableStruct.b);
+}
diff --git a/test/CodeGenCXX/cxx11-special-members.cpp b/test/CodeGenCXX/cxx11-special-members.cpp
index 037e59a6408f..96109ba5bac1 100644
--- a/test/CodeGenCXX/cxx11-special-members.cpp
+++ b/test/CodeGenCXX/cxx11-special-members.cpp
@@ -39,7 +39,9 @@ void f3() {
C<0> a;
D b;
}
-// CHECK: define {{.*}} @_ZN1CILi0EEC1Ev
+// Trivial default ctor, might or might not be defined, but we must not expect
+// someone else ot define it.
+// CHECK-NOT: declare {{.*}} @_ZN1CILi0EEC1Ev
// CHECK: define {{.*}} @_ZN1DC1Ev
// CHECK: define {{.*}} @_ZN1BC2EOS_(
diff --git a/test/CodeGenCXX/cxx1y-variable-template.cpp b/test/CodeGenCXX/cxx1y-variable-template.cpp
index cd73817d8508..dd8f28e42992 100644
--- a/test/CodeGenCXX/cxx1y-variable-template.cpp
+++ b/test/CodeGenCXX/cxx1y-variable-template.cpp
@@ -18,6 +18,12 @@ int init_arr();
template<typename T> template<typename U> template<typename V> int Outer<T>::Inner<U>::arr[sizeof(T) + sizeof(U) + sizeof(V)] = { init_arr() };
int *p = Outer<char[100]>::Inner<char[20]>::arr<char[3]>;
+namespace PR35456 {
+// CHECK: @_ZN7PR354561nILi0EEE = linkonce_odr global i32 0
+template<int> int n;
+int *p = &n<0>;
+}
+
// CHECK: @_ZN5OuterIA100_cE5InnerIA20_cE3arrIA3_cEE = linkonce_odr global [123 x i32] zeroinitializer
// CHECK: @_ZGVN5OuterIA100_cE5InnerIA20_cE3arrIA3_cEE = linkonce_odr global
diff --git a/test/CodeGenCXX/cxx1z-aligned-allocation.cpp b/test/CodeGenCXX/cxx1z-aligned-allocation.cpp
index 437597d963b0..4c579978cb96 100644
--- a/test/CodeGenCXX/cxx1z-aligned-allocation.cpp
+++ b/test/CodeGenCXX/cxx1z-aligned-allocation.cpp
@@ -4,6 +4,8 @@
// RUN: %clang_cc1 -std=c++14 -fexceptions -fsized-deallocation -faligned-allocation %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s
// RUN: %clang_cc1 -std=c++1z -fexceptions -fsized-deallocation %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s
+// RUN: %clang_cc1 -std=c++1z -fexceptions -fsized-deallocation %s -emit-llvm -triple x86_64-windows-msvc -o - | FileCheck %s --check-prefix=CHECK-MS
+
// Check that we don't used aligned (de)allocation without -faligned-allocation or C++1z.
// RUN: %clang_cc1 -std=c++14 -DUNALIGNED -fexceptions %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s --check-prefix=CHECK-UNALIGNED
// RUN: %clang_cc1 -std=c++1z -DUNALIGNED -fexceptions -fno-aligned-allocation %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s --check-prefix=CHECK-UNALIGNED
@@ -27,14 +29,28 @@ struct OVERALIGNED A { A(); int n[128]; };
// CHECK-LABEL: define {{.*}} @_Z2a0v()
// CHECK: %[[ALLOC:.*]] = call i8* @_ZnwmSt11align_val_t(i64 512, i64 32)
// CHECK: call void @_ZdlPvSt11align_val_t(i8* %[[ALLOC]], i64 32)
+// CHECK-MS-LABEL: define {{.*}} @"\01?a0@@YAPEAXXZ"()
+// CHECK-MS: %[[ALLOC:.*]] = call i8* @"\01??2@YAPEAX_KW4align_val_t@std@@@Z"(i64 512, i64 32)
+// CHECK-MS: cleanuppad
+// CHECK-MS: call void @"\01??3@YAXPEAXW4align_val_t@std@@@Z"(i8* %[[ALLOC]], i64 32)
void *a0() { return new A; }
+// FIXME: Why don't we call the sized array deallocation overload in this case?
+// The size is known.
+//
// CHECK-LABEL: define {{.*}} @_Z2a1l(
// CHECK: %[[ALLOC:.*]] = call i8* @_ZnamSt11align_val_t(i64 %{{.*}}, i64 32)
// No array cookie.
// CHECK-NOT: store
// CHECK: invoke void @_ZN1AC1Ev(
// CHECK: call void @_ZdaPvSt11align_val_t(i8* %[[ALLOC]], i64 32)
+// CHECK-MS-LABEL: define {{.*}} @"\01?a1@@YAPEAXJ@Z"(
+// CHECK-MS: %[[ALLOC:.*]] = call i8* @"\01??_U@YAPEAX_KW4align_val_t@std@@@Z"(i64 %{{.*}}, i64 32)
+// No array cookie.
+// CHECK-MS-NOT: store
+// CHECK-MS: invoke %struct.A* @"\01??0A@@QEAA@XZ"(
+// CHECK-MS: cleanuppad
+// CHECK-MS: call void @"\01??_V@YAXPEAXW4align_val_t@std@@@Z"(i8* %[[ALLOC]], i64 32)
void *a1(long n) { return new A[n]; }
// CHECK-LABEL: define {{.*}} @_Z2a2P1A(
diff --git a/test/CodeGenCXX/cxx1z-copy-omission.cpp b/test/CodeGenCXX/cxx1z-copy-omission.cpp
index 234e4b12589c..b33a21808175 100644
--- a/test/CodeGenCXX/cxx1z-copy-omission.cpp
+++ b/test/CodeGenCXX/cxx1z-copy-omission.cpp
@@ -6,6 +6,8 @@ struct A {
A(const A&);
~A();
+ operator bool();
+
int arr[10];
};
@@ -79,3 +81,27 @@ void i() {
// CHECK-LABEL: }
}
+
+// CHECK-LABEL: define {{.*}} @_Z1jv(
+void j() {
+ // CHECK: alloca %{{.*}}*
+ // CHECK: %[[OUTERTEMP:.*]] = alloca %{{.*}}
+ // CHECK: %[[INNERTEMP:.*]] = alloca %{{.*}}
+ // CHECK: call void @_ZN1AC1Ei(%{{.*}} %[[INNERTEMP]], i32 1)
+ // CHECK: call zeroext i1 @_ZN1AcvbEv(%{{.*}} %[[INNERTEMP]])
+ // CHECK: br i1
+ //
+ // CHECK: call void @_ZN1AC1EOS_(%{{.*}} %[[OUTERTEMP]], %{{.*}} %[[INNERTEMP]])
+ // CHECK: br label
+ //
+ // CHECK: call void @_ZN1AC1Ei(%{{.*}} %[[OUTERTEMP]], i32 2)
+ // CHECK: br label
+ //
+ // CHECK: call void @_ZN1AD1Ev(%{{.*}} %[[INNERTEMP]])
+ A &&a = A(1) ?: A(2);
+
+ // CHECK: call void @_Z1iv()
+ i();
+
+ // CHECK: call void @_ZN1AD1Ev(%{{.*}} %[[OUTERTEMP]])
+}
diff --git a/test/CodeGenCXX/cxx1z-inline-variables.cpp b/test/CodeGenCXX/cxx1z-inline-variables.cpp
index 183709373d12..2d16acd8a8c2 100644
--- a/test/CodeGenCXX/cxx1z-inline-variables.cpp
+++ b/test/CodeGenCXX/cxx1z-inline-variables.cpp
@@ -31,18 +31,28 @@ struct compat {
static constexpr int b = 2;
static constexpr int c = 3;
static inline constexpr int d = 4;
+ static const int e = 5;
+ static const int f = 6;
+ static const int g = 7;
};
const int &compat_use_before_redecl = compat::b;
const int compat::a;
const int compat::b;
const int compat::c;
const int compat::d;
+const int compat::e;
+constexpr int compat::f;
+constexpr inline int compat::g;
const int &compat_use_after_redecl1 = compat::c;
const int &compat_use_after_redecl2 = compat::d;
-// CHECK: @_ZN6compat1bE = weak_odr constant i32 2
-// CHECK: @_ZN6compat1aE = weak_odr constant i32 1
-// CHECK: @_ZN6compat1cE = weak_odr constant i32 3
-// CHECK: @_ZN6compat1dE = linkonce_odr constant i32 4
+const int &compat_use_after_redecl3 = compat::g;
+// CHECK-DAG: @_ZN6compat1bE = weak_odr constant i32 2
+// CHECK-DAG: @_ZN6compat1aE = weak_odr constant i32 1
+// CHECK-DAG: @_ZN6compat1cE = weak_odr constant i32 3
+// CHECK-DAG: @_ZN6compat1dE = linkonce_odr constant i32 4
+// CHECK-DAG: @_ZN6compat1eE = constant i32 5
+// CHECK-DAG: @_ZN6compat1fE = weak_odr constant i32 6
+// CHECK-DAG: @_ZN6compat1gE = linkonce_odr constant i32 7
template<typename T> struct X {
static int a;
@@ -57,6 +67,18 @@ int &use3 = X<int>::a;
template<> int X<int>::b = 20;
template<> inline int X<int>::c = 30;
+template<typename T> struct Y;
+template<> struct Y<int> {
+ static constexpr int a = 123;
+ static constexpr int b = 456;
+ static constexpr int c = 789;
+};
+// CHECK: @_ZN1YIiE1aE = weak_odr constant i32 123
+constexpr int Y<int>::a;
+// CHECK: @_ZN1YIiE1bE = linkonce_odr constant i32 456
+const int &yib = Y<int>::b;
+// CHECK-NOT: @_ZN1YIiE1cE
+
// CHECK-LABEL: define {{.*}}global_var_init
// CHECK: call i32 @_Z1fv
diff --git a/test/CodeGenCXX/cxx2a-destroying-delete.cpp b/test/CodeGenCXX/cxx2a-destroying-delete.cpp
new file mode 100644
index 000000000000..2e4d40715e15
--- /dev/null
+++ b/test/CodeGenCXX/cxx2a-destroying-delete.cpp
@@ -0,0 +1,161 @@
+// RUN: %clang_cc1 -std=c++2a -emit-llvm %s -triple x86_64-linux-gnu -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-ITANIUM
+// RUN: %clang_cc1 -std=c++2a -emit-llvm %s -triple x86_64-windows -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-MSABI
+
+namespace std {
+ using size_t = decltype(sizeof(0));
+ enum class align_val_t : size_t;
+ struct destroying_delete_t {};
+}
+
+struct A {
+ void *data;
+ ~A();
+ void operator delete(A*, std::destroying_delete_t);
+};
+void delete_A(A *a) { delete a; }
+// CHECK-LABEL: define {{.*}}delete_A
+// CHECK: %[[a:.*]] = load
+// CHECK: icmp eq %{{.*}} %[[a]], null
+// CHECK: br i1
+//
+// Ensure that we call the destroying delete and not the destructor.
+// CHECK-NOT: call
+// CHECK-ITANIUM: call void @_ZN1AdlEPS_St19destroying_delete_t(%{{.*}}* %[[a]])
+// CHECK-MSABI: call void @"\01??3A@@SAXPEAU0@Udestroying_delete_t@std@@@Z"(%{{.*}}* %[[a]], i8
+// CHECK-NOT: call
+// CHECK: }
+
+struct B {
+ virtual ~B();
+ void operator delete(B*, std::destroying_delete_t);
+};
+void delete_B(B *b) { delete b; }
+// CHECK-LABEL: define {{.*}}delete_B
+// CHECK: %[[b:.*]] = load
+// CHECK: icmp eq %{{.*}} %[[b]], null
+// CHECK: br i1
+//
+// Ensure that we call the virtual destructor and not the operator delete.
+// CHECK-NOT: call
+// CHECK: %[[VTABLE:.*]] = load
+// CHECK: %[[DTOR:.*]] = load
+// CHECK: call {{void|i8\*}} %[[DTOR]](%{{.*}}* %[[b]]
+// CHECK-MSABI-SAME: , i32 1)
+// CHECK-NOT: call
+// CHECK: }
+
+struct Padding {
+ virtual void f();
+};
+
+struct C : Padding, A {};
+void delete_C(C *c) { delete c; }
+// Check that we perform a derived-to-base conversion on the parameter to 'operator delete'.
+// CHECK-LABEL: define {{.*}}delete_C
+// CHECK: %[[c:.*]] = load
+// CHECK: icmp eq %{{.*}} %[[c]], null
+// CHECK: br i1
+//
+// CHECK: %[[base:.*]] = getelementptr {{.*}}, i64 8
+// CHECK: %[[castbase:.*]] = bitcast {{.*}} %[[base]]
+//
+// CHECK: %[[a:.*]] = phi {{.*}} %[[castbase]]
+// CHECK: icmp eq %{{.*}} %[[a]], null
+// CHECK: br i1
+//
+// CHECK-NOT: call
+// CHECK-ITANIUM: call void @_ZN1AdlEPS_St19destroying_delete_t(%{{.*}}* %[[a]])
+// CHECK-MSABI: call void @"\01??3A@@SAXPEAU0@Udestroying_delete_t@std@@@Z"(%{{.*}}* %[[a]], i8
+// CHECK-NOT: call
+// CHECK: }
+
+struct VDel { virtual ~VDel(); };
+struct D : Padding, VDel, B {};
+void delete_D(D *d) { delete d; }
+// CHECK-LABEL: define {{.*}}delete_D
+// CHECK: %[[d:.*]] = load
+// CHECK: icmp eq %{{.*}} %[[d]], null
+// CHECK: br i1
+//
+// CHECK-NOT: call
+// CHECK: %[[VTABLE:.*]] = load
+// CHECK: %[[DTOR:.*]] = load
+//
+// For MS, we don't add a new vtable slot to the primary vtable for the virtual
+// destructor. Instead we cast to the VDel base class.
+// CHECK-MSABI: bitcast {{.*}} %[[d]]
+// CHECK-MSABI-NEXT: getelementptr {{.*}}, i64 8
+// CHECK-MSABI-NEXT: %[[d:.*]] = bitcast i8*
+//
+// CHECK: call {{void|i8\*}} %[[DTOR]](%{{.*}}* %[[d]]
+// CHECK-MSABI-SAME: , i32 1)
+// CHECK-NOT: call
+// CHECK: }
+
+struct E { void *data; };
+struct F { void operator delete(F *, std::destroying_delete_t, std::size_t, std::align_val_t); void *data; };
+struct alignas(16) G : E, F { void *data; };
+
+void delete_G(G *g) { delete g; }
+// CHECK-LABEL: define {{.*}}delete_G
+// CHECK-NOT: call
+// CHECK-ITANIUM: call void @_ZN1FdlEPS_St19destroying_delete_tmSt11align_val_t(%{{.*}}* %[[a]], i64 32, i64 16)
+// CHECK-MSABI: call void @"\01??3F@@SAXPEAU0@Udestroying_delete_t@std@@_KW4align_val_t@2@@Z"(%{{.*}}* %[[a]], i8 {{[^,]*}}, i64 32, i64 16)
+// CHECK-NOT: call
+// CHECK: }
+
+void call_in_dtor();
+
+struct H : G { virtual ~H(); } h;
+H::~H() { call_in_dtor(); }
+// CHECK-ITANIUM-LABEL: define void @_ZN1HD0Ev(
+// CHECK-ITANIUM-NOT: call
+// CHECK-ITANIUM: getelementptr {{.*}}, i64 24
+// CHECK-ITANIUM-NOT: call
+// CHECK-ITANIUM: call void @_ZN1FdlEPS_St19destroying_delete_tmSt11align_val_t({{.*}}, i64 48, i64 16)
+// CHECK-ITANIUM-NOT: call
+// CHECK-ITANIUM: }
+
+// CHECK-MSABI: define {{.*}} @"\01??_GH@@UEAAPEAXI@Z"(
+// CHECK-MSABI-NOT: call{{ }}
+// CHECK-MSABI: load i32
+// CHECK-MSABI: icmp eq i32 {{.*}}, 0
+// CHECK-MSABI: br i1
+//
+// CHECK-MSABI-NOT: call{{ }}
+// CHECK-MSABI: getelementptr {{.*}}, i64 24
+// CHECK-MSABI-NOT: call{{ }}
+// CHECK-MSABI: call void @"\01??3F@@SAXPEAU0@Udestroying_delete_t@std@@_KW4align_val_t@2@@Z"({{.*}}, i64 48, i64 16)
+// CHECK-MSABI: br label %[[RETURN:.*]]
+//
+// CHECK-MSABI: call void @"\01??_DH@@QEAAXXZ"(
+// CHECK-MSABI: br label %[[RETURN]]
+//
+// CHECK-MSABI: }
+
+struct I : H { virtual ~I(); alignas(32) char buffer[32]; } i;
+I::~I() { call_in_dtor(); }
+// CHECK-ITANIUM-LABEL: define void @_ZN1ID0Ev(
+// CHECK-ITANIUM-NOT: call
+// CHECK-ITANIUM: getelementptr {{.*}}, i64 24
+// CHECK-ITANIUM-NOT: call
+// CHECK-ITANIUM: call void @_ZN1FdlEPS_St19destroying_delete_tmSt11align_val_t({{.*}}, i64 96, i64 32)
+// CHECK-ITANIUM-NOT: call
+// CHECK-ITANIUM: }
+
+// CHECK-MSABI: define {{.*}} @"\01??_GI@@UEAAPEAXI@Z"(
+// CHECK-MSABI-NOT: call{{ }}
+// CHECK-MSABI: load i32
+// CHECK-MSABI: icmp eq i32 {{.*}}, 0
+// CHECK-MSABI: br i1
+//
+// CHECK-MSABI-NOT: call{{ }}
+// CHECK-MSABI: getelementptr {{.*}}, i64 24
+// CHECK-MSABI-NOT: call{{ }}
+// CHECK-MSABI: call void @"\01??3F@@SAXPEAU0@Udestroying_delete_t@std@@_KW4align_val_t@2@@Z"({{.*}}, i64 96, i64 32)
+// CHECK-MSABI: br label %[[RETURN:.*]]
+//
+// CHECK-MSABI: call void @"\01??_DI@@QEAAXXZ"(
+// CHECK-MSABI: br label %[[RETURN]]
+//
+// CHECK-MSABI: }
diff --git a/test/CodeGenCXX/cxx2a-three-way-comparison.cpp b/test/CodeGenCXX/cxx2a-three-way-comparison.cpp
new file mode 100644
index 000000000000..fd72d4a39cb3
--- /dev/null
+++ b/test/CodeGenCXX/cxx2a-three-way-comparison.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -std=c++2a -emit-llvm %s -o - -triple %itanium_abi_triple | FileCheck %s --check-prefix=ITANIUM
+// RUN: not %clang_cc1 -std=c++2a -emit-llvm %s -o - -triple %ms_abi_triple 2>&1 | FileCheck %s --check-prefix=MSABI
+// RUN: not %clang_cc1 -std=c++2a -emit-llvm %s -o - -triple %itanium_abi_triple -DBUILTIN 2>&1 | FileCheck %s --check-prefix=BUILTIN
+// MSABI: cannot mangle this three-way comparison operator yet
+
+struct A {
+ void operator<=>(int);
+};
+
+// ITANIUM: define {{.*}}@_ZN1AssEi(
+void A::operator<=>(int) {}
+
+// ITANIUM: define {{.*}}@_Zssi1A(
+void operator<=>(int, A) {}
+
+int operator<=>(A, A);
+
+// ITANIUM: define {{.*}}_Z1f1A(
+int f(A a) {
+ // ITANIUM: %[[RET:.*]] = call {{.*}}_Zss1AS_(
+ // ITANIUM: ret i32 %[[RET]]
+ return a <=> a;
+}
+
+#ifdef BUILTIN
+void builtin(int a) {
+ a <=> a; // BUILTIN: cannot compile this scalar expression yet
+}
+#endif
diff --git a/test/CodeGenCXX/debug-info-anon-namespace.cpp b/test/CodeGenCXX/debug-info-anon-namespace.cpp
index 3f4ef2a38360..56c8528abdee 100644
--- a/test/CodeGenCXX/debug-info-anon-namespace.cpp
+++ b/test/CodeGenCXX/debug-info-anon-namespace.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited -triple x86_64-scei-ps4 -O0 %s -o - | FileCheck --check-prefix=PS4 %s
-// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited -triple x86_64-unknown-linux-gnu -O0 %s -o - | FileCheck --check-prefix=NON-PS4 %s
+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited -dwarf-explicit-import -O0 %s -o - | FileCheck --check-prefix=IMPORT %s
+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited -O0 %s -o - | FileCheck --check-prefix=NOIMPORT %s
namespace
{
@@ -17,11 +17,9 @@ namespace
int *b1 = &a1;
int *b2 = &a2;
-
-// PS4: [[NS:![0-9]+]] = !DINamespace
-// PS4: [[CU:![0-9]+]] = distinct !DICompileUnit
-// PS4: [[NS2:![0-9]+]] = !DINamespace
-// PS4: !DIImportedEntity(tag: DW_TAG_imported_module, scope: [[CU]], entity: [[NS]], file: {{![0-9]+}})
-// PS4: !DIImportedEntity(tag: DW_TAG_imported_module, scope: [[NS]], entity: [[NS2]], file: {{![0-9]+}}, line: {{[0-9]+}})
-// NON-PS4-NOT: !DIImportedEntity
-
+// IMPORT: [[NS:![0-9]+]] = !DINamespace
+// IMPORT: [[CU:![0-9]+]] = distinct !DICompileUnit
+// IMPORT: [[NS2:![0-9]+]] = !DINamespace
+// IMPORT: !DIImportedEntity(tag: DW_TAG_imported_module, scope: [[CU]], entity: [[NS]], file: {{![0-9]+}})
+// IMPORT: !DIImportedEntity(tag: DW_TAG_imported_module, scope: [[NS]], entity: [[NS2]], file: {{![0-9]+}}, line: {{[0-9]+}})
+// NOIMPORT-NOT: !DIImportedEntity
diff --git a/test/CodeGenCXX/debug-info-codeview-display-name.cpp b/test/CodeGenCXX/debug-info-codeview-display-name.cpp
index b1b5a1e9acb8..17049d506fa6 100644
--- a/test/CodeGenCXX/debug-info-codeview-display-name.cpp
+++ b/test/CodeGenCXX/debug-info-codeview-display-name.cpp
@@ -1,6 +1,6 @@
// RUN: %clang_cc1 -fblocks -debug-info-kind=limited -gcodeview -emit-llvm %s \
// RUN: -o - -triple=x86_64-pc-win32 -std=c++98 | \
-// RUN: grep 'DISubprogram' | sed -e 's/.*name: "\([^"]*\)".*/"\1"/' | \
+// RUN: grep 'DISubprogram\|DICompositeType' | sed -e 's/.*name: "\([^"]*\)".*/"\1"/' | \
// RUN: FileCheck %s --check-prefix=CHECK --check-prefix=UNQUAL
// RUN: %clang_cc1 -fblocks -debug-info-kind=line-tables-only -gcodeview -emit-llvm %s \
// RUN: -o - -triple=x86_64-pc-win32 -std=c++98 | \
@@ -91,3 +91,8 @@ void fn_tmpl() {}
template void fn_tmpl<int, freefunc>();
// CHECK-DAG: "fn_tmpl<int,&freefunc>"
+
+template <typename A, typename B, typename C> struct ClassTemplate { A a; B b; C c; };
+ClassTemplate<char, short, ClassTemplate<int, int, int> > f;
+// This will only show up in normal debug builds.
+// UNQUAL-DAG: "ClassTemplate<char,short,ClassTemplate<int,int,int> >"
diff --git a/test/CodeGenCXX/debug-info-codeview-nested-types.cpp b/test/CodeGenCXX/debug-info-codeview-nested-types.cpp
new file mode 100644
index 000000000000..7c8f78e7a001
--- /dev/null
+++ b/test/CodeGenCXX/debug-info-codeview-nested-types.cpp
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-pc-windows-msvc -debug-info-kind=limited -gcodeview -emit-llvm -o - | FileCheck %s
+
+struct HasNested {
+ enum InnerEnum { _BUF_SIZE = 1 };
+ typedef int InnerTypedef;
+ enum { InnerEnumerator = 2 };
+ struct InnerStruct { };
+};
+HasNested f;
+
+// CHECK: ![[INNERENUM:[0-9]+]] = !DICompositeType(tag: DW_TAG_enumeration_type, name: "InnerEnum", {{.*}})
+// CHECK: ![[HASNESTED:[0-9]+]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "HasNested",
+// CHECK-SAME: elements: ![[MEMBERS:[0-9]+]],
+//
+// CHECK: ![[MEMBERS]] = !{![[INNERENUM]], ![[INNERTYPEDEF:[0-9]+]], ![[UNNAMEDENUM:[0-9]+]], ![[INNERSTRUCT:[0-9]+]]}
+//
+// CHECK: ![[INNERTYPEDEF]] = !DIDerivedType(tag: DW_TAG_typedef, name: "InnerTypedef", scope: ![[HASNESTED]]{{.*}})
+//
+// CHECK: ![[UNNAMEDENUM]] = !DICompositeType(tag: DW_TAG_enumeration_type, scope: ![[HASNESTED]],
+// CHECK-SAME: elements: ![[UNNAMEDMEMBERS:[0-9]+]],
+// CHECK: ![[UNNAMEDMEMBERS]] = !{![[INNERENUMERATOR:[0-9]+]]}
+// CHECK: ![[INNERENUMERATOR]] = !DIEnumerator(name: "InnerEnumerator", value: 2)
+//
+// CHECK: ![[INNERSTRUCT]] = !DICompositeType(tag: DW_TAG_structure_type, name: "InnerStruct"
+// CHECK-SAME: flags: DIFlagFwdDecl
diff --git a/test/CodeGenCXX/debug-info-fwd-template-param.cpp b/test/CodeGenCXX/debug-info-fwd-template-param.cpp
new file mode 100644
index 000000000000..2983f842744a
--- /dev/null
+++ b/test/CodeGenCXX/debug-info-fwd-template-param.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 %s -triple=%itanium_abi_triple -debug-info-kind=limited -debug-forward-template-params -emit-llvm -o - | FileCheck --check-prefix=CHILD %s
+// RUN: %clang_cc1 %s -triple=%itanium_abi_triple -debug-info-kind=limited -emit-llvm -o - | FileCheck --check-prefix=NONE %s
+// A DWARF forward declaration of a template instantiation should have template
+// parameter children (if we ask for them).
+
+template<typename T> class A;
+A<int> *p;
+
+// CHILD: !DICompositeType(tag: DW_TAG_class_type, name: "A<int>"
+// CHILD-SAME: flags: DIFlagFwdDecl
+// CHILD-SAME: templateParams: [[PARAM_LIST:![0-9]*]]
+// CHILD: [[PARAM_LIST]] = !{[[PARAM:![0-9]*]]}
+// CHILD: [[PARAM]] = !DITemplateTypeParameter(name: "T",
+// CHILD-SAME: type: [[BTYPE:![0-9]*]]
+// CHILD: [[BTYPE]] = !DIBasicType(name: "int"
+
+// NONE: !DICompositeType(tag: DW_TAG_class_type, name: "A<int>"
+// NONE-SAME: flags: DIFlagFwdDecl
+// NONE-NOT: templateParams:
+// NONE-SAME: )
diff --git a/test/CodeGenCXX/debug-info-inheriting-constructor.cpp b/test/CodeGenCXX/debug-info-inheriting-constructor.cpp
index e3708e2080f0..8e47a0da6dff 100644
--- a/test/CodeGenCXX/debug-info-inheriting-constructor.cpp
+++ b/test/CodeGenCXX/debug-info-inheriting-constructor.cpp
@@ -13,7 +13,7 @@ A::A(int i, ...) {}
// CHECK: call void @llvm.dbg.declare
// CHECK-NOT ret void
// CHECK: call void @llvm.dbg.declare(metadata %{{.*}}** %{{[^,]+}},
-// CHECK-SAME: metadata ![[THIS:[0-9]+]], metadata !{{[0-9]+}}), !dbg ![[LOC:[0-9]+]]
+// CHECK-SAME: metadata ![[THIS:[0-9]+]], metadata !DIExpression()), !dbg ![[LOC:[0-9]+]]
// CHECK: ret void, !dbg ![[NOINL:[0-9]+]]
// CHECK: ![[FOO:.*]] = distinct !DISubprogram(name: "foo"
// CHECK-DAG: ![[A:.*]] = distinct !DISubprogram(name: "A", linkageName: "_ZN1BCI11AEiz"
diff --git a/test/CodeGenCXX/debug-info-inlined.cpp b/test/CodeGenCXX/debug-info-inlined.cpp
index 9969ef79ca7e..53e2cc9289c2 100644
--- a/test/CodeGenCXX/debug-info-inlined.cpp
+++ b/test/CodeGenCXX/debug-info-inlined.cpp
@@ -1,45 +1,29 @@
// RUN: %clang_cc1 -emit-llvm -triple i686-pc-windows-msvc19.0.24213 -gcodeview -debug-info-kind=limited -std=c++14 %s -o - | FileCheck %s
// PR33997.
-struct already_AddRefed {
- ~already_AddRefed();
+struct WithDtor {
+ ~WithDtor();
};
-struct RefPtr {
- operator int *();
+struct Base {
+ Base(WithDtor);
};
-struct ServoCssRulesStrong {
- already_AddRefed Consume();
+class Forward : Base {
+ using Base::Base;
};
-struct GroupRule {
- GroupRule(already_AddRefed);
+class A : Forward {
+ A();
};
-class ConditionRule : GroupRule {
- using GroupRule::GroupRule;
+class B : Forward {
+ B();
};
-class CSSMediaRule : ConditionRule {
- using ConditionRule::ConditionRule;
-};
-class CSSMozDocumentRule : ConditionRule {
- using ConditionRule::ConditionRule;
-};
-class ServoDocumentRule : CSSMozDocumentRule {
- ServoDocumentRule(RefPtr);
-};
-class ServoMediaRule : CSSMediaRule {
- ServoMediaRule(RefPtr);
-};
-ServoCssRulesStrong Servo_MediaRule_GetRules(int *);
-ServoCssRulesStrong Servo_DocumentRule_GetRules(int *);
-ServoDocumentRule::ServoDocumentRule(RefPtr aRawRule)
- : CSSMozDocumentRule(Servo_DocumentRule_GetRules(aRawRule).Consume()) {}
+A::A() : Forward(WithDtor()) {}
-ServoMediaRule::ServoMediaRule(RefPtr aRawRule)
- : CSSMediaRule(Servo_MediaRule_GetRules(aRawRule).Consume()) {}
+B::B() : Forward(WithDtor()) {}
-// CHECK: define{{.*}}ServoMediaRule
+// CHECK: define{{.*}}A
// CHECK-NOT: {{ ret }}
-// CHECK: store %class.ConditionRule* %
-// CHECK-SAME: %class.ConditionRule** %
+// CHECK: store %class.Forward* %
+// CHECK-SAME: %class.Forward** %
// CHECK-SAME: !dbg ![[INL:[0-9]+]]
-// CHECK: ![[INL]] = !DILocation(line: 16, scope: ![[SP:[0-9]+]], inlinedAt:
-// CHECK: ![[SP]] = distinct !DISubprogram(name: "GroupRule", {{.*}}isDefinition: true
+// CHECK: ![[INL]] = !DILocation(line: 10, scope: ![[SP:[0-9]+]], inlinedAt:
+// CHECK: ![[SP]] = distinct !DISubprogram(name: "Base", {{.*}}isDefinition: true
diff --git a/test/CodeGenCXX/debug-info-method.cpp b/test/CodeGenCXX/debug-info-method.cpp
index e0f9a284f2cf..af7103e57528 100644
--- a/test/CodeGenCXX/debug-info-method.cpp
+++ b/test/CodeGenCXX/debug-info-method.cpp
@@ -20,6 +20,7 @@ union {
class A {
protected:
void foo(int, A, decltype(u));
+ void bar();
};
void A::foo(int, A, decltype(u)) {
@@ -29,3 +30,5 @@ A a;
int A::*x = 0;
int (A::*y)(int) = 0;
+
+void A::bar() { foo(0, *this, u); }
diff --git a/test/CodeGenCXX/debug-info-ms-abi.cpp b/test/CodeGenCXX/debug-info-ms-abi.cpp
index 1bf8bab5f41c..e83d7e94230d 100644
--- a/test/CodeGenCXX/debug-info-ms-abi.cpp
+++ b/test/CodeGenCXX/debug-info-ms-abi.cpp
@@ -6,6 +6,7 @@ struct Foo {
virtual void f();
virtual void g();
virtual void h();
+ static void i(int, int);
struct Nested {};
};
Foo f;
@@ -18,7 +19,7 @@ Foo::Nested n;
// CHECK-SAME: elements: ![[elements:[0-9]+]]
// CHECK-SAME: identifier: ".?AUFoo@@"
-// CHECK: ![[elements]] = !{![[vshape:[0-9]+]], ![[vptr:[0-9]+]], ![[Nested]], ![[f:[0-9]+]], ![[g:[0-9]+]], ![[h:[0-9]+]]}
+// CHECK: ![[elements]] = !{![[vshape:[0-9]+]], ![[vptr:[0-9]+]], ![[Nested]], ![[f:[0-9]+]], ![[g:[0-9]+]], ![[h:[0-9]+]], ![[i:[0-9]+]]}
// CHECK: ![[vshape]] = !DIDerivedType(tag: DW_TAG_pointer_type, name: "__vtbl_ptr_type", baseType: null, size: 96)
@@ -38,3 +39,9 @@ Foo::Nested n;
// CHECK: ![[h]] = !DISubprogram(name: "h",
// CHECK-SAME: containingType: ![[Foo]], virtuality: DW_VIRTUALITY_virtual, virtualIndex: 2,
// CHECK-SAME: flags: DIFlagPrototyped | DIFlagIntroducedVirtual,
+
+// CHECK: ![[i]] = !DISubprogram(name: "i",
+// CHECK-SAME: flags: DIFlagPrototyped | DIFlagStaticMember
+// CHECK-NEXT: ![[dummy:[0-9]+]] = !DISubroutineType(types: ![[Signature:[0-9]+]])
+// CHECK: ![[Signature]] = !{null, ![[BasicInt:[0-9]+]], ![[BasicInt]]}
+// CHECK: ![[BasicInt]] = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
diff --git a/test/CodeGenCXX/debug-info-nested-exprs.cpp b/test/CodeGenCXX/debug-info-nested-exprs.cpp
new file mode 100644
index 000000000000..bd70373e2285
--- /dev/null
+++ b/test/CodeGenCXX/debug-info-nested-exprs.cpp
@@ -0,0 +1,202 @@
+// RUN: %clang_cc1 -triple=x86_64-pc-windows-msvc -debug-info-kind=limited \
+// RUN: -std=c++11 -gcodeview -emit-llvm -o - %s \
+// RUN: | FileCheck -check-prefix=NONEST %s
+// RUN: %clang_cc1 -triple=x86_64-pc-windows-msvc -debug-info-kind=limited \
+// RUN: -std=c++11 -gcodeview -dwarf-column-info -emit-llvm -o - %s \
+// RUN: | FileCheck -check-prefix=COLUMNS %s
+// RUN: %clang_cc1 -triple=x86_64-unknown-linux-gnu -debug-info-kind=limited \
+// RUN: -std=c++11 -emit-llvm -o - %s | FileCheck -check-prefix=NESTED %s
+// RUN: %clang_cc1 -triple=x86_64-unknown-linux-gnu -debug-info-kind=limited \
+// RUN: -std=c++11 -dwarf-column-info -emit-llvm -o - %s \
+// RUN: | FileCheck -check-prefix=COLUMNS %s
+
+class Foo {
+public:
+ static Foo create();
+ void func();
+ int *begin();
+ int *end();
+};
+
+int bar(int x, int y);
+int baz(int x, int y);
+int qux(int x, int y);
+int onearg(int x);
+int noargs();
+int noargs1();
+Foo range(int x);
+
+int foo(int x, int y, int z) {
+ int a = bar(x, y) +
+ baz(x, z) +
+ qux(y, z);
+ // NONEST: call i32 @{{.*}}bar{{.*}}, !dbg ![[LOC:[0-9]+]]
+ // NONEST: call i32 @{{.*}}baz{{.*}}, !dbg ![[LOC]]
+ // NONEST: call i32 @{{.*}}qux{{.*}}, !dbg ![[LOC]]
+ // NONEST: store i32 {{.*}}, i32* %a,{{.*}} !dbg ![[LOC]]
+ // NESTED: call i32 @{{.*}}bar{{.*}}, !dbg ![[BAR:[0-9]+]]
+ // NESTED: call i32 @{{.*}}baz{{.*}}, !dbg ![[BAZ:[0-9]+]]
+ // NESTED: call i32 @{{.*}}qux{{.*}}, !dbg ![[QUX:[0-9]+]]
+ // NESTED: store i32 {{.*}}, i32* %a,{{.*}} !dbg ![[BAR]]
+ // COLUMNS: call i32 @{{.*}}bar{{.*}}, !dbg ![[BAR:[0-9]+]]
+ // COLUMNS: call i32 @{{.*}}baz{{.*}}, !dbg ![[BAZ:[0-9]+]]
+ // COLUMNS: call i32 @{{.*}}qux{{.*}}, !dbg ![[QUX:[0-9]+]]
+ // COLUMNS: store i32 {{.*}}, i32* %a,{{.*}} !dbg ![[DECLA:[0-9]+]]
+
+ int i = 1, b = 0, c = 0;
+ // NONEST: store i32 1, i32* %i,{{.*}} !dbg ![[ILOC:[0-9]+]]
+ // NONEST: store i32 0, i32* %b,{{.*}} !dbg ![[ILOC]]
+ // NONEST: store i32 0, i32* %c,{{.*}} !dbg ![[ILOC]]
+ // NESTED: store i32 1, i32* %i,{{.*}} !dbg ![[ILOC:[0-9]+]]
+ // NESTED: store i32 0, i32* %b,{{.*}} !dbg ![[ILOC]]
+ // NESTED: store i32 0, i32* %c,{{.*}} !dbg ![[ILOC]]
+ // COLUMNS: store i32 1, i32* %i,{{.*}} !dbg ![[ILOC:[0-9]+]]
+ // COLUMNS: store i32 0, i32* %b,{{.*}} !dbg ![[BLOC:[0-9]+]]
+ // COLUMNS: store i32 0, i32* %c,{{.*}} !dbg ![[CLOC:[0-9]+]]
+
+ while (i > 0) {
+ b = bar(a, b);
+ --i;
+ }
+ // NONEST: call i32 @{{.*}}bar{{.*}}, !dbg ![[WHILE1:[0-9]+]]
+ // NONEST: store i32 %{{[^,]+}}, i32* %i,{{.*}} !dbg ![[WHILE2:[0-9]+]]
+ // NESTED: call i32 @{{.*}}bar{{.*}}, !dbg ![[WHILE1:[0-9]+]]
+ // NESTED: store i32 %{{[^,]+}}, i32* %i,{{.*}} !dbg ![[WHILE2:[0-9]+]]
+ // COLUMNS: call i32 @{{.*}}bar{{.*}}, !dbg ![[WHILE1:[0-9]+]]
+ // COLUMNS: store i32 %{{[^,]+}}, i32* %i,{{.*}} !dbg ![[WHILE2:[0-9]+]]
+
+ for (i = 0; i < 1; i++) {
+ b = bar(a, b);
+ c = qux(a, c);
+ }
+ // NONEST: call i32 @{{.*}}bar{{.*}}, !dbg ![[FOR1:[0-9]+]]
+ // NONEST: call i32 @{{.*}}qux{{.*}}, !dbg ![[FOR2:[0-9]+]]
+ // NESTED: call i32 @{{.*}}bar{{.*}}, !dbg ![[FOR1:[0-9]+]]
+ // NESTED: call i32 @{{.*}}qux{{.*}}, !dbg ![[FOR2:[0-9]+]]
+ // COLUMNS: call i32 @{{.*}}bar{{.*}}, !dbg ![[FOR1:[0-9]+]]
+ // COLUMNS: call i32 @{{.*}}qux{{.*}}, !dbg ![[FOR2:[0-9]+]]
+
+ if (a < b) {
+ int t = a;
+ a = b;
+ b = t;
+ }
+ // NONEST: store i32 %{{[^,]+}}, i32* %t,{{.*}} !dbg ![[IF1:[0-9]+]]
+ // NONEST: store i32 %{{[^,]+}}, i32* %a,{{.*}} !dbg ![[IF2:[0-9]+]]
+ // NONEST: store i32 %{{[^,]+}}, i32* %b,{{.*}} !dbg ![[IF3:[0-9]+]]
+ // NESTED: store i32 %{{[^,]+}}, i32* %t,{{.*}} !dbg ![[IF1:[0-9]+]]
+ // NESTED: store i32 %{{[^,]+}}, i32* %a,{{.*}} !dbg ![[IF2:[0-9]+]]
+ // NESTED: store i32 %{{[^,]+}}, i32* %b,{{.*}} !dbg ![[IF3:[0-9]+]]
+ // COLUMNS: store i32 %{{[^,]+}}, i32* %t,{{.*}} !dbg ![[IF1:[0-9]+]]
+ // COLUMNS: store i32 %{{[^,]+}}, i32* %a,{{.*}} !dbg ![[IF2:[0-9]+]]
+ // COLUMNS: store i32 %{{[^,]+}}, i32* %b,{{.*}} !dbg ![[IF3:[0-9]+]]
+
+ int d = onearg(
+ noargs());
+ // NONEST: call i32 @{{.*}}noargs{{.*}}, !dbg ![[DECLD:[0-9]+]]
+ // NONEST: call i32 @{{.*}}onearg{{.*}}, !dbg ![[DECLD]]
+ // NONEST: store i32 %{{[^,]+}}, i32* %d,{{.*}} !dbg ![[DECLD]]
+ // NESTED: call i32 @{{.*}}noargs{{.*}}, !dbg ![[DNOARGS:[0-9]+]]
+ // NESTED: call i32 @{{.*}}onearg{{.*}}, !dbg ![[DECLD:[0-9]+]]
+ // NESTED: store i32 %{{[^,]+}}, i32* %d,{{.*}} !dbg ![[DECLD]]
+ // COLUMNS: call i32 @{{.*}}noargs{{.*}}, !dbg ![[DNOARGS:[0-9]+]]
+ // COLUMNS: call i32 @{{.*}}onearg{{.*}}, !dbg ![[DONEARG:[0-9]+]]
+ // COLUMNS: store i32 %{{[^,]+}}, i32* %d,{{.*}} !dbg ![[DECLD:[0-9]+]]
+
+ d = onearg(noargs());
+ // NONEST: call i32 @{{.*}}noargs{{.*}}, !dbg ![[SETD:[0-9]+]]
+ // NONEST: call i32 @{{.*}}onearg{{.*}}, !dbg ![[SETD]]
+ // NONEST: store i32 %{{[^,]+}}, i32* %d,{{.*}} !dbg ![[SETD]]
+ // NESTED: call i32 @{{.*}}noargs{{.*}}, !dbg ![[SETD:[0-9]+]]
+ // NESTED: call i32 @{{.*}}onearg{{.*}}, !dbg ![[SETD]]
+ // NESTED: store i32 %{{[^,]+}}, i32* %d,{{.*}} !dbg ![[SETD]]
+ // COLUMNS: call i32 @{{.*}}noargs{{.*}}, !dbg ![[SETDNOARGS:[0-9]+]]
+ // COLUMNS: call i32 @{{.*}}onearg{{.*}}, !dbg ![[SETDONEARG:[0-9]+]]
+ // COLUMNS: store i32 %{{[^,]+}}, i32* %d,{{.*}} !dbg ![[SETD:[0-9]+]]
+
+ for (const auto x : range(noargs())) noargs1();
+ // NONEST: call i32 @{{.*}}noargs{{.*}}, !dbg ![[RANGEFOR:[0-9]+]]
+ // NONEST: call {{.+}} @{{.*}}range{{.*}}, !dbg ![[RANGEFOR]]
+ // NONEST: call i32 @{{.*}}noargs1{{.*}}, !dbg ![[RANGEFOR_BODY:[0-9]+]]
+ // NESTED: call i32 @{{.*}}noargs{{.*}}, !dbg ![[RANGEFOR:[0-9]+]]
+ // NESTED: call {{.+}} @{{.*}}range{{.*}}, !dbg ![[RANGEFOR]]
+ // NESTED: call i32 @{{.*}}noargs1{{.*}}, !dbg ![[RANGEFOR_BODY:[0-9]+]]
+ // COLUMNS: call i32 @{{.*}}noargs{{.*}}, !dbg ![[RANGEFOR_NOARGS:[0-9]+]]
+ // COLUMNS: call {{.+}} @{{.*}}range{{.*}}, !dbg ![[RANGEFOR_RANGE:[0-9]+]]
+ // COLUMNS: call i32 @{{.*}}noargs1{{.*}}, !dbg ![[RANGEFOR_BODY:[0-9]+]]
+
+ if (noargs() && noargs1()) {
+ Foo::create().func();
+ }
+ // NONEST: call i32 @{{.*}}noargs{{.*}}, !dbg ![[AND:[0-9]+]]
+ // NONEST: call i32 @{{.*}}noargs1{{.*}}, !dbg ![[AND]]
+ // NONEST: call {{.+}} @{{.*}}create{{.*}}, !dbg ![[AND_BODY:[0-9]+]]
+ // NONEST: call void @{{.*}}func{{.*}}, !dbg ![[AND_BODY]]
+ // NESTED: call i32 @{{.*}}noargs{{.*}}, !dbg ![[AND:[0-9]+]]
+ // NESTED: call i32 @{{.*}}noargs1{{.*}}, !dbg ![[AND]]
+ // NESTED: call {{.+}} @{{.*}}create{{.*}}, !dbg ![[AND_BODY:[0-9]+]]
+ // NESTED: call void @{{.*}}func{{.*}}, !dbg ![[AND_BODY]]
+ // COLUMNS: call i32 @{{.*}}noargs{{.*}}, !dbg ![[ANDLHS:[0-9]+]]
+ // COLUMNS: call i32 @{{.*}}noargs1{{.*}}, !dbg ![[ANDRHS:[0-9]+]]
+ // COLUMNS: call {{.+}} @{{.*}}create{{.*}}, !dbg ![[AND_CREATE:[0-9]+]]
+ // COLUMNS: call void @{{.*}}func{{.*}}, !dbg ![[AND_FUNC:[0-9]+]]
+
+ return a -
+ (b * z);
+ // NONEST: mul nsw i32 {{.*}}, !dbg ![[RETLOC:[0-9]+]]
+ // NONEST: sub nsw i32 {{.*}}, !dbg ![[RETLOC]]
+ // NONEST: ret i32 {{.*}}, !dbg ![[RETLOC]]
+ // NESTED: mul nsw i32 {{.*}}, !dbg ![[RETMUL:[0-9]+]]
+ // NESTED: sub nsw i32 {{.*}}, !dbg ![[RETSUB:[0-9]+]]
+ // NESTED: ret i32 {{.*}}, !dbg !
+ // COLUMNS: mul nsw i32 {{.*}}, !dbg ![[RETMUL:[0-9]+]]
+ // COLUMNS: sub nsw i32 {{.*}}, !dbg ![[RETSUB:[0-9]+]]
+ // COLUMNS: ret i32 {{.*}}, !dbg !
+}
+
+// NONEST: ![[WHILE1]] = !DILocation(
+// NONEST: ![[WHILE2]] = !DILocation(
+// NONEST: ![[FOR1]] = !DILocation(
+// NONEST: ![[FOR2]] = !DILocation(
+// NONEST: ![[IF1]] = !DILocation(
+// NONEST: ![[IF2]] = !DILocation(
+// NONEST: ![[IF3]] = !DILocation(
+// NONEST: ![[RANGEFOR]] = !DILocation(
+// NONEST-SAME: line: [[RANGEFOR_LINE:[0-9]+]]
+// NONEST: ![[RANGEFOR_BODY]] = !DILocation(
+// NONEST-SAME: line: [[RANGEFOR_LINE]]
+
+// NESTED: ![[BAR]] = !DILocation(
+// NESTED: ![[BAZ]] = !DILocation(
+// NESTED: ![[QUX]] = !DILocation(
+// NESTED: ![[DECLD]] = !DILocation
+// NESTED: ![[DNOARGS]] = !DILocation
+// NESTED: ![[RANGEFOR]] = !DILocation(
+// NESTED-SAME: line: [[RANGEFOR_LINE:[0-9]+]]
+// NESTED: ![[RANGEFOR_BODY]] = !DILocation(
+// NESTED-SAME: line: [[RANGEFOR_LINE]]
+// NESTED: ![[RETSUB]] = !DILocation(
+// NESTED: ![[RETMUL]] = !DILocation(
+
+// COLUMNS: ![[DECLA]] = !DILocation(
+// COLUMNS: ![[BAR]] = !DILocation(
+// COLUMNS: ![[BAZ]] = !DILocation(
+// COLUMNS: ![[QUX]] = !DILocation(
+// COLUMNS: ![[ILOC]] = !DILocation(
+// COLUMNS: ![[BLOC]] = !DILocation(
+// COLUMNS: ![[CLOC]] = !DILocation(
+// COLUMNS: ![[DECLD]] = !DILocation(
+// COLUMNS: ![[DNOARGS]] = !DILocation(
+// COLUMNS: ![[DONEARG]] = !DILocation(
+// COLUMNS: ![[SETDNOARGS]] = !DILocation(
+// COLUMNS: ![[SETDONEARG]] = !DILocation(
+// COLUMNS: ![[SETD]] = !DILocation(
+// COLUMNS: ![[RANGEFOR_NOARGS]] = !DILocation(
+// COLUMNS: ![[RANGEFOR_RANGE]] = !DILocation(
+// COLUMNS: ![[RANGEFOR_BODY]] = !DILocation(
+// COLUMNS: ![[ANDLHS]] = !DILocation
+// COLUMNS: ![[ANDRHS]] = !DILocation
+// COLUMNS: ![[AND_CREATE]] = !DILocation
+// COLUMNS: ![[AND_FUNC]] = !DILocation
+// COLUNMS: ![[RETSUB]] = !DILocation(
+// COLUMNS: ![[RETMUL]] = !DILocation(
diff --git a/test/CodeGenCXX/debug-info-static-member.cpp b/test/CodeGenCXX/debug-info-static-member.cpp
index c777ccb2aba2..3537754ced76 100644
--- a/test/CodeGenCXX/debug-info-static-member.cpp
+++ b/test/CodeGenCXX/debug-info-static-member.cpp
@@ -32,7 +32,7 @@ public:
// why the definition of "a" comes before the declarations while
// "b" and "c" come after.
-// CHECK: [[A]] = !DIGlobalVariableExpression(var: [[AV:.*]])
+// CHECK: [[A]] = !DIGlobalVariableExpression(var: [[AV:.*]], expr: !DIExpression())
// CHECK: [[AV]] = distinct !DIGlobalVariable(name: "a",
// CHECK-SAME: declaration: ![[DECL_A:[0-9]+]])
//
@@ -45,7 +45,7 @@ public:
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "static_decl_templ_var"
int C::a = 4;
-// CHECK: [[B]] = !DIGlobalVariableExpression(var: [[BV:.*]])
+// CHECK: [[B]] = !DIGlobalVariableExpression(var: [[BV:.*]], expr: !DIExpression())
// CHECK: [[BV]] = distinct !DIGlobalVariable(name: "b",
// CHECK-SAME: declaration: ![[DECL_B:[0-9]+]])
// CHECK: ![[DECL_B]] = !DIDerivedType(tag: DW_TAG_member, name: "b"
@@ -93,7 +93,7 @@ int C::a = 4;
// CHECK-SAME: flags: DIFlagPublic | DIFlagStaticMember)
int C::b = 2;
-// CHECK: [[C]] = !DIGlobalVariableExpression(var: [[CV:.*]])
+// CHECK: [[C]] = !DIGlobalVariableExpression(var: [[CV:.*]], expr: !DIExpression())
// CHECK: [[CV]] = distinct !DIGlobalVariable(name: "c", {{.*}} declaration: ![[DECL_C]])
int C::c = 1;
diff --git a/test/CodeGenCXX/debug-info-template-member.cpp b/test/CodeGenCXX/debug-info-template-member.cpp
index 2b840745ffeb..a6aa1a05a256 100644
--- a/test/CodeGenCXX/debug-info-template-member.cpp
+++ b/test/CodeGenCXX/debug-info-template-member.cpp
@@ -19,7 +19,7 @@ inline int add3(int x) {
}
// The compile unit pulls in the global variables first.
-// CHECK: [[X]] = !DIGlobalVariableExpression(var: [[XV:.*]])
+// CHECK: [[X]] = !DIGlobalVariableExpression(var: [[XV:.*]], expr: !DIExpression())
// CHECK: [[XV]] = distinct !DIGlobalVariable(name: "x",
// CHECK-SAME: type: ![[OUTER_FOO_INNER_ID:[0-9]+]]
diff --git a/test/CodeGenCXX/debug-info-template.cpp b/test/CodeGenCXX/debug-info-template.cpp
index 54fac0b36eec..0c3414516215 100644
--- a/test/CodeGenCXX/debug-info-template.cpp
+++ b/test/CodeGenCXX/debug-info-template.cpp
@@ -25,7 +25,7 @@ struct TC {
int glb;
void func();
-// CHECK: [[TCI]] = !DIGlobalVariableExpression(var: [[TCIV:.*]])
+// CHECK: [[TCI]] = !DIGlobalVariableExpression(var: [[TCIV:.*]], expr: !DIExpression())
// CHECK: [[TCIV]] = distinct !DIGlobalVariable(name: "tci",
// CHECK-SAME: type: ![[TCNESTED:[0-9]+]]
// CHECK: ![[TCNESTED]] ={{.*}}!DICompositeType(tag: DW_TAG_structure_type, name: "nested",
@@ -84,7 +84,7 @@ TC
// CHECK: [[TCARG7_3]] = !DITemplateValueParameter(type: [[INT]], value: i32 3)
3>::nested tci;
-// CHECK: [[TCN]] = !DIGlobalVariableExpression(var: [[TCNV:.*]])
+// CHECK: [[TCN]] = !DIGlobalVariableExpression(var: [[TCNV:.*]], expr: !DIExpression())
// CHECK: [[TCNV]] = distinct !DIGlobalVariable(name: "tcn"
// CHECK-SAME: type: ![[TCNT:[0-9]+]]
TC
@@ -125,7 +125,7 @@ template <template <typename> class tmpl, int &lvr, int &&rvr>
struct NN {
};
-// CHECK: [[NN]] = !DIGlobalVariableExpression(var: [[NNV:.*]])
+// CHECK: [[NN]] = !DIGlobalVariableExpression(var: [[NNV:.*]], expr: !DIExpression())
// CHECK: [[NNV]] = distinct !DIGlobalVariable(name: "nn"
// CHECK-SAME: type: ![[NNT:[0-9]+]]
diff --git a/test/CodeGenCXX/debug-info.cpp b/test/CodeGenCXX/debug-info.cpp
index 2b86150b52b5..6d6d0c7d19cf 100644
--- a/test/CodeGenCXX/debug-info.cpp
+++ b/test/CodeGenCXX/debug-info.cpp
@@ -4,11 +4,11 @@
// CHECK: @_ZN6pr96081xE = global [3 x i8]* null, align 8, !dbg [[X:![0-9]+]]
// CHECK: define void @_ZN7pr147634funcENS_3fooE
-// CHECK: call void @llvm.dbg.declare({{.*}}, metadata ![[F:[0-9]+]], metadata ![[EXPR:[0-9]+]])
+// CHECK: call void @llvm.dbg.declare({{.*}}, metadata ![[F:[0-9]+]], metadata !DIExpression())
// !llvm.dbg.cu pulls in globals and their types first.
// CHECK-NOT: !DIGlobalVariable(name: "c"
-// CHECK: [[X]] = !DIGlobalVariableExpression(var: [[XV:!.*]])
+// CHECK: [[X]] = !DIGlobalVariableExpression(var: [[XV:!.*]], expr: !DIExpression())
// CHECK: [[XV]] = distinct !DIGlobalVariable(name: "x", linkageName: "_ZN6pr96081xE"
// CHECK-SAME: type: [[INCARRAYPTR:![0-9]*]]
// CHECK: [[INCARRAYPTR]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: [[INCARRAY:![0-9]+]]
@@ -21,7 +21,6 @@
// CHECK: ![[INCTYPE]] = !DICompositeType(tag: DW_TAG_structure_type, name: "incomplete"
// CHECK-SAME: DIFlagFwdDecl
-// CHECK: ![[EXPR]] = !DIExpression()
template<typename T> struct Identity {
typedef T Type;
diff --git a/test/CodeGenCXX/default_calling_conv.cpp b/test/CodeGenCXX/default_calling_conv.cpp
index 95c214a223d4..b5b0f47ceb98 100644
--- a/test/CodeGenCXX/default_calling_conv.cpp
+++ b/test/CodeGenCXX/default_calling_conv.cpp
@@ -3,13 +3,23 @@
// RUN: %clang_cc1 -triple i486-unknown-linux-gnu -fdefault-calling-conv=stdcall -emit-llvm -o - %s | FileCheck %s --check-prefix=STDCALL --check-prefix=ALL
// RUN: %clang_cc1 -triple i486-unknown-linux-gnu -mrtd -emit-llvm -o - %s | FileCheck %s --check-prefix=STDCALL --check-prefix=ALL
// RUN: %clang_cc1 -triple i986-unknown-linux-gnu -fdefault-calling-conv=vectorcall -emit-llvm -o - %s | FileCheck %s --check-prefix=VECTORCALL --check-prefix=ALL
+// RUN: %clang_cc1 -triple i986-unknown-linux-gnu -fdefault-calling-conv=regcall -emit-llvm -o - %s | FileCheck %s --check-prefix=REGCALL --check-prefix=ALL
// CDECL: define void @_Z5test1v
// FASTCALL: define x86_fastcallcc void @_Z5test1v
// STDCALL: define x86_stdcallcc void @_Z5test1v
// VECTORCALL: define x86_vectorcallcc void @_Z5test1v
+// REGCALL: define x86_regcallcc void @_Z17__regcall3__test1v
void test1() {}
+// fastcall, stdcall, vectorcall and regcall do not support variadic functions.
+// CDECL: define void @_Z12testVariadicz
+// FASTCALL: define void @_Z12testVariadicz
+// STDCALL: define void @_Z12testVariadicz
+// VECTORCALL: define void @_Z12testVariadicz
+// REGCALL: define void @_Z12testVariadicz
+void testVariadic(...){}
+
// ALL: define void @_Z5test2v
void __attribute__((cdecl)) test2() {}
@@ -22,6 +32,9 @@ void __attribute__((stdcall)) test4() {}
// ALL: define x86_vectorcallcc void @_Z5test5v
void __attribute__((vectorcall)) test5() {}
+// ALL: define x86_regcallcc void @_Z17__regcall3__test6v
+void __attribute__((regcall)) test6() {}
+
// ALL: define linkonce_odr void @_ZN1A11test_memberEv
class A {
public:
@@ -32,3 +45,8 @@ void test() {
A a;
a.test_member();
}
+
+// ALL: define i32 @main
+int main() {
+ return 1;
+}
diff --git a/test/CodeGenCXX/dllexport-vtable-thunks.cpp b/test/CodeGenCXX/dllexport-vtable-thunks.cpp
new file mode 100644
index 000000000000..81811ace2ee6
--- /dev/null
+++ b/test/CodeGenCXX/dllexport-vtable-thunks.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -triple x86_64-windows-gnu -fdeclspec -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-windows-itanium -fdeclspec -emit-llvm -o - %s | FileCheck %s
+
+struct __declspec(dllexport) A {
+ virtual void m();
+};
+struct __declspec(dllexport) B {
+ virtual void m();
+};
+struct __declspec(dllexport) C : A, B {
+ virtual void m();
+};
+void C::m() {}
+// CHECK: define dllexport void @_ZThn8_N1C1mEv
+
+struct Base {
+ virtual void m();
+};
+struct __declspec(dllexport) Derived : virtual Base {
+ virtual void m();
+};
+void Derived::m() {}
+// CHECK: define dllexport void @_ZTv0_n24_N7Derived1mEv
diff --git a/test/CodeGenCXX/dllexport.cpp b/test/CodeGenCXX/dllexport.cpp
index bdef2eb06e69..a446147b6cdc 100644
--- a/test/CodeGenCXX/dllexport.cpp
+++ b/test/CodeGenCXX/dllexport.cpp
@@ -102,15 +102,9 @@ inline int __declspec(dllexport) inlineStaticLocalsFunc() {
// Declarations are not exported.
-// dllexport implies a definition.
-// MSC-NOT: @"\01??$VarTmplDef@UExplicitInst_Exported@@@@3HA"
-// GNU-NOT: @_Z10VarTmplDefI21ExplicitInst_ExportedE
-template<typename T> __declspec(dllexport) int VarTmplDef;
-INSTVAR(VarTmplDef<ExplicitInst_Exported>)
-
// MSC-DAG: @"\01??$VarTmplImplicitDef@UImplicitInst_Exported@@@@3HA" = external global
// GNU-DAG: @_Z18VarTmplImplicitDefI21ImplicitInst_ExportedE = external global
-template<typename T> __declspec(dllexport) int VarTmplImplicitDef;
+template<typename T> __declspec(dllexport) extern int VarTmplImplicitDef;
USEVAR(VarTmplImplicitDef<ImplicitInst_Exported>)
// Export definition.
@@ -826,11 +820,26 @@ struct __declspec(dllexport) B {
// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??_FB@pr26490@@QAEXXZ"
}
-// dllexport trumps dllexport on an explicit instantiation.
+// dllexport trumps dllimport on an explicit instantiation.
template <typename T> struct ExplicitInstantiationTwoAttributes { void f() {} };
template struct __declspec(dllexport) __declspec(dllimport) ExplicitInstantiationTwoAttributes<int>;
// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?f@?$ExplicitInstantiationTwoAttributes@H@@QAEXXZ"
+namespace pr34849 {
+// Specializations of exported class template member functions get exported.
+template <typename> struct __declspec(dllexport) ExportedClassTemplate { void foo(); };
+template<> void ExportedClassTemplate<int>::foo() {}
+template struct ExportedClassTemplate<int>;
+// M32-DAG: define dllexport x86_thiscallcc void @"\01?foo@?$ExportedClassTemplate@H@pr34849@@QAEXXZ"
+
+// Specializations of exported class member template functions do not get exported.
+struct __declspec(dllexport) ExportedClass { template <typename> void bar() ; };
+template<> void ExportedClass::bar<int>() {}
+// M32-DAG: define x86_thiscallcc void @"\01??$bar@H@ExportedClass@pr34849@@QAEXXZ"
+template <typename> struct __declspec(dllexport) ExportedClassTemplate2 { template <typename> void baz(); };
+template<> template<> void ExportedClassTemplate2<int>::baz<int>() {}
+// M32-DAG: define x86_thiscallcc void @"\01??$baz@H@?$ExportedClassTemplate2@H@pr34849@@QAEXXZ"
+}
//===----------------------------------------------------------------------===//
// Classes with template base classes
diff --git a/test/CodeGenCXX/dllimport-dtor-thunks.cpp b/test/CodeGenCXX/dllimport-dtor-thunks.cpp
new file mode 100644
index 000000000000..b381fff450da
--- /dev/null
+++ b/test/CodeGenCXX/dllimport-dtor-thunks.cpp
@@ -0,0 +1,49 @@
+// RUN: %clang_cc1 -mconstructor-aliases %s -triple x86_64-windows-msvc -fms-extensions -emit-llvm -o - | FileCheck %s
+
+// FIXME: We should really consider removing -mconstructor-aliases for MS C++
+// ABI. The risk of bugs introducing ABI incompatibility under
+// -mno-constructor-aliases is too high.
+
+// PR32990
+
+// Introduces the virtual destructor. We should use the base destructor
+// directly, no thunk needed.
+struct __declspec(dllimport) ImportIntroVDtor {
+ virtual ~ImportIntroVDtor() {}
+};
+
+struct BaseClass {
+ virtual ~BaseClass() {}
+};
+
+// Non-virtually inherits from a non-dllimport base class. We should again call
+// the derived base constructor directly. No need for the complete (aka vbase)
+// destructor.
+struct __declspec(dllimport) ImportOverrideVDtor : public BaseClass {
+ virtual ~ImportOverrideVDtor() {}
+};
+
+// Virtually inherits from a non-dllimport base class. This time we need to call
+// the complete destructor and emit it inline. It's not exported from the DLL,
+// and it must be emitted.
+struct __declspec(dllimport) ImportVBaseOverrideVDtor
+ : public virtual BaseClass {
+ virtual ~ImportVBaseOverrideVDtor() {}
+};
+
+extern "C" void testit() {
+ ImportIntroVDtor t1;
+ ImportOverrideVDtor t2;
+ ImportVBaseOverrideVDtor t3;
+}
+
+// The destructors are called in reverse order of construction. Only the third
+// needs the complete destructor (_D).
+// CHECK-LABEL: define void @testit()
+// CHECK: call void @"\01??_DImportVBaseOverrideVDtor@@QEAAXXZ"(%struct.ImportVBaseOverrideVDtor* %{{.*}})
+// CHECK: call void @"\01??1ImportOverrideVDtor@@UEAA@XZ"(%struct.ImportOverrideVDtor* %{{.*}})
+// CHECK: call void @"\01??1ImportIntroVDtor@@UEAA@XZ"(%struct.ImportIntroVDtor* %{{.*}})
+
+// CHECK-LABEL: define linkonce_odr void @"\01??_DImportVBaseOverrideVDtor@@QEAAXXZ"
+// CHECK-LABEL: declare dllimport void @"\01??1ImportOverrideVDtor@@UEAA@XZ"
+// CHECK-LABEL: declare dllimport void @"\01??1ImportIntroVDtor@@UEAA@XZ"
diff --git a/test/CodeGenCXX/dllimport-members.cpp b/test/CodeGenCXX/dllimport-members.cpp
index 19d9e1dfe7b6..ff7868382d8c 100644
--- a/test/CodeGenCXX/dllimport-members.cpp
+++ b/test/CodeGenCXX/dllimport-members.cpp
@@ -836,7 +836,7 @@ USEMV(MemVarTmpl, ImportedStaticVar<ImplicitInst_Imported>)
// Import explicit instantiation declaration of an imported member variable
// template.
-// MSC-DAG: @"\01??$ImportedStaticVar@UExplicitDecl_Imported@@@MemVarTmpl@@2HB" = external dllimport constant i32
+// MSC-DAG: @"\01??$ImportedStaticVar@UExplicitDecl_Imported@@@MemVarTmpl@@2HB" = available_externally dllimport constant i32 1
// GNU-DAG: @_ZN10MemVarTmpl17ImportedStaticVarI21ExplicitDecl_ImportedEE = external dllimport constant i32
extern template const int MemVarTmpl::ImportedStaticVar<ExplicitDecl_Imported>;
USEMV(MemVarTmpl, ImportedStaticVar<ExplicitDecl_Imported>)
@@ -861,7 +861,7 @@ USEMV(MemVarTmpl, ImportedStaticVar<ExplicitSpec_NotImported>)
// Import explicit instantiation declaration of a non-imported member variable
// template.
-// MSC-DAG: @"\01??$StaticVar@UExplicitDecl_Imported@@@MemVarTmpl@@2HB" = external dllimport constant i32
+// MSC-DAG: @"\01??$StaticVar@UExplicitDecl_Imported@@@MemVarTmpl@@2HB" = available_externally dllimport constant i32 1
// GNU-DAG: @_ZN10MemVarTmpl9StaticVarI21ExplicitDecl_ImportedEE = external dllimport constant i32
extern template __declspec(dllimport) const int MemVarTmpl::StaticVar<ExplicitDecl_Imported>;
USEMV(MemVarTmpl, StaticVar<ExplicitDecl_Imported>)
diff --git a/test/CodeGenCXX/dllimport.cpp b/test/CodeGenCXX/dllimport.cpp
index 372a96ba2efe..14558aec39a4 100644
--- a/test/CodeGenCXX/dllimport.cpp
+++ b/test/CodeGenCXX/dllimport.cpp
@@ -579,7 +579,7 @@ USE(inlineFuncTmpl<ExplicitDecl_Imported>)
// MSC-DAG: declare dllimport void @"\01??$inlineFuncTmpl@UExplicitInst_Imported@@@@YAXXZ"()
// GNU-DAG: declare dllimport void @_Z8funcTmplI21ExplicitInst_ImportedEvv()
// GNU-DAG: define weak_odr void @_Z14inlineFuncTmplI21ExplicitInst_ImportedEvv()
-// MO1-DAG: define available_externally dllimport void @"\01??$funcTmpl@UExplicitInst_Imported@@@@YAXXZ"()
+// MO1-DAG: declare dllimport void @"\01??$funcTmpl@UExplicitInst_Imported@@@@YAXXZ"()
// MO1-DAG: define available_externally dllimport void @"\01??$inlineFuncTmpl@UExplicitInst_Imported@@@@YAXXZ"()
// GO1-DAG: define available_externally dllimport void @_Z8funcTmplI21ExplicitInst_ImportedEvv()
// GO1-DAG: define weak_odr void @_Z14inlineFuncTmplI21ExplicitInst_ImportedEvv()
@@ -609,6 +609,15 @@ USE(funcTmpl<ExplicitSpec_Imported>)
template<> __declspec(dllimport) inline void funcTmpl<ExplicitSpec_InlineDef_Imported>() {}
USE(funcTmpl<ExplicitSpec_InlineDef_Imported>)
+#ifdef MSABI
+namespace pr35435 {
+struct X;
+template <typename T> struct __declspec(dllimport) S {
+ void foo(T *t) { t->problem(); }
+};
+template void S<X>::foo(X*); // Cannot be instantiated because X is incomplete; dllimport means it's treated as an instantiation decl.
+}
+#endif
//===----------------------------------------------------------------------===//
diff --git a/test/CodeGenCXX/eh.cpp b/test/CodeGenCXX/eh.cpp
index db0576a1baeb..dfbe48c37239 100644
--- a/test/CodeGenCXX/eh.cpp
+++ b/test/CodeGenCXX/eh.cpp
@@ -461,12 +461,12 @@ class DerivedException: public BaseException {
int foo() {
throw DerivedException();
- // The alignment passed to memset is 8, not 16, on Darwin.
+ // The alignment passed to memset is 16 on Darwin.
// CHECK: [[T0:%.*]] = call i8* @__cxa_allocate_exception(i64 16)
// CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to %"class.test17::DerivedException"*
// CHECK-NEXT: [[T2:%.*]] = bitcast %"class.test17::DerivedException"* [[T1]] to i8*
- // CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* [[T2]], i8 0, i64 16, i32 8, i1 false)
+ // CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* [[T2]], i8 0, i64 16, i32 16, i1 false)
}
}
diff --git a/test/CodeGenCXX/exceptions-seh.cpp b/test/CodeGenCXX/exceptions-seh.cpp
index 4f7eacd66720..fa2d834c1e38 100644
--- a/test/CodeGenCXX/exceptions-seh.cpp
+++ b/test/CodeGenCXX/exceptions-seh.cpp
@@ -76,6 +76,27 @@ extern "C" void use_seh() {
// CHECK: [[cont]]
// CHECK: br label %[[ret]]
+extern "C" void nested_finally() {
+ __try {
+ might_throw();
+ } __finally {
+ __try {
+ might_throw();
+ } __finally {
+ }
+ }
+}
+
+// CHECK-LABEL: define void @nested_finally() #{{[0-9]+}}
+// CHECK-SAME: personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*)
+// CHECK: invoke void @might_throw()
+// CHECK: call void @"\01?fin$0@0@nested_finally@@"(i8 1, i8* {{.*}})
+
+// CHECK-LABEL: define internal void @"\01?fin$0@0@nested_finally@@"
+// CHECK-SAME: personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*)
+// CHECK: invoke void @might_throw()
+// CHECK: call void @"\01?fin$1@0@nested_finally@@"(i8 1, i8* {{.*}})
+
void use_seh_in_lambda() {
([]() {
__try {
diff --git a/test/CodeGenCXX/explicit-instantiation.cpp b/test/CodeGenCXX/explicit-instantiation.cpp
index 85857fb6fb8c..ad20abde8f11 100644
--- a/test/CodeGenCXX/explicit-instantiation.cpp
+++ b/test/CodeGenCXX/explicit-instantiation.cpp
@@ -170,3 +170,22 @@ void use() {
f<int>();
}
}
+
+namespace DefaultedMembers {
+ struct B { B(); B(const B&); ~B(); };
+ template<typename T> struct A : B {
+ A() = default;
+ ~A() = default;
+ };
+ extern template struct A<int>;
+
+ // CHECK-LABEL: define {{.*}} @_ZN16DefaultedMembers1AIiEC2Ev
+ // CHECK-LABEL: define {{.*}} @_ZN16DefaultedMembers1AIiED2Ev
+ A<int> ai;
+
+ // CHECK-LABEL: define {{.*}} @_ZN16DefaultedMembers1AIiEC2ERKS1_
+ A<int> ai2(ai);
+
+ // CHECK-NOT: @_ZN16DefaultedMembers1AIcE
+ template struct A<char>;
+}
diff --git a/test/CodeGenCXX/extern-section-attribute.cpp b/test/CodeGenCXX/extern-section-attribute.cpp
new file mode 100644
index 000000000000..fa0227e6fe1a
--- /dev/null
+++ b/test/CodeGenCXX/extern-section-attribute.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-pc-linux-gnu | FileCheck %s
+
+extern int aa __attribute__((section(".sdata")));
+// CHECK-DAG: @aa = external global i32, section ".sdata", align 4
+
+extern int bb __attribute__((section(".sdata"))) = 1;
+// CHECK-DAG: @bb = global i32 1, section ".sdata", align 4
+
+int foo() {
+ return aa + bb;
+}
diff --git a/test/CodeGenCXX/finegrain-bitfield-access.cpp b/test/CodeGenCXX/finegrain-bitfield-access.cpp
new file mode 100644
index 000000000000..2973f9f73c4e
--- /dev/null
+++ b/test/CodeGenCXX/finegrain-bitfield-access.cpp
@@ -0,0 +1,162 @@
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -ffine-grained-bitfield-accesses \
+// RUN: -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -ffine-grained-bitfield-accesses \
+// RUN: -emit-llvm -fsanitize=address -o - %s | FileCheck %s --check-prefix=SANITIZE
+// Check -fsplit-bitfields will be ignored since sanitizer is enabled.
+
+struct S1 {
+ unsigned f1:2;
+ unsigned f2:6;
+ unsigned f3:8;
+ unsigned f4:4;
+ unsigned f5:8;
+};
+
+S1 a1;
+unsigned read8_1() {
+ // CHECK-LABEL: @_Z7read8_1v
+ // CHECK: %bf.load = load i8, i8* getelementptr inbounds (%struct.S1, %struct.S1* @a1, i32 0, i32 1), align 1
+ // CHECK-NEXT: %bf.cast = zext i8 %bf.load to i32
+ // CHECK-NEXT: ret i32 %bf.cast
+ // SANITIZE-LABEL: @_Z7read8_1v
+ // SANITIZE: %bf.load = load i32, i32* getelementptr inbounds {{.*}}, align 4
+ // SANITIZE: %bf.lshr = lshr i32 %bf.load, 8
+ // SANITIZE: %bf.clear = and i32 %bf.lshr, 255
+ // SANITIZE: ret i32 %bf.clear
+ return a1.f3;
+}
+void write8_1() {
+ // CHECK-LABEL: @_Z8write8_1v
+ // CHECK: store i8 3, i8* getelementptr inbounds (%struct.S1, %struct.S1* @a1, i32 0, i32 1), align 1
+ // CHECK-NEXT: ret void
+ // SANITIZE-LABEL: @_Z8write8_1v
+ // SANITIZE: %bf.load = load i32, i32* getelementptr inbounds {{.*}}, align 4
+ // SANITIZE-NEXT: %bf.clear = and i32 %bf.load, -65281
+ // SANITIZE-NEXT: %bf.set = or i32 %bf.clear, 768
+ // SANITIZE-NEXT: store i32 %bf.set, i32* getelementptr inbounds {{.*}}, align 4
+ // SANITIZE-NEXT: ret void
+ a1.f3 = 3;
+}
+
+unsigned read8_2() {
+ // CHECK-LABEL: @_Z7read8_2v
+ // CHECK: %bf.load = load i16, i16* getelementptr inbounds (%struct.S1, %struct.S1* @a1, i32 0, i32 2), align 2
+ // CHECK-NEXT: %bf.lshr = lshr i16 %bf.load, 4
+ // CHECK-NEXT: %bf.clear = and i16 %bf.lshr, 255
+ // CHECK-NEXT: %bf.cast = zext i16 %bf.clear to i32
+ // CHECK-NEXT: ret i32 %bf.cast
+ // SANITIZE-LABEL: @_Z7read8_2v
+ // SANITIZE: %bf.load = load i32, i32* getelementptr inbounds {{.*}}, align 4
+ // SANITIZE-NEXT: %bf.lshr = lshr i32 %bf.load, 20
+ // SANITIZE-NEXT: %bf.clear = and i32 %bf.lshr, 255
+ // SANITIZE-NEXT: ret i32 %bf.clear
+ return a1.f5;
+}
+void write8_2() {
+ // CHECK-LABEL: @_Z8write8_2v
+ // CHECK: %bf.load = load i16, i16* getelementptr inbounds (%struct.S1, %struct.S1* @a1, i32 0, i32 2), align 2
+ // CHECK-NEXT: %bf.clear = and i16 %bf.load, -4081
+ // CHECK-NEXT: %bf.set = or i16 %bf.clear, 48
+ // CHECK-NEXT: store i16 %bf.set, i16* getelementptr inbounds (%struct.S1, %struct.S1* @a1, i32 0, i32 2), align 2
+ // CHECK-NEXT: ret void
+ // SANITIZE-LABEL: @_Z8write8_2v
+ // SANITIZE: %bf.load = load i32, i32* getelementptr inbounds {{.*}}, align 4
+ // SANITIZE-NEXT: %bf.clear = and i32 %bf.load, -267386881
+ // SANITIZE-NEXT: %bf.set = or i32 %bf.clear, 3145728
+ // SANITIZE-NEXT: store i32 %bf.set, i32* getelementptr inbounds {{.*}}, align 4
+ // SANITIZE-NEXT: ret void
+ a1.f5 = 3;
+}
+
+struct S2 {
+ unsigned long f1:16;
+ unsigned long f2:16;
+ unsigned long f3:6;
+};
+
+S2 a2;
+unsigned read16_1() {
+ // CHECK-LABEL: @_Z8read16_1v
+ // CHECK: %bf.load = load i16, i16* getelementptr inbounds (%struct.S2, %struct.S2* @a2, i32 0, i32 0), align 8
+ // CHECK-NEXT: %bf.cast = zext i16 %bf.load to i64
+ // CHECK-NEXT: %conv = trunc i64 %bf.cast to i32
+ // CHECK-NEXT: ret i32 %conv
+ // SANITIZE-LABEL: @_Z8read16_1v
+ // SANITIZE: %bf.load = load i64, i64* bitcast {{.*}}, align 8
+ // SANITIZE-NEXT: %bf.clear = and i64 %bf.load, 65535
+ // SANITIZE-NEXT: %conv = trunc i64 %bf.clear to i32
+ // SANITIZE-NEXT: ret i32 %conv
+ return a2.f1;
+}
+unsigned read16_2() {
+ // CHECK-LABEL: @_Z8read16_2v
+ // CHECK: %bf.load = load i16, i16* getelementptr inbounds (%struct.S2, %struct.S2* @a2, i32 0, i32 1), align 2
+ // CHECK-NEXT: %bf.cast = zext i16 %bf.load to i64
+ // CHECK-NEXT: %conv = trunc i64 %bf.cast to i32
+ // CHECK-NEXT: ret i32 %conv
+ // SANITIZE-LABEL: @_Z8read16_2v
+ // SANITIZE: %bf.load = load i64, i64* bitcast {{.*}}, align 8
+ // SANITIZE-NEXT: %bf.lshr = lshr i64 %bf.load, 16
+ // SANITIZE-NEXT: %bf.clear = and i64 %bf.lshr, 65535
+ // SANITIZE-NEXT: %conv = trunc i64 %bf.clear to i32
+ // SANITIZE-NEXT: ret i32 %conv
+ return a2.f2;
+}
+
+void write16_1() {
+ // CHECK-LABEL: @_Z9write16_1v
+ // CHECK: store i16 5, i16* getelementptr inbounds (%struct.S2, %struct.S2* @a2, i32 0, i32 0), align 8
+ // CHECK-NEXT: ret void
+ // SANITIZE-LABEL: @_Z9write16_1v
+ // SANITIZE: %bf.load = load i64, i64* bitcast {{.*}}, align 8
+ // SANITIZE-NEXT: %bf.clear = and i64 %bf.load, -65536
+ // SANITIZE-NEXT: %bf.set = or i64 %bf.clear, 5
+ // SANITIZE-NEXT: store i64 %bf.set, i64* bitcast {{.*}}, align 8
+ // SANITIZE-NEXT: ret void
+ a2.f1 = 5;
+}
+void write16_2() {
+ // CHECK-LABEL: @_Z9write16_2v
+ // CHECK: store i16 5, i16* getelementptr inbounds (%struct.S2, %struct.S2* @a2, i32 0, i32 1), align 2
+ // CHECK-NEXT: ret void
+ // SANITIZE-LABEL: @_Z9write16_2v
+ // SANITIZE: %bf.load = load i64, i64* bitcast {{.*}}, align 8
+ // SANITIZE-NEXT: %bf.clear = and i64 %bf.load, -4294901761
+ // SANITIZE-NEXT: %bf.set = or i64 %bf.clear, 327680
+ // SANITIZE-NEXT: store i64 %bf.set, i64* bitcast {{.*}}, align 8
+ // SANITIZE-NEXT: ret void
+ a2.f2 = 5;
+}
+
+struct S3 {
+ unsigned long f1:14;
+ unsigned long f2:18;
+ unsigned long f3:32;
+};
+
+S3 a3;
+unsigned read32_1() {
+ // CHECK-LABEL: @_Z8read32_1v
+ // CHECK: %bf.load = load i32, i32* getelementptr inbounds (%struct.S3, %struct.S3* @a3, i32 0, i32 1), align 4
+ // CHECK-NEXT: %bf.cast = zext i32 %bf.load to i64
+ // CHECK-NEXT: %conv = trunc i64 %bf.cast to i32
+ // CHECK-NEXT: ret i32 %conv
+ // SANITIZE-LABEL: @_Z8read32_1v
+ // SANITIZE: %bf.load = load i64, i64* getelementptr inbounds {{.*}}, align 8
+ // SANITIZE-NEXT: %bf.lshr = lshr i64 %bf.load, 32
+ // SANITIZE-NEXT: %conv = trunc i64 %bf.lshr to i32
+ // SANITIZE-NEXT: ret i32 %conv
+ return a3.f3;
+}
+void write32_1() {
+ // CHECK-LABEL: @_Z9write32_1v
+ // CHECK: store i32 5, i32* getelementptr inbounds (%struct.S3, %struct.S3* @a3, i32 0, i32 1), align 4
+ // CHECK-NEXT: ret void
+ // SANITIZE-LABEL: @_Z9write32_1v
+ // SANITIZE: %bf.load = load i64, i64* getelementptr inbounds {{.*}}, align 8
+ // SANITIZE-NEXT: %bf.clear = and i64 %bf.load, 4294967295
+ // SANITIZE-NEXT: %bf.set = or i64 %bf.clear, 21474836480
+ // SANITIZE-NEXT: store i64 %bf.set, i64* getelementptr inbounds {{.*}}, align 8
+ // SANITIZE-NEXT: ret void
+ a3.f3 = 5;
+}
diff --git a/test/CodeGenCXX/float16-declarations.cpp b/test/CodeGenCXX/float16-declarations.cpp
new file mode 100644
index 000000000000..87ef139f8634
--- /dev/null
+++ b/test/CodeGenCXX/float16-declarations.cpp
@@ -0,0 +1,149 @@
+// RUN: %clang -std=c++11 --target=aarch64-arm--eabi -S -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-AARCH64
+// RUN: %clang -std=c++11 --target=x86_64 -S -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-X86
+
+/* Various contexts where type _Float16 can appear. */
+
+
+/* Namespace */
+
+namespace {
+ _Float16 f1n;
+// CHECK-DAG: @_ZN12_GLOBAL__N_13f1nE = internal global half 0xH0000, align 2
+
+ _Float16 f2n = 33.f16;
+// CHECK-DAG: @_ZN12_GLOBAL__N_13f2nE = internal global half 0xH5020, align 2
+
+ _Float16 arr1n[10];
+// CHECK-AARCH64-DAG: @_ZN12_GLOBAL__N_15arr1nE = internal global [10 x half] zeroinitializer, align 2
+// CHECK-X86-DAG: @_ZN12_GLOBAL__N_15arr1nE = internal global [10 x half] zeroinitializer, align 16
+
+ _Float16 arr2n[] = { 1.2, 3.0, 3.e4 };
+// CHECK-DAG: @_ZN12_GLOBAL__N_15arr2nE = internal global [3 x half] [half 0xH3CCD, half 0xH4200, half 0xH7753], align 2
+
+ const volatile _Float16 func1n(const _Float16 &arg) {
+ return arg + f2n + arr1n[4] - arr2n[1];
+ }
+}
+
+
+/* File */
+
+_Float16 f1f;
+// CHECK-AARCH64-DAG: @f1f = global half 0xH0000, align 2
+// CHECK-X86-DAG: @f1f = global half 0xH0000, align 2
+
+_Float16 f2f = 32.4;
+// CHECK-DAG: @f2f = global half 0xH500D, align 2
+
+_Float16 arr1f[10];
+// CHECK-AARCH64-DAG: @arr1f = global [10 x half] zeroinitializer, align 2
+// CHECK-X86-DAG: @arr1f = global [10 x half] zeroinitializer, align 16
+
+_Float16 arr2f[] = { -1.2, -3.0, -3.e4 };
+// CHECK-DAG: @arr2f = global [3 x half] [half 0xHBCCD, half 0xHC200, half 0xHF753], align 2
+
+_Float16 func1f(_Float16 arg);
+
+
+/* Class */
+
+class C1 {
+ _Float16 f1c;
+
+ static const _Float16 f2c;
+// CHECK-DAG: @_ZN2C13f2cE = external constant half, align 2
+
+ volatile _Float16 f3c;
+
+public:
+ C1(_Float16 arg) : f1c(arg), f3c(arg) { }
+// Check that we mangle _Float16 to DF16_
+// CHECK-DAG: define linkonce_odr void @_ZN2C1C2EDF16_(%class.C1*{{.*}}, half{{.*}})
+
+ _Float16 func1c(_Float16 arg ) {
+ return f1c + arg;
+ }
+// CHECK-DAG: define linkonce_odr half @_ZN2C16func1cEDF16_(%class.C1*{{.*}}, half{{.*}})
+
+ static _Float16 func2c(_Float16 arg) {
+ return arg * C1::f2c;
+ }
+// CHECK-DAG: define linkonce_odr half @_ZN2C16func2cEDF16_(half{{.*}})
+};
+
+/* Template */
+
+template <class C> C func1t(C arg) {
+ return arg * 2.f16;
+}
+// CHECK-DAG: define linkonce_odr half @_Z6func1tIDF16_ET_S0_(half{{.*}})
+
+template <class C> struct S1 {
+ C mem1;
+};
+
+template <> struct S1<_Float16> {
+ _Float16 mem2;
+};
+
+
+/* Local */
+
+extern int printf (const char *__restrict __format, ...);
+
+int main(void) {
+ _Float16 f1l = 1e3f16;
+// CHECK-DAG: store half 0xH63D0, half* %{{.*}}, align 2
+
+ _Float16 f2l = -0.f16;
+// CHECK-DAG: store half 0xH8000, half* %{{.*}}, align 2
+
+ _Float16 f3l = 1.000976562;
+// CHECK-DAG: store half 0xH3C01, half* %{{.*}}, align 2
+
+ C1 c1(f1l);
+// CHECK-DAG: [[F1L:%[a-z0-9]+]] = load half, half* %{{.*}}, align 2
+// CHECK-DAG: call void @_ZN2C1C2EDF16_(%class.C1* %{{.*}}, half %{{.*}})
+
+ S1<_Float16> s1 = { 132.f16 };
+// CHECK-DAG: @_ZZ4mainE2s1 = private unnamed_addr constant %struct.S1 { half 0xH5820 }, align 2
+// CHECK-DAG: [[S1:%[0-9]+]] = bitcast %struct.S1* %{{.*}} to i8*
+// CHECK-DAG: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[S1]], i8* bitcast (%struct.S1* @_ZZ4mainE2s1 to i8*), i64 2, i32 2, i1 false)
+
+ _Float16 f4l = func1n(f1l) + func1f(f2l) + c1.func1c(f3l) + c1.func2c(f1l) +
+ func1t(f1l) + s1.mem2 - f1n + f2n;
+
+ auto f5l = -1.f16, *f6l = &f2l, f7l = func1t(f3l);
+// CHECK-DAG: store half 0xHBC00, half* %{{.*}}, align 2
+// CHECK-DAG: store half* %{{.*}}, half** %{{.*}}, align 8
+
+ _Float16 f8l = f4l++;
+// CHECK-DAG: %{{.*}} = load half, half* %{{.*}}, align 2
+// CHECK-DAG: [[INC:%[a-z0-9]+]] = fadd half {{.*}}, 0xH3C00
+// CHECK-DAG: store half [[INC]], half* %{{.*}}, align 2
+
+ _Float16 arr1l[] = { -1.f16, -0.f16, -11.f16 };
+// CHECK-DAG: @_ZZ4mainE5arr1l = private unnamed_addr constant [3 x half] [half 0xHBC00, half 0xH8000, half 0xHC980], align 2
+
+ float cvtf = f2n;
+//CHECK-DAG: [[H2F:%[a-z0-9]+]] = fpext half {{%[0-9]+}} to float
+//CHECK-DAG: store float [[H2F]], float* %{{.*}}, align 4
+
+ double cvtd = f2n;
+//CHECK-DAG: [[H2D:%[a-z0-9]+]] = fpext half {{%[0-9]+}} to double
+//CHECK-DAG: store double [[H2D]], double* %{{.*}}, align 8
+
+
+ long double cvtld = f2n;
+//CHECK-AARCh64-DAG: [[H2LD:%[a-z0-9]+]] = fpext half {{%[0-9]+}} to fp128
+//CHECK-AARCh64-DAG: store fp128 [[H2LD]], fp128* %{{.*}}, align 16
+//CHECK-X86-DAG: [[H2LD:%[a-z0-9]+]] = fpext half {{%[0-9]+}} to x86_fp80
+//CHECK-X86-DAG: store x86_fp80 [[H2LD]], x86_fp80* %{{.*}}, align 16
+
+ _Float16 f2h = 42.0f;
+//CHECK-DAG: store half 0xH5140, half* %{{.*}}, align 2
+ _Float16 d2h = 42.0;
+//CHECK-DAG: store half 0xH5140, half* %{{.*}}, align 2
+ _Float16 ld2h = 42.0l;
+//CHECK-DAG:store half 0xH5140, half* %{{.*}}, align 2
+}
diff --git a/test/CodeGenCXX/fp16-mangle.cpp b/test/CodeGenCXX/fp16-mangle.cpp
index bd5a3194112c..5827fd549dc2 100644
--- a/test/CodeGenCXX/fp16-mangle.cpp
+++ b/test/CodeGenCXX/fp16-mangle.cpp
@@ -4,9 +4,9 @@
template <typename T, typename U> struct S { static int i; };
template <> int S<__fp16, __fp16>::i = 3;
-// CHECK-LABEL: define void @_Z1fPDh(i16* %x)
+// CHECK-LABEL: define void @_Z1fPDh(half* %x)
void f (__fp16 *x) { }
-// CHECK-LABEL: define void @_Z1gPDhS_(i16* %x, i16* %y)
+// CHECK-LABEL: define void @_Z1gPDhS_(half* %x, half* %y)
void g (__fp16 *x, __fp16 *y) { }
diff --git a/test/CodeGenCXX/inline-dllexport-member.cpp b/test/CodeGenCXX/inline-dllexport-member.cpp
index 66ef459bd80b..a98f5601d3bc 100644
--- a/test/CodeGenCXX/inline-dllexport-member.cpp
+++ b/test/CodeGenCXX/inline-dllexport-member.cpp
@@ -7,7 +7,7 @@ struct __declspec(dllexport) s {
static const unsigned int ui = 0;
};
-// CHECK: [[UI]] = !DIGlobalVariableExpression(var: [[UIV:.*]])
+// CHECK: [[UI]] = !DIGlobalVariableExpression(var: [[UIV:.*]], expr: !DIExpression())
// CHECK: [[UIV]] = distinct !DIGlobalVariable(name: "ui", linkageName: "\01?ui@s@@2IB", scope: ![[SCOPE:[0-9]+]],
// CHECK: ![[SCOPE]] = distinct !DICompileUnit(
diff --git a/test/CodeGenCXX/instrument-functions.cpp b/test/CodeGenCXX/instrument-functions.cpp
index 587b6389c9a9..45ae48235a9d 100644
--- a/test/CodeGenCXX/instrument-functions.cpp
+++ b/test/CodeGenCXX/instrument-functions.cpp
@@ -1,22 +1,26 @@
-// RUN: %clang_cc1 -S -emit-llvm -triple %itanium_abi_triple -o - %s -finstrument-functions | FileCheck %s
+// RUN: %clang_cc1 -S -emit-llvm -triple %itanium_abi_triple -o - %s -finstrument-functions -disable-llvm-passes | FileCheck %s
-// CHECK: @_Z5test1i
int test1(int x) {
-// CHECK: __cyg_profile_func_enter
-// CHECK: __cyg_profile_func_exit
+// CHECK: @_Z5test1i(i32 {{.*}}%x) #[[ATTR1:[0-9]+]]
// CHECK: ret
return x;
}
-// CHECK: @_Z5test2i
int test2(int) __attribute__((no_instrument_function));
int test2(int x) {
-// CHECK-NOT: __cyg_profile_func_enter
-// CHECK-NOT: __cyg_profile_func_exit
+// CHECK: @_Z5test2i(i32 {{.*}}%x) #[[ATTR2:[0-9]+]]
// CHECK: ret
return x;
}
+// CHECK: attributes #[[ATTR1]] =
+// CHECK-SAME: "instrument-function-entry"="__cyg_profile_func_enter"
+// CHECK-SAME: "instrument-function-exit"="__cyg_profile_func_exit"
+
+// CHECK: attributes #[[ATTR2]] =
+// CHECK-NOT: "instrument-function-entry"
+
+
// This test case previously crashed code generation. It exists solely
// to test -finstrument-function does not crash codegen for this trivial
// case.
diff --git a/test/CodeGenCXX/invariant.group-for-vptrs.cpp b/test/CodeGenCXX/invariant.group-for-vptrs.cpp
index 4e5d9b49d985..45671e5a2c2a 100644
--- a/test/CodeGenCXX/invariant.group-for-vptrs.cpp
+++ b/test/CodeGenCXX/invariant.group-for-vptrs.cpp
@@ -56,7 +56,7 @@ void testInternallyVisible(bool p) {
// Checking D::D()
// CHECK-LABEL: define linkonce_odr void @_ZN1DC2Ev(
-// CHECK: = call i8* @llvm.invariant.group.barrier(i8*
+// CHECK: = call i8* @llvm.invariant.group.barrier.p0i8(i8*
// CHECK: call void @_ZN1AC2Ev(%struct.A*
// CHECK: store {{.*}} !invariant.group ![[MD]]
diff --git a/test/CodeGenCXX/mangle-exprs.cpp b/test/CodeGenCXX/mangle-exprs.cpp
index ee7594b2fdd2..6c4640269403 100644
--- a/test/CodeGenCXX/mangle-exprs.cpp
+++ b/test/CodeGenCXX/mangle-exprs.cpp
@@ -314,6 +314,19 @@ namespace test7 {
template<class T> decltype(F{{1,2}},T()) fF1(T t) {}
template<class T> decltype(F({1,2}),T()) fF2(T t) {}
+ template<class T> decltype(T{}) fT1(T t) {}
+ template<class T> decltype(T()) fT2(T t) {}
+ template<class T> decltype(T{1}) fT3(T t) {}
+ template<class T> decltype(T(1)) fT4(T t) {}
+ template<class T> decltype(T{1,2}) fT5(T t) {}
+ template<class T> decltype(T(1,2)) fT6(T t) {}
+ template<class T> decltype(T{{}}) fT7(T t) {}
+ template<class T> decltype(T({})) fT8(T t) {}
+ template<class T> decltype(T{{1}}) fT9(T t) {}
+ template<class T> decltype(T({1})) fTA(T t) {}
+ template<class T> decltype(T{{1,2}}) fTB(T t) {}
+ template<class T> decltype(T({1,2})) fTC(T t) {}
+
int main() {
fA1(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fA1IiEEDTcmtlNS_1AELi1ELi2EEcvT__EES2_
fA2(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fA2IiEEDTcmcvNS_1AEilLi1ELi2EEcvT__EES2_
@@ -327,6 +340,18 @@ namespace test7 {
fE2(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fE2IiEEDTcmcvNS_1EEilLi1ELi2EEcvT__EES2_
fF1(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fF1IiEEDTcmtlNS_1FEilLi1ELi2EEEcvT__EES2_
fF2(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fF2IiEEDTcmcvNS_1FEilLi1ELi2EEcvT__EES2_
+ fT1(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fT1IiEEDTtlT_EES1_(
+ fT2(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fT2IiEEDTcvT__EES1_(
+ fT3(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fT3IiEEDTtlT_Li1EEES1_(
+ fT4(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fT4IiEEDTcvT_Li1EES1_(
+ fT5(b); // CHECK-LABEL: define {{.*}} @_ZN5test73fT5INS_1BEEEDTtlT_Li1ELi2EEES2_(
+ fT6(b); // CHECK-LABEL: define {{.*}} @_ZN5test73fT6INS_1BEEEDTcvT__Li1ELi2EEES2_(
+ fT7(A{}); // CHECK-LABEL: define {{.*}} @_ZN5test73fT7INS_1AEEEDTtlT_ilEEES2_(
+ fT8(A{}); // CHECK-LABEL: define {{.*}} @_ZN5test73fT8INS_1AEEEDTcvT_ilEES2_(
+ fT9(A{}); // CHECK-LABEL: define {{.*}} @_ZN5test73fT9INS_1AEEEDTtlT_ilLi1EEEES2_(
+ fTA(A{}); // CHECK-LABEL: define {{.*}} @_ZN5test73fTAINS_1AEEEDTcvT_ilLi1EEES2_(
+ fTB<C>(b); // CHECK-LABEL: define {{.*}} @_ZN5test73fTBINS_1CEEEDTtlT_ilLi1ELi2EEEES2_(
+ fTC<C>(b); // CHECK-LABEL: define {{.*}} @_ZN5test73fTCINS_1CEEEDTcvT_ilLi1ELi2EEES2_(
}
}
@@ -341,3 +366,10 @@ namespace test8 {
// CHECK-LABEL: define weak_odr i32 @_ZNK5test81XIiE3barIiEEDTcl3fooIT_EEEv
template int X<int>::bar<int>() const;
}
+
+namespace designated_init {
+ struct A { struct B { int b[5][5]; } a; };
+ // CHECK-LABEL: define {{.*}} @_ZN15designated_init1fINS_1AEEEvDTtlT_di1adi1bdxLi3EdXLi1ELi4ELi9EEE(
+ template<typename T> void f(decltype(T{.a.b[3][1 ... 4] = 9}) x) {}
+ void use_f(A a) { f<A>(a); }
+}
diff --git a/test/CodeGenCXX/mangle-fail.cpp b/test/CodeGenCXX/mangle-fail.cpp
index 02548964efc9..b588d57749fa 100644
--- a/test/CodeGenCXX/mangle-fail.cpp
+++ b/test/CodeGenCXX/mangle-fail.cpp
@@ -1,6 +1,5 @@
// RUN: %clang_cc1 -emit-llvm-only -x c++ -std=c++11 -triple %itanium_abi_triple -verify %s -DN=1
// RUN: %clang_cc1 -emit-llvm-only -x c++ -std=c++11 -triple %itanium_abi_triple -verify %s -DN=2
-// RUN: %clang_cc1 -emit-llvm-only -x c++ -std=c++11 -triple %itanium_abi_triple -verify %s -DN=3
struct A { int a; };
@@ -14,11 +13,6 @@ template void test<int>(int (&)[sizeof(int)]);
template<class T> void test(int (&)[sizeof((A){}, T())]) {} // expected-error {{cannot yet mangle}}
template void test<int>(int (&)[sizeof(A)]);
-#elif N == 3
-// DesignatedInitExpr
-template<class T> void test(int (&)[sizeof(A{.a = 10}, T())]) {} // expected-error {{cannot yet mangle}}
-template void test<int>(int (&)[sizeof(A)]);
-
// FIXME: There are several more cases we can't yet mangle.
#else
diff --git a/test/CodeGenCXX/mangle-lambdas.cpp b/test/CodeGenCXX/mangle-lambdas.cpp
index 15987ebe46bd..d49ed4b2a5e1 100644
--- a/test/CodeGenCXX/mangle-lambdas.cpp
+++ b/test/CodeGenCXX/mangle-lambdas.cpp
@@ -26,6 +26,24 @@ void call_inline_func() {
inline_func(17);
}
+// CHECK-LABEL: define linkonce_odr i32* @_ZNK10inline_varMUlvE_clEv(
+// CHECK: @_ZZNK10inline_varMUlvE_clEvE1n
+inline auto inline_var = [] {
+ static int n = 5;
+ return &n;
+};
+
+int *use_inline_var = inline_var();
+
+// CHECK-LABEL: define linkonce_odr i32* @_ZNK12var_templateIiEMUlvE_clEv(
+// CHECK: @_ZZNK12var_templateIiEMUlvE_clEvE1n
+template<typename T> auto var_template = [] {
+ static int n = 9;
+ return &n;
+};
+
+int *use_var_template = var_template<int>();
+
struct S {
void f(int = []{return 1;}()
+ []{return 2;}(),
@@ -118,7 +136,7 @@ T StaticMembers<T>::z = accept_lambda([]{return 4;});
template<typename T>
int (*StaticMembers<T>::f)() = []{return 5;};
-// CHECK-LABEL: define internal void @__cxx_global_var_init()
+// CHECK-LABEL: define internal void @__cxx_global_var_init
// CHECK: call i32 @_ZNK13StaticMembersIfE1xMUlvE_clEv
// CHECK-NEXT: call i32 @_ZNK13StaticMembersIfE1xMUlvE0_clEv
// CHECK-NEXT: add nsw
@@ -128,23 +146,23 @@ int (*StaticMembers<T>::f)() = []{return 5;};
// CHECK: ret i32 2
template float StaticMembers<float>::x;
-// CHECK-LABEL: define internal void @__cxx_global_var_init.1()
+// CHECK-LABEL: define internal void @__cxx_global_var_init
// CHECK: call i32 @_ZNK13StaticMembersIfE1yMUlvE_clEv
// CHECK-LABEL: define linkonce_odr i32 @_ZNK13StaticMembersIfE1yMUlvE_clEv
// CHECK: ret i32 3
template float StaticMembers<float>::y;
-// CHECK-LABEL: define internal void @__cxx_global_var_init.2()
+// CHECK-LABEL: define internal void @__cxx_global_var_init
// CHECK: call i32 @_Z13accept_lambdaIN13StaticMembersIfE1zMUlvE_EEiT_
// CHECK: declare i32 @_Z13accept_lambdaIN13StaticMembersIfE1zMUlvE_EEiT_()
template float StaticMembers<float>::z;
-// CHECK-LABEL: define internal void @__cxx_global_var_init.3()
+// CHECK-LABEL: define internal void @__cxx_global_var_init
// CHECK: call {{.*}} @_ZNK13StaticMembersIfE1fMUlvE_cvPFivEEv
// CHECK-LABEL: define linkonce_odr i32 ()* @_ZNK13StaticMembersIfE1fMUlvE_cvPFivEEv
template int (*StaticMembers<float>::f)();
-// CHECK-LABEL: define internal void @__cxx_global_var_init.4
+// CHECK-LABEL: define internal void @__cxx_global_var_init
// CHECK: call i32 @"_ZNK13StaticMembersIdE3$_2clEv"
// CHECK-LABEL: define internal i32 @"_ZNK13StaticMembersIdE3$_2clEv"
// CHECK: ret i32 42
diff --git a/test/CodeGenCXX/mangle-ms-cxx11.cpp b/test/CodeGenCXX/mangle-ms-cxx11.cpp
index 819b0d9c9d0d..b22c04698ea2 100644
--- a/test/CodeGenCXX/mangle-ms-cxx11.cpp
+++ b/test/CodeGenCXX/mangle-ms-cxx11.cpp
@@ -160,6 +160,8 @@ struct { } a;
decltype(a) fun(decltype(a) x, decltype(a)) { return x; }
// CHECK-DAG: @"\01?fun@PR18022@@YA?AU<unnamed-type-a>@1@U21@0@Z"
+void use_fun() { fun(a, a); }
+
}
inline int define_lambda() {
@@ -280,7 +282,7 @@ void g() {
namespace PR18204 {
template <typename T>
-int f(T *);
+int f(T *) { return 0; }
static union {
int n = f(this);
};
@@ -346,4 +348,5 @@ int call_it = (A::default_args(), 1);
enum { enumerator };
void f(decltype(enumerator)) {}
-// CHECK-DAG: define void @"\01?f@@YAXW4<unnamed-enum-enumerator>@@@Z"(
+// CHECK-DAG: define internal void @"\01?f@@YAXW4<unnamed-enum-enumerator>@@@Z"(
+void use_f() { f(enumerator); }
diff --git a/test/CodeGenCXX/mangle.cpp b/test/CodeGenCXX/mangle.cpp
index 91fe6aeef298..919f8afb1607 100644
--- a/test/CodeGenCXX/mangle.cpp
+++ b/test/CodeGenCXX/mangle.cpp
@@ -893,7 +893,8 @@ namespace test39 {
struct {} a;
} *foo;
template<typename T> void func(T) {}
- void test(foo x) {
+ void test() {
+ foo x;
func(x->a);
}
}
diff --git a/test/CodeGenCXX/member-expr-references-variable.cpp b/test/CodeGenCXX/member-expr-references-variable.cpp
new file mode 100644
index 000000000000..8c1dded800f6
--- /dev/null
+++ b/test/CodeGenCXX/member-expr-references-variable.cpp
@@ -0,0 +1,104 @@
+// RUN: %clang_cc1 -std=c++11 %s -triple x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+
+struct Agg { const char * x; const char * y; constexpr Agg() : x(0), y(0) {} };
+
+struct Struct {
+ constexpr static const char *name = "foo";
+
+ constexpr static __complex float complexValue = 42.0;
+
+ static constexpr const Agg &agg = Agg();
+
+ Struct();
+ Struct(int x);
+};
+
+void use(int n, const char *c);
+
+Struct *getPtr();
+
+// CHECK: @[[STR:.*]] = private unnamed_addr constant [4 x i8] c"foo\00", align 1
+
+void scalarStaticVariableInMemberExpr(Struct *ptr, Struct &ref) {
+ use(1, Struct::name);
+// CHECK: call void @_Z3useiPKc(i32 1, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @[[STR]], i32 0, i32 0))
+ Struct s;
+ use(2, s.name);
+// CHECK: call void @_Z3useiPKc(i32 2, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @[[STR]], i32 0, i32 0))
+ use(3, ptr->name);
+// CHECK: load %struct.Struct*, %struct.Struct** %{{.*}}, align 8
+// CHECK: call void @_Z3useiPKc(i32 3, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @[[STR]], i32 0, i32 0))
+ use(4, ref.name);
+// CHECK: load %struct.Struct*, %struct.Struct** %{{.*}}, align 8
+// CHECK: call void @_Z3useiPKc(i32 4, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @[[STR]], i32 0, i32 0))
+ use(5, Struct(2).name);
+// CHECK: call void @_ZN6StructC1Ei(%struct.Struct* %{{.*}}, i32 2)
+// CHECK: call void @_Z3useiPKc(i32 5, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @[[STR]], i32 0, i32 0))
+ use(6, getPtr()->name);
+// CHECK: call %struct.Struct* @_Z6getPtrv()
+// CHECK: call void @_Z3useiPKc(i32 6, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @[[STR]], i32 0, i32 0))
+}
+
+void use(int n, __complex float v);
+
+void complexStaticVariableInMemberExpr(Struct *ptr, Struct &ref) {
+ use(1, Struct::complexValue);
+// CHECK: store float 4.200000e+01, float* %[[coerce0:.*]].{{.*}}, align 4
+// CHECK: store float 0.000000e+00, float* %[[coerce0]].{{.*}}, align 4
+// CHECK: %[[cast0:.*]] = bitcast { float, float }* %[[coerce0]] to <2 x float>*
+// CHECK: %[[vector0:.*]] = load <2 x float>, <2 x float>* %[[cast0]], align 4
+// CHECK: call void @_Z3useiCf(i32 1, <2 x float> %[[vector0]])
+ Struct s;
+ use(2, s.complexValue);
+// CHECK: store float 4.200000e+01, float* %[[coerce1:.*]].{{.*}}, align 4
+// CHECK: store float 0.000000e+00, float* %[[coerce1]].{{.*}}, align 4
+// CHECK: %[[cast1:.*]] = bitcast { float, float }* %[[coerce1]] to <2 x float>*
+// CHECK: %[[vector1:.*]] = load <2 x float>, <2 x float>* %[[cast1]], align 4
+// CHECK: call void @_Z3useiCf(i32 2, <2 x float> %[[vector1]])
+ use(3, ptr->complexValue);
+// CHECK: load %struct.Struct*, %struct.Struct** %{{.*}}, align 8
+// CHECK: store float 4.200000e+01, float* %[[coerce2:.*]].{{.*}}, align 4
+// CHECK: store float 0.000000e+00, float* %[[coerce2]].{{.*}}, align 4
+// CHECK: %[[cast2:.*]] = bitcast { float, float }* %[[coerce2]] to <2 x float>*
+// CHECK: %[[vector2:.*]] = load <2 x float>, <2 x float>* %[[cast2]], align 4
+// CHECK: call void @_Z3useiCf(i32 3, <2 x float> %[[vector2]])
+ use(4, ref.complexValue);
+// CHECK: load %struct.Struct*, %struct.Struct** %{{.*}}, align 8
+// CHECK: store float 4.200000e+01, float* %[[coerce3:.*]].{{.*}}, align 4
+// CHECK: store float 0.000000e+00, float* %[[coerce3]].{{.*}}, align 4
+// CHECK: %[[cast3:.*]] = bitcast { float, float }* %[[coerce3]] to <2 x float>*
+// CHECK: %[[vector3:.*]] = load <2 x float>, <2 x float>* %[[cast3]], align 4
+// CHECK: call void @_Z3useiCf(i32 4, <2 x float> %[[vector3]])
+ use(5, Struct(2).complexValue);
+// CHECK: call void @_ZN6StructC1Ei(%struct.Struct* %{{.*}}, i32 2)
+// CHECK: store float 4.200000e+01, float* %[[coerce4:.*]].{{.*}}, align 4
+// CHECK: store float 0.000000e+00, float* %[[coerce4]].{{.*}}, align 4
+// CHECK: %[[cast4:.*]] = bitcast { float, float }* %[[coerce4]] to <2 x float>*
+// CHECK: %[[vector4:.*]] = load <2 x float>, <2 x float>* %[[cast4]], align 4
+// CHECK: call void @_Z3useiCf(i32 5, <2 x float> %[[vector4]])
+ use(6, getPtr()->complexValue);
+// CHECK: call %struct.Struct* @_Z6getPtrv()
+// CHECK: store float 4.200000e+01, float* %[[coerce5:.*]].{{.*}}, align 4
+// CHECK: store float 0.000000e+00, float* %[[coerce5]].{{.*}}, align 4
+// CHECK: %[[cast5:.*]] = bitcast { float, float }* %[[coerce5]] to <2 x float>*
+// CHECK: %[[vector5:.*]] = load <2 x float>, <2 x float>* %[[cast5]], align 4
+// CHECK: call void @_Z3useiCf(i32 6, <2 x float> %[[vector5]])
+}
+
+void aggregateRefInMemberExpr(Struct *ptr, Struct &ref) {
+ use(1, Struct::agg.x);
+// CHECK: %[[value0:.*]] = load i8*, i8** getelementptr inbounds (%struct.Agg, %struct.Agg* @_ZGRN6Struct3aggE_, i32 0, i32 0), align 8
+// CHECK: call void @_Z3useiPKc(i32 1, i8* %[[value0]])
+ Struct s;
+ use(2, s.agg.x);
+// CHECK: %[[value1:.*]] = load i8*, i8** getelementptr inbounds (%struct.Agg, %struct.Agg* @_ZGRN6Struct3aggE_, i32 0, i32 0), align 8
+// CHECK: call void @_Z3useiPKc(i32 2, i8* %[[value1]])
+ use(3, ptr->agg.x);
+// CHECK: load %struct.Struct*, %struct.Struct** %{{.*}}, align 8
+// CHECK: %[[value2:.*]] = load i8*, i8** getelementptr inbounds (%struct.Agg, %struct.Agg* @_ZGRN6Struct3aggE_, i32 0, i32 0), align 8
+// CHECK: call void @_Z3useiPKc(i32 3, i8* %[[value2]])
+ use(4, ref.agg.x);
+// CHECK: load %struct.Struct*, %struct.Struct** %{{.*}}, align 8
+// CHECK: %[[value3:.*]] = load i8*, i8** getelementptr inbounds (%struct.Agg, %struct.Agg* @_ZGRN6Struct3aggE_, i32 0, i32 0), align 8
+// CHECK: call void @_Z3useiPKc(i32 4, i8* %[[value3]])
+}
diff --git a/test/CodeGenCXX/microsoft-abi-dynamic-cast.cpp b/test/CodeGenCXX/microsoft-abi-dynamic-cast.cpp
index f3e43079c3eb..8d75ed4d9d69 100644
--- a/test/CodeGenCXX/microsoft-abi-dynamic-cast.cpp
+++ b/test/CodeGenCXX/microsoft-abi-dynamic-cast.cpp
@@ -78,7 +78,7 @@ T* test6(B* x) { return dynamic_cast<T*>(x); }
// CHECK-NEXT: [[VBOFFS:%.*]] = load i32, i32* [[VBOFFP]], align 4
// CHECK-NEXT: [[DELTA:%.*]] = add nsw i32 [[VBOFFS]], 4
// CHECK-NEXT: [[ADJ:%.*]] = getelementptr inbounds i8, i8* [[CAST]], i32 [[DELTA]]
-// CHECK-NEXT: [[CALL:%.*]] = tail call i8* @__RTDynamicCast(i8* [[ADJ]], i32 [[DELTA]], i8* {{.*}}bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUB@@@8" to i8*), i8* {{.*}}bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUT@@@8" to i8*), i32 0)
+// CHECK-NEXT: [[CALL:%.*]] = tail call i8* @__RTDynamicCast(i8* nonnull [[ADJ]], i32 [[DELTA]], i8* {{.*}}bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUB@@@8" to i8*), i8* {{.*}}bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUT@@@8" to i8*), i32 0)
// CHECK-NEXT: [[RES:%.*]] = bitcast i8* [[CALL]] to %struct.T*
// CHECK-NEXT: br label
// CHECK: [[RET:%.*]] = phi %struct.T*
@@ -117,7 +117,7 @@ void* test9(B* x) { return dynamic_cast<void*>(x); }
// CHECK-NEXT: [[VBOFFS:%.*]] = load i32, i32* [[VBOFFP]], align 4
// CHECK-NEXT: [[DELTA:%.*]] = add nsw i32 [[VBOFFS]], 4
// CHECK-NEXT: [[ADJ:%.*]] = getelementptr inbounds i8, i8* [[CAST]], i32 [[DELTA]]
-// CHECK-NEXT: [[CALL:%.*]] = tail call i8* @__RTCastToVoid(i8* [[ADJ]])
+// CHECK-NEXT: [[CALL:%.*]] = tail call i8* @__RTCastToVoid(i8* nonnull [[ADJ]])
// CHECK-NEXT: br label
// CHECK: [[RET:%.*]] = phi i8*
// CHECK-NEXT: ret i8* [[RET]]
diff --git a/test/CodeGenCXX/microsoft-abi-multiple-nonvirtual-inheritance.cpp b/test/CodeGenCXX/microsoft-abi-multiple-nonvirtual-inheritance.cpp
index f9db2680e336..5bed69ff117f 100644
--- a/test/CodeGenCXX/microsoft-abi-multiple-nonvirtual-inheritance.cpp
+++ b/test/CodeGenCXX/microsoft-abi-multiple-nonvirtual-inheritance.cpp
@@ -19,7 +19,7 @@ struct ChildOverride : Left, Right {
extern "C" void foo(void *);
void call_left_no_override(ChildNoOverride *child) {
-// CHECK: define void @"\01?call_left_no_override
+// CHECK-LABEL: define void @"\01?call_left_no_override
// CHECK: %[[CHILD:.*]] = load %struct.ChildNoOverride
child->left();
@@ -34,7 +34,8 @@ void call_left_no_override(ChildNoOverride *child) {
}
void ChildOverride::left() {
-// CHECK: define x86_thiscallcc void @"\01?left@ChildOverride@@UAEXXZ"(%struct.ChildOverride* %[[THIS:.*]])
+// CHECK-LABEL: define x86_thiscallcc void @"\01?left@ChildOverride@@UAEXXZ"
+// CHECK-SAME: (%struct.ChildOverride* %[[THIS:.*]])
//
// No need to adjust 'this' as the ChildOverride's layout begins with Left.
// CHECK: %[[THIS_ADDR:.*]] = alloca %struct.ChildOverride*, align 4
@@ -48,7 +49,7 @@ void ChildOverride::left() {
}
void call_left_override(ChildOverride *child) {
-// CHECK: define void @"\01?call_left_override
+// CHECK-LABEL: define void @"\01?call_left_override
// CHECK: %[[CHILD:.*]] = load %struct.ChildOverride
child->left();
@@ -62,7 +63,7 @@ void call_left_override(ChildOverride *child) {
}
void call_right_no_override(ChildNoOverride *child) {
-// CHECK: define void @"\01?call_right_no_override
+// CHECK-LABEL: define void @"\01?call_right_no_override
// CHECK: %[[CHILD:.*]] = load %struct.ChildNoOverride
child->right();
@@ -82,25 +83,27 @@ void call_right_no_override(ChildNoOverride *child) {
}
void ChildOverride::right() {
-// CHECK: define x86_thiscallcc void @"\01?right@ChildOverride@@UAEXXZ"(i8*
+// CHECK-LABEL: define x86_thiscallcc void @"\01?right@ChildOverride@@UAEXXZ"(i8*
//
// ChildOverride::right gets 'this' cast to Right* in ECX (i.e. this+4) so we
// need to adjust 'this' before use.
//
// CHECK: %[[THIS_ADDR:.*]] = alloca %struct.ChildOverride*, align 4
-// CHECK: %[[THIS_i8:.*]] = getelementptr inbounds i8, i8* %[[ECX:.*]], i32 -4
-// CHECK: %[[THIS:.*]] = bitcast i8* %[[THIS_i8]] to %struct.ChildOverride*
-// CHECK: store %struct.ChildOverride* %[[THIS]], %struct.ChildOverride** %[[THIS_ADDR]], align 4
+// CHECK: %[[THIS_INIT:.*]] = bitcast i8* %[[ECX:.*]] to %struct.ChildOverride*
+// CHECK: store %struct.ChildOverride* %[[THIS_INIT]], %struct.ChildOverride** %[[THIS_ADDR]], align 4
+// CHECK: %[[THIS_RELOAD:.*]] = load %struct.ChildOverride*, %struct.ChildOverride** %[[THIS_ADDR]]
+// CHECK: %[[THIS_i8:.*]] = bitcast %struct.ChildOverride* %[[THIS_RELOAD]] to i8*
+// CHECK: %[[THIS_ADJUSTED:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 -4
+// CHECK: %[[THIS:.*]] = bitcast i8* %[[THIS_ADJUSTED]] to %struct.ChildOverride*
foo(this);
-// CHECK: %[[THIS:.*]] = load %struct.ChildOverride*, %struct.ChildOverride** %[[THIS_ADDR]]
// CHECK: %[[THIS_PARAM:.*]] = bitcast %struct.ChildOverride* %[[THIS]] to i8*
// CHECK: call void @foo(i8* %[[THIS_PARAM]])
// CHECK: ret
}
void call_right_override(ChildOverride *child) {
-// CHECK: define void @"\01?call_right_override
+// CHECK-LABEL: define void @"\01?call_right_override
// CHECK: %[[CHILD:.*]] = load %struct.ChildOverride
child->right();
@@ -127,15 +130,17 @@ struct GrandchildOverride : ChildOverride {
};
void GrandchildOverride::right() {
-// CHECK: define x86_thiscallcc void @"\01?right@GrandchildOverride@@UAEXXZ"(i8*
+// CHECK-LABEL: define x86_thiscallcc void @"\01?right@GrandchildOverride@@UAEXXZ"(i8*
//
// CHECK: %[[THIS_ADDR:.*]] = alloca %struct.GrandchildOverride*, align 4
-// CHECK: %[[THIS_i8:.*]] = getelementptr inbounds i8, i8* %[[ECX:.*]], i32 -4
-// CHECK: %[[THIS:.*]] = bitcast i8* %[[THIS_i8]] to %struct.GrandchildOverride*
-// CHECK: store %struct.GrandchildOverride* %[[THIS]], %struct.GrandchildOverride** %[[THIS_ADDR]], align 4
+// CHECK: %[[THIS_INIT:.*]] = bitcast i8* %[[ECX:.*]] to %struct.GrandchildOverride*
+// CHECK: store %struct.GrandchildOverride* %[[THIS_INIT]], %struct.GrandchildOverride** %[[THIS_ADDR]], align 4
+// CHECK: %[[THIS_RELOAD:.*]] = load %struct.GrandchildOverride*, %struct.GrandchildOverride** %[[THIS_ADDR]]
+// CHECK: %[[THIS_i8:.*]] = bitcast %struct.GrandchildOverride* %[[THIS_RELOAD]] to i8*
+// CHECK: %[[THIS_ADJUSTED:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 -4
+// CHECK: %[[THIS:.*]] = bitcast i8* %[[THIS_ADJUSTED]] to %struct.GrandchildOverride*
foo(this);
-// CHECK: %[[THIS:.*]] = load %struct.GrandchildOverride*, %struct.GrandchildOverride** %[[THIS_ADDR]]
// CHECK: %[[THIS_PARAM:.*]] = bitcast %struct.GrandchildOverride* %[[THIS]] to i8*
// CHECK: call void @foo(i8* %[[THIS_PARAM]])
// CHECK: ret
@@ -148,19 +153,19 @@ void call_grandchild_right(GrandchildOverride *obj) {
void emit_ctors() {
Left l;
- // CHECK: define {{.*}} @"\01??0Left@@QAE@XZ"
+ // CHECK-LABEL: define {{.*}} @"\01??0Left@@QAE@XZ"
// CHECK-NOT: getelementptr
// CHECK: store i32 (...)** bitcast ({ [1 x i8*] }* @"\01??_7Left@@6B@" to i32 (...)**)
// CHECK: ret
Right r;
- // CHECK: define {{.*}} @"\01??0Right@@QAE@XZ"
+ // CHECK-LABEL: define {{.*}} @"\01??0Right@@QAE@XZ"
// CHECK-NOT: getelementptr
// CHECK: store i32 (...)** bitcast ({ [1 x i8*] }* @"\01??_7Right@@6B@" to i32 (...)**)
// CHECK: ret
ChildOverride co;
- // CHECK: define {{.*}} @"\01??0ChildOverride@@QAE@XZ"
+ // CHECK-LABEL: define {{.*}} @"\01??0ChildOverride@@QAE@XZ"
// CHECK: %[[THIS:.*]] = load %struct.ChildOverride*, %struct.ChildOverride**
// CHECK: %[[VFPTR:.*]] = bitcast %struct.ChildOverride* %[[THIS]] to i32 (...)***
// CHECK: store i32 (...)** bitcast ({ [1 x i8*] }* @"\01??_7ChildOverride@@6BLeft@@@" to i32 (...)**), i32 (...)*** %[[VFPTR]]
@@ -171,7 +176,7 @@ void emit_ctors() {
// CHECK: ret
GrandchildOverride gc;
- // CHECK: define {{.*}} @"\01??0GrandchildOverride@@QAE@XZ"
+ // CHECK-LABEL: define {{.*}} @"\01??0GrandchildOverride@@QAE@XZ"
// CHECK: %[[THIS:.*]] = load %struct.GrandchildOverride*, %struct.GrandchildOverride**
// CHECK: %[[VFPTR:.*]] = bitcast %struct.GrandchildOverride* %[[THIS]] to i32 (...)***
// CHECK: store i32 (...)** bitcast ({ [1 x i8*] }* @"\01??_7GrandchildOverride@@6BLeft@@@" to i32 (...)**), i32 (...)*** %[[VFPTR]]
diff --git a/test/CodeGenCXX/microsoft-abi-static-initializers.cpp b/test/CodeGenCXX/microsoft-abi-static-initializers.cpp
index 57a72d4e2a6c..0b84f07e1154 100644
--- a/test/CodeGenCXX/microsoft-abi-static-initializers.cpp
+++ b/test/CodeGenCXX/microsoft-abi-static-initializers.cpp
@@ -146,7 +146,7 @@ inline S &getS() {
// CHECK-LABEL: define linkonce_odr dereferenceable({{[0-9]+}}) %struct.S* @"\01?getS@@YAAAUS@@XZ"() {{.*}} comdat
// CHECK: load i32, i32* @"\01??_B?1??getS@@YAAAUS@@XZ@51"
// CHECK: and i32 {{.*}}, 1
-// CHECK: icmp ne i32 {{.*}}, 0
+// CHECK: icmp eq i32 {{.*}}, 0
// CHECK: br i1
// init:
// CHECK: or i32 {{.*}}, 1
diff --git a/test/CodeGenCXX/microsoft-abi-thread-safe-statics.cpp b/test/CodeGenCXX/microsoft-abi-thread-safe-statics.cpp
index 0202586c8a62..3f53e631c964 100644
--- a/test/CodeGenCXX/microsoft-abi-thread-safe-statics.cpp
+++ b/test/CodeGenCXX/microsoft-abi-thread-safe-statics.cpp
@@ -24,8 +24,8 @@ extern inline S &f() {
static thread_local S s;
// CHECK: %[[guard:.*]] = load i32, i32* @"\01??__J?1??f@@YAAAUS@@XZ@51"
// CHECK-NEXT: %[[mask:.*]] = and i32 %[[guard]], 1
-// CHECK-NEXT: %[[cmp:.*]] = icmp ne i32 %[[mask]], 0
-// CHECK-NEXT: br i1 %[[cmp]], label %[[init_end:.*]], label %[[init:.*]]
+// CHECK-NEXT: %[[cmp:.*]] = icmp eq i32 %[[mask]], 0
+// CHECK-NEXT: br i1 %[[cmp]], label %[[init:.*]], label %[[init_end:.*]], !prof ![[unlikely_threadlocal:.*]]
//
// CHECK: [[init]]:
// CHECK-NEXT: %[[or:.*]] = or i32 %[[guard]], 1
@@ -56,7 +56,7 @@ extern inline S &g() {
// CHECK: %[[guard:.*]] = load atomic i32, i32* @"\01?$TSS0@?1??g@@YAAAUS@@XZ@4HA" unordered, align 4
// CHECK-NEXT: %[[epoch:.*]] = load i32, i32* @_Init_thread_epoch
// CHECK-NEXT: %[[cmp:.*]] = icmp sgt i32 %[[guard]], %[[epoch]]
-// CHECK-NEXT: br i1 %[[cmp]], label %[[init_attempt:.*]], label %[[init_end:.*]]
+// CHECK-NEXT: br i1 %[[cmp]], label %[[init_attempt:.*]], label %[[init_end:.*]], !prof ![[unlikely_staticlocal:.*]]
//
// CHECK: [[init_attempt]]:
// CHECK-NEXT: call void @_Init_thread_header(i32* @"\01?$TSS0@?1??g@@YAAAUS@@XZ@4HA")
@@ -95,3 +95,6 @@ int g1() {
static int i = f1();
return i;
}
+
+// CHECK-DAG: ![[unlikely_threadlocal]] = !{!"branch_weights", i32 1, i32 1023}
+// CHECK-DAG: ![[unlikely_staticlocal]] = !{!"branch_weights", i32 1, i32 1048575}
diff --git a/test/CodeGenCXX/microsoft-abi-virtual-inheritance-vtordisps.cpp b/test/CodeGenCXX/microsoft-abi-virtual-inheritance-vtordisps.cpp
index bb73f8773ccb..2f141b2a66ec 100644
--- a/test/CodeGenCXX/microsoft-abi-virtual-inheritance-vtordisps.cpp
+++ b/test/CodeGenCXX/microsoft-abi-virtual-inheritance-vtordisps.cpp
@@ -24,6 +24,7 @@ struct D : virtual C {
D::D() {} // Forces vftable emission.
// CHECK-LABEL: define linkonce_odr x86_thiscallcc void @"\01?f@D@@$4PPPPPPPM@A@AEXXZ"
+// Note that the vtordisp is applied before really adjusting to D*.
// CHECK: %[[ECX:.*]] = load %struct.D*, %struct.D** %{{.*}}
// CHECK: %[[ECX_i8:.*]] = bitcast %struct.D* %[[ECX]] to i8*
// CHECK: %[[VTORDISP_PTR_i8:.*]] = getelementptr inbounds i8, i8* %[[ECX_i8]], i32 -4
diff --git a/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp b/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp
index 20ecaf431650..c9dd1dd7d8e2 100644
--- a/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp
+++ b/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp
@@ -1,9 +1,9 @@
-// RUN: %clang_cc1 %s -fno-rtti -triple=i386-pc-win32 -emit-llvm -o %t
+// RUN: %clang_cc1 %s -fno-rtti -std=c++11 -Wno-inaccessible-base -triple=i386-pc-win32 -emit-llvm -o %t
// RUN: FileCheck %s < %t
// RUN: FileCheck --check-prefix=CHECK2 %s < %t
// For now, just make sure x86_64 doesn't crash.
-// RUN: %clang_cc1 %s -fno-rtti -triple=x86_64-pc-win32 -emit-llvm -o %t
+// RUN: %clang_cc1 %s -fno-rtti -std=c++11 -Wno-inaccessible-base -triple=x86_64-pc-win32 -emit-llvm -o %t
struct VBase {
virtual ~VBase();
@@ -52,12 +52,14 @@ B::B() {
B::~B() {
// CHECK-LABEL: define x86_thiscallcc void @"\01??1B@@UAE@XZ"
- // Adjust the this parameter:
- // CHECK: %[[THIS_PARAM_i8:.*]] = bitcast %struct.B* {{.*}} to i8*
- // CHECK: %[[THIS_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_PARAM_i8]], i32 -8
- // CHECK: %[[THIS:.*]] = bitcast i8* %[[THIS_i8]] to %struct.B*
- // CHECK: store %struct.B* %[[THIS]], %struct.B** %[[THIS_ADDR:.*]], align 4
- // CHECK: %[[THIS:.*]] = load %struct.B*, %struct.B** %[[THIS_ADDR]]
+ // Store initial this:
+ // CHECK: %[[THIS_ADDR:.*]] = alloca %struct.B*
+ // CHECK: store %struct.B* %{{.*}}, %struct.B** %[[THIS_ADDR]], align 4
+ // Reload and adjust the this parameter:
+ // CHECK: %[[THIS_RELOAD:.*]] = load %struct.B*, %struct.B** %[[THIS_ADDR]]
+ // CHECK: %[[THIS_UNADJ_i8:.*]] = bitcast %struct.B* %[[THIS_RELOAD]] to i8*
+ // CHECK: %[[THIS_ADJ_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_UNADJ_i8]], i32 -8
+ // CHECK: %[[THIS:.*]] = bitcast i8* %[[THIS_ADJ_i8]] to %struct.B*
// Restore the vfptr that could have been changed by a subclass.
// CHECK: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
@@ -97,11 +99,11 @@ B::~B() {
// CHECK2: ret
// CHECK2-LABEL: define linkonce_odr x86_thiscallcc i8* @"\01??_GB@@UAEPAXI@Z"
- // CHECK2: %[[THIS_PARAM_i8:.*]] = bitcast %struct.B* {{.*}} to i8*
+ // CHECK2: store %struct.B* %{{.*}}, %struct.B** %[[THIS_ADDR:.*]], align 4
+ // CHECK2: %[[THIS:.*]] = load %struct.B*, %struct.B** %[[THIS_ADDR]]
+ // CHECK2: %[[THIS_PARAM_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
// CHECK2: %[[THIS_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_PARAM_i8:.*]], i32 -8
// CHECK2: %[[THIS:.*]] = bitcast i8* %[[THIS_i8]] to %struct.B*
- // CHECK2: store %struct.B* %[[THIS]], %struct.B** %[[THIS_ADDR:.*]], align 4
- // CHECK2: %[[THIS:.*]] = load %struct.B*, %struct.B** %[[THIS_ADDR]]
// CHECK2: call x86_thiscallcc void @"\01??_DB@@QAEXXZ"(%struct.B* %[[THIS]])
// ...
// CHECK2: ret
@@ -113,13 +115,17 @@ void B::foo() {
// B::foo gets 'this' cast to VBase* in ECX (i.e. this+8) so we
// need to adjust 'this' before use.
//
-// CHECK: %[[THIS_ADDR:.*]] = alloca %struct.B*, align 4
-// CHECK: %[[THIS_i8:.*]] = getelementptr inbounds i8, i8* %[[ECX:.*]], i32 -8
-// CHECK: %[[THIS:.*]] = bitcast i8* %[[THIS_i8]] to %struct.B*
-// CHECK: store %struct.B* %[[THIS]], %struct.B** %[[THIS_ADDR]], align 4
+// Store initial this:
+// CHECK: %[[THIS_ADDR:.*]] = alloca %struct.B*
+// CHECK: store %struct.B* %{{.*}}, %struct.B** %[[THIS_ADDR]], align 4
+//
+// Reload and adjust the this parameter:
+// CHECK: %[[THIS_RELOAD:.*]] = load %struct.B*, %struct.B** %[[THIS_ADDR]]
+// CHECK: %[[THIS_UNADJ_i8:.*]] = bitcast %struct.B* %[[THIS_RELOAD]] to i8*
+// CHECK: %[[THIS_ADJ_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_UNADJ_i8]], i32 -8
+// CHECK: %[[THIS:.*]] = bitcast i8* %[[THIS_ADJ_i8]] to %struct.B*
field = 42;
-// CHECK: %[[THIS:.*]] = load %struct.B*, %struct.B** %[[THIS_ADDR]]
// CHECK: %[[THIS8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
// CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8, i8* %[[THIS8]], i32 0
// CHECK: %[[VBPTR8:.*]] = bitcast i8* %[[VBPTR]] to i32**
@@ -284,11 +290,16 @@ struct D : virtual Z, B, C {
D::~D() {
// CHECK-LABEL: define x86_thiscallcc void @"\01??1D@diamond@@UAE@XZ"(%"struct.diamond::D"*{{.*}})
- // CHECK: %[[ARG_i8:.*]] = bitcast %"struct.diamond::D"* %{{.*}} to i8*
- // CHECK: %[[THIS_i8:.*]] = getelementptr inbounds i8, i8* %[[ARG_i8]], i32 -24
- // CHECK: %[[THIS:.*]] = bitcast i8* %[[THIS_i8]] to %"struct.diamond::D"*
- // CHECK: store %"struct.diamond::D"* %[[THIS]], %"struct.diamond::D"** %[[THIS_VAL:.*]], align 4
- // CHECK: %[[THIS:.*]] = load %"struct.diamond::D"*, %"struct.diamond::D"** %[[THIS_VAL]]
+ // Store initial this:
+ // CHECK: %[[THIS_ADDR:.*]] = alloca %"struct.diamond::D"*
+ // CHECK: store %"struct.diamond::D"* %{{.*}}, %"struct.diamond::D"** %[[THIS_ADDR]], align 4
+ //
+ // Reload and adjust the this parameter:
+ // CHECK: %[[THIS_RELOAD:.*]] = load %"struct.diamond::D"*, %"struct.diamond::D"** %[[THIS_ADDR]]
+ // CHECK: %[[THIS_UNADJ_i8:.*]] = bitcast %"struct.diamond::D"* %[[THIS_RELOAD]] to i8*
+ // CHECK: %[[THIS_ADJ_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_UNADJ_i8]], i32 -24
+ // CHECK: %[[THIS:.*]] = bitcast i8* %[[THIS_ADJ_i8]] to %"struct.diamond::D"*
+ //
// CHECK: %[[D_i8:.*]] = bitcast %"struct.diamond::D"* %[[THIS]] to i8*
// CHECK: %[[C_i8:.*]] = getelementptr inbounds i8, i8* %[[D_i8]], i32 4
// CHECK: %[[C:.*]] = bitcast i8* %[[C_i8]] to %"struct.diamond::C"*
diff --git a/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-this-adjustment.cpp b/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-this-adjustment.cpp
index b97c432f5e02..385e9cc17b1b 100644
--- a/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-this-adjustment.cpp
+++ b/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-this-adjustment.cpp
@@ -196,7 +196,11 @@ void C::g(NonTrivial o) {
}
// BITCODE-LABEL: define void @"\01?g@C@pr30293@@UAAXUNonTrivial@2@@Z"(<{ i8*, %"struct.pr30293::NonTrivial" }>* inalloca)
-// BITCODE: %[[this1:[^ ]*]] = load i8*, i8** %[[thisaddr:[^ ]*]], align 4
-// BITCODE-NEXT: %[[this2:[^ ]*]] = getelementptr inbounds i8, i8* %[[this1]], i32 -4
-// BITCODE-NEXT: store i8* %[[this2]], i8** %[[thisaddr]], align 4
+// BITCODE: %[[thisaddr:[^ ]*]] = getelementptr inbounds <{ i8*, %"struct.pr30293::NonTrivial" }>, <{ i8*, %"struct.pr30293::NonTrivial" }>* {{.*}}, i32 0, i32 0
+// BITCODE: %[[thisaddr1:[^ ]*]] = bitcast i8** %[[thisaddr]] to %"struct.pr30293::C"**
+// BITCODE: %[[this1:[^ ]*]] = load %"struct.pr30293::C"*, %"struct.pr30293::C"** %[[thisaddr1]], align 4
+// BITCODE: %[[this2:[^ ]*]] = bitcast %"struct.pr30293::C"* %[[this1]] to i8*
+// BITCODE: %[[this3:[^ ]*]] = getelementptr inbounds i8, i8* %[[this2]], i32 -4
+// BITCODE: %[[this4:[^ ]*]] = bitcast i8* %[[this3]] to %"struct.pr30293::C"*
+// BITCODE: store %"struct.pr30293::C"* %[[this4]], %"struct.pr30293::C"** @"\01?whatsthis@pr30293@@3PAUC@1@A", align 4
}
diff --git a/test/CodeGenCXX/microsoft-abi-vtables-return-thunks.cpp b/test/CodeGenCXX/microsoft-abi-vtables-return-thunks.cpp
index 2bf7da58ea9c..feba91c50556 100644
--- a/test/CodeGenCXX/microsoft-abi-vtables-return-thunks.cpp
+++ b/test/CodeGenCXX/microsoft-abi-vtables-return-thunks.cpp
@@ -201,3 +201,18 @@ D::D() {}
// GLOBALS: @"\01?fn@D@test3@@$4PPPPPPPM@A@AEPAUB@2@XZ"
// GLOBALS: @"\01?fn@D@test3@@$4PPPPPPPM@A@AEPAU12@XZ"
}
+
+namespace pr34302 {
+// C::f is lives in the vftable inside its virtual B subobject. In the MS ABI,
+// covariant return type virtual methods extend vftables from virtual bases,
+// even though that can make it impossible to implement certain diamond
+// hierarchies correctly.
+struct A { virtual ~A(); };
+struct B : A { virtual B *f(); };
+struct C : virtual B { C *f(); };
+C c;
+// VFTABLES-LABEL: VFTable indices for 'pr34302::C' (2 entries).
+// VFTABLES-NEXT: -- accessible via vbtable index 1, vfptr at offset 0 --
+// VFTABLES-NEXT: 0 | pr34302::C::~C() [scalar deleting]
+// VFTABLES-NEXT: 2 | pr34302::C *pr34302::C::f()
+}
diff --git a/test/CodeGenCXX/microsoft-inaccessible-base.cpp b/test/CodeGenCXX/microsoft-inaccessible-base.cpp
new file mode 100644
index 000000000000..2c0d124eb01e
--- /dev/null
+++ b/test/CodeGenCXX/microsoft-inaccessible-base.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -fms-compatibility -triple x86_64-windows-msvc %s -emit-llvm -o - | FileCheck %s
+
+// Make sure we choose the *direct* base path when doing these conversions.
+
+// CHECK: %struct.C = type { %struct.A, %struct.B }
+// CHECK: %struct.D = type { %struct.B, %struct.A }
+
+struct A { int a; };
+struct B : A { int b; };
+
+struct C : A, B { };
+extern "C" A *a_from_c(C *p) { return p; }
+// CHECK-LABEL: define %struct.A* @a_from_c(%struct.C* %{{.*}})
+// CHECK: bitcast %struct.C* %{{.*}} to %struct.A*
+
+struct D : B, A { };
+extern "C" A *a_from_d(D *p) { return p; }
+// CHECK-LABEL: define %struct.A* @a_from_d(%struct.D* %{{.*}})
+// CHECK: %[[p_i8:[^ ]*]] = bitcast %struct.D* %{{.*}} to i8*
+// CHECK: getelementptr inbounds i8, i8* %[[p_i8]], i64 8
diff --git a/test/CodeGenCXX/mingw-w64-exceptions.c b/test/CodeGenCXX/mingw-w64-exceptions.c
new file mode 100644
index 000000000000..e980ebd33505
--- /dev/null
+++ b/test/CodeGenCXX/mingw-w64-exceptions.c
@@ -0,0 +1,22 @@
+// RUN: %clang -target x86_64-windows-gnu -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SEH
+// RUN: %clang -target i686-windows-gnu -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-DWARF
+
+// RUN: %clang -target x86_64-windows-gnu -fsjlj-exceptions -c %s -### 2>&1 | \
+// RUN: FileCheck %s --check-prefix=CHECK-SJLJ
+
+// RUN: %clang -target x86_64-windows-gnu -fdwarf-exceptions -c %s -### 2>&1 | \
+// RUN: FileCheck %s --check-prefix=CHECK-DWARF
+
+// RUN: %clang -target x86_64-windows-gnu -fsjlj-exceptions -fseh-exceptions -c %s -### 2>&1 | \
+// RUN: FileCheck %s --check-prefix=CHECK-SEH
+
+// RUN: %clang -target x86_64-windows-gnu -fseh-exceptions -fsjlj-exceptions -c %s -### 2>&1 | \
+// RUN: FileCheck %s --check-prefix=CHECK-SJLJ
+
+// RUN: %clang -target x86_64-windows-gnu -fseh-exceptions -fdwarf-exceptions -c %s -### 2>&1 | \
+// RUN: FileCheck %s --check-prefix=CHECK-DWARF
+
+// CHECK-SEH: "-fseh-exceptions"
+// CHECK-SJLJ: "-fsjlj-exceptions"
+// CHECK-DWARF-NOT: "-fsjlj-exceptions"
+// CHECK-DWARF-NOT: "-fseh-exceptions"
diff --git a/test/CodeGenCXX/mingw-w64-seh-exceptions.cpp b/test/CodeGenCXX/mingw-w64-seh-exceptions.cpp
index 9025f877c551..046c4a815f46 100644
--- a/test/CodeGenCXX/mingw-w64-seh-exceptions.cpp
+++ b/test/CodeGenCXX/mingw-w64-seh-exceptions.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 %s -fexceptions -emit-llvm -triple x86_64-w64-windows-gnu -o - | FileCheck %s --check-prefix=X64
+// RUN: %clang_cc1 %s -fexceptions -fseh-exceptions -emit-llvm -triple x86_64-w64-windows-gnu -o - | FileCheck %s --check-prefix=X64
+// RUN: %clang_cc1 %s -fexceptions -fdwarf-exceptions -emit-llvm -triple i686-w64-windows-gnu -o - | FileCheck %s --check-prefix=X86
// RUN: %clang_cc1 %s -fexceptions -emit-llvm -triple i686-w64-windows-gnu -o - | FileCheck %s --check-prefix=X86
extern "C" void foo();
diff --git a/test/CodeGenCXX/ms-eh-personality.cpp b/test/CodeGenCXX/ms-eh-personality.cpp
new file mode 100644
index 000000000000..592ab69efaf2
--- /dev/null
+++ b/test/CodeGenCXX/ms-eh-personality.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -triple x86_64-windows-msvc -fexceptions -fcxx-exceptions %s -emit-llvm -o - | FileCheck %s --check-prefix=MSVC
+// RUN: %clang_cc1 -triple x86_64-windows-msvc -fexceptions -fcxx-exceptions -fsjlj-exceptions %s -emit-llvm -o - | FileCheck %s --check-prefix=SJLJ
+// RUN: %clang_cc1 -triple x86_64-windows-msvc -fexceptions -fcxx-exceptions -fseh-exceptions %s -emit-llvm -o - | FileCheck %s --check-prefix=MSVC
+// RUN: %clang_cc1 -triple x86_64-windows-msvc -fexceptions -fcxx-exceptions -fdwarf-exceptions %s -emit-llvm -o - | FileCheck %s --check-prefix=DWARF
+
+// MSVC: define void @f(){{.*}}@__CxxFrameHandler3
+// SJLJ: define void @f(){{.*}}@__gxx_personality_sj0
+// DWARF: define void @f(){{.*}}@__gxx_personality_v0
+
+struct Cleanup {
+ Cleanup();
+ ~Cleanup();
+ int x = 0;
+};
+
+void g();
+extern "C" void f() {
+ Cleanup c;
+ g();
+}
diff --git a/test/CodeGenCXX/ms-inline-asm-return.cpp b/test/CodeGenCXX/ms-inline-asm-return.cpp
index 51671c0bcdaa..837f1b437a4c 100644
--- a/test/CodeGenCXX/ms-inline-asm-return.cpp
+++ b/test/CodeGenCXX/ms-inline-asm-return.cpp
@@ -70,7 +70,7 @@ FourChars f_s4() {
}
}
// CHECK-LABEL: define i32 @f_s4()
-// CHECK: %[[r:[^ ]*]] = call i32 asm sideeffect inteldialect "mov eax, $$0x01010101", "={eax},~{eax},{{.*}}"
+// CHECK: %[[r:[^ ]*]] = call i32 asm sideeffect inteldialect "mov eax, $$16843009", "={eax},~{eax},{{.*}}"
// CHECK: store i32 %[[r]], i32* %{{.*}}
// CHECK: %[[r_i32:[^ ]*]] = load i32, i32* %{{.*}}
// CHECK: ret i32 %[[r_i32]]
@@ -85,7 +85,7 @@ EightChars f_s8() {
}
}
// CHECK-LABEL: define i64 @f_s8()
-// CHECK: %[[r:[^ ]*]] = call i64 asm sideeffect inteldialect "mov eax, $$01010101h\0A\09mov edx, $$01010101b", "=A,~{eax},{{.*}}"
+// CHECK: %[[r:[^ ]*]] = call i64 asm sideeffect inteldialect "mov eax, $$16843009\0A\09mov edx, $$85", "=A,~{eax},{{.*}}"
// CHECK: store i64 %[[r]], i64* %{{.*}}
// CHECK: %[[r_i64:[^ ]*]] = load i64, i64* %{{.*}}
// CHECK: ret i64 %[[r_i64]]
diff --git a/test/CodeGenCXX/new-overflow.cpp b/test/CodeGenCXX/new-overflow.cpp
index 0c4c3c823d19..b27984f66ab6 100644
--- a/test/CodeGenCXX/new-overflow.cpp
+++ b/test/CodeGenCXX/new-overflow.cpp
@@ -85,9 +85,7 @@ namespace test4 {
// CHECK: define [[A:%.*]]* @_ZN5test44testEs(i16 signext
// CHECK: [[N:%.*]] = sext i16 {{%.*}} to i32
- // CHECK-NEXT: [[T0:%.*]] = icmp slt i32 [[N]], 0
- // CHECK-NEXT: [[T1:%.*]] = select i1 [[T0]], i32 -1, i32 [[N]]
- // CHECK-NEXT: call i8* @_Znaj(i32 [[T1]])
+ // CHECK-NEXT: call i8* @_Znaj(i32 [[N]])
// CHECK: getelementptr inbounds {{.*}}, i32 [[N]]
elt *test(short s) {
return new elt[s];
@@ -104,9 +102,7 @@ namespace test5 {
// CHECK: define [[A:%.*]]* @_ZN5test54testEi(i32
// CHECK: [[N:%.*]] = load i32, i32*
- // CHECK-NEXT: [[T0:%.*]] = icmp slt i32 [[N]], 0
- // CHECK-NEXT: [[T1:%.*]] = select i1 [[T0]], i32 -1, i32 [[N]]
- // CHECK-NEXT: call i8* @_Znaj(i32 [[T1]])
+ // CHECK-NEXT: call i8* @_Znaj(i32 [[N]])
// CHECK: getelementptr inbounds {{.*}}, i32 [[N]]
elt *test(int s) {
return new elt[s];
@@ -169,13 +165,11 @@ namespace test8 {
// CHECK: define [[A:%.*]]* @_ZN5test84testEx(i64
// CHECK: [[N:%.*]] = load i64, i64*
- // CHECK-NEXT: [[T0:%.*]] = icmp uge i64 [[N]], 4294967296
// CHECK-NEXT: [[T1:%.*]] = trunc i64 [[N]] to i32
// CHECK-NEXT: [[T2:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[T1]], i32 4)
// CHECK-NEXT: [[T3:%.*]] = extractvalue { i32, i1 } [[T2]], 1
- // CHECK-NEXT: [[T4:%.*]] = or i1 [[T0]], [[T3]]
// CHECK-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T2]], 0
- // CHECK-NEXT: [[T6:%.*]] = select i1 [[T4]], i32 -1, i32 [[T5]]
+ // CHECK-NEXT: [[T6:%.*]] = select i1 [[T3]], i32 -1, i32 [[T5]]
// CHECK-NEXT: call i8* @_Znaj(i32 [[T6]])
// CHECK: getelementptr inbounds {{.*}}, i32 [[T1]]
elt *test(long long s) {
@@ -194,13 +188,11 @@ namespace test9 {
// CHECK: define [[A:%.*]]* @_ZN5test94testEy(i64
// CHECK: [[N:%.*]] = load i64, i64*
- // CHECK-NEXT: [[T0:%.*]] = icmp uge i64 [[N]], 4294967296
// CHECK-NEXT: [[T1:%.*]] = trunc i64 [[N]] to i32
// CHECK-NEXT: [[T2:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[T1]], i32 4)
// CHECK-NEXT: [[T3:%.*]] = extractvalue { i32, i1 } [[T2]], 1
- // CHECK-NEXT: [[T4:%.*]] = or i1 [[T0]], [[T3]]
// CHECK-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T2]], 0
- // CHECK-NEXT: [[T6:%.*]] = select i1 [[T4]], i32 -1, i32 [[T5]]
+ // CHECK-NEXT: [[T6:%.*]] = select i1 [[T3]], i32 -1, i32 [[T5]]
// CHECK-NEXT: call i8* @_Znaj(i32 [[T6]])
// CHECK: getelementptr inbounds {{.*}}, i32 [[T1]]
elt *test(unsigned long long s) {
diff --git a/test/CodeGenCXX/new.cpp b/test/CodeGenCXX/new.cpp
index ae2ec1505c5d..3bebc2ab8ac8 100644
--- a/test/CodeGenCXX/new.cpp
+++ b/test/CodeGenCXX/new.cpp
@@ -255,8 +255,6 @@ namespace test15 {
// CHECK-LABEL: define void @_ZN6test155test2EPvi(
// CHECK: [[N:%.*]] = load i32, i32*
// CHECK-NEXT: [[T0:%.*]] = sext i32 [[N]] to i64
- // CHECK-NEXT: [[T1:%.*]] = icmp slt i64 [[T0]], 0
- // CHECK-NEXT: [[T2:%.*]] = select i1 [[T1]], i64 -1, i64 [[T0]]
// CHECK-NEXT: [[P:%.*]] = load i8*, i8**
// CHECK: [[BEGIN:%.*]] = bitcast i8* [[P]] to [[A:%.*]]*
// CHECK-NEXT: [[ISEMPTY:%.*]] = icmp eq i64 [[T0]], 0
diff --git a/test/CodeGenCXX/noescape.cpp b/test/CodeGenCXX/noescape.cpp
new file mode 100644
index 000000000000..90d24de3da29
--- /dev/null
+++ b/test/CodeGenCXX/noescape.cpp
@@ -0,0 +1,67 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -emit-llvm -o - %s | FileCheck %s
+
+struct S {
+ int a[4];
+ S(int *, int * __attribute__((noescape)));
+ S &operator=(int * __attribute__((noescape)));
+ void m0(int *, int * __attribute__((noescape)));
+ virtual void vm1(int *, int * __attribute__((noescape)));
+};
+
+// CHECK: define void @_ZN1SC2EPiS0_(%struct.S* {{.*}}, {{.*}}, {{.*}} nocapture)
+// CHECK: define void @_ZN1SC1EPiS0_(%struct.S* {{.*}}, {{.*}}, {{.*}} nocapture) {{.*}} {
+// CHECK: call void @_ZN1SC2EPiS0_(%struct.S* {{.*}}, {{.*}}, {{.*}} nocapture {{.*}})
+
+S::S(int *, int * __attribute__((noescape))) {}
+
+// CHECK: define {{.*}} %struct.S* @_ZN1SaSEPi(%struct.S* {{.*}}, {{.*}} nocapture)
+S &S::operator=(int * __attribute__((noescape))) { return *this; }
+
+// CHECK: define void @_ZN1S2m0EPiS0_(%struct.S* {{.*}}, {{.*}} nocapture)
+void S::m0(int *, int * __attribute__((noescape))) {}
+
+// CHECK: define void @_ZN1S3vm1EPiS0_(%struct.S* {{.*}}, {{.*}} nocapture)
+void S::vm1(int *, int * __attribute__((noescape))) {}
+
+// CHECK-LABEL: define void @_Z5test0P1SPiS1_(
+// CHECK: call void @_ZN1SC1EPiS0_(%struct.S* {{.*}}, {{.*}}, {{.*}} nocapture {{.*}})
+// CHECK: call {{.*}} %struct.S* @_ZN1SaSEPi(%struct.S* {{.*}}, {{.*}} nocapture {{.*}})
+// CHECK: call void @_ZN1S2m0EPiS0_(%struct.S* {{.*}}, {{.*}}, {{.*}} nocapture {{.*}})
+// CHECK: call void {{.*}}(%struct.S* {{.*}}, {{.*}}, {{.*}} nocapture {{.*}})
+void test0(S *s, int *p0, int *p1) {
+ S t(p0, p1);
+ t = p1;
+ s->m0(p0, p1);
+ s->vm1(p0, p1);
+}
+
+namespace std {
+ typedef decltype(sizeof(0)) size_t;
+}
+
+// CHECK: define {{.*}} @_ZnwmPv({{.*}}, {{.*}} nocapture {{.*}})
+void *operator new(std::size_t, void * __attribute__((noescape)) p) {
+ return p;
+}
+
+// CHECK-LABEL: define i8* @_Z5test1Pv(
+// CHECK : %call = call {{.*}} @_ZnwmPv({{.*}}, {{.*}} nocapture {{.*}})
+void *test1(void *p0) {
+ return ::operator new(16, p0);
+}
+
+// CHECK-LABEL: define void @_Z5test2PiS_(
+// CHECK: call void @"_ZZ5test2PiS_ENK3$_0clES_S_"({{.*}}, {{.*}}, {{.*}} nocapture {{.*}})
+// CHECK: define internal void @"_ZZ5test2PiS_ENK3$_0clES_S_"({{.*}}, {{.*}}, {{.*}} nocapture)
+void test2(int *p0, int *p1) {
+ auto t = [](int *, int * __attribute__((noescape))){};
+ t(p0, p1);
+}
+
+// CHECK-LABEL: define void @_Z5test3PFvU8noescapePiES_(
+// CHECK: call void {{.*}}(i32* nocapture {{.*}})
+typedef void (*NoEscapeFunc)(__attribute__((noescape)) int *);
+
+void test3(NoEscapeFunc f, int *p) {
+ f(p);
+}
diff --git a/test/CodeGenCXX/pr29160.cpp b/test/CodeGenCXX/pr29160.cpp
new file mode 100644
index 000000000000..09cf2a637072
--- /dev/null
+++ b/test/CodeGenCXX/pr29160.cpp
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -std=c++11 -triple i686-linux-gnu %s -o /dev/null -S -emit-llvm
+//
+// This test's failure mode is running ~forever. (For some value of "forever"
+// that's greater than 25 minutes on my machine)
+
+template <typename... Ts>
+struct Foo {
+ template <typename... T>
+ static void ignore() {}
+ Foo() { ignore<Ts...>(); }
+};
+
+struct Base {
+ Base();
+ ~Base();
+};
+
+#define STAMP(thiz, prev) using thiz = Foo< \
+ prev, prev, prev, prev, prev, prev, prev, prev, prev, prev, prev, prev, \
+ prev, prev, prev, prev, prev, prev, prev, prev, prev, prev, prev, prev, \
+ prev, prev, prev, prev, prev, prev, prev, prev, prev, prev, prev, prev \
+ >;
+STAMP(A, Base);
+STAMP(B, A);
+STAMP(C, B);
+STAMP(D, C);
+STAMP(E, D);
+STAMP(F, E);
+STAMP(G, F);
+STAMP(H, G);
+STAMP(I, H);
+STAMP(J, I);
+STAMP(K, J);
+STAMP(L, K);
+STAMP(M, L);
+STAMP(N, M);
+STAMP(O, N);
+STAMP(P, O);
+STAMP(Q, P);
+
+int main() { Q q; }
diff --git a/test/CodeGenCXX/regcall.cpp b/test/CodeGenCXX/regcall.cpp
index 0ff6fdf12a58..2b7b9e2a6eff 100644
--- a/test/CodeGenCXX/regcall.cpp
+++ b/test/CodeGenCXX/regcall.cpp
@@ -73,8 +73,8 @@ bool __regcall operator ==(const test_class&, const test_class&){ --x; return fa
// CHECK-WIN64-DAG: define x86_regcallcc zeroext i1 @"\01??8@Yw_NAEBVtest_class@@0@Z"
// CHECK-WIN32-DAG: define x86_regcallcc zeroext i1 @"\01??8@Yw_NABVtest_class@@0@Z"
-test_class __regcall operator""_test_class (unsigned long long) { ++x; return test_class{};}
-// CHECK-LIN64-DAG: define x86_regcallcc %class.test_class @_Zli11_test_classy(i64)
+test_class __regcall operator""_test_class (unsigned long long) { ++x; return test_class{};}
+// CHECK-LIN64-DAG: define x86_regcallcc void @_Zli11_test_classy(%class.test_class* noalias sret %agg.result, i64)
// CHECK-LIN32-DAG: define x86_regcallcc void @_Zli11_test_classy(%class.test_class* inreg noalias sret %agg.result, i64)
// CHECK-WIN64-DAG: \01??__K_test_class@@Yw?AVtest_class@@_K@Z"
// CHECK-WIN32-DAG: \01??__K_test_class@@Yw?AVtest_class@@_K@Z"
@@ -95,3 +95,11 @@ void force_gen() {
freeTempFunc(1);
t3.do_thing();
}
+
+long double _Complex __regcall foo(long double _Complex f) {
+ return f;
+}
+// CHECK-LIN64-DAG: define x86_regcallcc void @_Z15__regcall3__fooCe({ x86_fp80, x86_fp80 }* noalias sret %agg.result, { x86_fp80, x86_fp80 }* byval align 16 %f)
+// CHECK-LIN32-DAG: define x86_regcallcc void @_Z15__regcall3__fooCe({ x86_fp80, x86_fp80 }* inreg noalias sret %agg.result, { x86_fp80, x86_fp80 }* byval align 4 %f)
+// CHECK-WIN64-DAG: define x86_regcallcc { double, double } @"\01?foo@@YwU?$_Complex@O@__clang@@U12@@Z"(double %f.0, double %f.1)
+// CHECK-WIN32-DAG: define x86_regcallcc { double, double } @"\01?foo@@YwU?$_Complex@O@__clang@@U12@@Z"(double %f.0, double %f.1)
diff --git a/test/CodeGenCXX/rtti-mingw64.cpp b/test/CodeGenCXX/rtti-mingw64.cpp
index 818b11b64bc5..9f3e03961e89 100644
--- a/test/CodeGenCXX/rtti-mingw64.cpp
+++ b/test/CodeGenCXX/rtti-mingw64.cpp
@@ -2,7 +2,12 @@
struct A { int a; };
struct B : virtual A { int b; };
B b;
+class C {
+ virtual ~C();
+};
+C::~C() {}
+// CHECK: @_ZTI1C = linkonce_odr
// CHECK: @_ZTI1B = linkonce_odr constant { i8*, i8*, i32, i32, i8*, i64 }
// CHECK-SAME: i8* bitcast (i8** getelementptr inbounds (i8*, i8** @_ZTVN10__cxxabiv121__vmi_class_type_infoE, i64 2) to i8*),
// CHECK-SAME: i8* getelementptr inbounds ([3 x i8], [3 x i8]* @_ZTS1B, i32 0, i32 0),
diff --git a/test/CodeGenCXX/runtime-dllstorage.cpp b/test/CodeGenCXX/runtime-dllstorage.cpp
index 76c002c0e407..8ccf0291687c 100644
--- a/test/CodeGenCXX/runtime-dllstorage.cpp
+++ b/test/CodeGenCXX/runtime-dllstorage.cpp
@@ -12,7 +12,7 @@
// %clang_cc1 -triple i686-windows-itanium -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -fno-use-cxa-atexit -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-IA -check-prefix CHECK-DYNAMIC-IA -check-prefix CHECK-DYNAMIC-IA-ATEXIT
// %clang_cc1 -triple i686-windows-itanium -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -fno-use-cxa-atexit -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-IA -check-prefix CHECK-STATIC-IA -check-prefix CHECK-STATIC-IA-ATEXIT
-// RUN: %clang_cc1 -triple i686-windows-gnu -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-IA -check-prefix CHECK-DYNAMIC-IA
+// RUN: %clang_cc1 -triple i686-windows-gnu -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-IA -check-prefix CHECK-STATIC-IA
// RUN: %clang_cc1 -triple i686-windows-gnu -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -flto-visibility-public-std -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-IA -check-prefix CHECK-STATIC-IA
// RUN: %clang_cc1 -triple i686-windows-cygnus -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-IA -check-prefix CHECK-DYNAMIC-IA
// RUN: %clang_cc1 -triple i686-windows-cygnus -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -flto-visibility-public-std -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-IA -check-prefix CHECK-STATIC-IA
diff --git a/test/CodeGenCXX/sanitize-dtor-callback.cpp b/test/CodeGenCXX/sanitize-dtor-callback.cpp
index e208a6f7e5a5..ecb0f2b2d13b 100644
--- a/test/CodeGenCXX/sanitize-dtor-callback.cpp
+++ b/test/CodeGenCXX/sanitize-dtor-callback.cpp
@@ -55,16 +55,19 @@ Defaulted_Non_Trivial def_non_trivial;
// to confirm that all invoked dtors have member poisoning
// instrumentation inserted.
// CHECK-LABEL: define {{.*}}SimpleD2Ev
+// CHECK-NOT: store i{{[0-9]+}} 0, {{.*}}@__msan_param_tls
// CHECK: call void @__sanitizer_dtor_callback
// CHECK-NOT: call void @__sanitizer_dtor_callback
// CHECK: ret void
// CHECK-LABEL: define {{.*}}InlinedD2Ev
+// CHECK-NOT: store i{{[0-9]+}} 0, {{.*}}@__msan_param_tls
// CHECK: call void @__sanitizer_dtor_callback
// CHECK-NOT: call void @__sanitizer_dtor_callback
// CHECK: ret void
// CHECK-LABEL: define {{.*}}Defaulted_Non_TrivialD2Ev
+// CHECK-NOT: store i{{[0-9]+}} 0, {{.*}}@__msan_param_tls
// CHECK: call void @__sanitizer_dtor_callback
// CHECK-NOT: call void @__sanitizer_dtor_callback
// CHECK: ret void
diff --git a/test/CodeGenCXX/static-init-wasm.cpp b/test/CodeGenCXX/static-init-wasm.cpp
index 289c3ea6024d..68d139157e2d 100644
--- a/test/CodeGenCXX/static-init-wasm.cpp
+++ b/test/CodeGenCXX/static-init-wasm.cpp
@@ -20,7 +20,7 @@ void g() {
// WEBASSEMBLY32: %[[R0:.+]] = load atomic i8, i8* bitcast (i32* @_ZGVZ1gvE1a to i8*) acquire, align 4
// WEBASSEMBLY32-NEXT: %[[R1:.+]] = and i8 %[[R0]], 1
// WEBASSEMBLY32-NEXT: %[[R2:.+]] = icmp eq i8 %[[R1]], 0
-// WEBASSEMBLY32-NEXT: br i1 %[[R2]], label %[[CHECK:.+]], label %[[END:.+]]
+// WEBASSEMBLY32-NEXT: br i1 %[[R2]], label %[[CHECK:.+]], label %[[END:.+]],
// WEBASSEMBLY32: [[CHECK]]
// WEBASSEMBLY32: call i32 @__cxa_guard_acquire
// WEBASSEMBLY32: [[END]]
@@ -30,7 +30,7 @@ void g() {
// WEBASSEMBLY64: %[[R0:.+]] = load atomic i8, i8* bitcast (i64* @_ZGVZ1gvE1a to i8*) acquire, align 8
// WEBASSEMBLY64-NEXT: %[[R1:.+]] = and i8 %[[R0]], 1
// WEBASSEMBLY64-NEXT: %[[R2:.+]] = icmp eq i8 %[[R1]], 0
-// WEBASSEMBLY64-NEXT: br i1 %[[R2]], label %[[CHECK:.+]], label %[[END:.+]]
+// WEBASSEMBLY64-NEXT: br i1 %[[R2]], label %[[CHECK:.+]], label %[[END:.+]],
// WEBASSEMBLY64: [[CHECK]]
// WEBASSEMBLY64: call i32 @__cxa_guard_acquire
// WEBASSEMBLY64: [[END]]
@@ -43,12 +43,12 @@ struct A {
A theA;
-// WEBASSEMBLY32: define internal void @__cxx_global_var_init() #3 section ".text.__startup" {
+// WEBASSEMBLY32: define internal void @__cxx_global_var_init() #3 {
// WEBASSEMBLY32: call %struct.A* @_ZN1AC1Ev(%struct.A* @theA)
-// WEBASSEMBLY32: define internal void @_GLOBAL__sub_I_static_init_wasm.cpp() #3 section ".text.__startup" {
+// WEBASSEMBLY32: define internal void @_GLOBAL__sub_I_static_init_wasm.cpp() #3 {
// WEBASSEMBLY32: call void @__cxx_global_var_init()
//
-// WEBASSEMBLY64: define internal void @__cxx_global_var_init() #3 section ".text.__startup" {
+// WEBASSEMBLY64: define internal void @__cxx_global_var_init() #3 {
// WEBASSEMBLY64: call %struct.A* @_ZN1AC1Ev(%struct.A* @theA)
-// WEBASSEMBLY64: define internal void @_GLOBAL__sub_I_static_init_wasm.cpp() #3 section ".text.__startup" {
+// WEBASSEMBLY64: define internal void @_GLOBAL__sub_I_static_init_wasm.cpp() #3 {
// WEBASSEMBLY64: call void @__cxx_global_var_init()
diff --git a/test/CodeGenCXX/static-initializer-branch-weights.cpp b/test/CodeGenCXX/static-initializer-branch-weights.cpp
new file mode 100644
index 000000000000..f9e77812714c
--- /dev/null
+++ b/test/CodeGenCXX/static-initializer-branch-weights.cpp
@@ -0,0 +1,126 @@
+// RUN: %clang_cc1 -emit-llvm -std=c++1z %s -o - -triple=x86_64-linux-gnu | FileCheck %s
+
+struct S { S(); ~S(); };
+
+// CHECK-LABEL: define {{.*}}global_var_init
+// CHECK-NOT: br
+// CHECK: call void @_ZN1SC1Ev({{.*}}* @global)
+S global;
+
+// CHECK-LABEL: define {{.*}}global_var_init
+// FIXME: Do we really need thread-safe initialization here? We don't run
+// global ctors on multiple threads. (If we were to do so, we'd need thread-safe
+// init for B<int>::member and B<int>::inline_member too.)
+// CHECK: load atomic i8, i8* bitcast (i64* @_ZGV13inline_global to i8*) acquire,
+// CHECK: icmp eq i8 {{.*}}, 0
+// CHECK: br i1
+// CHECK-NOT: !prof
+// CHECK: call void @_ZN1SC1Ev({{.*}}* @inline_global)
+inline S inline_global;
+
+// CHECK-LABEL: define {{.*}}global_var_init
+// CHECK-NOT: br
+// CHECK: call void @_ZN1SC1Ev({{.*}}* @thread_local_global)
+thread_local S thread_local_global;
+
+// CHECK-LABEL: define {{.*}}global_var_init
+// CHECK: load i8, i8* bitcast (i64* @_ZGV26thread_local_inline_global to i8*)
+// CHECK: icmp eq i8 {{.*}}, 0
+// CHECK: br i1
+// CHECK-NOT: !prof
+// CHECK: call void @_ZN1SC1Ev({{.*}}* @thread_local_inline_global)
+thread_local inline S thread_local_inline_global;
+
+struct A {
+ static S member;
+ static thread_local S thread_local_member;
+
+ // CHECK-LABEL: define {{.*}}global_var_init
+ // CHECK: load atomic i8, i8* bitcast (i64* @_ZGVN1A13inline_memberE to i8*) acquire,
+ // CHECK: icmp eq i8 {{.*}}, 0
+ // CHECK: br i1
+ // CHECK-NOT: !prof
+ // CHECK: call void @_ZN1SC1Ev({{.*}}* @_ZN1A13inline_memberE)
+ static inline S inline_member;
+
+ // CHECK-LABEL: define {{.*}}global_var_init
+ // CHECK: load i8, i8* bitcast (i64* @_ZGVN1A26thread_local_inline_memberE to i8*)
+ // CHECK: icmp eq i8 {{.*}}, 0
+ // CHECK: br i1
+ // CHECK-NOT: !prof
+ // CHECK: call void @_ZN1SC1Ev({{.*}}* @_ZN1A26thread_local_inline_memberE)
+ static thread_local inline S thread_local_inline_member;
+};
+
+// CHECK-LABEL: define void @_Z1fv()
+void f() {
+ // CHECK: load atomic i8, i8* bitcast (i64* @_ZGVZ1fvE12static_local to i8*) acquire,
+ // CHECK: icmp eq i8 {{.*}}, 0
+ // CHECK: br i1 {{.*}}, !prof ![[WEIGHTS_LOCAL:[0-9]*]]
+ static S static_local;
+
+ // CHECK: load i8, i8* @_ZGVZ1fvE19static_thread_local,
+ // CHECK: icmp eq i8 {{.*}}, 0
+ // CHECK: br i1 {{.*}}, !prof ![[WEIGHTS_THREAD_LOCAL:[0-9]*]]
+ static thread_local S static_thread_local;
+}
+
+// CHECK-LABEL: define {{.*}}global_var_init
+// CHECK-NOT: br
+// CHECK: call void @_ZN1SC1Ev({{.*}}* @_ZN1A6memberE)
+S A::member;
+
+// CHECK-LABEL: define {{.*}}global_var_init
+// CHECK-NOT: br
+// CHECK: call void @_ZN1SC1Ev({{.*}}* @_ZN1A19thread_local_memberE)
+thread_local S A::thread_local_member;
+
+template <typename T> struct B {
+ // CHECK-LABEL: define {{.*}}global_var_init
+ // CHECK: load i8, i8* bitcast (i64* @_ZGVN1BIiE6memberE to i8*)
+ // CHECK: icmp eq i8 {{.*}}, 0
+ // CHECK: br i1
+ // CHECK-NOT: !prof
+ // CHECK: call void @_ZN1SC1Ev({{.*}}* @_ZN1BIiE6memberE)
+ static S member;
+
+ // CHECK-LABEL: define {{.*}}global_var_init
+ // CHECK: load i8, i8* bitcast (i64* @_ZGVN1BIiE13inline_memberE to i8*)
+ // CHECK: icmp eq i8 {{.*}}, 0
+ // CHECK: br i1
+ // CHECK-NOT: !prof
+ // CHECK: call void @_ZN1SC1Ev({{.*}}* @_ZN1BIiE13inline_memberE)
+ static inline S inline_member;
+
+ // CHECK-LABEL: define {{.*}}global_var_init
+ // CHECK: load i8, i8* bitcast (i64* @_ZGVN1BIiE19thread_local_memberE to i8*)
+ // CHECK: icmp eq i8 {{.*}}, 0
+ // CHECK: br i1
+ // CHECK-NOT: !prof
+ // CHECK: call void @_ZN1SC1Ev({{.*}}* @_ZN1BIiE19thread_local_memberE)
+ static thread_local S thread_local_member;
+
+ // CHECK-LABEL: define {{.*}}global_var_init
+ // CHECK: load i8, i8* bitcast (i64* @_ZGVN1BIiE26thread_local_inline_memberE to i8*)
+ // CHECK: icmp eq i8 {{.*}}, 0
+ // CHECK: br i1
+ // CHECK-NOT: !prof
+ // CHECK: call void @_ZN1SC1Ev({{.*}}* @_ZN1BIiE26thread_local_inline_memberE)
+ static thread_local inline S thread_local_inline_member;
+};
+template<typename T> S B<T>::member;
+template<typename T> thread_local S B<T>::thread_local_member;
+
+template<typename ...T> void use(T &...);
+void use_b() {
+ use(B<int>::member, B<int>::inline_member, B<int>::thread_local_member,
+ B<int>::thread_local_inline_member);
+}
+
+// CHECK-LABEL: define {{.*}}tls_init()
+// CHECK: load i8, i8* @__tls_guard, align 1
+// CHECK: icmp eq i8 {{.*}}, 0
+// CHECK: br i1 {{.*}}, !prof ![[WEIGHTS_THREAD_LOCAL]]
+
+// CHECK-DAG: ![[WEIGHTS_THREAD_LOCAL]] = !{!"branch_weights", i32 1, i32 1023}
+// CHECK-DAG: ![[WEIGHTS_LOCAL]] = !{!"branch_weights", i32 1, i32 1048575}
diff --git a/test/CodeGenCXX/stmtexpr.cpp b/test/CodeGenCXX/stmtexpr.cpp
index 5bd9908d6c25..4586a3c38fff 100644
--- a/test/CodeGenCXX/stmtexpr.cpp
+++ b/test/CodeGenCXX/stmtexpr.cpp
@@ -173,7 +173,7 @@ extern "C" int cleanup_exit_lvalue_local(bool cond) {
_Complex float bar_complex(A, int);
extern "C" int cleanup_exit_complex(bool b) {
_Complex float v = bar_complex(A(1), ({ if (b) return 42; 13; }));
- return v;
+ return (float)v;
}
// CHECK-LABEL: define{{.*}} i32 @cleanup_exit_complex({{.*}})
diff --git a/test/CodeGenCXX/strict-vtable-pointers.cpp b/test/CodeGenCXX/strict-vtable-pointers.cpp
index c3798920abdd..c45e7a60fa8f 100644
--- a/test/CodeGenCXX/strict-vtable-pointers.cpp
+++ b/test/CodeGenCXX/strict-vtable-pointers.cpp
@@ -53,7 +53,7 @@ struct DynamicFrom2Virtuals :
};
// CHECK-NEW-LABEL: define void @_Z12LocalObjectsv()
-// CHECK-NEW-NOT: @llvm.invariant.group.barrier(
+// CHECK-NEW-NOT: @llvm.invariant.group.barrier.p0i8(
// CHECK-NEW-LABEL: {{^}}}
void LocalObjects() {
DynamicBase1 DB;
@@ -81,20 +81,20 @@ void LocalObjects() {
struct DynamicFromVirtualStatic1;
// CHECK-CTORS-LABEL: define linkonce_odr void @_ZN25DynamicFromVirtualStatic1C1Ev
-// CHECK-CTORS-NOT: @llvm.invariant.group.barrier(
+// CHECK-CTORS-NOT: @llvm.invariant.group.barrier.p0i8(
// CHECK-CTORS-LABEL: {{^}}}
struct DynamicFrom2Virtuals;
// CHECK-CTORS-LABEL: define linkonce_odr void @_ZN20DynamicFrom2VirtualsC1Ev
-// CHECK-CTORS: call i8* @llvm.invariant.group.barrier(
+// CHECK-CTORS: call i8* @llvm.invariant.group.barrier.p0i8(
// CHECK-CTORS-LABEL: {{^}}}
// CHECK-NEW-LABEL: define void @_Z9Pointers1v()
-// CHECK-NEW-NOT: @llvm.invariant.group.barrier(
+// CHECK-NEW-NOT: @llvm.invariant.group.barrier.p0i8(
// CHECK-NEW-LABEL: call void @_ZN12DynamicBase1C1Ev(
-// CHECK-NEW: %[[THIS3:.*]] = call i8* @llvm.invariant.group.barrier(i8* %[[THIS2:.*]])
+// CHECK-NEW: %[[THIS3:.*]] = call i8* @llvm.invariant.group.barrier.p0i8(i8* %[[THIS2:.*]])
// CHECK-NEW: %[[THIS4:.*]] = bitcast i8* %[[THIS3]] to %[[DynamicDerived:.*]]*
// CHECK-NEW: call void @_ZN14DynamicDerivedC1Ev(%[[DynamicDerived:.*]]* %[[THIS4]])
// CHECK-NEW-LABEL: {{^}}}
@@ -109,9 +109,9 @@ void Pointers1() {
// CHECK-NEW-LABEL: define void @_Z14HackingObjectsv()
// CHECK-NEW: call void @_ZN12DynamicBase1C1Ev
-// CHECK-NEW: call i8* @llvm.invariant.group.barrier(
+// CHECK-NEW: call i8* @llvm.invariant.group.barrier.p0i8(
// CHECK-NEW: call void @_ZN14DynamicDerivedC1Ev(
-// CHECK-NEW: call i8* @llvm.invariant.group.barrier(
+// CHECK-NEW: call i8* @llvm.invariant.group.barrier.p0i8(
// CHECK-NEW: call void @_ZN12DynamicBase1C1Ev(
// CHECK-NEW-LABEL: {{^}}}
void HackingObjects() {
@@ -131,7 +131,7 @@ void HackingObjects() {
/*** Testing Constructors ***/
struct DynamicBase1;
// CHECK-CTORS-LABEL: define linkonce_odr void @_ZN12DynamicBase1C2Ev(
-// CHECK-CTORS-NOT: call i8* @llvm.invariant.group.barrier(
+// CHECK-CTORS-NOT: call i8* @llvm.invariant.group.barrier.p0i8(
// CHECK-CTORS-LABEL: {{^}}}
@@ -140,7 +140,7 @@ struct DynamicDerived;
// CHECK-CTORS-LABEL: define linkonce_odr void @_ZN14DynamicDerivedC2Ev(
// CHECK-CTORS: %[[THIS0:.*]] = load %[[DynamicDerived:.*]]*, %[[DynamicDerived]]** {{.*}}
// CHECK-CTORS: %[[THIS1:.*]] = bitcast %[[DynamicDerived:.*]]* %[[THIS0]] to i8*
-// CHECK-CTORS: %[[THIS2:.*]] = call i8* @llvm.invariant.group.barrier(i8* %[[THIS1:.*]])
+// CHECK-CTORS: %[[THIS2:.*]] = call i8* @llvm.invariant.group.barrier.p0i8(i8* %[[THIS1:.*]])
// CHECK-CTORS: %[[THIS3:.*]] = bitcast i8* %[[THIS2]] to %[[DynamicDerived]]*
// CHECK-CTORS: %[[THIS4:.*]] = bitcast %[[DynamicDerived]]* %[[THIS3]] to %[[DynamicBase:.*]]*
// CHECK-CTORS: call void @_ZN12DynamicBase1C2Ev(%[[DynamicBase]]* %[[THIS4]])
@@ -154,15 +154,15 @@ struct DynamicDerivedMultiple;
// CHECK-CTORS: %[[THIS0:.*]] = load %[[CLASS:.*]]*, %[[CLASS]]** {{.*}}
// CHECK-CTORS: %[[THIS1:.*]] = bitcast %[[CLASS:.*]]* %[[THIS0]] to i8*
-// CHECK-CTORS: %[[THIS2:.*]] = call i8* @llvm.invariant.group.barrier(i8* %[[THIS1]])
+// CHECK-CTORS: %[[THIS2:.*]] = call i8* @llvm.invariant.group.barrier.p0i8(i8* %[[THIS1]])
// CHECK-CTORS: %[[THIS3:.*]] = bitcast i8* %[[THIS2]] to %[[CLASS]]*
// CHECK-CTORS: %[[THIS4:.*]] = bitcast %[[CLASS]]* %[[THIS3]] to %[[BASE_CLASS:.*]]*
// CHECK-CTORS: call void @_ZN12DynamicBase1C2Ev(%[[BASE_CLASS]]* %[[THIS4]])
-// CHECK-CTORS: call i8* @llvm.invariant.group.barrier(
+// CHECK-CTORS: call i8* @llvm.invariant.group.barrier.p0i8(
// CHECK-CTORS: call void @_ZN12DynamicBase2C2Ev(
-// CHECK-CTORS-NOT: @llvm.invariant.group.barrier
+// CHECK-CTORS-NOT: @llvm.invariant.group.barrier.p0i8
// CHECK-CTORS: %[[THIS10:.*]] = bitcast %struct.DynamicDerivedMultiple* %[[THIS0]] to i32 (...)***
@@ -177,7 +177,7 @@ struct DynamicDerivedMultiple;
struct DynamicFromStatic;
// CHECK-CTORS-LABEL: define linkonce_odr void @_ZN17DynamicFromStaticC2Ev(
-// CHECK-CTORS-NOT: @llvm.invariant.group.barrier(
+// CHECK-CTORS-NOT: @llvm.invariant.group.barrier.p0i8(
// CHECK-CTORS-LABEL: {{^}}}
struct A {
@@ -206,15 +206,15 @@ void g2(A *a) {
void UnionsBarriers(U *u) {
// CHECK-NEW: call void @_Z9changeToBP1U(
changeToB(u);
- // CHECK-NEW: call i8* @llvm.invariant.group.barrier(i8*
+ // CHECK-NEW: call i8* @llvm.invariant.group.barrier.p0i8(i8*
// CHECK-NEW: call void @_Z2g2P1A(%struct.A*
g2(&u->b);
// CHECK-NEW: call void @_Z9changeToAP1U(%union.U*
changeToA(u);
- // CHECK-NEW: call i8* @llvm.invariant.group.barrier(i8*
+ // CHECK-NEW: call i8* @llvm.invariant.group.barrier.p0i8(i8*
// call void @_Z2g2P1A(%struct.A* %a)
g2(&u->a);
- // CHECK-NEW-NOT: call i8* @llvm.invariant.group.barrier(i8*
+ // CHECK-NEW-NOT: call i8* @llvm.invariant.group.barrier.p0i8(i8*
}
struct HoldingVirtuals {
@@ -233,10 +233,10 @@ void take(AnotherEmpty &);
// CHECK-NEW-LABEL: noBarriers
void noBarriers(NoVptrs &noVptrs) {
- // CHECK-NEW-NOT: call i8* @llvm.invariant.group.barrier(i8*
+ // CHECK-NEW-NOT: call i8* @llvm.invariant.group.barrier.p0i8(i8*
// CHECK-NEW: 42
noVptrs.a += 42;
- // CHECK-NEW-NOT: call i8* @llvm.invariant.group.barrier(i8*
+ // CHECK-NEW-NOT: call i8* @llvm.invariant.group.barrier.p0i8(i8*
// CHECK-NEW: call void @_Z4takeR12AnotherEmpty(
take(noVptrs.empty);
}
@@ -249,10 +249,10 @@ void take(HoldingVirtuals &);
// CHECK-NEW-LABEL: define void @_Z15UnionsBarriers2R2U2
void UnionsBarriers2(U2 &u) {
- // CHECK-NEW-NOT: call i8* @llvm.invariant.group.barrier(i8*
+ // CHECK-NEW-NOT: call i8* @llvm.invariant.group.barrier.p0i8(i8*
// CHECK-NEW: 42
u.z += 42;
- // CHECK-NEW: call i8* @llvm.invariant.group.barrier(i8*
+ // CHECK-NEW: call i8* @llvm.invariant.group.barrier.p0i8(i8*
// CHECK-NEW: call void @_Z4takeR15HoldingVirtuals(
take(u.h);
}
@@ -279,24 +279,24 @@ void take(VirtualInVBase &);
void take(VirtualInheritance &);
void UnionsBarrier3(U3 &u) {
- // CHECK-NEW-NOT: call i8* @llvm.invariant.group.barrier(i8*
+ // CHECK-NEW-NOT: call i8* @llvm.invariant.group.barrier.p0i8(i8*
// CHECK-NEW: 42
u.z += 42;
- // CHECK-NEW: call i8* @llvm.invariant.group.barrier(i8*
+ // CHECK-NEW: call i8* @llvm.invariant.group.barrier.p0i8(i8*
// CHECK-NEW: call void @_Z4takeR13VirtualInBase(
take(u.v1);
- // CHECK-NEW: call i8* @llvm.invariant.group.barrier(i8*
+ // CHECK-NEW: call i8* @llvm.invariant.group.barrier.p0i8(i8*
// CHECK-NEW: call void @_Z4takeR13VirtualInBase(
take(u.v2);
- // CHECK-NEW: call i8* @llvm.invariant.group.barrier(i8*
+ // CHECK-NEW: call i8* @llvm.invariant.group.barrier.p0i8(i8*
// CHECK-NEW: call void @_Z4takeR18VirtualInheritance(
take(u.v3);
}
/** DTORS **/
// CHECK-DTORS-LABEL: define linkonce_odr void @_ZN10StaticBaseD2Ev(
-// CHECK-DTORS-NOT: call i8* @llvm.invariant.group.barrier(
+// CHECK-DTORS-NOT: call i8* @llvm.invariant.group.barrier.p0i8(
// CHECK-DTORS-LABEL: {{^}}}
@@ -305,22 +305,22 @@ void UnionsBarrier3(U3 &u) {
// CHECK-DTORS-LABEL: {{^}}}
// CHECK-DTORS-LABEL: define linkonce_odr void @_ZN17DynamicFromStaticD2Ev
-// CHECK-DTORS-NOT: call i8* @llvm.invariant.group.barrier(
+// CHECK-DTORS-NOT: call i8* @llvm.invariant.group.barrier.p0i8(
// CHECK-DTORS-LABEL: {{^}}}
// CHECK-DTORS-LABEL: define linkonce_odr void @_ZN22DynamicDerivedMultipleD2Ev(
// CHECK-DTORS-LABEL: define linkonce_odr void @_ZN12DynamicBase2D2Ev(
-// CHECK-DTORS: call i8* @llvm.invariant.group.barrier(
+// CHECK-DTORS: call i8* @llvm.invariant.group.barrier.p0i8(
// CHECK-DTORS-LABEL: {{^}}}
// CHECK-DTORS-LABEL: define linkonce_odr void @_ZN12DynamicBase1D2Ev
-// CHECK-DTORS: call i8* @llvm.invariant.group.barrier(
+// CHECK-DTORS: call i8* @llvm.invariant.group.barrier.p0i8(
// CHECK-DTORS-LABEL: {{^}}}
// CHECK-DTORS-LABEL: define linkonce_odr void @_ZN14DynamicDerivedD2Ev
-// CHECK-DTORS-NOT: call i8* @llvm.invariant.group.barrier(
+// CHECK-DTORS-NOT: call i8* @llvm.invariant.group.barrier.p0i8(
// CHECK-DTORS-LABEL: {{^}}}
diff --git a/test/CodeGenCXX/tmp-md-nodes1.cpp b/test/CodeGenCXX/tmp-md-nodes1.cpp
new file mode 100644
index 000000000000..41a0159b0fc4
--- /dev/null
+++ b/test/CodeGenCXX/tmp-md-nodes1.cpp
@@ -0,0 +1,18 @@
+// REQUIRES: asserts
+// RUN: %clang_cc1 -O0 -triple %itanium_abi_triple -debug-info-kind=limited -S -emit-llvm %s -o - | \
+// RUN: FileCheck %s
+
+// This test simply checks that the varargs thunk is created. The failing test
+// case asserts.
+
+struct Alpha {
+ virtual void bravo(...);
+};
+struct Charlie {
+ virtual ~Charlie() {}
+};
+struct CharlieImpl : Charlie, Alpha {
+ void bravo(...) {}
+} delta;
+
+// CHECK: define {{.*}} void @_ZThn{{[48]}}_N11CharlieImpl5bravoEz(
diff --git a/test/CodeGenCXX/tmp-md-nodes2.cpp b/test/CodeGenCXX/tmp-md-nodes2.cpp
new file mode 100644
index 000000000000..e50220cfb7c3
--- /dev/null
+++ b/test/CodeGenCXX/tmp-md-nodes2.cpp
@@ -0,0 +1,33 @@
+// REQUIRES: asserts
+// RUN: %clang_cc1 -O0 -triple %itanium_abi_triple -debug-info-kind=limited -S -emit-llvm %s -o - | \
+// RUN: FileCheck %s
+
+// This test simply checks that the varargs thunk is created. The failing test
+// case asserts.
+
+typedef signed char __int8_t;
+typedef int BOOL;
+class CMsgAgent;
+
+class CFs {
+public:
+ typedef enum {} CACHE_HINT;
+ virtual BOOL ReqCacheHint( CMsgAgent* p_ma, CACHE_HINT hint, ... ) ;
+};
+
+typedef struct {} _Lldiv_t;
+
+class CBdVfs {
+public:
+ virtual ~CBdVfs( ) {}
+};
+
+class CBdVfsImpl : public CBdVfs, public CFs {
+ BOOL ReqCacheHint( CMsgAgent* p_ma, CACHE_HINT hint, ... );
+};
+
+BOOL CBdVfsImpl::ReqCacheHint( CMsgAgent* p_ma, CACHE_HINT hint, ... ) {
+ return true;
+}
+
+// CHECK: define {{.*}} @_ZThn{{[48]}}_N10CBdVfsImpl12ReqCacheHintEP9CMsgAgentN3CFs10CACHE_HINTEz(
diff --git a/test/CodeGenCXX/ubsan-devirtualized-calls.cpp b/test/CodeGenCXX/ubsan-devirtualized-calls.cpp
index bc8861aa8314..f4ccdbf6474a 100644
--- a/test/CodeGenCXX/ubsan-devirtualized-calls.cpp
+++ b/test/CodeGenCXX/ubsan-devirtualized-calls.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -emit-llvm -fsanitize=vptr %s -o - | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -emit-llvm -fsanitize=null,vptr %s -o - | FileCheck %s
struct Base1 {
virtual void f1() {}
@@ -64,6 +64,11 @@ void t4() {
// CHECK-NEXT: call void @__ubsan_handle_dynamic_type_cache{{[_a-z]*}}({{.*}} [[UBSAN_TI_DERIVED3]] {{.*}}, i{{[0-9]+}} %[[P1]]
static_cast<Base1 *>(badp)->f1(); //< No devirt, test 'badp isa Base1'.
+ // We were able to skip the null check on the first type check because 'p'
+ // is backed by an alloca. We can't skip the second null check because 'badp'
+ // is a (bitcast (load ...)).
+ // CHECK: call void @__ubsan_handle_type_mismatch
+ //
// CHECK: %[[BADP1:[0-9]+]] = ptrtoint %struct.Base1* {{%[0-9]+}} to i{{[0-9]+}}, !nosanitize
// CHECK-NEXT: call void @__ubsan_handle_dynamic_type_cache{{[_a-z]*}}({{.*}} [[UBSAN_TI_BASE1]] {{.*}}, i{{[0-9]+}} %[[BADP1]]
}
@@ -76,6 +81,8 @@ void t5() {
// CHECK-NEXT: call void @__ubsan_handle_dynamic_type_cache{{[_a-z]*}}({{.*}} [[UBSAN_TI_DERIVED4_1]] {{.*}}, i{{[0-9]+}} %[[P1]]
static_cast<Base1 *>(badp)->f1(); //< Devirt Base1::f1 to Derived4::f1.
+ // CHECK: call void @__ubsan_handle_type_mismatch
+ //
// CHECK: %[[BADP1:[0-9]+]] = ptrtoint %struct.Derived4* {{%[0-9]+}} to i{{[0-9]+}}, !nosanitize
// CHECK-NEXT: call void @__ubsan_handle_dynamic_type_cache{{[_a-z]*}}({{.*}} [[UBSAN_TI_DERIVED4_2]] {{.*}}, i{{[0-9]+}} %[[BADP1]]
}
diff --git a/test/CodeGenCXX/ubsan-suppress-checks.cpp b/test/CodeGenCXX/ubsan-suppress-checks.cpp
index ae7c94b34f29..fa7ea29d94f2 100644
--- a/test/CodeGenCXX/ubsan-suppress-checks.cpp
+++ b/test/CodeGenCXX/ubsan-suppress-checks.cpp
@@ -17,6 +17,17 @@ void load_non_null_pointers() {
// CHECK: ret void
}
+// CHECK-LABEL: define void @_Z31use_us16_aligned_array_elementsv
+void use_us16_aligned_array_elements() {
+ static const unsigned short Arr[] = {0, 1, 2};
+ auto use_array = [](const unsigned short(&X)[3]) -> void {};
+ use_array(Arr);
+
+ // CHECK-NOT: br i1 true
+ // ALIGN-NOT: call void @__ubsan_handle_type_mismatch
+ // CHECK: ret void
+}
+
struct A {
int foo;
@@ -229,4 +240,5 @@ void force_irgen() {
d->load_member_3();
load_non_null_pointers();
+ use_us16_aligned_array_elements();
}
diff --git a/test/CodeGenCXX/ubsan-type-checks.cpp b/test/CodeGenCXX/ubsan-type-checks.cpp
index 786d049dfb56..e53ab2466e73 100644
--- a/test/CodeGenCXX/ubsan-type-checks.cpp
+++ b/test/CodeGenCXX/ubsan-type-checks.cpp
@@ -1,6 +1,8 @@
// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=alignment | FileCheck %s -check-prefixes=ALIGN,COMMON
// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=null | FileCheck %s -check-prefixes=NULL,COMMON
// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=object-size | FileCheck %s -check-prefixes=OBJSIZE,COMMON
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=null,vptr | FileCheck %s -check-prefixes=VPTR
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=vptr | FileCheck %s -check-prefixes=VPTR_NO_NULL
struct A {
// COMMON-LABEL: define linkonce_odr void @_ZN1A10do_nothingEv
@@ -24,13 +26,60 @@ struct B {
// NULL: icmp ne %struct.B* %{{.*}}, null, !nosanitize
// OBJSIZE-NOT: call i64 @llvm.objectsize
+ // OBJSIZE: ret void
}
};
-void force_irgen() {
+struct Animal {
+ virtual const char *speak() = 0;
+};
+
+struct Cat : Animal {
+ const char *speak() override { return "meow"; }
+};
+
+struct Dog : Animal {
+ const char *speak() override { return "woof"; }
+};
+
+// VPTR-LABEL: define void @_Z12invalid_castP3Cat
+void invalid_cast(Cat *cat = nullptr) {
+ // If -fsanitize=null is available, we'll reuse its check:
+ //
+ // VPTR: [[ICMP:%.*]] = icmp ne %struct.Dog* {{.*}}, null
+ // VPTR-NEXT: br i1 [[ICMP]]
+ // VPTR: call void @__ubsan_handle_type_mismatch
+ // VPTR-NOT: icmp ne %struct.Dog* {{.*}}, null
+ // VPTR: br i1 [[ICMP]]
+ // VPTR: call void @__ubsan_handle_dynamic_type_cache_miss
+ //
+ // Fall back to the vptr sanitizer's null check when -fsanitize=null isn't
+ // available.
+ //
+ // VPTR_NO_NULL-NOT: call void @__ubsan_handle_type_mismatch
+ // VPTR_NO_NULL: [[ICMP:%.*]] = icmp ne %struct.Dog* {{.*}}, null
+ // VPTR_NO_NULL-NEXT: br i1 [[ICMP]]
+ // VPTR_NO_NULL: call void @__ubsan_handle_dynamic_type_cache_miss
+ auto *badDog = reinterpret_cast<Dog *>(cat);
+ badDog->speak();
+}
+
+// VPTR_NO_NULL-LABEL: define void @_Z13invalid_cast2v
+void invalid_cast2() {
+ // We've got a pointer to an alloca, so there's no run-time null check needed.
+ // VPTR_NO_NULL-NOT: call void @__ubsan_handle_type_mismatch
+ // VPTR_NO_NULL: call void @__ubsan_handle_dynamic_type_cache_miss
+ Cat cat;
+ cat.speak();
+}
+
+int main() {
A a;
a.do_nothing();
B b;
b.do_nothing();
+
+ invalid_cast();
+ return 0;
}
diff --git a/test/CodeGenCXX/ubsan-vtable-checks.cpp b/test/CodeGenCXX/ubsan-vtable-checks.cpp
index e684ae9180f1..5e17913a2c89 100644
--- a/test/CodeGenCXX/ubsan-vtable-checks.cpp
+++ b/test/CodeGenCXX/ubsan-vtable-checks.cpp
@@ -1,7 +1,7 @@
// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-linux -emit-llvm -fsanitize=null %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NULL --check-prefix=ITANIUM
// RUN: %clang_cc1 -std=c++11 -triple x86_64-windows -emit-llvm -fsanitize=null %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NULL --check-prefix=MSABI
-// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-linux -emit-llvm -fsanitize=vptr %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-VPTR --check-prefix=ITANIUM
-// RUN: %clang_cc1 -std=c++11 -triple x86_64-windows -emit-llvm -fsanitize=vptr %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-VPTR --check-prefix=MSABI
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-linux -emit-llvm -fsanitize=null,vptr %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-VPTR --check-prefix=ITANIUM
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-windows -emit-llvm -fsanitize=null,vptr %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-VPTR --check-prefix=MSABI
struct T {
virtual ~T() {}
virtual int v() { return 1; }
diff --git a/test/CodeGenCXX/virt-dtor-key.cpp b/test/CodeGenCXX/virt-dtor-key.cpp
index 40c5a537cc53..d1055d4e30ca 100644
--- a/test/CodeGenCXX/virt-dtor-key.cpp
+++ b/test/CodeGenCXX/virt-dtor-key.cpp
@@ -1,5 +1,7 @@
-// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple i386-linux -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple i386-windows-gnu -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-MINGW
// CHECK: @_ZTI3foo = constant
+// CHECK-MINGW: @_ZTI3foo = linkonce_odr
class foo {
foo();
virtual ~foo();
diff --git a/test/CodeGenCXX/visibility-inlines-hidden.cpp b/test/CodeGenCXX/visibility-inlines-hidden.cpp
index 6ea234807ec2..20e4a1f45e3c 100644
--- a/test/CodeGenCXX/visibility-inlines-hidden.cpp
+++ b/test/CodeGenCXX/visibility-inlines-hidden.cpp
@@ -162,3 +162,16 @@ namespace test6 {
C::g();
}
}
+
+namespace PR34811 {
+ template <typename T> void tf() {}
+
+ // CHECK-LABEL: define linkonce_odr hidden i8* @_ZN7PR348111fEv(
+ inline void *f() {
+ auto l = []() {};
+ // CHECK-LABEL: define linkonce_odr hidden void @_ZN7PR348112tfIZNS_1fEvEUlvE_EEvv(
+ return (void *)&tf<decltype(l)>;
+ }
+
+ void *p = (void *)f;
+}
diff --git a/test/CodeGenCXX/vla.cpp b/test/CodeGenCXX/vla.cpp
index 957a9f9568b3..b8652f8329a5 100644
--- a/test/CodeGenCXX/vla.cpp
+++ b/test/CodeGenCXX/vla.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin %s -emit-llvm -o - | FileCheck -check-prefixes=X64,CHECK %s
+// RUN: %clang_cc1 -std=c++11 -triple amdgcn---amdgiz %s -emit-llvm -o - | FileCheck -check-prefixes=AMD,CHECK %s
template<typename T>
struct S {
@@ -9,7 +10,7 @@ template<typename T> int S<T>::n = 5;
int f() {
// Make sure that the reference here is enough to trigger the instantiation of
// the static data member.
- // CHECK: @_ZN1SIiE1nE = linkonce_odr global i32 5
+ // CHECK: @_ZN1SIiE1nE = linkonce_odr{{.*}} global i32 5
int a[S<int>::n];
return sizeof a;
}
@@ -17,10 +18,18 @@ int f() {
// rdar://problem/9506377
void test0(void *array, int n) {
// CHECK-LABEL: define void @_Z5test0Pvi(
- // CHECK: [[ARRAY:%.*]] = alloca i8*, align 8
- // CHECK-NEXT: [[N:%.*]] = alloca i32, align 4
- // CHECK-NEXT: [[REF:%.*]] = alloca i16*, align 8
- // CHECK-NEXT: [[S:%.*]] = alloca i16, align 2
+ // X64: [[ARRAY:%.*]] = alloca i8*, align 8
+ // AMD: [[ARRAY0:%.*]] = alloca i8*, align 8, addrspace(5)
+ // AMD-NEXT: [[ARRAY:%.*]] = addrspacecast i8* addrspace(5)* [[ARRAY0]] to i8**
+ // X64-NEXT: [[N:%.*]] = alloca i32, align 4
+ // AMD: [[N0:%.*]] = alloca i32, align 4, addrspace(5)
+ // AMD-NEXT: [[N:%.*]] = addrspacecast i32 addrspace(5)* [[N0]] to i32*
+ // X64-NEXT: [[REF:%.*]] = alloca i16*, align 8
+ // AMD: [[REF0:%.*]] = alloca i16*, align 8, addrspace(5)
+ // AMD-NEXT: [[REF:%.*]] = addrspacecast i16* addrspace(5)* [[REF0]] to i16**
+ // X64-NEXT: [[S:%.*]] = alloca i16, align 2
+ // AMD: [[S0:%.*]] = alloca i16, align 2, addrspace(5)
+ // AMD-NEXT: [[S:%.*]] = addrspacecast i16 addrspace(5)* [[S0]] to i16*
// CHECK-NEXT: store i8*
// CHECK-NEXT: store i32
@@ -59,6 +68,8 @@ void test0(void *array, int n) {
void test2(int b) {
// CHECK-LABEL: define void {{.*}}test2{{.*}}(i32 %b)
int varr[b];
+ // AMD: %__end = alloca i32*, align 8, addrspace(5)
+ // AMD: [[END:%.*]] = addrspacecast i32* addrspace(5)* %__end to i32**
// get the address of %b by checking the first store that stores it
//CHECK: store i32 %b, i32* [[PTR_B:%.*]]
@@ -75,13 +86,16 @@ void test2(int b) {
//CHECK: [[VLA_SIZEOF:%.*]] = mul nuw i64 4, [[VLA_NUM_ELEMENTS_PRE]]
//CHECK-NEXT: [[VLA_NUM_ELEMENTS_POST:%.*]] = udiv i64 [[VLA_SIZEOF]], 4
//CHECK-NEXT: [[VLA_END_PTR:%.*]] = getelementptr inbounds i32, i32* {{%.*}}, i64 [[VLA_NUM_ELEMENTS_POST]]
- //CHECK-NEXT: store i32* [[VLA_END_PTR]], i32** %__end
+ //X64-NEXT: store i32* [[VLA_END_PTR]], i32** %__end
+ //AMD-NEXT: store i32* [[VLA_END_PTR]], i32** [[END]]
for (int d : varr) 0;
}
void test3(int b, int c) {
// CHECK-LABEL: define void {{.*}}test3{{.*}}(i32 %b, i32 %c)
int varr[b][c];
+ // AMD: %__end = alloca i32*, align 8, addrspace(5)
+ // AMD: [[END:%.*]] = addrspacecast i32* addrspace(5)* %__end to i32**
// get the address of %b by checking the first store that stores it
//CHECK: store i32 %b, i32* [[PTR_B:%.*]]
//CHECK-NEXT: store i32 %c, i32* [[PTR_C:%.*]]
@@ -105,7 +119,8 @@ void test3(int b, int c) {
//CHECK-NEXT: [[VLA_NUM_ELEMENTS:%.*]] = udiv i64 [[VLA_SIZEOF]], [[VLA_SIZEOF_DIM2]]
//CHECK-NEXT: [[VLA_END_INDEX:%.*]] = mul nsw i64 [[VLA_NUM_ELEMENTS]], [[VLA_DIM2_PRE]]
//CHECK-NEXT: [[VLA_END_PTR:%.*]] = getelementptr inbounds i32, i32* {{%.*}}, i64 [[VLA_END_INDEX]]
- //CHECK-NEXT: store i32* [[VLA_END_PTR]], i32** %__end
+ //X64-NEXT: store i32* [[VLA_END_PTR]], i32** %__end
+ //AMD-NEXT: store i32* [[VLA_END_PTR]], i32** [[END]]
for (auto &d : varr) 0;
}
diff --git a/test/CodeGenCXX/vtable-available-externally.cpp b/test/CodeGenCXX/vtable-available-externally.cpp
index 2e2cdbbfeff5..0e7e8b4a3226 100644
--- a/test/CodeGenCXX/vtable-available-externally.cpp
+++ b/test/CodeGenCXX/vtable-available-externally.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -emit-llvm -o %t
-// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -O2 -disable-llvm-passes -emit-llvm -o %t.opt
+// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -std=c++98 -emit-llvm -o %t
+// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -std=c++98 -O2 -disable-llvm-passes -emit-llvm -o %t.opt
// RUN: FileCheck --check-prefix=CHECK-TEST1 %s < %t
// RUN: FileCheck --check-prefix=CHECK-TEST2 %s < %t
// RUN: FileCheck --check-prefix=CHECK-TEST5 %s < %t
diff --git a/test/CodeGenCXX/warn-padded-packed.cpp b/test/CodeGenCXX/warn-padded-packed.cpp
index f2af60865e05..2cb049537348 100644
--- a/test/CodeGenCXX/warn-padded-packed.cpp
+++ b/test/CodeGenCXX/warn-padded-packed.cpp
@@ -17,7 +17,7 @@ struct S3 {
} __attribute__((packed));
struct S4 {
- int i; // expected-warning {{packed attribute is unnecessary for 'i'}}
+ int i;
char c;
} __attribute__((packed));
@@ -46,18 +46,18 @@ struct S8 : B {
int i; // expected-warning {{padding struct 'S8' with 3 bytes to align 'i'}}
};
-struct S9 { // expected-warning {{packed attribute is unnecessary for 'S9'}}
- int x; // expected-warning {{packed attribute is unnecessary for 'x'}}
- int y; // expected-warning {{packed attribute is unnecessary for 'y'}}
+struct S9 {
+ int x;
+ int y;
} __attribute__((packed));
-struct S10 { // expected-warning {{packed attribute is unnecessary for 'S10'}}
- int x; // expected-warning {{packed attribute is unnecessary for 'x'}}
+struct S10 {
+ int x;
char a,b,c,d;
} __attribute__((packed));
-struct S11 {
+struct S11 { // expected-warning {{packed attribute is unnecessary for 'S11'}}
bool x;
char a,b,c,d;
} __attribute__((packed));
@@ -72,5 +72,82 @@ struct S13 { // expected-warning {{padding size of 'S13' with 6 bits to alignmen
bool b : 10;
};
+struct S14 { // expected-warning {{packed attribute is unnecessary for 'S14'}}
+ char a,b,c,d;
+} __attribute__((packed));
+
+struct S15 { // expected-warning {{packed attribute is unnecessary for 'S15'}}
+ struct S14 s;
+ char a;
+} __attribute__((packed));
+
+struct S16 { // expected-warning {{padding size of 'S16' with 2 bytes to alignment boundary}} expected-warning {{packed attribute is unnecessary for 'S16'}}
+ char a,b;
+} __attribute__((packed, aligned(4)));
+
+struct S17 {
+ struct S16 s;
+ char a,b;
+} __attribute__((packed, aligned(2)));
+
+struct S18 { // expected-warning {{padding size of 'S18' with 2 bytes to alignment boundary}} expected-warning {{packed attribute is unnecessary for 'S18'}}
+ struct S16 s;
+ char a,b;
+} __attribute__((packed, aligned(4)));
+
+struct S19 { // expected-warning {{packed attribute is unnecessary for 'S19'}}
+ bool b;
+ char a;
+} __attribute__((packed, aligned(1)));
+
+struct S20 {
+ int i;
+ char a;
+} __attribute__((packed, aligned(1)));
+
+struct S21 { // expected-warning {{padding size of 'S21' with 4 bits to alignment boundary}}
+ unsigned char a : 6;
+ unsigned char b : 6;
+} __attribute__((packed, aligned(1)));
+
+struct S22 { // expected-warning {{packed attribute is unnecessary for 'S22'}}
+ unsigned char a : 4;
+ unsigned char b : 4;
+} __attribute__((packed));
+
+struct S23 { // expected-warning {{padding size of 'S23' with 4 bits to alignment boundary}} expected-warning {{packed attribute is unnecessary for 'S23'}}
+ unsigned char a : 2;
+ unsigned char b : 2;
+} __attribute__((packed));
+
+struct S24 {
+ unsigned char a : 6;
+ unsigned char b : 6;
+ unsigned char c : 6;
+ unsigned char d : 6;
+ unsigned char e : 6;
+ unsigned char f : 6;
+ unsigned char g : 6;
+ unsigned char h : 6;
+} __attribute__((packed));
+
+struct S25 { // expected-warning {{padding size of 'S25' with 7 bits to alignment boundary}} expected-warning {{packed attribute is unnecessary for 'S25'}}
+ unsigned char a;
+ unsigned char b : 1;
+} __attribute__((packed));
+
+struct S26 { // expected-warning {{packed attribute is unnecessary for 'S26'}}
+ unsigned char a : 1;
+ unsigned char b; //expected-warning {{padding struct 'S26' with 7 bits to align 'b'}}
+} __attribute__((packed));
+
+struct S27 { // expected-warning {{padding size of 'S27' with 7 bits to alignment boundary}}
+ unsigned char a : 1;
+ unsigned char b : 8;
+} __attribute__((packed));
+
+
// The warnings are emitted when the layout of the structs is computed, so we have to use them.
-void f(S1*, S2*, S3*, S4*, S5*, S6*, S7*, S8*, S9*, S10*, S11*, S12*, S13*) { }
+void f(S1*, S2*, S3*, S4*, S5*, S6*, S7*, S8*, S9*, S10*, S11*, S12*, S13*,
+ S14*, S15*, S16*, S17*, S18*, S19*, S20*, S21*, S22*, S23*, S24*, S25*,
+ S26*, S27*){}
diff --git a/test/CodeGenCoroutines/coro-await.cpp b/test/CodeGenCoroutines/coro-await.cpp
index fc6559f1e0ad..41881d712337 100644
--- a/test/CodeGenCoroutines/coro-await.cpp
+++ b/test/CodeGenCoroutines/coro-await.cpp
@@ -12,6 +12,7 @@ template <>
struct coroutine_handle<void> {
void *ptr;
static coroutine_handle from_address(void *);
+ void *address();
};
template <typename Promise>
@@ -326,3 +327,20 @@ void AwaitReturnsLValue(double) {
// CHECK-NEXT: store %struct.RefTag* %[[RES3]], %struct.RefTag** %[[ZVAR]],
RefTag& z = co_yield 42;
}
+
+struct TailCallAwait {
+ bool await_ready();
+ std::experimental::coroutine_handle<> await_suspend(std::experimental::coroutine_handle<>);
+ void await_resume();
+};
+
+// CHECK-LABEL: @TestTailcall(
+extern "C" void TestTailcall() {
+ co_await TailCallAwait{};
+
+ // CHECK: %[[RESULT:.+]] = call i8* @_ZN13TailCallAwait13await_suspendENSt12experimental16coroutine_handleIvEE(%struct.TailCallAwait*
+ // CHECK: %[[COERCE:.+]] = getelementptr inbounds %"struct.std::experimental::coroutine_handle", %"struct.std::experimental::coroutine_handle"* %[[TMP:.+]], i32 0, i32 0
+ // CHECK: store i8* %[[RESULT]], i8** %[[COERCE]]
+ // CHECK: %[[ADDR:.+]] = call i8* @_ZNSt12experimental16coroutine_handleIvE7addressEv(%"struct.std::experimental::coroutine_handle"* %[[TMP]])
+ // CHECK: call void @llvm.coro.resume(i8* %[[ADDR]])
+}
diff --git a/test/CodeGenCoroutines/coro-dest-slot.cpp b/test/CodeGenCoroutines/coro-dest-slot.cpp
new file mode 100644
index 000000000000..4c7395ba608c
--- /dev/null
+++ b/test/CodeGenCoroutines/coro-dest-slot.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fcoroutines-ts -std=c++14 -emit-llvm %s -o - -disable-llvm-passes | FileCheck %s
+
+#include "Inputs/coroutine.h"
+
+using namespace std::experimental;
+
+struct coro {
+ struct promise_type {
+ coro get_return_object();
+ suspend_always initial_suspend();
+ suspend_never final_suspend();
+ void return_void();
+ static void unhandled_exception();
+ };
+};
+
+extern "C" coro f(int) { co_return; }
+// Verify that cleanup.dest.slot is eliminated in a coroutine.
+// CHECK-LABEL: f(
+// CHECK: call void @_ZNSt12experimental13coroutines_v113suspend_never12await_resumeEv(
+// CHECK: %[[CLEANUP_DEST:.+]] = phi i32 [ 0, %{{.+}} ], [ 2, %{{.+}} ], [ 2, %{{.+}} ]
+// CHECK: call i8* @llvm.coro.free(
+// CHECK: switch i32 %cleanup.dest.slot.0, label %{{.+}} [
+// CHECK-NEXT: i32 0
+// CHECK-NEXT: i32 2
+// CHECK-NEXT: ]
diff --git a/test/CodeGenCoroutines/coro-ret-void.cpp b/test/CodeGenCoroutines/coro-ret-void.cpp
index 6b07f6ea1d64..6ebb44dfaefa 100644
--- a/test/CodeGenCoroutines/coro-ret-void.cpp
+++ b/test/CodeGenCoroutines/coro-ret-void.cpp
@@ -21,6 +21,20 @@ coro1 f() {
// CHECK: call void @_ZNSt12experimental13coroutines_v113suspend_never12await_resumeEv(%"struct.std::experimental::coroutines_v1::suspend_never"*
// CHECK: call void @_ZN5coro112promise_type11return_voidEv(%"struct.coro1::promise_type"* %__promise)
+struct A {
+ A();
+ ~A();
+};
+
+coro1 f2() {
+ co_return (void) A{};
+}
+
+// CHECK-LABEL: define void @_Z2f2v(
+// CHECK: call void @_ZN1AC1Ev(%struct.A* %[[AVar:.*]])
+// CHECK-NEXT: call void @_ZN1AD1Ev(%struct.A* %[[AVar]])
+// CHECK-NEXT: call void @_ZN5coro112promise_type11return_voidEv(%"struct.coro1::promise_type"*
+
struct coro2 {
struct promise_type {
coro2 get_return_object();
diff --git a/test/CodeGenObjC/NSFastEnumeration.m b/test/CodeGenObjC/NSFastEnumeration.m
new file mode 100644
index 000000000000..ba131fc4c7ca
--- /dev/null
+++ b/test/CodeGenObjC/NSFastEnumeration.m
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -triple i686-apple-ios10.3 -fobjc-runtime=ios-6.0 -Os -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK32
+// RUN: %clang_cc1 -triple i686--windows-msvc -fobjc-runtime=ios-6.0 -Os -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK32
+// RUN: %clang_cc1 -triple x86_64-apple-ios10.3 -fobjc-runtime=ios-6.0 -Os -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK64
+// RUN: %clang_cc1 -triple x86_64--windows-msvc -fobjc-runtime=ios-6.0 -Os -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK64
+
+void f(id a) {
+ for (id i in a)
+ (void)i;
+}
+
+// CHECK32: call i32 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i32 (i8*, i8*, %struct.__objcFastEnumerationState*, [16 x i8*]*, i32)*)
+// CHECK32: call i32 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i32 (i8*, i8*, %struct.__objcFastEnumerationState*, [16 x i8*]*, i32)*)
+
+// CHECK64: call i64 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i64 (i8*, i8*, %struct.__objcFastEnumerationState*, [16 x i8*]*, i64)*)
+// CHECK64: call i64 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i64 (i8*, i8*, %struct.__objcFastEnumerationState*, [16 x i8*]*, i64)*)
+
diff --git a/test/CodeGenObjC/arc-arm.m b/test/CodeGenObjC/arc-arm.m
index 8d5f0d5c4b35..63c861f28951 100644
--- a/test/CodeGenObjC/arc-arm.m
+++ b/test/CodeGenObjC/arc-arm.m
@@ -13,7 +13,7 @@ id test0(void) {
void test1(void) {
extern id test1_helper(void);
// CHECK: [[T0:%.*]] = call [[CC]]i8* @test1_helper()
- // CHECK-NEXT: call void asm sideeffect "mov
+ // CHECK-NEXT: call void asm sideeffect "mov\09{{fp, fp|r7, r7}}\09\09// marker for objc_retainAutoreleaseReturnValue"
// CHECK-NEXT: [[T1:%.*]] = call [[CC]]i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]])
// CHECK-NEXT: store i8* [[T1]],
// CHECK-NEXT: call [[CC]]void @objc_storeStrong(
diff --git a/test/CodeGenObjC/arc-bridged-cast.m b/test/CodeGenObjC/arc-bridged-cast.m
index 97a45c5a2f10..42795d5d8009 100644
--- a/test/CodeGenObjC/arc-bridged-cast.m
+++ b/test/CodeGenObjC/arc-bridged-cast.m
@@ -97,3 +97,11 @@ void bridge_of_cf(int *i) {
// CHECK-NEXT: ret void
}
+// CHECK-LABEL: define %struct.__CFString* @bridge_of_paren_expr()
+CFStringRef bridge_of_paren_expr() {
+ // CHECK-NOT: call i8* @objc_retainAutoreleasedReturnValue(
+ // CHECK-NOT: call void @objc_release(
+ CFStringRef r = (__bridge CFStringRef)(CreateNSString());
+ r = (__bridge CFStringRef)((NSString *)(CreateNSString()));
+ return r;
+}
diff --git a/test/CodeGenObjC/attr-exception.m b/test/CodeGenObjC/attr-exception.m
index 00ebb0f2a0f1..30b637c8bc87 100644
--- a/test/CodeGenObjC/attr-exception.m
+++ b/test/CodeGenObjC/attr-exception.m
@@ -13,8 +13,8 @@ __attribute__((objc_exception))
@implementation A
@end
-// CHECK: @"OBJC_EHTYPE_$_A" = global {{%.*}} { i8** getelementptr (i8*, i8** @objc_ehtype_vtable, i32 2)
-// CHECK-HIDDEN: @"OBJC_EHTYPE_$_A" = hidden global {{%.*}} { i8** getelementptr (i8*, i8** @objc_ehtype_vtable, i32 2)
+// CHECK: @"OBJC_EHTYPE_$_A" = global {{%.*}} { i8** getelementptr inbounds (i8*, i8** @objc_ehtype_vtable, i32 2)
+// CHECK-HIDDEN: @"OBJC_EHTYPE_$_A" = hidden global {{%.*}} { i8** getelementptr inbounds (i8*, i8** @objc_ehtype_vtable, i32 2)
__attribute__((objc_exception))
__attribute__((visibility("default")))
@@ -23,5 +23,5 @@ __attribute__((visibility("default")))
@implementation B
@end
-// CHECK: @"OBJC_EHTYPE_$_B" = global {{%.*}} { i8** getelementptr (i8*, i8** @objc_ehtype_vtable, i32 2)
-// CHECK-HIDDEN: @"OBJC_EHTYPE_$_B" = global {{%.*}} { i8** getelementptr (i8*, i8** @objc_ehtype_vtable, i32 2)
+// CHECK: @"OBJC_EHTYPE_$_B" = global {{%.*}} { i8** getelementptr inbounds (i8*, i8** @objc_ehtype_vtable, i32 2)
+// CHECK-HIDDEN: @"OBJC_EHTYPE_$_B" = global {{%.*}} { i8** getelementptr inbounds (i8*, i8** @objc_ehtype_vtable, i32 2)
diff --git a/test/CodeGenObjC/debug-info-block-captured-self.m b/test/CodeGenObjC/debug-info-block-captured-self.m
deleted file mode 100644
index e142a0bceb8f..000000000000
--- a/test/CodeGenObjC/debug-info-block-captured-self.m
+++ /dev/null
@@ -1,72 +0,0 @@
-// RUN: %clang_cc1 -fblocks -debug-info-kind=limited -emit-llvm -triple x86_64-apple-darwin -o - %s | FileCheck %s
-//
-// Test that debug location is generated for a captured "self" inside
-// a block.
-//
-// This test is split into two parts, this one for the frontend, and
-// then llvm/test/DebugInfo/debug-info-block-captured-self.ll to
-// ensure that DW_AT_location is generated for the captured self.
-@class T;
-@interface S
-@end
-@interface Mode
--(int) count;
-@end
-@interface Context
-@end
-@interface ViewController
-@property (nonatomic, readwrite, strong) Context *context;
-@end
-typedef enum {
- Unknown = 0,
-} State;
-@interface Main : ViewController
-{
- T * t1;
- T * t2;
-}
-@property(readwrite, nonatomic) State state;
-@end
-@implementation Main
-- (id) initWithContext:(Context *) context
-{
- t1 = [self.context withBlock:^(id obj){
- id *mode1;
- t2 = [mode1 withBlock:^(id object){
- Mode *mode2 = object;
- if ([mode2 count] != 0) {
- self.state = 0;
- }
- }];
- }];
-}
-@end
-// The important part of this test is that there is a dbg.value
-// intrinsic associated with the implicit .block_descriptor argument
-// of the block. We also test that this value gets alloca'd, so the
-// register llocator won't accidentally kill it.
-
-// outer block:
-// CHECK: define internal void {{.*}}_block_invoke{{.*}}
-
-// inner block:
-// CHECK: define internal void {{.*}}_block_invoke{{.*}}
-// CHECK: %[[MEM1:.*]] = alloca i8*, align 8
-// CHECK-NEXT: %[[MEM2:.*]] = alloca i8*, align 8
-// CHECK-NEXT: [[DBGADDR:%.*]] = alloca [[BLOCK_T:<{.*}>]]*, align 8
-// CHECK: store i8* [[BLOCK_DESC:%.*]], i8** %[[MEM1]], align 8
-// CHECK: %[[TMP0:.*]] = load i8*, i8** %[[MEM1]]
-// CHECK: call void @llvm.dbg.value(metadata i8* %[[TMP0]], i64 0, metadata ![[BDMD:[0-9]+]], metadata !{{.*}})
-// CHECK: call void @llvm.dbg.declare(metadata i8* [[BLOCK_DESC]], metadata ![[BDMD:[0-9]+]], metadata !{{.*}})
-// CHECK: store [[BLOCK_T]]* {{%.*}}, [[BLOCK_T]]** [[DBGADDR]], align 8
-// CHECK: call void @llvm.dbg.declare(metadata [[BLOCK_T]]** [[DBGADDR]], metadata ![[SELF:.*]], metadata !{{.*}})
-// make sure we are still in the same function
-// CHECK: define {{.*}}__copy_helper_block_
-// Metadata
-// CHECK: ![[MAIN:.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Main"
-// CHECK-SAME: line: 23,
-// CHECK: ![[PMAIN:.*]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[MAIN]],
-// CHECK: ![[BDMD]] = !DILocalVariable(name: ".block_descriptor", arg:
-// CHECK: ![[SELF]] = !DILocalVariable(name: "self"
-// CHECK-NOT: arg:
-// CHECK-SAME: line: 40,
diff --git a/test/CodeGenObjC/debug-info-blocks.m b/test/CodeGenObjC/debug-info-blocks.m
index 0bf566395aa9..848e389f701b 100644
--- a/test/CodeGenObjC/debug-info-blocks.m
+++ b/test/CodeGenObjC/debug-info-blocks.m
@@ -10,23 +10,20 @@
// CHECK-NEXT: call void @llvm.dbg.declare(metadata <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, %0* }>** %[[ALLOCA]], metadata ![[SELF:[0-9]+]], metadata !{{.*}})
// CHECK-NEXT: call void @llvm.dbg.declare(metadata %1** %d, metadata ![[D:[0-9]+]], metadata !{{.*}})
-// rdar://problem/14386148
-// Test that we don't emit bogus line numbers for the helper functions.
-// Test that we do emit scope info for the helper functions.
+// Test that we do emit scope info for the helper functions, and that the
+// parameters to these functions are marked as artificial (so the debugger
+// doesn't accidentally step into the function).
// CHECK: define {{.*}} @__copy_helper_block_{{.*}}(i8*, i8*)
// CHECK-NOT: ret
// CHECK: call {{.*}}, !dbg ![[DBG_LINE:[0-9]+]]
// CHECK-NOT: ret
// CHECK: load {{.*}}, !dbg ![[COPY_LINE:[0-9]+]]
+// CHECK: ret void, !dbg ![[COPY_LINE]]
// CHECK: define {{.*}} @__destroy_helper_block_{{.*}}(i8*)
// CHECK-NOT: ret
// CHECK: load {{.*}}, !dbg ![[DESTROY_LINE:[0-9]+]]
+// CHECK: ret void, !dbg ![[DESTROY_LINE]]
-// CHECK-DAG: [[DBG_LINE]] = !DILocation(line: 0, scope: ![[COPY_SP:[0-9]+]])
-// CHECK-DAG: [[COPY_LINE]] = !DILocation(line: 0, scope: ![[COPY_SP:[0-9]+]])
-// CHECK-DAG: [[COPY_SP]] = distinct !DISubprogram(name: "__copy_helper_block_"
-// CHECK-DAG: [[DESTROY_LINE]] = !DILocation(line: 0, scope: ![[DESTROY_SP:[0-9]+]])
-// CHECK-DAG: [[DESTROY_SP]] = distinct !DISubprogram(name: "__destroy_helper_block_"
typedef unsigned int NSUInteger;
@protocol NSObject
@@ -60,6 +57,14 @@ static void run(void (^block)(void))
- (id)init
{
if ((self = [super init])) {
+ // CHECK-DAG: [[DBG_LINE]] = !DILocation(line: 0, scope: ![[COPY_SP:[0-9]+]])
+ // CHECK-DAG: [[COPY_LINE]] = !DILocation(line: [[@LINE+7]], scope: ![[COPY_SP:[0-9]+]])
+ // CHECK-DAG: [[COPY_SP]] = distinct !DISubprogram(name: "__copy_helper_block_"
+ // CHECK-DAG: [[DESTROY_LINE]] = !DILocation(line: [[@LINE+5]], scope: ![[DESTROY_SP:[0-9]+]])
+ // CHECK-DAG: [[DESTROY_SP]] = distinct !DISubprogram(name: "__destroy_helper_block_"
+ // CHECK-DAG: !DILocalVariable(arg: 1, scope: ![[COPY_SP]], {{.*}}, flags: DIFlagArtificial)
+ // CHECK-DAG: !DILocalVariable(arg: 2, scope: ![[COPY_SP]], {{.*}}, flags: DIFlagArtificial)
+ // CHECK-DAG: !DILocalVariable(arg: 1, scope: ![[DESTROY_SP]], {{.*}}, flags: DIFlagArtificial)
run(^{
// CHECK-DAG: ![[SELF]] = !DILocalVariable(name: "self", scope:{{.*}}, line: [[@LINE+4]],
// CHECK-DAG: ![[D]] = !DILocalVariable(name: "d", scope:{{.*}}, line: [[@LINE+1]],
diff --git a/test/CodeGenObjC/dllstorage.m b/test/CodeGenObjC/dllstorage.m
index 4bdbd509151b..a2665eefad85 100644
--- a/test/CodeGenObjC/dllstorage.m
+++ b/test/CodeGenObjC/dllstorage.m
@@ -1,3 +1,4 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-windows-msvc -fdeclspec -fobjc-runtime=ios -fobjc-exceptions -S -emit-llvm -o - %s | FileCheck -check-prefix CHECK-IR %s
// RUN: %clang_cc1 -triple i686-windows-itanium -fms-extensions -fobjc-runtime=macosx -fdeclspec -fobjc-exceptions -S -emit-llvm -o - %s | FileCheck -check-prefix CHECK-IR %s
// RUN: %clang_cc1 -triple i686-windows-itanium -fms-extensions -fobjc-runtime=objfw -fdeclspec -fobjc-exceptions -S -emit-llvm -o - %s | FileCheck -check-prefix CHECK-FW %s
@@ -114,6 +115,15 @@ __attribute__((__objc_exception__))
// CHECK-IR-DAG: @"OBJC_EHTYPE_$_P" = external global %struct._objc_typeinfo
+@interface Q : M
+@end
+
+id f(Q *q) {
+ return q->_ivar;
+}
+
+// CHECK-IR-DAG: @"OBJC_IVAR_$_M._ivar" = external dllimport global i32
+
int g() {
@autoreleasepool {
M *mi = [M new];
diff --git a/test/CodeGenObjC/ivar-layout-flexible-array.m b/test/CodeGenObjC/ivar-layout-flexible-array.m
new file mode 100644
index 000000000000..28849c86c2af
--- /dev/null
+++ b/test/CodeGenObjC/ivar-layout-flexible-array.m
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -Wno-objc-root-class -fobjc-arc -emit-llvm -o - %s | FileCheck %s
+
+// rdar://problem/21054495
+@interface FlexibleArrayMember {
+ char flexible_array[][4][2];
+}
+@end
+@implementation FlexibleArrayMember
+@end
+// CHECK: @OBJC_METH_VAR_NAME_{{.*}} = private unnamed_addr constant {{.*}} c"flexible_array\00"
+// CHECK-NEXT: @OBJC_METH_VAR_TYPE_{{.*}} = private unnamed_addr constant {{.*}} c"^[4[2c]]\00"
+
+
+typedef char FlexibleArray[];
+
+struct Packet {
+ int size;
+ FlexibleArray data;
+};
+
+@interface VariableSizeIvar {
+ struct Packet flexible_struct;
+}
+@end
+@implementation VariableSizeIvar
+@end
+// CHECK: @OBJC_METH_VAR_NAME_{{.*}} = private unnamed_addr constant {{.*}} c"flexible_struct\00"
+// CHECK-NEXT: @OBJC_METH_VAR_TYPE_{{.*}} = private unnamed_addr constant {{.*}} c"{Packet=\22size\22i\22data\22[0c]}\00"
diff --git a/test/CodeGenObjC/local-static-block.m b/test/CodeGenObjC/local-static-block.m
index 73c670f5c925..67ede63fc0a2 100644
--- a/test/CodeGenObjC/local-static-block.m
+++ b/test/CodeGenObjC/local-static-block.m
@@ -46,6 +46,17 @@ void FUNC()
}
}
+void FUNC2() {
+ static void (^const block1)(int) = ^(int a){
+ if (a--)
+ block1(a);
+ };
+}
+
+// CHECK-LABEL-LP64: define void @FUNC2(
+// CHECK: define internal void @_block_invoke{{.*}}(
+// CHECK: call void %{{.*}}(i8* bitcast ({ i8**, i32, i32, i8*, %struct.__block_descriptor* }* @__block_literal_global{{.*}} to i8*), i32 %{{.*}})
+
void FUNC1()
{
static NSArray *(^ArrayRecurs)(NSArray *addresses, unsigned long level) = ^(NSArray *addresses, unsigned long level) {
diff --git a/test/CodeGenObjC/mangle-blocks.m b/test/CodeGenObjC/mangle-blocks.m
index 4cc320403322..73522cd41c63 100644
--- a/test/CodeGenObjC/mangle-blocks.m
+++ b/test/CodeGenObjC/mangle-blocks.m
@@ -18,11 +18,11 @@ void __assert_rtn(const char *, const char *, int, const char *);
@end
// CHECK: @"__func__.__14-[Test mangle]_block_invoke_2" = private unnamed_addr constant [30 x i8] c"-[Test mangle]_block_invoke_2\00", align 1
-// CHECK: @.str = private unnamed_addr constant {{.*}}, align 1
-// CHECK: @.str.1 = private unnamed_addr constant [7 x i8] c"mangle\00", align 1
+// CHECK: @.str{{.*}} = private unnamed_addr constant {{.*}}, align 1
+// CHECK: @.str[[STR1:.*]] = private unnamed_addr constant [7 x i8] c"mangle\00", align 1
// CHECK: define internal void @"__14-[Test mangle]_block_invoke"(i8* %.block_descriptor)
// CHECK: define internal void @"__14-[Test mangle]_block_invoke_2"(i8* %.block_descriptor){{.*}}{
-// CHECK: call void @__assert_rtn(i8* getelementptr inbounds ([30 x i8], [30 x i8]* @"__func__.__14-[Test mangle]_block_invoke_2", i32 0, i32 0), i8* getelementptr inbounds {{.*}}, i32 14, i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str.1, i32 0, i32 0))
+// CHECK: call void @__assert_rtn(i8* getelementptr inbounds ([30 x i8], [30 x i8]* @"__func__.__14-[Test mangle]_block_invoke_2", i32 0, i32 0), i8* getelementptr inbounds {{.*}}, i32 14, i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str[[STR1]], i32 0, i32 0))
// CHECK: }
diff --git a/test/CodeGenObjC/no-sanitize.m b/test/CodeGenObjC/no-sanitize.m
index 39f8575670d5..07a196b6419d 100644
--- a/test/CodeGenObjC/no-sanitize.m
+++ b/test/CodeGenObjC/no-sanitize.m
@@ -1,8 +1,9 @@
-// RUN: %clang_cc1 %s -emit-llvm -fsanitize=address -o - | FileCheck %s
+// RUN: %clang_cc1 %s -emit-llvm -fsanitize=address -fblocks -o - | FileCheck %s
@interface I0 @end
@implementation I0
// CHECK-NOT: sanitize_address
- (void) im0: (int) a0 __attribute__((no_sanitize("address"))) {
+ int (^blockName)() = ^int() { return 0; };
}
@end
diff --git a/test/CodeGenObjC/noescape.m b/test/CodeGenObjC/noescape.m
new file mode 100644
index 000000000000..49bc0e4a7d33
--- /dev/null
+++ b/test/CodeGenObjC/noescape.m
@@ -0,0 +1,71 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -fblocks -emit-llvm -o - %s | FileCheck %s
+
+typedef void (^BlockTy)(void);
+
+union U {
+ int *i;
+ long long *ll;
+} __attribute__((transparent_union));
+
+void noescapeFunc0(id, __attribute__((noescape)) BlockTy);
+void noescapeFunc1(__attribute__((noescape)) int *);
+void noescapeFunc2(__attribute__((noescape)) id);
+void noescapeFunc3(__attribute__((noescape)) union U);
+
+// CHECK-LABEL: define void @test0(
+// CHECK: call void @noescapeFunc0({{.*}}, {{.*}} nocapture {{.*}})
+// CHECK: declare void @noescapeFunc0(i8*, {{.*}} nocapture)
+void test0(BlockTy b) {
+ noescapeFunc0(0, b);
+}
+
+// CHECK-LABEL: define void @test1(
+// CHECK: call void @noescapeFunc1({{.*}} nocapture {{.*}})
+// CHECK: declare void @noescapeFunc1({{.*}} nocapture)
+void test1(int *i) {
+ noescapeFunc1(i);
+}
+
+// CHECK-LABEL: define void @test2(
+// CHECK: call void @noescapeFunc2({{.*}} nocapture {{.*}})
+// CHECK: declare void @noescapeFunc2({{.*}} nocapture)
+void test2(id i) {
+ noescapeFunc2(i);
+}
+
+// CHECK-LABEL: define void @test3(
+// CHECK: call void @noescapeFunc3({{.*}} nocapture {{.*}})
+// CHECK: declare void @noescapeFunc3({{.*}} nocapture)
+void test3(union U u) {
+ noescapeFunc3(u);
+}
+
+// CHECK: define internal void @"\01-[C0 m0:]"({{.*}}, {{.*}}, {{.*}} nocapture {{.*}})
+
+// CHECK-LABEL: define void @test4(
+// CHECK: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, i32*)*)(i8* {{.*}}, i8* {{.*}}, i32* nocapture {{.*}})
+
+@interface C0
+-(void) m0:(int*)__attribute__((noescape)) p0;
+@end
+
+@implementation C0
+-(void) m0:(int*)__attribute__((noescape)) p0 {
+}
+@end
+
+void test4(C0 *c0, int *p) {
+ [c0 m0:p];
+}
+
+// CHECK-LABEL: define void @test5(
+// CHECK: call void {{.*}}(i8* bitcast ({ i8**, i32, i32, i8*, {{.*}} }* @{{.*}} to i8*), i32* nocapture {{.*}})
+// CHECK: call void {{.*}}(i8* {{.*}}, i32* nocapture {{.*}})
+// CHECK: define internal void @{{.*}}(i8* {{.*}}, i32* nocapture {{.*}})
+
+typedef void (^BlockTy2)(__attribute__((noescape)) int *);
+
+void test5(BlockTy2 b, int *p) {
+ ^(int *__attribute__((noescape)) p0){}(p);
+ b(p);
+}
diff --git a/test/CodeGenObjC/objc-asm-attribute-neg-test.m b/test/CodeGenObjC/objc-asm-attribute-neg-test.m
index e9bef4cdb762..de809d8a048d 100644
--- a/test/CodeGenObjC/objc-asm-attribute-neg-test.m
+++ b/test/CodeGenObjC/objc-asm-attribute-neg-test.m
@@ -7,15 +7,15 @@ __attribute__((objc_runtime_name("MySecretNamespace.Protocol")))
__attribute__((objc_runtime_name("MySecretNamespace.Message")))
@interface Message <Protocol> {
-__attribute__((objc_runtime_name("MySecretNamespace.Message"))) // expected-error {{'objc_runtime_name' attribute only applies to interface or protocol declarations}}
+__attribute__((objc_runtime_name("MySecretNamespace.Message"))) // expected-error {{'objc_runtime_name' attribute only applies to Objective-C interfaces and Objective-C protocols}}
id MyIVAR;
}
__attribute__((objc_runtime_name("MySecretNamespace.Message")))
@property int MyProperty; // expected-error {{prefix attribute must be followed by an interface or protocol}}}}
-- (int) getMyProperty __attribute__((objc_runtime_name("MySecretNamespace.Message"))); // expected-error {{'objc_runtime_name' attribute only applies to interface or protocol declarations}}
+- (int) getMyProperty __attribute__((objc_runtime_name("MySecretNamespace.Message"))); // expected-error {{'objc_runtime_name' attribute only applies to}}
-- (void) setMyProperty : (int) arg __attribute__((objc_runtime_name("MySecretNamespace.Message"))); // expected-error {{'objc_runtime_name' attribute only applies to interface or protocol declarations}}
+- (void) setMyProperty : (int) arg __attribute__((objc_runtime_name("MySecretNamespace.Message"))); // expected-error {{'objc_runtime_name' attribute only applies to}}
@end
diff --git a/test/CodeGenObjC/os_log.m b/test/CodeGenObjC/os_log.m
index 5d48783de472..1cf0c9f1f35c 100644
--- a/test/CodeGenObjC/os_log.m
+++ b/test/CodeGenObjC/os_log.m
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 %s -emit-llvm -o - -triple x86_64-darwin-apple -fobjc-arc -O2 | FileCheck %s
+// RUN: %clang_cc1 %s -emit-llvm -o - -triple x86_64-darwin-apple -fobjc-arc -O0 | FileCheck %s -check-prefix=CHECK-O0
// Make sure we emit clang.arc.use before calling objc_release as part of the
// cleanup. This way we make sure the object will not be released until the
@@ -12,28 +13,67 @@ extern __attribute__((visibility("default"))) NSString *GenString();
// Behavior of __builtin_os_log differs between platforms, so only test on X86
#ifdef __x86_64__
// CHECK-LABEL: define i8* @test_builtin_os_log
+// CHECK-O0-LABEL: define i8* @test_builtin_os_log
+// CHECK: (i8* returned %[[BUF:.*]])
+// CHECK-O0: (i8* %[[BUF:.*]])
void *test_builtin_os_log(void *buf) {
return __builtin_os_log_format(buf, "capabilities: %@", GenString());
- // CHECK: store i8 2, i8*
- // CHECK: [[NUM_ARGS:%.*]] = getelementptr i8, i8* {{.*}}, i64 1
- // CHECK: store i8 1, i8* [[NUM_ARGS]]
- //
- // CHECK: [[ARG1_DESC:%.*]] = getelementptr i8, i8* {{.*}}, i64 2
- // CHECK: store i8 64, i8* [[ARG1_DESC]]
- // CHECK: [[ARG1_SIZE:%.*]] = getelementptr i8, i8* {{.*}}, i64 3
- // CHECK: store i8 8, i8* [[ARG1_SIZE]]
- // CHECK: [[ARG1:%.*]] = getelementptr i8, i8* {{.*}}, i64 4
- // CHECK: [[ARG1_CAST:%.*]] = bitcast i8* [[ARG1]] to
-
- // CHECK: [[STRING:%.*]] = {{.*}} call {{.*}} @GenString()
- // CHECK: [[STRING_CAST:%.*]] = bitcast {{.*}} [[STRING]] to
- // CHECK: call {{.*}} @objc_retainAutoreleasedReturnValue(i8* [[STRING_CAST]])
- // CHECK: store {{.*}} [[STRING]], {{.*}} [[ARG1_CAST]]
-
- // CHECK: call void (...) @clang.arc.use({{.*}} [[STRING]])
- // CHECK: call void @objc_release(i8* [[STRING_CAST]])
- // CHECK: ret i8*
+ // CHECK: %[[CALL:.*]] = tail call %[[TY0:.*]]* (...) @GenString()
+ // CHECK: %[[V0:.*]] = bitcast %[[TY0]]* %[[CALL]] to i8*
+ // CHECK: %[[V1:.*]] = tail call i8* @objc_retainAutoreleasedReturnValue(i8* %[[V0]])
+ // CHECK: %[[V2:.*]] = ptrtoint %[[TY0]]* %[[CALL]] to i64
+ // CHECK: store i8 2, i8* %[[BUF]], align 1
+ // CHECK: %[[NUMARGS_I:.*]] = getelementptr i8, i8* %[[BUF]], i64 1
+ // CHECK: store i8 1, i8* %[[NUMARGS_I]], align 1
+ // CHECK: %[[ARGDESCRIPTOR_I:.*]] = getelementptr i8, i8* %[[BUF]], i64 2
+ // CHECK: store i8 64, i8* %[[ARGDESCRIPTOR_I]], align 1
+ // CHECK: %[[ARGSIZE_I:.*]] = getelementptr i8, i8* %[[BUF]], i64 3
+ // CHECK: store i8 8, i8* %[[ARGSIZE_I]], align 1
+ // CHECK: %[[ARGDATA_I:.*]] = getelementptr i8, i8* %[[BUF]], i64 4
+ // CHECK: %[[ARGDATACAST_I:.*]] = bitcast i8* %[[ARGDATA_I]] to i64*
+ // CHECK: store i64 %[[V2]], i64* %[[ARGDATACAST_I]], align 1
+ // CHECK: tail call void (...) @clang.arc.use(%[[TY0]]* %[[CALL]])
+ // CHECK: tail call void @objc_release(i8* %[[V0]])
+ // CHECK: ret i8* %[[BUF]]
+
+ // clang.arc.use is used and removed in IR optimizations. At O0, we should not
+ // emit clang.arc.use, since it will not be removed and we will have a link
+ // error.
+ // CHECK-O0: %[[BUF_ADDR:.*]] = alloca i8*, align 8
+ // CHECK-O0: store i8* %[[BUF]], i8** %[[BUF_ADDR]], align 8
+ // CHECK-O0: %[[V0:.*]] = load i8*, i8** %[[BUF_ADDR]], align 8
+ // CHECK-O0: %[[CALL:.*]] = call %[[TY0:.*]]* (...) @GenString()
+ // CHECK-O0: %[[V1:.*]] = bitcast %[[TY0]]* %[[CALL]] to i8*
+ // CHECK-O0: %[[V2:.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* %[[V1]])
+ // CHECK-O0: %[[V3:.*]] = bitcast i8* %[[V2]] to %[[TY0]]*
+ // CHECK-O0: %[[V4:.*]] = ptrtoint %[[TY0]]* %[[V3]] to i64
+ // CHECK-O0: call void @__os_log_helper_1_2_1_8_64(i8* %[[V0]], i64 %[[V4]])
+ // CHECK-O0: %[[V5:.*]] = bitcast %[[TY0]]* %[[V3]] to i8*
+ // CHECK-O0-NOT call void (...) @clang.arc.use({{.*}}
+ // CHECK-O0: call void @objc_release(i8* %[[V5]])
+ // CHECK-O0: ret i8* %[[V0]]
}
+// CHECK-O0-LABEL: define linkonce_odr hidden void @__os_log_helper_1_2_1_8_64
+// CHECK-O0: (i8* %[[BUFFER:.*]], i64 %[[ARG0:.*]])
+
+// CHECK-O0: %[[BUFFER_ADDR:.*]] = alloca i8*, align 8
+// CHECK-O0: %[[ARG0_ADDR:.*]] = alloca i64, align 8
+// CHECK-O0: store i8* %[[BUFFER]], i8** %[[BUFFER_ADDR]], align 8
+// CHECK-O0: store i64 %[[ARG0]], i64* %[[ARG0_ADDR]], align 8
+// CHECK-O0: %[[BUF:.*]] = load i8*, i8** %[[BUFFER_ADDR]], align 8
+// CHECK-O0: %[[SUMMARY:.*]] = getelementptr i8, i8* %[[BUF]], i64 0
+// CHECK-O0: store i8 2, i8* %[[SUMMARY]], align 1
+// CHECK-O0: %[[NUMARGS:.*]] = getelementptr i8, i8* %[[BUF]], i64 1
+// CHECK-O0: store i8 1, i8* %[[NUMARGS]], align 1
+// CHECK-O0: %[[ARGDESCRIPTOR:.*]] = getelementptr i8, i8* %[[BUF]], i64 2
+// CHECK-O0: store i8 64, i8* %[[ARGDESCRIPTOR]], align 1
+// CHECK-O0: %[[ARGSIZE:.*]] = getelementptr i8, i8* %[[BUF]], i64 3
+// CHECK-O0: store i8 8, i8* %[[ARGSIZE]], align 1
+// CHECK-O0: %[[ARGDATA:.*]] = getelementptr i8, i8* %[[BUF]], i64 4
+// CHECK-O0: %[[ARGDATACAST:.*]] = bitcast i8* %[[ARGDATA]] to i64*
+// CHECK-O0: %[[V0:.*]] = load i64, i64* %[[ARG0_ADDR]], align 8
+// CHECK-O0: store i64 %[[V0]], i64* %[[ARGDATACAST]], align 1
+
#endif
diff --git a/test/CodeGenObjCXX/arc-forwarded-lambda-call.mm b/test/CodeGenObjCXX/arc-forwarded-lambda-call.mm
new file mode 100644
index 000000000000..35abe19183bf
--- /dev/null
+++ b/test/CodeGenObjCXX/arc-forwarded-lambda-call.mm
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.12.0 -emit-llvm -disable-llvm-passes -O3 -fblocks -fobjc-arc -fobjc-runtime-has-weak -std=c++11 -o - %s | FileCheck %s
+
+void test0(id x) {
+ extern void test0_helper(id (^)(void));
+ test0_helper([=]() { return x; });
+ // CHECK-LABEL: define internal i8* @___Z5test0P11objc_object_block_invoke
+ // CHECK: [[T0:%.*]] = call i8* @"_ZZ5test0P11objc_objectENK3$_0clEv"
+ // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]])
+ // CHECK-NEXT: [[T2:%.*]] = tail call i8* @objc_autoreleaseReturnValue(i8* [[T1]])
+ // CHECK-NEXT: ret i8* [[T2]]
+}
+
+id test1_rv;
+
+void test1() {
+ extern void test1_helper(id (*)(void));
+ test1_helper([](){ return test1_rv; });
+ // CHECK-LABEL: define internal i8* @"_ZZ5test1vEN3$_18__invokeEv"
+ // CHECK: [[T0:%.*]] = call i8* @"_ZZ5test1vENK3$_1clEv"
+ // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]])
+ // CHECK-NEXT: [[T2:%.*]] = tail call i8* @objc_autoreleaseReturnValue(i8* [[T1]])
+ // CHECK-NEXT: ret i8* [[T2]]
+}
diff --git a/test/CodeGenObjCXX/mangle-blocks.mm b/test/CodeGenObjCXX/mangle-blocks.mm
index 283996d18aa1..bbe5c1f77f4d 100644
--- a/test/CodeGenObjCXX/mangle-blocks.mm
+++ b/test/CodeGenObjCXX/mangle-blocks.mm
@@ -1,8 +1,9 @@
// RUN: %clang_cc1 -emit-llvm -fblocks -o - -triple x86_64-apple-darwin10 -fobjc-runtime=macosx-fragile-10.5 %s | FileCheck %s
-// CHECK: @_ZZZN26externally_visible_statics1S3fooEiEd_Ub0_E1k = linkonce_odr global i32 0
-// CHECK: @_ZZZN26externally_visible_statics10inlinefuncEvEUb0_E1i = linkonce_odr global i32 0
-// CHECK: @_ZZ26externally_visible_statics1S1xMUb0_E1j = linkonce_odr global i32 0
+// CHECK-DAG: @_ZZZN26externally_visible_statics1S3fooEiEd_Ub_E1k = linkonce_odr global i32 0
+// CHECK-DAG: @_ZZZN26externally_visible_statics10inlinefuncEvEUb_E1i = linkonce_odr global i32 0
+// CHECK-DAG: @_ZZZN26externally_visible_statics10inlinefuncEvEUb0_E1j = linkonce_odr global i32 0
+// CHECK-DAG: @_ZZ26externally_visible_statics1S1xMUb_E1j = linkonce_odr global i32 0
int f();
@@ -68,6 +69,9 @@ namespace externally_visible_statics {
^{
static int i = f();
}();
+ ^{
+ static int j = f();
+ }();
}
struct S {
int x = ^{
diff --git a/test/CodeGenObjCXX/microsoft-abi-arc-param-order.mm b/test/CodeGenObjCXX/microsoft-abi-arc-param-order.mm
index 0b01b27fa799..cb71bcf0aad3 100644
--- a/test/CodeGenObjCXX/microsoft-abi-arc-param-order.mm
+++ b/test/CodeGenObjCXX/microsoft-abi-arc-param-order.mm
@@ -9,7 +9,7 @@ struct A {
// Verify that we destruct things from left to right in the MS C++ ABI: a, b, c, d.
//
-// CHECK-LABEL: define void @"\01?test_arc_order@@YAXUA@@PAAAPAUobjc_object@@01@Z"
+// CHECK-LABEL: define void @"\01?test_arc_order@@YAXUA@@PAUobjc_object@@01@Z"
// CHECK: (<{ %struct.A, i8*, %struct.A, i8* }>* inalloca)
void test_arc_order(A a, id __attribute__((ns_consumed)) b , A c, id __attribute__((ns_consumed)) d) {
// CHECK: call x86_thiscallcc void @"\01??1A@@QAE@XZ"(%struct.A* %{{.*}})
diff --git a/test/CodeGenObjCXX/msabi-objc-types.mm b/test/CodeGenObjCXX/msabi-objc-types.mm
new file mode 100644
index 000000000000..013a9c84daee
--- /dev/null
+++ b/test/CodeGenObjCXX/msabi-objc-types.mm
@@ -0,0 +1,122 @@
+// RUN: %clang_cc1 -triple thumbv7-windows-msvc -fdeclspec -std=c++11 -fobjc-runtime=ios-6.0 -o - -emit-llvm %s | FileCheck %s
+
+@class I;
+
+id kid;
+// CHECK: @"\01?kid@@3PAUobjc_object@@A" = global
+
+Class klass;
+// CHECK: @"\01?klass@@3PAUobjc_class@@A" = global
+
+I *kI;
+// CHECK: @"\01?kI@@3PAUI@@A" = global
+
+void f(I *) {}
+// CHECK-LABEL: "\01?f@@YAXPAUI@@@Z"
+
+void f(const I *) {}
+// CHECK-LABEL: "\01?f@@YAXPBUI@@@Z"
+
+void f(I &) {}
+// CHECK-LABEL: "\01?f@@YAXAAUI@@@Z"
+
+void f(const I &) {}
+// CHECK-LABEL: "\01?f@@YAXABUI@@@Z"
+
+void f(const I &&) {}
+// CHECK-LABEL: "\01?f@@YAX$$QBUI@@@Z"
+
+void g(id) {}
+// CHECK-LABEL: "\01?g@@YAXPAUobjc_object@@@Z"
+
+void g(id &) {}
+// CHECK-LABEL: "\01?g@@YAXAAPAUobjc_object@@@Z"
+
+void g(const id &) {}
+// CHECK-LABEL: "\01?g@@YAXABPAUobjc_object@@@Z"
+
+void g(id &&) {}
+// CHECK-LABEL: "\01?g@@YAX$$QAPAUobjc_object@@@Z"
+
+void h(Class) {}
+// CHECK-LABEL: "\01?h@@YAXPAUobjc_class@@@Z"
+
+void h(Class &) {}
+// CHECK-LABEL: "\01?h@@YAXAAPAUobjc_class@@@Z"
+
+void h(const Class &) {}
+// CHECK-LABEL: "\01?h@@YAXABPAUobjc_class@@@Z"
+
+void h(Class &&) {}
+// CHECK-LABEL: "\01?h@@YAX$$QAPAUobjc_class@@@Z"
+
+I *i() { return nullptr; }
+// CHECK-LABEL: "\01?i@@YAPAUI@@XZ"
+
+const I *j() { return nullptr; }
+// CHECK-LABEL: "\01?j@@YAPBUI@@XZ"
+
+I &k() { return *kI; }
+// CHECK-LABEL: "\01?k@@YAAAUI@@XZ"
+
+const I &l() { return *kI; }
+// CHECK-LABEL: "\01?l@@YAABUI@@XZ"
+
+struct __declspec(dllexport) s {
+ struct s &operator=(const struct s &) = delete;
+
+ void m(I *) {}
+ // CHECK-LABEL: "\01?m@s@@QAAXPAUI@@@Z"
+
+ void m(const I *) {}
+ // CHECK-LABEL: "\01?m@s@@QAAXPBUI@@@Z"
+
+ void m(I &) {}
+ // CHECK-LABEL: "\01?m@s@@QAAXAAUI@@@Z"
+
+ void m(const I &) {}
+ // CHECK-LABEL: "\01?m@s@@QAAXABUI@@@Z"
+
+ void m(I &&) {}
+ // CHECK-LABEL: "\01?m@s@@QAAX$$QAUI@@@Z"
+
+ void m(const I &&) {}
+ // CHECK-LABEL: "\01?m@s@@QAAX$$QBUI@@@Z"
+
+ void m(id) {}
+ // CHECK-LABEL: "\01?m@s@@QAAXPAUobjc_object@@@Z"
+
+ void m(id &) {}
+ // CHECK-LABEL: "\01?m@s@@QAAXAAPAUobjc_object@@@Z"
+
+ void m(id &&) {}
+ // CHECK-LABEL: "\01?m@s@@QAAX$$QAPAUobjc_object@@@Z"
+
+ void m(const id &) {}
+ // CHECK-LABEL: "\01?m@s@@QAAXABPAUobjc_object@@@Z"
+
+ void m(const id &&) {}
+ // CHECK-LABEL: "\01?m@s@@QAAX$$QBPAUobjc_object@@@Z"
+
+ void m(Class *) {}
+ // CHECK-LABEL: "\01?m@s@@QAAXPAPAUobjc_class@@@Z"
+
+ void m(const Class *) {}
+ // CHECK-LABEL: "\01?m@s@@QAAXPBPAUobjc_class@@@Z"
+
+ void m(Class) {}
+ // CHECK-LABEL: "\01?m@s@@QAAXPAUobjc_class@@@Z"
+
+ void m(Class &) {}
+ // CHECK-LABEL: "\01?m@s@@QAAXAAPAUobjc_class@@@Z"
+
+ void m(const Class &) {}
+ // CHECK-LABEL: "\01?m@s@@QAAXABPAUobjc_class@@@Z"
+
+ void m(Class &&) {}
+ // CHECK-LABEL: "\01?m@s@@QAAX$$QAPAUobjc_class@@@Z"
+
+ void m(const Class &&) {}
+ // CHECK-LABEL: "\01?m@s@@QAAX$$QBPAUobjc_class@@@Z"
+};
+
diff --git a/test/CodeGenOpenCL/addr-space-struct-arg.cl b/test/CodeGenOpenCL/addr-space-struct-arg.cl
index 6ea0aff0a074..68fc8035b4cc 100644
--- a/test/CodeGenOpenCL/addr-space-struct-arg.cl
+++ b/test/CodeGenOpenCL/addr-space-struct-arg.cl
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 %s -emit-llvm -o - -O0 -finclude-default-header -ffake-address-space-map -triple i686-pc-darwin | FileCheck -check-prefixes=COM,X86 %s
-// RUN: %clang_cc1 %s -emit-llvm -o - -O0 -finclude-default-header -triple amdgcn-amdhsa-amd-amdgizcl | FileCheck -check-prefixes=COM,AMD %s
+// RUN: %clang_cc1 %s -emit-llvm -o - -O0 -finclude-default-header -ffake-address-space-map -triple i686-pc-darwin | FileCheck -enable-var-scope -check-prefixes=COM,X86 %s
+// RUN: %clang_cc1 %s -emit-llvm -o - -O0 -finclude-default-header -triple amdgcn-amdhsa-amd-amdgizcl | FileCheck -enable-var-scope -check-prefixes=COM,AMD %s
typedef struct {
int cells[9];
@@ -9,6 +9,14 @@ typedef struct {
int cells[16];
} Mat4X4;
+typedef struct {
+ int cells[1024];
+} Mat32X32;
+
+typedef struct {
+ int cells[4096];
+} Mat64X64;
+
struct StructOneMember {
int2 x;
};
@@ -18,7 +26,18 @@ struct StructTwoMember {
int2 y;
};
-// COM-LABEL: define void @foo
+struct LargeStructOneMember {
+ int2 x[100];
+};
+
+struct LargeStructTwoMember {
+ int2 x[40];
+ int2 y[20];
+};
+
+
+// X86-LABEL: define void @foo(%struct.Mat4X4* noalias sret %agg.result, %struct.Mat3X3* byval align 4 %in)
+// AMD-LABEL: define %struct.Mat4X4 @foo([9 x i32] %in.coerce)
Mat4X4 __attribute__((noinline)) foo(Mat3X3 in) {
Mat4X4 out;
return out;
@@ -29,37 +48,86 @@ Mat4X4 __attribute__((noinline)) foo(Mat3X3 in) {
// the return value.
// X86: call void @llvm.memcpy.p0i8.p1i8.i32(i8*
// X86: call void @llvm.memcpy.p1i8.p0i8.i32(i8 addrspace(1)*
-// AMD: call void @llvm.memcpy.p5i8.p1i8.i64(i8 addrspace(5)*
+
+// AMD: load [9 x i32], [9 x i32] addrspace(1)*
+// AMD: call %struct.Mat4X4 @foo([9 x i32]
// AMD: call void @llvm.memcpy.p1i8.p5i8.i64(i8 addrspace(1)*
kernel void ker(global Mat3X3 *in, global Mat4X4 *out) {
out[0] = foo(in[1]);
}
-// AMD-LABEL: define void @FuncOneMember(%struct.StructOneMember addrspace(5)* byval align 8 %u)
+// X86-LABEL: define void @foo_large(%struct.Mat64X64* noalias sret %agg.result, %struct.Mat32X32* byval align 4 %in)
+// AMD-LABEL: define void @foo_large(%struct.Mat64X64 addrspace(5)* noalias sret %agg.result, %struct.Mat32X32 addrspace(5)* byval align 4 %in)
+Mat64X64 __attribute__((noinline)) foo_large(Mat32X32 in) {
+ Mat64X64 out;
+ return out;
+}
+
+// COM-LABEL: define {{.*}} void @ker_large
+// Expect two mem copies: one for the argument "in", and one for
+// the return value.
+// X86: call void @llvm.memcpy.p0i8.p1i8.i32(i8*
+// X86: call void @llvm.memcpy.p1i8.p0i8.i32(i8 addrspace(1)*
+// AMD: call void @llvm.memcpy.p5i8.p1i8.i64(i8 addrspace(5)*
+// AMD: call void @llvm.memcpy.p1i8.p5i8.i64(i8 addrspace(1)*
+kernel void ker_large(global Mat32X32 *in, global Mat64X64 *out) {
+ out[0] = foo_large(in[1]);
+}
+
+// AMD-LABEL: define void @FuncOneMember(<2 x i32> %u.coerce)
void FuncOneMember(struct StructOneMember u) {
u.x = (int2)(0, 0);
}
+// AMD-LABEL: define void @FuncOneLargeMember(%struct.LargeStructOneMember addrspace(5)* byval align 8 %u)
+void FuncOneLargeMember(struct LargeStructOneMember u) {
+ u.x[0] = (int2)(0, 0);
+}
+
// AMD-LABEL: define amdgpu_kernel void @KernelOneMember
// AMD-SAME: (<2 x i32> %[[u_coerce:.*]])
// AMD: %[[u:.*]] = alloca %struct.StructOneMember, align 8, addrspace(5)
// AMD: %[[coerce_dive:.*]] = getelementptr inbounds %struct.StructOneMember, %struct.StructOneMember addrspace(5)* %[[u]], i32 0, i32 0
// AMD: store <2 x i32> %[[u_coerce]], <2 x i32> addrspace(5)* %[[coerce_dive]]
-// AMD: call void @FuncOneMember(%struct.StructOneMember addrspace(5)* byval align 8 %[[u]])
+// AMD: call void @FuncOneMember(<2 x i32>
kernel void KernelOneMember(struct StructOneMember u) {
FuncOneMember(u);
}
-// AMD-LABEL: define void @FuncTwoMember(%struct.StructTwoMember addrspace(5)* byval align 8 %u)
+// AMD-LABEL: define amdgpu_kernel void @KernelLargeOneMember(
+// AMD: %[[U:.*]] = alloca %struct.LargeStructOneMember, align 8, addrspace(5)
+// AMD: store %struct.LargeStructOneMember %u.coerce, %struct.LargeStructOneMember addrspace(5)* %[[U]], align 8
+// AMD: call void @FuncOneLargeMember(%struct.LargeStructOneMember addrspace(5)* byval align 8 %[[U]])
+kernel void KernelLargeOneMember(struct LargeStructOneMember u) {
+ FuncOneLargeMember(u);
+}
+
+// AMD-LABEL: define void @FuncTwoMember(<2 x i32> %u.coerce0, <2 x i32> %u.coerce1)
void FuncTwoMember(struct StructTwoMember u) {
- u.x = (int2)(0, 0);
+ u.y = (int2)(0, 0);
+}
+
+// AMD-LABEL: define void @FuncLargeTwoMember(%struct.LargeStructTwoMember addrspace(5)* byval align 8 %u)
+void FuncLargeTwoMember(struct LargeStructTwoMember u) {
+ u.y[0] = (int2)(0, 0);
}
+
// AMD-LABEL: define amdgpu_kernel void @KernelTwoMember
// AMD-SAME: (%struct.StructTwoMember %[[u_coerce:.*]])
// AMD: %[[u:.*]] = alloca %struct.StructTwoMember, align 8, addrspace(5)
-// AMD: store %struct.StructTwoMember %[[u_coerce]], %struct.StructTwoMember addrspace(5)* %[[u]]
-// AMD: call void @FuncTwoMember(%struct.StructTwoMember addrspace(5)* byval align 8 %[[u]])
+// AMD: %[[LD0:.*]] = load <2 x i32>, <2 x i32> addrspace(5)*
+// AMD: %[[LD1:.*]] = load <2 x i32>, <2 x i32> addrspace(5)*
+// AMD: call void @FuncTwoMember(<2 x i32> %[[LD0]], <2 x i32> %[[LD1]])
kernel void KernelTwoMember(struct StructTwoMember u) {
FuncTwoMember(u);
}
+
+// AMD-LABEL: define amdgpu_kernel void @KernelLargeTwoMember
+// AMD-SAME: (%struct.LargeStructTwoMember %[[u_coerce:.*]])
+// AMD: %[[u:.*]] = alloca %struct.LargeStructTwoMember, align 8, addrspace(5)
+// AMD: store %struct.LargeStructTwoMember %[[u_coerce]], %struct.LargeStructTwoMember addrspace(5)* %[[u]]
+// AMD: call void @FuncLargeTwoMember(%struct.LargeStructTwoMember addrspace(5)* byval align 8 %[[u]])
+kernel void KernelLargeTwoMember(struct LargeStructTwoMember u) {
+ FuncLargeTwoMember(u);
+}
diff --git a/test/CodeGenOpenCL/address-spaces-mangling.cl b/test/CodeGenOpenCL/address-spaces-mangling.cl
index 3c74c718c2a2..b6e6b87d9e6d 100644
--- a/test/CodeGenOpenCL/address-spaces-mangling.cl
+++ b/test/CodeGenOpenCL/address-spaces-mangling.cl
@@ -1,5 +1,7 @@
-// RUN: %clang_cc1 %s -ffake-address-space-map -faddress-space-map-mangling=yes -triple %itanium_abi_triple -emit-llvm -o - | FileCheck -check-prefix=ASMANG %s
-// RUN: %clang_cc1 %s -ffake-address-space-map -faddress-space-map-mangling=no -triple %itanium_abi_triple -emit-llvm -o - | FileCheck -check-prefix=NOASMANG %s
+// RUN: %clang_cc1 %s -ffake-address-space-map -faddress-space-map-mangling=yes -triple %itanium_abi_triple -emit-llvm -o - | FileCheck -check-prefixes=ASMANG,ASMAN10 %s
+// RUN: %clang_cc1 %s -cl-std=CL2.0 -ffake-address-space-map -faddress-space-map-mangling=yes -triple %itanium_abi_triple -emit-llvm -o - | FileCheck -check-prefixes=ASMANG,ASMAN20 %s
+// RUN: %clang_cc1 %s -ffake-address-space-map -faddress-space-map-mangling=no -triple %itanium_abi_triple -emit-llvm -o - | FileCheck -check-prefixes=NOASMANG,NOASMAN10 %s
+// RUN: %clang_cc1 %s -cl-std=CL2.0 -ffake-address-space-map -faddress-space-map-mangling=no -triple %itanium_abi_triple -emit-llvm -o - | FileCheck -check-prefixes=NOASMANG,NOASMAN20 %s
// We check that the address spaces are mangled the same in both version of OpenCL
// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=CL2.0 -emit-llvm -o - | FileCheck -check-prefix=OCL-20 %s
@@ -10,15 +12,17 @@
// warnings, but we do want it for comparison purposes.
__attribute__((overloadable))
void ff(int *arg) { }
-// ASMANG: @_Z2ffPi
-// NOASMANG: @_Z2ffPi
+// ASMANG10: @_Z2ffPi
+// ASMANG20: @_Z2ffPU3AS4i
+// NOASMANG10: @_Z2ffPi
+// NOASMANG20: @_Z2ffPU9CLgenerici
// OCL-20-DAG: @_Z2ffPU3AS4i
// OCL-12-DAG: @_Z2ffPi
__attribute__((overloadable))
void f(private int *arg) { }
// ASMANG: @_Z1fPi
-// NOASMANG: @_Z1fPi
+// NOASMANG: @_Z1fPU9CLprivatei
// OCL-20-DAG: @_Z1fPi
// OCL-12-DAG: @_Z1fPi
@@ -42,3 +46,11 @@ void f(constant int *arg) { }
// NOASMANG: @_Z1fPU10CLconstanti
// OCL-20-DAG: @_Z1fPU3AS2i
// OCL-12-DAG: @_Z1fPU3AS2i
+
+#if __OPENCL_C_VERSION__ >= 200
+__attribute__((overloadable))
+void f(generic int *arg) { }
+// ASMANG20: @_Z1fPU3AS4i
+// NOASMANG20: @_Z1fPU9CLgenerici
+// OCL-20-DAG: @_Z1fPU3AS4i
+#endif
diff --git a/test/CodeGenOpenCL/address-spaces.cl b/test/CodeGenOpenCL/address-spaces.cl
index 488b8f9d480e..cb641f593711 100644
--- a/test/CodeGenOpenCL/address-spaces.cl
+++ b/test/CodeGenOpenCL/address-spaces.cl
@@ -7,6 +7,24 @@
// RUN: %clang_cc1 %s -O0 -triple amdgcn-mesa-mesa3d -emit-llvm -o - | FileCheck --check-prefixes=CHECK,SPIR %s
// RUN: %clang_cc1 %s -O0 -triple r600-- -emit-llvm -o - | FileCheck --check-prefixes=CHECK,SPIR %s
+// SPIR: %struct.S = type { i32, i32, i32* }
+// CL20SPIR: %struct.S = type { i32, i32, i32 addrspace(4)* }
+struct S {
+ int x;
+ int y;
+ int *z;
+};
+
+// CL20-DAG: @g_extern_var = external addrspace(1) global float
+// CL20-DAG: @l_extern_var = external addrspace(1) global float
+// CL20-DAG: @test_static.l_static_var = internal addrspace(1) global float 0.000000e+00
+// CL20-DAG: @g_static_var = internal addrspace(1) global float 0.000000e+00
+
+#ifdef CL20
+// CL20-DAG: @g_s = common addrspace(1) global %struct.S zeroinitializer
+struct S g_s;
+#endif
+
// SPIR: i32* %arg
// GIZ: i32 addrspace(5)* %arg
void f__p(__private int *arg) {}
@@ -58,3 +76,53 @@ void f(int *arg) {
// CL20-DAG: @f.ii = internal addrspace(1) global i32 0
#endif
}
+
+typedef int int_td;
+typedef int *intp_td;
+// SPIR: define void @test_typedef(i32 addrspace(1)* %x, i32 addrspace(2)* %y, i32* %z)
+void test_typedef(global int_td *x, constant int_td *y, intp_td z) {
+ *x = *y;
+ *z = 0;
+}
+
+// SPIR: define void @test_struct()
+void test_struct() {
+ // SPIR: %ps = alloca %struct.S*
+ // CL20SPIR: %ps = alloca %struct.S addrspace(4)*
+ struct S *ps;
+ // SPIR: store i32 0, i32* %x
+ // CL20SPIR: store i32 0, i32 addrspace(4)* %x
+ ps->x = 0;
+#ifdef CL20
+ // CL20SPIR: store i32 0, i32 addrspace(1)* getelementptr inbounds (%struct.S, %struct.S addrspace(1)* @g_s, i32 0, i32 0)
+ g_s.x = 0;
+#endif
+}
+
+// SPIR-LABEL: define void @test_void_par()
+void test_void_par(void) {}
+
+// On ppc64 returns signext i32.
+// SPIR-LABEL: define{{.*}} i32 @test_func_return_type()
+int test_func_return_type(void) {
+ return 0;
+}
+
+#ifdef CL20
+extern float g_extern_var;
+
+// CL20-LABEL: define {{.*}}void @test_extern(
+kernel void test_extern(global float *buf) {
+ extern float l_extern_var;
+ buf[0] += g_extern_var + l_extern_var;
+}
+
+static float g_static_var;
+
+// CL20-LABEL: define {{.*}}void @test_static(
+kernel void test_static(global float *buf) {
+ static float l_static_var;
+ buf[0] += g_static_var + l_static_var;
+}
+
+#endif
diff --git a/test/CodeGenOpenCL/amdgcn-automatic-variable.cl b/test/CodeGenOpenCL/amdgcn-automatic-variable.cl
index 19287c7d8998..fefe1c4a41d5 100644
--- a/test/CodeGenOpenCL/amdgcn-automatic-variable.cl
+++ b/test/CodeGenOpenCL/amdgcn-automatic-variable.cl
@@ -58,3 +58,11 @@ void func2(void) {
const int lvc = 4;
lv1 = lvc;
}
+
+// CHECK-LABEL: define void @func3()
+// CHECK: %a = alloca [16 x [1 x float]], align 4, addrspace(5)
+// CHECK: %[[CAST:.+]] = bitcast [16 x [1 x float]] addrspace(5)* %a to i8 addrspace(5)*
+// CHECK: call void @llvm.memset.p5i8.i64(i8 addrspace(5)* %[[CAST]], i8 0, i64 64, i32 4, i1 false)
+void func3(void) {
+ float a[16][1] = {{0.}};
+}
diff --git a/test/CodeGenOpenCL/amdgpu-abi-struct-coerce.cl b/test/CodeGenOpenCL/amdgpu-abi-struct-coerce.cl
index 3c69d11f9678..21bdb15b094d 100644
--- a/test/CodeGenOpenCL/amdgpu-abi-struct-coerce.cl
+++ b/test/CodeGenOpenCL/amdgpu-abi-struct-coerce.cl
@@ -1,13 +1,38 @@
// REQUIRES: amdgpu-registered-target
-// RUN: %clang_cc1 -triple amdgcn-unknown-unknown -S -emit-llvm -o - %s | FileCheck %s
-// RUN: %clang_cc1 -triple r600-unknown-unknown -S -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple amdgcn-unknown-unknown-amdgiz -S -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK,AMDGCN %s
+// RUN: %clang_cc1 -triple r600-unknown-unknown -S -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK,R600 %s
-// CHECK-NOT: %struct.single_element_struct_arg = type { i32 }
+typedef __attribute__(( ext_vector_type(2) )) char char2;
+typedef __attribute__(( ext_vector_type(3) )) char char3;
+typedef __attribute__(( ext_vector_type(4) )) char char4;
+
+typedef __attribute__(( ext_vector_type(2) )) short short2;
+typedef __attribute__(( ext_vector_type(3) )) short short3;
+typedef __attribute__(( ext_vector_type(4) )) short short4;
+
+typedef __attribute__(( ext_vector_type(2) )) int int2;
+typedef __attribute__(( ext_vector_type(3) )) int int3;
+typedef __attribute__(( ext_vector_type(4) )) int int4;
+typedef __attribute__(( ext_vector_type(16) )) int int16;
+typedef __attribute__(( ext_vector_type(32) )) int int32;
+
+// CHECK: %struct.empty_struct = type {}
+typedef struct empty_struct
+{
+} empty_struct;
+
+// CHECK-NOT: %struct.single_element_struct_arg
typedef struct single_element_struct_arg
{
int i;
} single_element_struct_arg_t;
+// CHECK-NOT: %struct.nested_single_element_struct_arg
+typedef struct nested_single_element_struct_arg
+{
+ single_element_struct_arg_t i;
+} nested_single_element_struct_arg_t;
+
// CHECK: %struct.struct_arg = type { i32, float, i32 }
typedef struct struct_arg
{
@@ -16,6 +41,13 @@ typedef struct struct_arg
int i2;
} struct_arg_t;
+// CHECK: %struct.struct_padding_arg = type { i8, i64 }
+typedef struct struct_padding_arg
+{
+ char i1;
+ long f;
+} struct_padding_arg;
+
// CHECK: %struct.struct_of_arrays_arg = type { [2 x i32], float, [4 x i32], [3 x float], i32 }
typedef struct struct_of_arrays_arg
{
@@ -35,33 +67,469 @@ typedef struct struct_of_structs_arg
int i2;
} struct_of_structs_arg_t;
-// CHECK-LABEL: @test_single_element_struct_arg
-// CHECK: i32 %arg1.coerce
-__kernel void test_single_element_struct_arg(single_element_struct_arg_t arg1)
+// CHECK: %union.transparent_u = type { i32 }
+typedef union
{
+ int b1;
+ float b2;
+} transparent_u __attribute__((__transparent_union__));
+
+// CHECK: %struct.single_array_element_struct_arg = type { [4 x i32] }
+typedef struct single_array_element_struct_arg
+{
+ int i[4];
+} single_array_element_struct_arg_t;
+
+// CHECK: %struct.single_struct_element_struct_arg = type { %struct.inner }
+// CHECK: %struct.inner = type { i32, i64 }
+typedef struct single_struct_element_struct_arg
+{
+ struct inner {
+ int a;
+ long b;
+ } s;
+} single_struct_element_struct_arg_t;
+
+// CHECK: %struct.different_size_type_pair
+typedef struct different_size_type_pair {
+ long l;
+ int i;
+} different_size_type_pair;
+
+// CHECK: %struct.flexible_array = type { i32, [0 x i32] }
+typedef struct flexible_array
+{
+ int i;
+ int flexible[];
+} flexible_array;
+
+// CHECK: %struct.struct_arr16 = type { [16 x i32] }
+typedef struct struct_arr16
+{
+ int arr[16];
+} struct_arr16;
+
+// CHECK: %struct.struct_arr32 = type { [32 x i32] }
+typedef struct struct_arr32
+{
+ int arr[32];
+} struct_arr32;
+
+// CHECK: %struct.struct_arr33 = type { [33 x i32] }
+typedef struct struct_arr33
+{
+ int arr[33];
+} struct_arr33;
+
+// CHECK: %struct.struct_char_arr32 = type { [32 x i8] }
+typedef struct struct_char_arr32
+{
+ char arr[32];
+} struct_char_arr32;
+
+// CHECK-NOT: %struct.struct_char_x8
+typedef struct struct_char_x8 {
+ char x, y, z, w;
+ char a, b, c, d;
+} struct_char_x8;
+
+// CHECK-NOT: %struct.struct_char_x4
+typedef struct struct_char_x4 {
+ char x, y, z, w;
+} struct_char_x4;
+
+// CHECK-NOT: %struct.struct_char_x3
+typedef struct struct_char_x3 {
+ char x, y, z;
+} struct_char_x3;
+
+// CHECK-NOT: %struct.struct_char_x2
+typedef struct struct_char_x2 {
+ char x, y;
+} struct_char_x2;
+
+// CHECK-NOT: %struct.struct_char_x1
+typedef struct struct_char_x1 {
+ char x;
+} struct_char_x1;
+
+// 4 registers from fields, 5 if padding included.
+// CHECK: %struct.nested = type { i8, i64 }
+// CHECK: %struct.num_regs_nested_struct = type { i32, %struct.nested }
+typedef struct num_regs_nested_struct {
+ int x;
+ struct nested {
+ char z;
+ long y;
+ } inner;
+} num_regs_nested_struct;
+
+// CHECK: %struct.double_nested = type { %struct.inner_inner }
+// CHECK: %struct.inner_inner = type { i8, i32, i8 }
+// CHECK: %struct.double_nested_struct = type { i32, %struct.double_nested, i16 }
+typedef struct double_nested_struct {
+ int x;
+ struct double_nested {
+ struct inner_inner {
+ char y;
+ int q;
+ char z;
+ } inner_inner;
+ } inner;
+
+ short w;
+} double_nested_struct;
+
+// This is a large struct, but uses fewer registers than the limit.
+// CHECK: %struct.large_struct_padding = type { i8, i32, i8, i32, i8, i8, i16, i16, [3 x i8], i64, i32, i8, i32, i16, i8 }
+typedef struct large_struct_padding {
+ char e0;
+ int e1;
+ char e2;
+ int e3;
+ char e4;
+ char e5;
+ short e6;
+ short e7;
+ char e8[3];
+ long e9;
+ int e10;
+ char e11;
+ int e12;
+ short e13;
+ char e14;
+} large_struct_padding;
+
+// CHECK: %struct.int3_pair = type { <3 x i32>, <3 x i32> }
+// The number of registers computed should be 6, not 8.
+typedef struct int3_pair {
+ int3 dx;
+ int3 dy;
+} int3_pair;
+
+// CHECK: %struct.struct_4regs = type { i32, i32, i32, i32 }
+typedef struct struct_4regs
+{
+ int x;
+ int y;
+ int z;
+ int w;
+} struct_4regs;
+
+// CHECK: void @kernel_empty_struct_arg(%struct.empty_struct %s.coerce)
+__kernel void kernel_empty_struct_arg(empty_struct s) { }
+
+// CHECK: void @kernel_single_element_struct_arg(i32 %arg1.coerce)
+__kernel void kernel_single_element_struct_arg(single_element_struct_arg_t arg1) { }
+
+// CHECK: void @kernel_nested_single_element_struct_arg(i32 %arg1.coerce)
+__kernel void kernel_nested_single_element_struct_arg(nested_single_element_struct_arg_t arg1) { }
+
+// CHECK: void @kernel_struct_arg(%struct.struct_arg %arg1.coerce)
+__kernel void kernel_struct_arg(struct_arg_t arg1) { }
+
+// CHECK: void @kernel_struct_padding_arg(%struct.struct_padding_arg %arg1.coerce)
+__kernel void kernel_struct_padding_arg(struct_padding_arg arg1) { }
+
+// CHECK: void @kernel_test_struct_of_arrays_arg(%struct.struct_of_arrays_arg %arg1.coerce)
+__kernel void kernel_test_struct_of_arrays_arg(struct_of_arrays_arg_t arg1) { }
+
+// CHECK: void @kernel_struct_of_structs_arg(%struct.struct_of_structs_arg %arg1.coerce)
+__kernel void kernel_struct_of_structs_arg(struct_of_structs_arg_t arg1) { }
+
+// CHECK: void @test_kernel_transparent_union_arg(%union.transparent_u %u.coerce)
+__kernel void test_kernel_transparent_union_arg(transparent_u u) { }
+
+// CHECK: void @kernel_single_array_element_struct_arg(%struct.single_array_element_struct_arg %arg1.coerce)
+__kernel void kernel_single_array_element_struct_arg(single_array_element_struct_arg_t arg1) { }
+
+// CHECK: void @kernel_single_struct_element_struct_arg(%struct.single_struct_element_struct_arg %arg1.coerce)
+__kernel void kernel_single_struct_element_struct_arg(single_struct_element_struct_arg_t arg1) { }
+
+// CHECK: void @kernel_different_size_type_pair_arg(%struct.different_size_type_pair %arg1.coerce)
+__kernel void kernel_different_size_type_pair_arg(different_size_type_pair arg1) { }
+
+// CHECK: define void @func_f32_arg(float %arg)
+void func_f32_arg(float arg) { }
+
+// CHECK: define void @func_v2i16_arg(<2 x i16> %arg)
+void func_v2i16_arg(short2 arg) { }
+
+// CHECK: define void @func_v3i32_arg(<3 x i32> %arg)
+void func_v3i32_arg(int3 arg) { }
+
+// CHECK: define void @func_v4i32_arg(<4 x i32> %arg)
+void func_v4i32_arg(int4 arg) { }
+
+// CHECK: define void @func_v16i32_arg(<16 x i32> %arg)
+void func_v16i32_arg(int16 arg) { }
+
+// CHECK: define void @func_v32i32_arg(<32 x i32> %arg)
+void func_v32i32_arg(int32 arg) { }
+
+// CHECK: define void @func_empty_struct_arg()
+void func_empty_struct_arg(empty_struct empty) { }
+
+// CHECK: void @func_single_element_struct_arg(i32 %arg1.coerce)
+void func_single_element_struct_arg(single_element_struct_arg_t arg1) { }
+
+// CHECK: void @func_nested_single_element_struct_arg(i32 %arg1.coerce)
+void func_nested_single_element_struct_arg(nested_single_element_struct_arg_t arg1) { }
+
+// CHECK: void @func_struct_arg(i32 %arg1.coerce0, float %arg1.coerce1, i32 %arg1.coerce2)
+void func_struct_arg(struct_arg_t arg1) { }
+
+// CHECK: void @func_struct_padding_arg(i8 %arg1.coerce0, i64 %arg1.coerce1)
+void func_struct_padding_arg(struct_padding_arg arg1) { }
+
+// CHECK: define void @func_struct_char_x8([2 x i32] %arg.coerce)
+void func_struct_char_x8(struct_char_x8 arg) { }
+
+// CHECK: define void @func_struct_char_x4(i32 %arg.coerce)
+void func_struct_char_x4(struct_char_x4 arg) { }
+
+// CHECK: define void @func_struct_char_x3(i32 %arg.coerce)
+void func_struct_char_x3(struct_char_x3 arg) { }
+
+// CHECK: define void @func_struct_char_x2(i16 %arg.coerce)
+void func_struct_char_x2(struct_char_x2 arg) { }
+
+// CHECK: define void @func_struct_char_x1(i8 %arg.coerce)
+void func_struct_char_x1(struct_char_x1 arg) { }
+
+// CHECK: void @func_transparent_union_arg(i32 %u.coerce)
+void func_transparent_union_arg(transparent_u u) { }
+
+// CHECK: void @func_single_array_element_struct_arg([4 x i32] %arg1.coerce)
+void func_single_array_element_struct_arg(single_array_element_struct_arg_t arg1) { }
+
+// CHECK: void @func_single_struct_element_struct_arg(%struct.inner %arg1.coerce)
+void func_single_struct_element_struct_arg(single_struct_element_struct_arg_t arg1) { }
+
+// CHECK: void @func_different_size_type_pair_arg(i64 %arg1.coerce0, i32 %arg1.coerce1)
+void func_different_size_type_pair_arg(different_size_type_pair arg1) { }
+
+// AMDGCN: void @func_flexible_array_arg(%struct.flexible_array addrspace(5)* byval nocapture align 4 %arg)
+// R600: void @func_flexible_array_arg(%struct.flexible_array* byval nocapture align 4 %arg)
+void func_flexible_array_arg(flexible_array arg) { }
+
+// CHECK: define float @func_f32_ret()
+float func_f32_ret()
+{
+ return 0.0f;
+}
+
+// CHECK: define void @func_empty_struct_ret()
+empty_struct func_empty_struct_ret()
+{
+ empty_struct s = {};
+ return s;
+}
+
+// CHECK: define i32 @single_element_struct_ret()
+// CHECK: ret i32 0
+single_element_struct_arg_t single_element_struct_ret()
+{
+ single_element_struct_arg_t s = { 0 };
+ return s;
+}
+
+// CHECK: define i32 @nested_single_element_struct_ret()
+// CHECK: ret i32 0
+nested_single_element_struct_arg_t nested_single_element_struct_ret()
+{
+ nested_single_element_struct_arg_t s = { 0 };
+ return s;
+}
+
+// CHECK: define %struct.struct_arg @func_struct_ret()
+// CHECK: ret %struct.struct_arg zeroinitializer
+struct_arg_t func_struct_ret()
+{
+ struct_arg_t s = { 0 };
+ return s;
+}
+
+// CHECK: define %struct.struct_padding_arg @func_struct_padding_ret()
+// CHECK: ret %struct.struct_padding_arg zeroinitializer
+struct_padding_arg func_struct_padding_ret()
+{
+ struct_padding_arg s = { 0 };
+ return s;
+}
+
+// CHECK: define [2 x i32] @func_struct_char_x8_ret()
+// CHECK: ret [2 x i32] zeroinitializer
+struct_char_x8 func_struct_char_x8_ret()
+{
+ struct_char_x8 s = { 0 };
+ return s;
+}
+
+// CHECK: define i32 @func_struct_char_x4_ret()
+// CHECK: ret i32 0
+struct_char_x4 func_struct_char_x4_ret()
+{
+ struct_char_x4 s = { 0 };
+ return s;
+}
+
+// CHECK: define i32 @func_struct_char_x3_ret()
+// CHECK: ret i32 0
+struct_char_x3 func_struct_char_x3_ret()
+{
+ struct_char_x3 s = { 0 };
+ return s;
+}
+
+// CHECK: define i16 @func_struct_char_x2_ret()
+struct_char_x2 func_struct_char_x2_ret()
+{
+ struct_char_x2 s = { 0 };
+ return s;
}
-// CHECK-LABEL: @test_struct_arg
-// CHECK: %struct.struct_arg %arg1.coerce
-__kernel void test_struct_arg(struct_arg_t arg1)
+// CHECK: define i8 @func_struct_char_x1_ret()
+// CHECK: ret i8 0
+struct_char_x1 func_struct_char_x1_ret()
{
+ struct_char_x1 s = { 0 };
+ return s;
}
-// CHECK-LABEL: @test_struct_of_arrays_arg
-// CHECK: %struct.struct_of_arrays_arg %arg1.coerce
-__kernel void test_struct_of_arrays_arg(struct_of_arrays_arg_t arg1)
+// CHECK: define %struct.struct_arr16 @func_ret_struct_arr16()
+// CHECK: ret %struct.struct_arr16 zeroinitializer
+struct_arr16 func_ret_struct_arr16()
{
+ struct_arr16 s = { 0 };
+ return s;
}
-// CHECK-LABEL: @test_struct_of_structs_arg
-// CHECK: %struct.struct_of_structs_arg %arg1.coerce
-__kernel void test_struct_of_structs_arg(struct_of_structs_arg_t arg1)
+// AMDGCN: define void @func_ret_struct_arr32(%struct.struct_arr32 addrspace(5)* noalias nocapture sret %agg.result)
+// R600: define void @func_ret_struct_arr32(%struct.struct_arr32* noalias nocapture sret %agg.result)
+struct_arr32 func_ret_struct_arr32()
{
+ struct_arr32 s = { 0 };
+ return s;
}
-// CHECK-LABEL: @test_non_kernel_struct_arg
-// CHECK-NOT: %struct.struct_arg %arg1.coerce
-// CHECK: %struct.struct_arg* byval
-void test_non_kernel_struct_arg(struct_arg_t arg1)
+// AMDGCN: define void @func_ret_struct_arr33(%struct.struct_arr33 addrspace(5)* noalias nocapture sret %agg.result)
+// R600: define void @func_ret_struct_arr33(%struct.struct_arr33* noalias nocapture sret %agg.result)
+struct_arr33 func_ret_struct_arr33()
{
+ struct_arr33 s = { 0 };
+ return s;
}
+
+// CHECK: define %struct.struct_char_arr32 @func_ret_struct_char_arr32()
+struct_char_arr32 func_ret_struct_char_arr32()
+{
+ struct_char_arr32 s = { 0 };
+ return s;
+}
+
+// CHECK: define i32 @func_transparent_union_ret() local_unnamed_addr #0 {
+// CHECK: ret i32 0
+transparent_u func_transparent_union_ret()
+{
+ transparent_u u = { 0 };
+ return u;
+}
+
+// CHECK: define %struct.different_size_type_pair @func_different_size_type_pair_ret()
+different_size_type_pair func_different_size_type_pair_ret()
+{
+ different_size_type_pair s = { 0 };
+ return s;
+}
+
+// AMDGCN: define void @func_flexible_array_ret(%struct.flexible_array addrspace(5)* noalias nocapture sret %agg.result)
+// R600: define void @func_flexible_array_ret(%struct.flexible_array* noalias nocapture sret %agg.result)
+flexible_array func_flexible_array_ret()
+{
+ flexible_array s = { 0 };
+ return s;
+}
+
+// CHECK: define void @func_reg_state_lo(<4 x i32> %arg0, <4 x i32> %arg1, <4 x i32> %arg2, i32 %arg3, i32 %s.coerce0, float %s.coerce1, i32 %s.coerce2)
+void func_reg_state_lo(int4 arg0, int4 arg1, int4 arg2, int arg3, struct_arg_t s) { }
+
+// AMDGCN: define void @func_reg_state_hi(<4 x i32> %arg0, <4 x i32> %arg1, <4 x i32> %arg2, i32 %arg3, i32 %arg4, %struct.struct_arg addrspace(5)* byval nocapture align 4 %s)
+// R600: define void @func_reg_state_hi(<4 x i32> %arg0, <4 x i32> %arg1, <4 x i32> %arg2, i32 %arg3, i32 %arg4, %struct.struct_arg* byval nocapture align 4 %s)
+void func_reg_state_hi(int4 arg0, int4 arg1, int4 arg2, int arg3, int arg4, struct_arg_t s) { }
+
+// XXX - Why don't the inner structs flatten?
+// AMDGCN: define void @func_reg_state_num_regs_nested_struct(<4 x i32> %arg0, i32 %arg1, i32 %arg2.coerce0, %struct.nested %arg2.coerce1, i32 %arg3.coerce0, %struct.nested %arg3.coerce1, %struct.num_regs_nested_struct addrspace(5)* byval nocapture align 8 %arg4)
+// R600: define void @func_reg_state_num_regs_nested_struct(<4 x i32> %arg0, i32 %arg1, i32 %arg2.coerce0, %struct.nested %arg2.coerce1, i32 %arg3.coerce0, %struct.nested %arg3.coerce1, %struct.num_regs_nested_struct* byval nocapture align 8 %arg4)
+void func_reg_state_num_regs_nested_struct(int4 arg0, int arg1, num_regs_nested_struct arg2, num_regs_nested_struct arg3, num_regs_nested_struct arg4) { }
+
+// CHECK: define void @func_double_nested_struct_arg(<4 x i32> %arg0, i32 %arg1, i32 %arg2.coerce0, %struct.double_nested %arg2.coerce1, i16 %arg2.coerce2)
+void func_double_nested_struct_arg(int4 arg0, int arg1, double_nested_struct arg2) { }
+
+// CHECK: define %struct.double_nested_struct @func_double_nested_struct_ret(<4 x i32> %arg0, i32 %arg1)
+double_nested_struct func_double_nested_struct_ret(int4 arg0, int arg1) {
+ double_nested_struct s = { 0 };
+ return s;
+}
+
+// CHECK: define void @func_large_struct_padding_arg_direct(i8 %arg.coerce0, i32 %arg.coerce1, i8 %arg.coerce2, i32 %arg.coerce3, i8 %arg.coerce4, i8 %arg.coerce5, i16 %arg.coerce6, i16 %arg.coerce7, [3 x i8] %arg.coerce8, i64 %arg.coerce9, i32 %arg.coerce10, i8 %arg.coerce11, i32 %arg.coerce12, i16 %arg.coerce13, i8 %arg.coerce14)
+void func_large_struct_padding_arg_direct(large_struct_padding arg) { }
+
+// AMDGCN: define void @func_large_struct_padding_arg_store(%struct.large_struct_padding addrspace(1)* nocapture %out, %struct.large_struct_padding addrspace(5)* byval nocapture readonly align 8 %arg)
+// R600: define void @func_large_struct_padding_arg_store(%struct.large_struct_padding addrspace(1)* nocapture %out, %struct.large_struct_padding* byval nocapture readonly align 8 %arg)
+void func_large_struct_padding_arg_store(global large_struct_padding* out, large_struct_padding arg) {
+ *out = arg;
+}
+
+// CHECK: define void @v3i32_reg_count(<3 x i32> %arg1, <3 x i32> %arg2, <3 x i32> %arg3, <3 x i32> %arg4, i32 %arg5.coerce0, float %arg5.coerce1, i32 %arg5.coerce2)
+void v3i32_reg_count(int3 arg1, int3 arg2, int3 arg3, int3 arg4, struct_arg_t arg5) { }
+
+// Function signature from blender, nothing should be passed byval. The v3i32
+// should not count as 4 passed registers.
+// AMDGCN: define void @v3i32_pair_reg_count(%struct.int3_pair addrspace(5)* nocapture %arg0, <3 x i32> %arg1.coerce0, <3 x i32> %arg1.coerce1, <3 x i32> %arg2, <3 x i32> %arg3.coerce0, <3 x i32> %arg3.coerce1, <3 x i32> %arg4, float %arg5)
+// R600: define void @v3i32_pair_reg_count(%struct.int3_pair* nocapture %arg0, <3 x i32> %arg1.coerce0, <3 x i32> %arg1.coerce1, <3 x i32> %arg2, <3 x i32> %arg3.coerce0, <3 x i32> %arg3.coerce1, <3 x i32> %arg4, float %arg5)
+void v3i32_pair_reg_count(int3_pair *arg0, int3_pair arg1, int3 arg2, int3_pair arg3, int3 arg4, float arg5) { }
+
+// Each short4 should fit pack into 2 registers.
+// CHECK: define void @v4i16_reg_count(<4 x i16> %arg0, <4 x i16> %arg1, <4 x i16> %arg2, <4 x i16> %arg3, <4 x i16> %arg4, <4 x i16> %arg5, i32 %arg6.coerce0, i32 %arg6.coerce1, i32 %arg6.coerce2, i32 %arg6.coerce3)
+void v4i16_reg_count(short4 arg0, short4 arg1, short4 arg2, short4 arg3,
+ short4 arg4, short4 arg5, struct_4regs arg6) { }
+
+// AMDGCN: define void @v4i16_pair_reg_count_over(<4 x i16> %arg0, <4 x i16> %arg1, <4 x i16> %arg2, <4 x i16> %arg3, <4 x i16> %arg4, <4 x i16> %arg5, <4 x i16> %arg6, %struct.struct_4regs addrspace(5)* byval nocapture align 4 %arg7)
+// R600: define void @v4i16_pair_reg_count_over(<4 x i16> %arg0, <4 x i16> %arg1, <4 x i16> %arg2, <4 x i16> %arg3, <4 x i16> %arg4, <4 x i16> %arg5, <4 x i16> %arg6, %struct.struct_4regs* byval nocapture align 4 %arg7)
+void v4i16_pair_reg_count_over(short4 arg0, short4 arg1, short4 arg2, short4 arg3,
+ short4 arg4, short4 arg5, short4 arg6, struct_4regs arg7) { }
+
+// CHECK: define void @v3i16_reg_count(<3 x i16> %arg0, <3 x i16> %arg1, <3 x i16> %arg2, <3 x i16> %arg3, <3 x i16> %arg4, <3 x i16> %arg5, i32 %arg6.coerce0, i32 %arg6.coerce1, i32 %arg6.coerce2, i32 %arg6.coerce3)
+void v3i16_reg_count(short3 arg0, short3 arg1, short3 arg2, short3 arg3,
+ short3 arg4, short3 arg5, struct_4regs arg6) { }
+
+// AMDGCN: define void @v3i16_reg_count_over(<3 x i16> %arg0, <3 x i16> %arg1, <3 x i16> %arg2, <3 x i16> %arg3, <3 x i16> %arg4, <3 x i16> %arg5, <3 x i16> %arg6, %struct.struct_4regs addrspace(5)* byval nocapture align 4 %arg7)
+// R600: define void @v3i16_reg_count_over(<3 x i16> %arg0, <3 x i16> %arg1, <3 x i16> %arg2, <3 x i16> %arg3, <3 x i16> %arg4, <3 x i16> %arg5, <3 x i16> %arg6, %struct.struct_4regs* byval nocapture align 4 %arg7)
+void v3i16_reg_count_over(short3 arg0, short3 arg1, short3 arg2, short3 arg3,
+ short3 arg4, short3 arg5, short3 arg6, struct_4regs arg7) { }
+
+// CHECK: define void @v2i16_reg_count(<2 x i16> %arg0, <2 x i16> %arg1, <2 x i16> %arg2, <2 x i16> %arg3, <2 x i16> %arg4, <2 x i16> %arg5, <2 x i16> %arg6, <2 x i16> %arg7, <2 x i16> %arg8, <2 x i16> %arg9, <2 x i16> %arg10, <2 x i16> %arg11, i32 %arg13.coerce0, i32 %arg13.coerce1, i32 %arg13.coerce2, i32 %arg13.coerce3)
+void v2i16_reg_count(short2 arg0, short2 arg1, short2 arg2, short2 arg3,
+ short2 arg4, short2 arg5, short2 arg6, short2 arg7,
+ short2 arg8, short2 arg9, short2 arg10, short2 arg11,
+ struct_4regs arg13) { }
+
+// AMDGCN: define void @v2i16_reg_count_over(<2 x i16> %arg0, <2 x i16> %arg1, <2 x i16> %arg2, <2 x i16> %arg3, <2 x i16> %arg4, <2 x i16> %arg5, <2 x i16> %arg6, <2 x i16> %arg7, <2 x i16> %arg8, <2 x i16> %arg9, <2 x i16> %arg10, <2 x i16> %arg11, <2 x i16> %arg12, %struct.struct_4regs addrspace(5)* byval nocapture align 4 %arg13)
+// R600: define void @v2i16_reg_count_over(<2 x i16> %arg0, <2 x i16> %arg1, <2 x i16> %arg2, <2 x i16> %arg3, <2 x i16> %arg4, <2 x i16> %arg5, <2 x i16> %arg6, <2 x i16> %arg7, <2 x i16> %arg8, <2 x i16> %arg9, <2 x i16> %arg10, <2 x i16> %arg11, <2 x i16> %arg12, %struct.struct_4regs* byval nocapture align 4 %arg13)
+void v2i16_reg_count_over(short2 arg0, short2 arg1, short2 arg2, short2 arg3,
+ short2 arg4, short2 arg5, short2 arg6, short2 arg7,
+ short2 arg8, short2 arg9, short2 arg10, short2 arg11,
+ short2 arg12, struct_4regs arg13) { }
+
+// CHECK: define void @v2i8_reg_count(<2 x i8> %arg0, <2 x i8> %arg1, <2 x i8> %arg2, <2 x i8> %arg3, <2 x i8> %arg4, <2 x i8> %arg5, i32 %arg6.coerce0, i32 %arg6.coerce1, i32 %arg6.coerce2, i32 %arg6.coerce3)
+void v2i8_reg_count(char2 arg0, char2 arg1, char2 arg2, char2 arg3,
+ char2 arg4, char2 arg5, struct_4regs arg6) { }
+
+// AMDGCN: define void @v2i8_reg_count_over(<2 x i8> %arg0, <2 x i8> %arg1, <2 x i8> %arg2, <2 x i8> %arg3, <2 x i8> %arg4, <2 x i8> %arg5, i32 %arg6, %struct.struct_4regs addrspace(5)* byval nocapture align 4 %arg7)
+// R600: define void @v2i8_reg_count_over(<2 x i8> %arg0, <2 x i8> %arg1, <2 x i8> %arg2, <2 x i8> %arg3, <2 x i8> %arg4, <2 x i8> %arg5, i32 %arg6, %struct.struct_4regs* byval nocapture align 4 %arg7)
+void v2i8_reg_count_over(char2 arg0, char2 arg1, char2 arg2, char2 arg3,
+ char2 arg4, char2 arg5, int arg6, struct_4regs arg7) { }
+
+// CHECK: define void @num_regs_left_64bit_aggregate(<4 x i32> %arg0, <4 x i32> %arg1, <4 x i32> %arg2, <3 x i32> %arg3, [2 x i32] %arg4.coerce, i32 %arg5)
+void num_regs_left_64bit_aggregate(int4 arg0, int4 arg1, int4 arg2, int3 arg3, struct_char_x8 arg4, int arg5) { }
diff --git a/test/CodeGenOpenCL/amdgpu-attrs.cl b/test/CodeGenOpenCL/amdgpu-attrs.cl
index 230e0948f8cc..2696123f1434 100644
--- a/test/CodeGenOpenCL/amdgpu-attrs.cl
+++ b/test/CodeGenOpenCL/amdgpu-attrs.cl
@@ -151,28 +151,28 @@ kernel void reqd_work_group_size_32_2_1_flat_work_group_size_16_128() {
// CHECK-NOT: "amdgpu-num-sgpr"="0"
// CHECK-NOT: "amdgpu-num-vgpr"="0"
-// CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_32_64]] = { noinline nounwind optnone "amdgpu-flat-work-group-size"="32,64"
-// CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_64_64]] = { noinline nounwind optnone "amdgpu-flat-work-group-size"="64,64"
-// CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_16_128]] = { noinline nounwind optnone "amdgpu-flat-work-group-size"="16,128"
-// CHECK-DAG: attributes [[WAVES_PER_EU_2]] = { noinline nounwind optnone "amdgpu-waves-per-eu"="2"
-// CHECK-DAG: attributes [[WAVES_PER_EU_2_4]] = { noinline nounwind optnone "amdgpu-waves-per-eu"="2,4"
-// CHECK-DAG: attributes [[NUM_SGPR_32]] = { noinline nounwind optnone "amdgpu-num-sgpr"="32"
-// CHECK-DAG: attributes [[NUM_VGPR_64]] = { noinline nounwind optnone "amdgpu-num-vgpr"="64"
-
-// CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_32_64_WAVES_PER_EU_2]] = { noinline nounwind optnone "amdgpu-flat-work-group-size"="32,64" "amdgpu-waves-per-eu"="2"
-// CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_32_64_WAVES_PER_EU_2_4]] = { noinline nounwind optnone "amdgpu-flat-work-group-size"="32,64" "amdgpu-waves-per-eu"="2,4"
-// CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_32_64_NUM_SGPR_32]] = { noinline nounwind optnone "amdgpu-flat-work-group-size"="32,64" "amdgpu-num-sgpr"="32"
-// CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_32_64_NUM_VGPR_64]] = { noinline nounwind optnone "amdgpu-flat-work-group-size"="32,64" "amdgpu-num-vgpr"="64"
-// CHECK-DAG: attributes [[WAVES_PER_EU_2_NUM_SGPR_32]] = { noinline nounwind optnone "amdgpu-num-sgpr"="32" "amdgpu-waves-per-eu"="2"
-// CHECK-DAG: attributes [[WAVES_PER_EU_2_NUM_VGPR_64]] = { noinline nounwind optnone "amdgpu-num-vgpr"="64" "amdgpu-waves-per-eu"="2"
-// CHECK-DAG: attributes [[WAVES_PER_EU_2_4_NUM_SGPR_32]] = { noinline nounwind optnone "amdgpu-num-sgpr"="32" "amdgpu-waves-per-eu"="2,4"
-// CHECK-DAG: attributes [[WAVES_PER_EU_2_4_NUM_VGPR_64]] = { noinline nounwind optnone "amdgpu-num-vgpr"="64" "amdgpu-waves-per-eu"="2,4"
-// CHECK-DAG: attributes [[NUM_SGPR_32_NUM_VGPR_64]] = { noinline nounwind optnone "amdgpu-num-sgpr"="32" "amdgpu-num-vgpr"="64"
-
-// CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_32_64_WAVES_PER_EU_2_NUM_SGPR_32]] = { noinline nounwind optnone "amdgpu-flat-work-group-size"="32,64" "amdgpu-num-sgpr"="32" "amdgpu-waves-per-eu"="2"
-// CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_32_64_WAVES_PER_EU_2_NUM_VGPR_64]] = { noinline nounwind optnone "amdgpu-flat-work-group-size"="32,64" "amdgpu-num-vgpr"="64" "amdgpu-waves-per-eu"="2"
-// CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_32_64_WAVES_PER_EU_2_4_NUM_SGPR_32]] = { noinline nounwind optnone "amdgpu-flat-work-group-size"="32,64" "amdgpu-num-sgpr"="32" "amdgpu-waves-per-eu"="2,4"
-// CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_32_64_WAVES_PER_EU_2_4_NUM_VGPR_64]] = { noinline nounwind optnone "amdgpu-flat-work-group-size"="32,64" "amdgpu-num-vgpr"="64" "amdgpu-waves-per-eu"="2,4"
-
-// CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_32_64_WAVES_PER_EU_2_NUM_SGPR_32_NUM_VGPR_64]] = { noinline nounwind optnone "amdgpu-flat-work-group-size"="32,64" "amdgpu-num-sgpr"="32" "amdgpu-num-vgpr"="64" "amdgpu-waves-per-eu"="2"
-// CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_32_64_WAVES_PER_EU_2_4_NUM_SGPR_32_NUM_VGPR_64]] = { noinline nounwind optnone "amdgpu-flat-work-group-size"="32,64" "amdgpu-num-sgpr"="32" "amdgpu-num-vgpr"="64" "amdgpu-waves-per-eu"="2,4"
+// CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_32_64]] = { convergent noinline nounwind optnone "amdgpu-flat-work-group-size"="32,64"
+// CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_64_64]] = { convergent noinline nounwind optnone "amdgpu-flat-work-group-size"="64,64"
+// CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_16_128]] = { convergent noinline nounwind optnone "amdgpu-flat-work-group-size"="16,128"
+// CHECK-DAG: attributes [[WAVES_PER_EU_2]] = { convergent noinline nounwind optnone "amdgpu-waves-per-eu"="2"
+// CHECK-DAG: attributes [[WAVES_PER_EU_2_4]] = { convergent noinline nounwind optnone "amdgpu-waves-per-eu"="2,4"
+// CHECK-DAG: attributes [[NUM_SGPR_32]] = { convergent noinline nounwind optnone "amdgpu-num-sgpr"="32"
+// CHECK-DAG: attributes [[NUM_VGPR_64]] = { convergent noinline nounwind optnone "amdgpu-num-vgpr"="64"
+
+// CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_32_64_WAVES_PER_EU_2]] = { convergent noinline nounwind optnone "amdgpu-flat-work-group-size"="32,64" "amdgpu-waves-per-eu"="2"
+// CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_32_64_WAVES_PER_EU_2_4]] = { convergent noinline nounwind optnone "amdgpu-flat-work-group-size"="32,64" "amdgpu-waves-per-eu"="2,4"
+// CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_32_64_NUM_SGPR_32]] = { convergent noinline nounwind optnone "amdgpu-flat-work-group-size"="32,64" "amdgpu-num-sgpr"="32"
+// CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_32_64_NUM_VGPR_64]] = { convergent noinline nounwind optnone "amdgpu-flat-work-group-size"="32,64" "amdgpu-num-vgpr"="64"
+// CHECK-DAG: attributes [[WAVES_PER_EU_2_NUM_SGPR_32]] = { convergent noinline nounwind optnone "amdgpu-num-sgpr"="32" "amdgpu-waves-per-eu"="2"
+// CHECK-DAG: attributes [[WAVES_PER_EU_2_NUM_VGPR_64]] = { convergent noinline nounwind optnone "amdgpu-num-vgpr"="64" "amdgpu-waves-per-eu"="2"
+// CHECK-DAG: attributes [[WAVES_PER_EU_2_4_NUM_SGPR_32]] = { convergent noinline nounwind optnone "amdgpu-num-sgpr"="32" "amdgpu-waves-per-eu"="2,4"
+// CHECK-DAG: attributes [[WAVES_PER_EU_2_4_NUM_VGPR_64]] = { convergent noinline nounwind optnone "amdgpu-num-vgpr"="64" "amdgpu-waves-per-eu"="2,4"
+// CHECK-DAG: attributes [[NUM_SGPR_32_NUM_VGPR_64]] = { convergent noinline nounwind optnone "amdgpu-num-sgpr"="32" "amdgpu-num-vgpr"="64"
+
+// CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_32_64_WAVES_PER_EU_2_NUM_SGPR_32]] = { convergent noinline nounwind optnone "amdgpu-flat-work-group-size"="32,64" "amdgpu-num-sgpr"="32" "amdgpu-waves-per-eu"="2"
+// CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_32_64_WAVES_PER_EU_2_NUM_VGPR_64]] = { convergent noinline nounwind optnone "amdgpu-flat-work-group-size"="32,64" "amdgpu-num-vgpr"="64" "amdgpu-waves-per-eu"="2"
+// CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_32_64_WAVES_PER_EU_2_4_NUM_SGPR_32]] = { convergent noinline nounwind optnone "amdgpu-flat-work-group-size"="32,64" "amdgpu-num-sgpr"="32" "amdgpu-waves-per-eu"="2,4"
+// CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_32_64_WAVES_PER_EU_2_4_NUM_VGPR_64]] = { convergent noinline nounwind optnone "amdgpu-flat-work-group-size"="32,64" "amdgpu-num-vgpr"="64" "amdgpu-waves-per-eu"="2,4"
+
+// CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_32_64_WAVES_PER_EU_2_NUM_SGPR_32_NUM_VGPR_64]] = { convergent noinline nounwind optnone "amdgpu-flat-work-group-size"="32,64" "amdgpu-num-sgpr"="32" "amdgpu-num-vgpr"="64" "amdgpu-waves-per-eu"="2"
+// CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_32_64_WAVES_PER_EU_2_4_NUM_SGPR_32_NUM_VGPR_64]] = { convergent noinline nounwind optnone "amdgpu-flat-work-group-size"="32,64" "amdgpu-num-sgpr"="32" "amdgpu-num-vgpr"="64" "amdgpu-waves-per-eu"="2,4"
diff --git a/test/CodeGenOpenCL/amdgpu-debug-info-variable-expression.cl b/test/CodeGenOpenCL/amdgpu-debug-info-variable-expression.cl
index d3b2869896f1..4d46b40561ee 100644
--- a/test/CodeGenOpenCL/amdgpu-debug-info-variable-expression.cl
+++ b/test/CodeGenOpenCL/amdgpu-debug-info-variable-expression.cl
@@ -1,131 +1,128 @@
// RUN: %clang -cl-std=CL2.0 -emit-llvm -g -O0 -S -target amdgcn-amd-amdhsa -mcpu=fiji -o - %s | FileCheck %s
// RUN: %clang -cl-std=CL2.0 -emit-llvm -g -O0 -S -target amdgcn-amd-amdhsa-opencl -mcpu=fiji -o - %s | FileCheck %s
-// CHECK-DAG: ![[LOCAL:[0-9]+]] = !DIExpression(DW_OP_constu, 2, DW_OP_swap, DW_OP_xderef)
-// CHECK-DAG: ![[PRIVATE:[0-9]+]] = !DIExpression(DW_OP_constu, 1, DW_OP_swap, DW_OP_xderef)
-
// CHECK-DAG: ![[FILEVAR0:[0-9]+]] = distinct !DIGlobalVariable(name: "FileVar0", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: false, isDefinition: true)
-// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR0]])
+// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR0]], expr: !DIExpression())
global int *FileVar0;
// CHECK-DAG: ![[FILEVAR1:[0-9]+]] = distinct !DIGlobalVariable(name: "FileVar1", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: false, isDefinition: true)
-// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR1]])
+// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR1]], expr: !DIExpression())
constant int *FileVar1;
// CHECK-DAG: ![[FILEVAR2:[0-9]+]] = distinct !DIGlobalVariable(name: "FileVar2", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: false, isDefinition: true)
-// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR2]])
+// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR2]], expr: !DIExpression())
local int *FileVar2;
// CHECK-DAG: ![[FILEVAR3:[0-9]+]] = distinct !DIGlobalVariable(name: "FileVar3", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: false, isDefinition: true)
-// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR3]])
+// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR3]], expr: !DIExpression())
private int *FileVar3;
// CHECK-DAG: ![[FILEVAR4:[0-9]+]] = distinct !DIGlobalVariable(name: "FileVar4", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: false, isDefinition: true)
-// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR4]])
+// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR4]], expr: !DIExpression())
int *FileVar4;
// CHECK-DAG: ![[FILEVAR5:[0-9]+]] = distinct !DIGlobalVariable(name: "FileVar5", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: false, isDefinition: true)
-// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR5]])
+// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR5]], expr: !DIExpression())
global int *global FileVar5;
// CHECK-DAG: ![[FILEVAR6:[0-9]+]] = distinct !DIGlobalVariable(name: "FileVar6", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: false, isDefinition: true)
-// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR6]])
+// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR6]], expr: !DIExpression())
constant int *global FileVar6;
// CHECK-DAG: ![[FILEVAR7:[0-9]+]] = distinct !DIGlobalVariable(name: "FileVar7", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: false, isDefinition: true)
-// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR7]])
+// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR7]], expr: !DIExpression())
local int *global FileVar7;
// CHECK-DAG: ![[FILEVAR8:[0-9]+]] = distinct !DIGlobalVariable(name: "FileVar8", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: false, isDefinition: true)
-// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR8]])
+// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR8]], expr: !DIExpression())
private int *global FileVar8;
// CHECK-DAG: ![[FILEVAR9:[0-9]+]] = distinct !DIGlobalVariable(name: "FileVar9", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: false, isDefinition: true)
-// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR9]])
+// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR9]], expr: !DIExpression())
int *global FileVar9;
// CHECK-DAG: ![[FILEVAR10:[0-9]+]] = distinct !DIGlobalVariable(name: "FileVar10", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: false, isDefinition: true)
-// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR10]])
+// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR10]], expr: !DIExpression())
global int *constant FileVar10 = 0;
// CHECK-DAG: ![[FILEVAR11:[0-9]+]] = distinct !DIGlobalVariable(name: "FileVar11", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: false, isDefinition: true)
-// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR11]])
+// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR11]], expr: !DIExpression())
constant int *constant FileVar11 = 0;
// CHECK-DAG: ![[FILEVAR12:[0-9]+]] = distinct !DIGlobalVariable(name: "FileVar12", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: false, isDefinition: true)
-// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR12]])
+// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR12]], expr: !DIExpression())
local int *constant FileVar12 = 0;
// CHECK-DAG: ![[FILEVAR13:[0-9]+]] = distinct !DIGlobalVariable(name: "FileVar13", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: false, isDefinition: true)
-// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR13]])
+// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR13]], expr: !DIExpression())
private int *constant FileVar13 = 0;
// CHECK-DAG: ![[FILEVAR14:[0-9]+]] = distinct !DIGlobalVariable(name: "FileVar14", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: false, isDefinition: true)
-// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR14]])
+// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR14]], expr: !DIExpression())
int *constant FileVar14 = 0;
kernel void kernel1(
// CHECK-DAG: ![[KERNELARG0:[0-9]+]] = !DILocalVariable(name: "KernelArg0", arg: {{[0-9]+}}, scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
- // CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(1)** {{.*}}, metadata ![[KERNELARG0]], metadata ![[PRIVATE]]), !dbg !{{[0-9]+}}
+ // CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(1)** {{.*}}, metadata ![[KERNELARG0]], metadata !DIExpression(DW_OP_constu, 1, DW_OP_swap, DW_OP_xderef)), !dbg !{{[0-9]+}}
global int *KernelArg0,
// CHECK-DAG: ![[KERNELARG1:[0-9]+]] = !DILocalVariable(name: "KernelArg1", arg: {{[0-9]+}}, scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
- // CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(2)** {{.*}}, metadata ![[KERNELARG1]], metadata ![[PRIVATE]]), !dbg !{{[0-9]+}}
+ // CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(2)** {{.*}}, metadata ![[KERNELARG1]], metadata !DIExpression(DW_OP_constu, 1, DW_OP_swap, DW_OP_xderef)), !dbg !{{[0-9]+}}
constant int *KernelArg1,
// CHECK-DAG: ![[KERNELARG2:[0-9]+]] = !DILocalVariable(name: "KernelArg2", arg: {{[0-9]+}}, scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
- // CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(3)** {{.*}}, metadata ![[KERNELARG2]], metadata ![[PRIVATE]]), !dbg !{{[0-9]+}}
+ // CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(3)** {{.*}}, metadata ![[KERNELARG2]], metadata !DIExpression(DW_OP_constu, 1, DW_OP_swap, DW_OP_xderef)), !dbg !{{[0-9]+}}
local int *KernelArg2) {
private int *Tmp0;
int *Tmp1;
// CHECK-DAG: ![[FUNCVAR0:[0-9]+]] = !DILocalVariable(name: "FuncVar0", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
- // CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(1)** {{.*}}, metadata ![[FUNCVAR0]], metadata ![[PRIVATE]]), !dbg !{{[0-9]+}}
+ // CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(1)** {{.*}}, metadata ![[FUNCVAR0]], metadata !DIExpression(DW_OP_constu, 1, DW_OP_swap, DW_OP_xderef)), !dbg !{{[0-9]+}}
global int *FuncVar0 = KernelArg0;
// CHECK-DAG: ![[FUNCVAR1:[0-9]+]] = !DILocalVariable(name: "FuncVar1", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
- // CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(2)** {{.*}}, metadata ![[FUNCVAR1]], metadata ![[PRIVATE]]), !dbg !{{[0-9]+}}
+ // CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(2)** {{.*}}, metadata ![[FUNCVAR1]], metadata !DIExpression(DW_OP_constu, 1, DW_OP_swap, DW_OP_xderef)), !dbg !{{[0-9]+}}
constant int *FuncVar1 = KernelArg1;
// CHECK-DAG: ![[FUNCVAR2:[0-9]+]] = !DILocalVariable(name: "FuncVar2", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
- // CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(3)** {{.*}}, metadata ![[FUNCVAR2]], metadata ![[PRIVATE]]), !dbg !{{[0-9]+}}
+ // CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(3)** {{.*}}, metadata ![[FUNCVAR2]], metadata !DIExpression(DW_OP_constu, 1, DW_OP_swap, DW_OP_xderef)), !dbg !{{[0-9]+}}
local int *FuncVar2 = KernelArg2;
// CHECK-DAG: ![[FUNCVAR3:[0-9]+]] = !DILocalVariable(name: "FuncVar3", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
- // CHECK-DAG: call void @llvm.dbg.declare(metadata i32** {{.*}}, metadata ![[FUNCVAR3]], metadata ![[PRIVATE]]), !dbg !{{[0-9]+}}
+ // CHECK-DAG: call void @llvm.dbg.declare(metadata i32** {{.*}}, metadata ![[FUNCVAR3]], metadata !DIExpression(DW_OP_constu, 1, DW_OP_swap, DW_OP_xderef)), !dbg !{{[0-9]+}}
private int *FuncVar3 = Tmp0;
// CHECK-DAG: ![[FUNCVAR4:[0-9]+]] = !DILocalVariable(name: "FuncVar4", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
- // CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(4)** {{.*}}, metadata ![[FUNCVAR4]], metadata ![[PRIVATE]]), !dbg !{{[0-9]+}}
+ // CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(4)** {{.*}}, metadata ![[FUNCVAR4]], metadata !DIExpression(DW_OP_constu, 1, DW_OP_swap, DW_OP_xderef)), !dbg !{{[0-9]+}}
int *FuncVar4 = Tmp1;
// CHECK-DAG: ![[FUNCVAR5:[0-9]+]] = distinct !DIGlobalVariable(name: "FuncVar5", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: true, isDefinition: true)
- // CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR5]])
+ // CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR5]], expr: !DIExpression())
global int *constant FuncVar5 = 0;
// CHECK-DAG: ![[FUNCVAR6:[0-9]+]] = distinct !DIGlobalVariable(name: "FuncVar6", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: true, isDefinition: true)
- // CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR6]])
+ // CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR6]], expr: !DIExpression())
constant int *constant FuncVar6 = 0;
// CHECK-DAG: ![[FUNCVAR7:[0-9]+]] = distinct !DIGlobalVariable(name: "FuncVar7", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: true, isDefinition: true)
- // CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR7]])
+ // CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR7]], expr: !DIExpression())
local int *constant FuncVar7 = 0;
// CHECK-DAG: ![[FUNCVAR8:[0-9]+]] = distinct !DIGlobalVariable(name: "FuncVar8", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: true, isDefinition: true)
- // CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR8]])
+ // CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR8]], expr: !DIExpression())
private int *constant FuncVar8 = 0;
// CHECK-DAG: ![[FUNCVAR9:[0-9]+]] = distinct !DIGlobalVariable(name: "FuncVar9", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: true, isDefinition: true)
- // CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR9]])
+ // CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR9]], expr: !DIExpression())
int *constant FuncVar9 = 0;
// CHECK-DAG: ![[FUNCVAR10:[0-9]+]] = distinct !DIGlobalVariable(name: "FuncVar10", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: true, isDefinition: true)
- // CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR10]], expr: ![[LOCAL]])
+ // CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR10]], expr: !DIExpression(DW_OP_constu, 2, DW_OP_swap, DW_OP_xderef))
global int *local FuncVar10; FuncVar10 = KernelArg0;
// CHECK-DAG: ![[FUNCVAR11:[0-9]+]] = distinct !DIGlobalVariable(name: "FuncVar11", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: true, isDefinition: true)
- // CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR11]], expr: ![[LOCAL]])
+ // CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR11]], expr: !DIExpression(DW_OP_constu, 2, DW_OP_swap, DW_OP_xderef))
constant int *local FuncVar11; FuncVar11 = KernelArg1;
// CHECK-DAG: ![[FUNCVAR12:[0-9]+]] = distinct !DIGlobalVariable(name: "FuncVar12", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: true, isDefinition: true)
- // CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR12]], expr: ![[LOCAL]])
+ // CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR12]], expr: !DIExpression(DW_OP_constu, 2, DW_OP_swap, DW_OP_xderef))
local int *local FuncVar12; FuncVar12 = KernelArg2;
// CHECK-DAG: ![[FUNCVAR13:[0-9]+]] = distinct !DIGlobalVariable(name: "FuncVar13", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: true, isDefinition: true)
- // CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR13]], expr: ![[LOCAL]])
+ // CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR13]], expr: !DIExpression(DW_OP_constu, 2, DW_OP_swap, DW_OP_xderef))
private int *local FuncVar13; FuncVar13 = Tmp0;
// CHECK-DAG: ![[FUNCVAR14:[0-9]+]] = distinct !DIGlobalVariable(name: "FuncVar14", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: true, isDefinition: true)
- // CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR14]], expr: ![[LOCAL]])
+ // CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR14]], expr: !DIExpression(DW_OP_constu, 2, DW_OP_swap, DW_OP_xderef))
int *local FuncVar14; FuncVar14 = Tmp1;
// CHECK-DAG: ![[FUNCVAR15:[0-9]+]] = !DILocalVariable(name: "FuncVar15", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
- // CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(1)** {{.*}}, metadata ![[FUNCVAR15]], metadata ![[PRIVATE]]), !dbg !{{[0-9]+}}
+ // CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(1)** {{.*}}, metadata ![[FUNCVAR15]], metadata !DIExpression(DW_OP_constu, 1, DW_OP_swap, DW_OP_xderef)), !dbg !{{[0-9]+}}
global int *private FuncVar15 = KernelArg0;
// CHECK-DAG: ![[FUNCVAR16:[0-9]+]] = !DILocalVariable(name: "FuncVar16", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
- // CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(2)** {{.*}}, metadata ![[FUNCVAR16]], metadata ![[PRIVATE]]), !dbg !{{[0-9]+}}
+ // CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(2)** {{.*}}, metadata ![[FUNCVAR16]], metadata !DIExpression(DW_OP_constu, 1, DW_OP_swap, DW_OP_xderef)), !dbg !{{[0-9]+}}
constant int *private FuncVar16 = KernelArg1;
// CHECK-DAG: ![[FUNCVAR17:[0-9]+]] = !DILocalVariable(name: "FuncVar17", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
- // CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(3)** {{.*}}, metadata ![[FUNCVAR17]], metadata ![[PRIVATE]]), !dbg !{{[0-9]+}}
+ // CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(3)** {{.*}}, metadata ![[FUNCVAR17]], metadata !DIExpression(DW_OP_constu, 1, DW_OP_swap, DW_OP_xderef)), !dbg !{{[0-9]+}}
local int *private FuncVar17 = KernelArg2;
// CHECK-DAG: ![[FUNCVAR18:[0-9]+]] = !DILocalVariable(name: "FuncVar18", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
- // CHECK-DAG: call void @llvm.dbg.declare(metadata i32** {{.*}}, metadata ![[FUNCVAR18]], metadata ![[PRIVATE]]), !dbg !{{[0-9]+}}
+ // CHECK-DAG: call void @llvm.dbg.declare(metadata i32** {{.*}}, metadata ![[FUNCVAR18]], metadata !DIExpression(DW_OP_constu, 1, DW_OP_swap, DW_OP_xderef)), !dbg !{{[0-9]+}}
private int *private FuncVar18 = Tmp0;
// CHECK-DAG: ![[FUNCVAR19:[0-9]+]] = !DILocalVariable(name: "FuncVar19", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
- // CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(4)** {{.*}}, metadata ![[FUNCVAR19]], metadata ![[PRIVATE]]), !dbg !{{[0-9]+}}
+ // CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(4)** {{.*}}, metadata ![[FUNCVAR19]], metadata !DIExpression(DW_OP_constu, 1, DW_OP_swap, DW_OP_xderef)), !dbg !{{[0-9]+}}
int *private FuncVar19 = Tmp1;
}
diff --git a/test/CodeGenOpenCL/amdgpu-enqueue-kernel.cl b/test/CodeGenOpenCL/amdgpu-enqueue-kernel.cl
new file mode 100644
index 000000000000..b2db4d782719
--- /dev/null
+++ b/test/CodeGenOpenCL/amdgpu-enqueue-kernel.cl
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 %s -cl-std=CL2.0 -O0 -emit-llvm -o - -triple amdgcn | FileCheck %s --check-prefix=CHECK
+
+typedef struct {int a;} ndrange_t;
+
+// CHECK-LABEL: define amdgpu_kernel void @test
+kernel void test(global char *a, char b, global long *c, long d) {
+ queue_t default_queue;
+ unsigned flags = 0;
+ ndrange_t ndrange;
+
+ enqueue_kernel(default_queue, flags, ndrange,
+ ^(void) {
+ a[0] = b;
+ });
+
+ enqueue_kernel(default_queue, flags, ndrange,
+ ^(void) {
+ a[0] = b;
+ c[0] = d;
+ });
+ enqueue_kernel(default_queue, flags, ndrange,
+ ^(local void *lp) {
+ a[0] = b;
+ c[0] = d;
+ ((local int*)lp)[0] = 1;
+ }, 100);
+}
+
+// CHECK-LABEL: define internal amdgpu_kernel void @__test_block_invoke_kernel(<{ i32, i32, i8 addrspace(4)*, i8 addrspace(1)*, i8 }>)
+// CHECK-SAME: #[[ATTR:[0-9]+]] !kernel_arg_addr_space !{{.*}} !kernel_arg_access_qual !{{.*}} !kernel_arg_type !{{.*}} !kernel_arg_base_type !{{.*}} !kernel_arg_type_qual !{{.*}}
+// CHECK: entry:
+// CHECK: %1 = alloca <{ i32, i32, i8 addrspace(4)*, i8 addrspace(1)*, i8 }>, align 8
+// CHECK: store <{ i32, i32, i8 addrspace(4)*, i8 addrspace(1)*, i8 }> %0, <{ i32, i32, i8 addrspace(4)*, i8 addrspace(1)*, i8 }>* %1, align 8
+// CHECK: %2 = addrspacecast <{ i32, i32, i8 addrspace(4)*, i8 addrspace(1)*, i8 }>* %1 to i8 addrspace(4)*
+// CHECK: call void @__test_block_invoke(i8 addrspace(4)* %2)
+// CHECK: ret void
+// CHECK:}
+
+// CHECK-LABEL: define internal amdgpu_kernel void @__test_block_invoke_2_kernel(<{ i32, i32, i8 addrspace(4)*, i8 addrspace(1)*, i64 addrspace(1)*, i64, i8 }>)
+// CHECK-SAME: #[[ATTR]] !kernel_arg_addr_space !{{.*}} !kernel_arg_access_qual !{{.*}} !kernel_arg_type !{{.*}} !kernel_arg_base_type !{{.*}} !kernel_arg_type_qual !{{.*}}
+
+// CHECK-LABEL: define internal amdgpu_kernel void @__test_block_invoke_3_kernel(<{ i32, i32, i8 addrspace(4)*, i8 addrspace(1)*, i64 addrspace(1)*, i64, i8 }>, i8 addrspace(3)*)
+// CHECK-SAME: #[[ATTR]] !kernel_arg_addr_space !{{.*}} !kernel_arg_access_qual !{{.*}} !kernel_arg_type !{{.*}} !kernel_arg_base_type !{{.*}} !kernel_arg_type_qual !{{.*}}
+
+// CHECK: attributes #[[ATTR]] = { nounwind "enqueued-block" }
diff --git a/test/CodeGenOpenCL/amdgpu-nullptr.cl b/test/CodeGenOpenCL/amdgpu-nullptr.cl
index 69f54fcaa483..513d56c19d60 100644
--- a/test/CodeGenOpenCL/amdgpu-nullptr.cl
+++ b/test/CodeGenOpenCL/amdgpu-nullptr.cl
@@ -511,9 +511,9 @@ typedef struct {
// CHECK-LABEL: test_memset_private
// CHECK: call void @llvm.memset.p0i8.i64(i8* nonnull {{.*}}, i8 0, i64 40, i32 8, i1 false)
-StructTy3 test_memset_private(void) {
+void test_memset_private(private StructTy3 *ptr) {
StructTy3 S3 = {0, 0, 0, 0, 0};
- return S3;
+ *ptr = S3;
}
// Test casting literal 0 to pointer.
diff --git a/test/CodeGenOpenCL/atomic-ops-libcall.cl b/test/CodeGenOpenCL/atomic-ops-libcall.cl
new file mode 100644
index 000000000000..a6f7e14f29c3
--- /dev/null
+++ b/test/CodeGenOpenCL/atomic-ops-libcall.cl
@@ -0,0 +1,82 @@
+// RUN: %clang_cc1 < %s -cl-std=CL2.0 -triple spir64 -emit-llvm | FileCheck -check-prefix=SPIR %s
+// RUN: %clang_cc1 < %s -cl-std=CL2.0 -triple armv5e-none-linux-gnueabi -emit-llvm | FileCheck -check-prefix=ARM %s
+typedef enum memory_order {
+ memory_order_relaxed = __ATOMIC_RELAXED,
+ memory_order_acquire = __ATOMIC_ACQUIRE,
+ memory_order_release = __ATOMIC_RELEASE,
+ memory_order_acq_rel = __ATOMIC_ACQ_REL,
+ memory_order_seq_cst = __ATOMIC_SEQ_CST
+} memory_order;
+
+typedef enum memory_scope {
+ memory_scope_work_item = __OPENCL_MEMORY_SCOPE_WORK_ITEM,
+ memory_scope_work_group = __OPENCL_MEMORY_SCOPE_WORK_GROUP,
+ memory_scope_device = __OPENCL_MEMORY_SCOPE_DEVICE,
+ memory_scope_all_svm_devices = __OPENCL_MEMORY_SCOPE_ALL_SVM_DEVICES,
+#if defined(cl_intel_subgroups) || defined(cl_khr_subgroups)
+ memory_scope_sub_group = __OPENCL_MEMORY_SCOPE_SUB_GROUP
+#endif
+} memory_scope;
+
+void f(atomic_int *i, global atomic_int *gi, local atomic_int *li, private atomic_int *pi, atomic_uint *ui, int cmp, int order, int scope) {
+ int x;
+ // SPIR: {{%[^ ]*}} = call i32 @__opencl_atomic_load_4(i8 addrspace(4)* {{%[0-9]+}}, i32 5, i32 1)
+ // ARM: {{%[^ ]*}} = call i32 @__opencl_atomic_load_4(i8* {{%[0-9]+}}, i32 5, i32 1)
+ x = __opencl_atomic_load(i, memory_order_seq_cst, memory_scope_work_group);
+
+ // SPIR: call void @__opencl_atomic_store_4(i8 addrspace(4)* {{%[0-9]+}}, i32 {{%[0-9]+}}, i32 5, i32 1)
+ // ARM: call void @__opencl_atomic_store_4(i8* {{%[0-9]+}}, i32 {{%[0-9]+}}, i32 5, i32 1)
+ __opencl_atomic_store(i, 1, memory_order_seq_cst, memory_scope_work_group);
+
+ // SPIR: %[[GP:[0-9]+]] = addrspacecast i8 addrspace(1)* {{%[0-9]+}} to i8 addrspace(4)*
+ // SPIR: call void @__opencl_atomic_store_4(i8 addrspace(4)* %[[GP]], i32 {{%[0-9]+}}, i32 5, i32 1)
+ // ARM: call void @__opencl_atomic_store_4(i8* {{%[0-9]+}}, i32 {{%[0-9]+}}, i32 5, i32 1)
+ __opencl_atomic_store(gi, 1, memory_order_seq_cst, memory_scope_work_group);
+
+ // SPIR: %[[GP:[0-9]+]] = addrspacecast i8 addrspace(3)* {{%[0-9]+}} to i8 addrspace(4)*
+ // SPIR: call void @__opencl_atomic_store_4(i8 addrspace(4)* %[[GP]], i32 {{%[0-9]+}}, i32 5, i32 1)
+ // ARM: call void @__opencl_atomic_store_4(i8* {{%[0-9]+}}, i32 {{%[0-9]+}}, i32 5, i32 1)
+ __opencl_atomic_store(li, 1, memory_order_seq_cst, memory_scope_work_group);
+
+ // SPIR: %[[GP:[0-9]+]] = addrspacecast i8* {{%[0-9]+}} to i8 addrspace(4)*
+ // SPIR: call void @__opencl_atomic_store_4(i8 addrspace(4)* %[[GP]], i32 {{%[0-9]+}}, i32 5, i32 1)
+ // ARM: call void @__opencl_atomic_store_4(i8* {{%[0-9]+}}, i32 {{%[0-9]+}}, i32 5, i32 1)
+ __opencl_atomic_store(pi, 1, memory_order_seq_cst, memory_scope_work_group);
+
+ // SPIR: {{%[^ ]*}} = call i32 @__opencl_atomic_fetch_add_4(i8 addrspace(4)* {{%[0-9]+}}, i32 {{%[0-9]+}}, i32 5, i32 1)
+ // ARM: {{%[^ ]*}} = call i32 @__opencl_atomic_fetch_add_4(i8* {{%[0-9]+}}, i32 {{%[0-9]+}}, i32 5, i32 1)
+ x = __opencl_atomic_fetch_add(i, 3, memory_order_seq_cst, memory_scope_work_group);
+
+ // SPIR: {{%[^ ]*}} = call i32 @__opencl_atomic_fetch_min_4(i8 addrspace(4)* {{%[0-9]+}}, i32 {{%[0-9]+}}, i32 5, i32 1)
+ // ARM: {{%[^ ]*}} = call i32 @__opencl_atomic_fetch_min_4(i8* {{%[0-9]+}}, i32 {{%[0-9]+}}, i32 5, i32 1)
+ x = __opencl_atomic_fetch_min(i, 3, memory_order_seq_cst, memory_scope_work_group);
+
+ // SPIR: {{%[^ ]*}} = call i32 @__opencl_atomic_fetch_umin_4(i8 addrspace(4)* {{%[0-9]+}}, i32 {{%[0-9]+}}, i32 5, i32 1)
+ // ARM: {{%[^ ]*}} = call i32 @__opencl_atomic_fetch_umin_4(i8* {{%[0-9]+}}, i32 {{%[0-9]+}}, i32 5, i32 1)
+ x = __opencl_atomic_fetch_min(ui, 3, memory_order_seq_cst, memory_scope_work_group);
+
+ // SPIR: {{%[^ ]*}} = call zeroext i1 @__opencl_atomic_compare_exchange_4(i8 addrspace(4)* {{%[0-9]+}}, i8 addrspace(4)* {{%[0-9]+}}, i32 {{%[0-9]+}}, i32 5, i32 5, i32 1)
+ // ARM: {{%[^ ]*}} = call zeroext i1 @__opencl_atomic_compare_exchange_4(i8* {{%[0-9]+}}, i8* {{%[0-9]+}}, i32 {{%[0-9]+}}, i32 5, i32 5, i32 1)
+ x = __opencl_atomic_compare_exchange_strong(i, &cmp, 1, memory_order_seq_cst, memory_order_seq_cst, memory_scope_work_group);
+
+ // SPIR: {{%[^ ]*}} = call zeroext i1 @__opencl_atomic_compare_exchange_4(i8 addrspace(4)* {{%[0-9]+}}, i8 addrspace(4)* {{%[0-9]+}}, i32 {{%[0-9]+}}, i32 5, i32 5, i32 1)
+ // ARM: {{%[^ ]*}} = call zeroext i1 @__opencl_atomic_compare_exchange_4(i8* {{%[0-9]+}}, i8* {{%[0-9]+}}, i32 {{%[0-9]+}}, i32 5, i32 5, i32 1)
+ x = __opencl_atomic_compare_exchange_weak(i, &cmp, 1, memory_order_seq_cst, memory_order_seq_cst, memory_scope_work_group);
+
+ // SPIR: {{%[^ ]*}} = call zeroext i1 @__opencl_atomic_compare_exchange_4(i8 addrspace(4)* {{%[0-9]+}}, i8 addrspace(4)* {{%[0-9]+}}, i32 {{%[0-9]+}}, i32 5, i32 5, i32 2)
+ // ARM: {{%[^ ]*}} = call zeroext i1 @__opencl_atomic_compare_exchange_4(i8* {{%[0-9]+}}, i8* {{%[0-9]+}}, i32 {{%[0-9]+}}, i32 5, i32 5, i32 2)
+ x = __opencl_atomic_compare_exchange_weak(i, &cmp, 1, memory_order_seq_cst, memory_order_seq_cst, memory_scope_device);
+
+ // SPIR: {{%[^ ]*}} = call zeroext i1 @__opencl_atomic_compare_exchange_4(i8 addrspace(4)* {{%[0-9]+}}, i8 addrspace(4)* {{%[0-9]+}}, i32 {{%[0-9]+}}, i32 5, i32 5, i32 3)
+ // ARM: {{%[^ ]*}} = call zeroext i1 @__opencl_atomic_compare_exchange_4(i8* {{%[0-9]+}}, i8* {{%[0-9]+}}, i32 {{%[0-9]+}}, i32 5, i32 5, i32 3)
+ x = __opencl_atomic_compare_exchange_weak(i, &cmp, 1, memory_order_seq_cst, memory_order_seq_cst, memory_scope_all_svm_devices);
+
+#ifdef cl_khr_subgroups
+ // SPIR: {{%[^ ]*}} = call zeroext i1 @__opencl_atomic_compare_exchange_4(i8 addrspace(4)* {{%[0-9]+}}, i8 addrspace(4)* {{%[0-9]+}}, i32 {{%[0-9]+}}, i32 5, i32 5, i32 4)
+ x = __opencl_atomic_compare_exchange_weak(i, &cmp, 1, memory_order_seq_cst, memory_order_seq_cst, memory_scope_sub_group);
+#endif
+
+ // SPIR: {{%[^ ]*}} = call zeroext i1 @__opencl_atomic_compare_exchange_4(i8 addrspace(4)* {{%[0-9]+}}, i8 addrspace(4)* {{%[0-9]+}}, i32 {{%[0-9]+}}, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}})
+ // ARM: {{%[^ ]*}} = call zeroext i1 @__opencl_atomic_compare_exchange_4(i8* {{%[0-9]+}}, i8* {{%[0-9]+}}, i32 {{%[0-9]+}}, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}})
+ x = __opencl_atomic_compare_exchange_weak(i, &cmp, 1, order, order, scope);
+}
diff --git a/test/CodeGenOpenCL/atomic-ops.cl b/test/CodeGenOpenCL/atomic-ops.cl
new file mode 100644
index 000000000000..160f7fbd528d
--- /dev/null
+++ b/test/CodeGenOpenCL/atomic-ops.cl
@@ -0,0 +1,291 @@
+// RUN: %clang_cc1 %s -cl-std=CL2.0 -emit-llvm -O0 -o - -triple=amdgcn-amd-amdhsa-amdgizcl | opt -instnamer -S | FileCheck %s
+
+// Also test serialization of atomic operations here, to avoid duplicating the test.
+// RUN: %clang_cc1 %s -cl-std=CL2.0 -emit-pch -O0 -o %t -triple=amdgcn-amd-amdhsa-amdgizcl
+// RUN: %clang_cc1 %s -cl-std=CL2.0 -include-pch %t -O0 -triple=amdgcn-amd-amdhsa-amdgizcl -emit-llvm -o - | opt -instnamer -S | FileCheck %s
+
+#ifndef ALREADY_INCLUDED
+#define ALREADY_INCLUDED
+
+typedef __INTPTR_TYPE__ intptr_t;
+typedef int int8 __attribute__((ext_vector_type(8)));
+
+typedef enum memory_order {
+ memory_order_relaxed = __ATOMIC_RELAXED,
+ memory_order_acquire = __ATOMIC_ACQUIRE,
+ memory_order_release = __ATOMIC_RELEASE,
+ memory_order_acq_rel = __ATOMIC_ACQ_REL,
+ memory_order_seq_cst = __ATOMIC_SEQ_CST
+} memory_order;
+
+typedef enum memory_scope {
+ memory_scope_work_item = __OPENCL_MEMORY_SCOPE_WORK_ITEM,
+ memory_scope_work_group = __OPENCL_MEMORY_SCOPE_WORK_GROUP,
+ memory_scope_device = __OPENCL_MEMORY_SCOPE_DEVICE,
+ memory_scope_all_svm_devices = __OPENCL_MEMORY_SCOPE_ALL_SVM_DEVICES,
+#if defined(cl_intel_subgroups) || defined(cl_khr_subgroups)
+ memory_scope_sub_group = __OPENCL_MEMORY_SCOPE_SUB_GROUP
+#endif
+} memory_scope;
+
+atomic_int j;
+
+void fi1(atomic_int *i) {
+ // CHECK-LABEL: @fi1
+ // CHECK: load atomic i32, i32* %{{[.0-9A-Z_a-z]+}} syncscope("workgroup") seq_cst
+ int x = __opencl_atomic_load(i, memory_order_seq_cst, memory_scope_work_group);
+
+ // CHECK: load atomic i32, i32* %{{[.0-9A-Z_a-z]+}} syncscope("agent") seq_cst
+ x = __opencl_atomic_load(i, memory_order_seq_cst, memory_scope_device);
+
+ // CHECK: load atomic i32, i32* %{{[.0-9A-Z_a-z]+}} seq_cst
+ x = __opencl_atomic_load(i, memory_order_seq_cst, memory_scope_all_svm_devices);
+
+ // CHECK: load atomic i32, i32* %{{[.0-9A-Z_a-z]+}} syncscope("subgroup") seq_cst
+ x = __opencl_atomic_load(i, memory_order_seq_cst, memory_scope_sub_group);
+}
+
+void fi2(atomic_int *i) {
+ // CHECK-LABEL: @fi2
+ // CHECK: store atomic i32 %{{[.0-9A-Z_a-z]+}}, i32* %{{[.0-9A-Z_a-z]+}} syncscope("workgroup") seq_cst
+ __opencl_atomic_store(i, 1, memory_order_seq_cst, memory_scope_work_group);
+}
+
+void test_addr(global atomic_int *ig, private atomic_int *ip, local atomic_int *il) {
+ // CHECK-LABEL: @test_addr
+ // CHECK: store atomic i32 %{{[.0-9A-Z_a-z]+}}, i32 addrspace(1)* %{{[.0-9A-Z_a-z]+}} syncscope("workgroup") seq_cst
+ __opencl_atomic_store(ig, 1, memory_order_seq_cst, memory_scope_work_group);
+
+ // CHECK: store atomic i32 %{{[.0-9A-Z_a-z]+}}, i32 addrspace(5)* %{{[.0-9A-Z_a-z]+}} syncscope("workgroup") seq_cst
+ __opencl_atomic_store(ip, 1, memory_order_seq_cst, memory_scope_work_group);
+
+ // CHECK: store atomic i32 %{{[.0-9A-Z_a-z]+}}, i32 addrspace(3)* %{{[.0-9A-Z_a-z]+}} syncscope("workgroup") seq_cst
+ __opencl_atomic_store(il, 1, memory_order_seq_cst, memory_scope_work_group);
+}
+
+void fi3(atomic_int *i, atomic_uint *ui) {
+ // CHECK-LABEL: @fi3
+ // CHECK: atomicrmw and i32* %{{[.0-9A-Z_a-z]+}}, i32 %{{[.0-9A-Z_a-z]+}} syncscope("workgroup") seq_cst
+ int x = __opencl_atomic_fetch_and(i, 1, memory_order_seq_cst, memory_scope_work_group);
+
+ // CHECK: atomicrmw min i32* %{{[.0-9A-Z_a-z]+}}, i32 %{{[.0-9A-Z_a-z]+}} syncscope("workgroup") seq_cst
+ x = __opencl_atomic_fetch_min(i, 1, memory_order_seq_cst, memory_scope_work_group);
+
+ // CHECK: atomicrmw max i32* %{{[.0-9A-Z_a-z]+}}, i32 %{{[.0-9A-Z_a-z]+}} syncscope("workgroup") seq_cst
+ x = __opencl_atomic_fetch_max(i, 1, memory_order_seq_cst, memory_scope_work_group);
+
+ // CHECK: atomicrmw umin i32* %{{[.0-9A-Z_a-z]+}}, i32 %{{[.0-9A-Z_a-z]+}} syncscope("workgroup") seq_cst
+ x = __opencl_atomic_fetch_min(ui, 1, memory_order_seq_cst, memory_scope_work_group);
+
+ // CHECK: atomicrmw umax i32* %{{[.0-9A-Z_a-z]+}}, i32 %{{[.0-9A-Z_a-z]+}} syncscope("workgroup") seq_cst
+ x = __opencl_atomic_fetch_max(ui, 1, memory_order_seq_cst, memory_scope_work_group);
+}
+
+bool fi4(atomic_int *i) {
+ // CHECK-LABEL: @fi4(
+ // CHECK: [[PAIR:%[.0-9A-Z_a-z]+]] = cmpxchg i32* [[PTR:%[.0-9A-Z_a-z]+]], i32 [[EXPECTED:%[.0-9A-Z_a-z]+]], i32 [[DESIRED:%[.0-9A-Z_a-z]+]] syncscope("workgroup") acquire acquire
+ // CHECK: [[OLD:%[.0-9A-Z_a-z]+]] = extractvalue { i32, i1 } [[PAIR]], 0
+ // CHECK: [[CMP:%[.0-9A-Z_a-z]+]] = extractvalue { i32, i1 } [[PAIR]], 1
+ // CHECK: br i1 [[CMP]], label %[[STORE_EXPECTED:[.0-9A-Z_a-z]+]], label %[[CONTINUE:[.0-9A-Z_a-z]+]]
+ // CHECK: store i32 [[OLD]]
+ int cmp = 0;
+ return __opencl_atomic_compare_exchange_strong(i, &cmp, 1, memory_order_acquire, memory_order_acquire, memory_scope_work_group);
+}
+
+void fi5(atomic_int *i, int scope) {
+ // CHECK-LABEL: @fi5
+ // CHECK: switch i32 %{{.*}}, label %[[opencl_allsvmdevices:.*]] [
+ // CHECK-NEXT: i32 1, label %[[opencl_workgroup:.*]]
+ // CHECK-NEXT: i32 2, label %[[opencl_device:.*]]
+ // CHECK-NEXT: i32 4, label %[[opencl_subgroup:.*]]
+ // CHECK-NEXT: ]
+ // CHECK: [[opencl_workgroup]]:
+ // CHECK: load atomic i32, i32* %{{.*}} syncscope("workgroup") seq_cst
+ // CHECK: br label %[[continue:.*]]
+ // CHECK: [[opencl_device]]:
+ // CHECK: load atomic i32, i32* %{{.*}} syncscope("agent") seq_cst
+ // CHECK: br label %[[continue]]
+ // CHECK: [[opencl_allsvmdevices]]:
+ // CHECK: load atomic i32, i32* %{{.*}} seq_cst
+ // CHECK: br label %[[continue]]
+ // CHECK: [[opencl_subgroup]]:
+ // CHECK: load atomic i32, i32* %{{.*}} syncscope("subgroup") seq_cst
+ // CHECK: br label %[[continue]]
+ // CHECK: [[continue]]:
+ int x = __opencl_atomic_load(i, memory_order_seq_cst, scope);
+}
+
+void fi6(atomic_int *i, int order, int scope) {
+ // CHECK-LABEL: @fi6
+ // CHECK: switch i32 %{{.*}}, label %[[monotonic:.*]] [
+ // CHECK-NEXT: i32 1, label %[[acquire:.*]]
+ // CHECK-NEXT: i32 2, label %[[acquire:.*]]
+ // CHECK-NEXT: i32 5, label %[[seqcst:.*]]
+ // CHECK-NEXT: ]
+ // CHECK: [[monotonic]]:
+ // CHECK: switch i32 %{{.*}}, label %[[MON_ALL:.*]] [
+ // CHECK-NEXT: i32 1, label %[[MON_WG:.*]]
+ // CHECK-NEXT: i32 2, label %[[MON_DEV:.*]]
+ // CHECK-NEXT: i32 4, label %[[MON_SUB:.*]]
+ // CHECK-NEXT: ]
+ // CHECK: [[acquire]]:
+ // CHECK: switch i32 %{{.*}}, label %[[ACQ_ALL:.*]] [
+ // CHECK-NEXT: i32 1, label %[[ACQ_WG:.*]]
+ // CHECK-NEXT: i32 2, label %[[ACQ_DEV:.*]]
+ // CHECK-NEXT: i32 4, label %[[ACQ_SUB:.*]]
+ // CHECK-NEXT: ]
+ // CHECK: [[seqcst]]:
+ // CHECK: switch i32 %{{.*}}, label %[[SEQ_ALL:.*]] [
+ // CHECK-NEXT: i32 1, label %[[SEQ_WG:.*]]
+ // CHECK-NEXT: i32 2, label %[[SEQ_DEV:.*]]
+ // CHECK-NEXT: i32 4, label %[[SEQ_SUB:.*]]
+ // CHECK-NEXT: ]
+ // CHECK: [[MON_WG]]:
+ // CHECK: load atomic i32, i32* %{{.*}} syncscope("workgroup") monotonic
+ // CHECK: [[MON_DEV]]:
+ // CHECK: load atomic i32, i32* %{{.*}} syncscope("agent") monotonic
+ // CHECK: [[MON_ALL]]:
+ // CHECK: load atomic i32, i32* %{{.*}} monotonic
+ // CHECK: [[MON_SUB]]:
+ // CHECK: load atomic i32, i32* %{{.*}} syncscope("subgroup") monotonic
+ // CHECK: [[ACQ_WG]]:
+ // CHECK: load atomic i32, i32* %{{.*}} syncscope("workgroup") acquire
+ // CHECK: [[ACQ_DEV]]:
+ // CHECK: load atomic i32, i32* %{{.*}} syncscope("agent") acquire
+ // CHECK: [[ACQ_ALL]]:
+ // CHECK: load atomic i32, i32* %{{.*}} acquire
+ // CHECK: [[ACQ_SUB]]:
+ // CHECK: load atomic i32, i32* %{{.*}} syncscope("subgroup") acquire
+ // CHECK: [[SEQ_WG]]:
+ // CHECK: load atomic i32, i32* %{{.*}} syncscope("workgroup") seq_cst
+ // CHECK: [[SEQ_DEV]]:
+ // CHECK: load atomic i32, i32* %{{.*}} syncscope("agent") seq_cst
+ // CHECK: [[SEQ_ALL]]:
+ // CHECK: load atomic i32, i32* %{{.*}} seq_cst
+ // CHECK: [[SEQ_SUB]]:
+ // CHECK: load atomic i32, i32* %{{.*}} syncscope("subgroup") seq_cst
+ int x = __opencl_atomic_load(i, order, scope);
+}
+
+float ff1(global atomic_float *d) {
+ // CHECK-LABEL: @ff1
+ // CHECK: load atomic i32, i32 addrspace(1)* {{.*}} syncscope("workgroup") monotonic
+ return __opencl_atomic_load(d, memory_order_relaxed, memory_scope_work_group);
+}
+
+void ff2(atomic_float *d) {
+ // CHECK-LABEL: @ff2
+ // CHECK: store atomic i32 {{.*}} syncscope("workgroup") release
+ __opencl_atomic_store(d, 1, memory_order_release, memory_scope_work_group);
+}
+
+float ff3(atomic_float *d) {
+ // CHECK-LABEL: @ff3
+ // CHECK: atomicrmw xchg i32* {{.*}} syncscope("workgroup") seq_cst
+ return __opencl_atomic_exchange(d, 2, memory_order_seq_cst, memory_scope_work_group);
+}
+
+// CHECK-LABEL: @atomic_init_foo
+void atomic_init_foo()
+{
+ // CHECK-NOT: atomic
+ // CHECK: store
+ __opencl_atomic_init(&j, 42);
+
+ // CHECK-NOT: atomic
+ // CHECK: }
+}
+
+// CHECK-LABEL: @failureOrder
+void failureOrder(atomic_int *ptr, int *ptr2) {
+ // CHECK: cmpxchg i32* {{%[0-9A-Za-z._]+}}, i32 {{%[0-9A-Za-z._]+}}, i32 {{%[0-9A-Za-z_.]+}} syncscope("workgroup") acquire monotonic
+ __opencl_atomic_compare_exchange_strong(ptr, ptr2, 43, memory_order_acquire, memory_order_relaxed, memory_scope_work_group);
+
+ // CHECK: cmpxchg weak i32* {{%[0-9A-Za-z._]+}}, i32 {{%[0-9A-Za-z._]+}}, i32 {{%[0-9A-Za-z_.]+}} syncscope("workgroup") seq_cst acquire
+ __opencl_atomic_compare_exchange_weak(ptr, ptr2, 43, memory_order_seq_cst, memory_order_acquire, memory_scope_work_group);
+}
+
+// CHECK-LABEL: @generalFailureOrder
+void generalFailureOrder(atomic_int *ptr, int *ptr2, int success, int fail) {
+ __opencl_atomic_compare_exchange_strong(ptr, ptr2, 42, success, fail, memory_scope_work_group);
+ // CHECK: switch i32 {{.*}}, label %[[MONOTONIC:[0-9a-zA-Z._]+]] [
+ // CHECK-NEXT: i32 1, label %[[ACQUIRE:[0-9a-zA-Z._]+]]
+ // CHECK-NEXT: i32 2, label %[[ACQUIRE]]
+ // CHECK-NEXT: i32 3, label %[[RELEASE:[0-9a-zA-Z._]+]]
+ // CHECK-NEXT: i32 4, label %[[ACQREL:[0-9a-zA-Z._]+]]
+ // CHECK-NEXT: i32 5, label %[[SEQCST:[0-9a-zA-Z._]+]]
+
+ // CHECK: [[MONOTONIC]]
+ // CHECK: switch {{.*}}, label %[[MONOTONIC_MONOTONIC:[0-9a-zA-Z._]+]] [
+ // CHECK-NEXT: ]
+
+ // CHECK: [[ACQUIRE]]
+ // CHECK: switch {{.*}}, label %[[ACQUIRE_MONOTONIC:[0-9a-zA-Z._]+]] [
+ // CHECK-NEXT: i32 1, label %[[ACQUIRE_ACQUIRE:[0-9a-zA-Z._]+]]
+ // CHECK-NEXT: i32 2, label %[[ACQUIRE_ACQUIRE:[0-9a-zA-Z._]+]]
+ // CHECK-NEXT: ]
+
+ // CHECK: [[RELEASE]]
+ // CHECK: switch {{.*}}, label %[[RELEASE_MONOTONIC:[0-9a-zA-Z._]+]] [
+ // CHECK-NEXT: ]
+
+ // CHECK: [[ACQREL]]
+ // CHECK: switch {{.*}}, label %[[ACQREL_MONOTONIC:[0-9a-zA-Z._]+]] [
+ // CHECK-NEXT: i32 1, label %[[ACQREL_ACQUIRE:[0-9a-zA-Z._]+]]
+ // CHECK-NEXT: i32 2, label %[[ACQREL_ACQUIRE:[0-9a-zA-Z._]+]]
+ // CHECK-NEXT: ]
+
+ // CHECK: [[SEQCST]]
+ // CHECK: switch {{.*}}, label %[[SEQCST_MONOTONIC:[0-9a-zA-Z._]+]] [
+ // CHECK-NEXT: i32 1, label %[[SEQCST_ACQUIRE:[0-9a-zA-Z._]+]]
+ // CHECK-NEXT: i32 2, label %[[SEQCST_ACQUIRE:[0-9a-zA-Z._]+]]
+ // CHECK-NEXT: i32 5, label %[[SEQCST_SEQCST:[0-9a-zA-Z._]+]]
+ // CHECK-NEXT: ]
+
+ // CHECK: [[MONOTONIC_MONOTONIC]]
+ // CHECK: cmpxchg {{.*}} monotonic monotonic
+ // CHECK: br
+
+ // CHECK: [[ACQUIRE_MONOTONIC]]
+ // CHECK: cmpxchg {{.*}} acquire monotonic
+ // CHECK: br
+
+ // CHECK: [[ACQUIRE_ACQUIRE]]
+ // CHECK: cmpxchg {{.*}} acquire acquire
+ // CHECK: br
+
+ // CHECK: [[ACQREL_MONOTONIC]]
+ // CHECK: cmpxchg {{.*}} acq_rel monotonic
+ // CHECK: br
+
+ // CHECK: [[ACQREL_ACQUIRE]]
+ // CHECK: cmpxchg {{.*}} acq_rel acquire
+ // CHECK: br
+
+ // CHECK: [[SEQCST_MONOTONIC]]
+ // CHECK: cmpxchg {{.*}} seq_cst monotonic
+ // CHECK: br
+
+ // CHECK: [[SEQCST_ACQUIRE]]
+ // CHECK: cmpxchg {{.*}} seq_cst acquire
+ // CHECK: br
+
+ // CHECK: [[SEQCST_SEQCST]]
+ // CHECK: cmpxchg {{.*}} seq_cst seq_cst
+ // CHECK: br
+}
+
+int test_volatile(volatile atomic_int *i) {
+ // CHECK-LABEL: @test_volatile
+ // CHECK: %[[i_addr:.*]] = alloca i32
+ // CHECK-NEXT: %[[atomicdst:.*]] = alloca i32
+ // CHECK-NEXT: store i32* %i, i32* addrspace(5)* %[[i_addr]]
+ // CHECK-NEXT: %[[addr:.*]] = load i32*, i32* addrspace(5)* %[[i_addr]]
+ // CHECK-NEXT: %[[res:.*]] = load atomic volatile i32, i32* %[[addr]] syncscope("workgroup") seq_cst
+ // CHECK-NEXT: store i32 %[[res]], i32 addrspace(5)* %[[atomicdst]]
+ // CHECK-NEXT: %[[retval:.*]] = load i32, i32 addrspace(5)* %[[atomicdst]]
+ // CHECK-NEXT: ret i32 %[[retval]]
+ return __opencl_atomic_load(i, memory_order_seq_cst, memory_scope_work_group);
+}
+
+#endif
diff --git a/test/CodeGenOpenCL/blocks.cl b/test/CodeGenOpenCL/blocks.cl
index 5f0cceaf6cdb..146d9dc113a8 100644
--- a/test/CodeGenOpenCL/blocks.cl
+++ b/test/CodeGenOpenCL/blocks.cl
@@ -1,17 +1,54 @@
-// RUN: %clang_cc1 %s -cl-std=CL2.0 -emit-llvm -o - -O0 -triple spir-unknown-unknown | FileCheck -check-prefix=GENERIC -check-prefix=COMMON %s
-// RUN: %clang_cc1 %s -cl-std=CL2.0 -emit-llvm -o - -O0 -triple amdgcn-amd-amdhsa-opencl | FileCheck -check-prefix=AMD -check-prefix=COMMON %s
+// RUN: %clang_cc1 %s -cl-std=CL2.0 -emit-llvm -o - -O0 -triple spir-unknown-unknown | FileCheck -check-prefixes=COMMON,SPIR %s
+// RUN: %clang_cc1 %s -cl-std=CL2.0 -emit-llvm -o - -O0 -triple amdgcn-amd-amdhsa-opencl | FileCheck -check-prefixes=COMMON,AMD %s
-// Checking for null instead of @__NSConcreteGlobalBlock symbol
-// COMMON: @__block_literal_global = internal addrspace(1) constant { i8**, i32, i32, i8*, %struct.__block_descriptor addrspace(2)* } { i8** null
+// COMMON: %struct.__opencl_block_literal_generic = type { i32, i32, i8 addrspace(4)* }
+// SPIR: @__block_literal_global = internal addrspace(1) constant { i32, i32, i8 addrspace(4)* } { i32 12, i32 4, i8 addrspace(4)* addrspacecast (i8* bitcast (void (i8 addrspace(4)*, i8 addrspace(3)*)* @block_A_block_invoke to i8*) to i8 addrspace(4)*) }
+// AMD: @__block_literal_global = internal addrspace(1) constant { i32, i32, i8 addrspace(4)* } { i32 16, i32 8, i8 addrspace(4)* addrspacecast (i8* bitcast (void (i8 addrspace(4)*, i8 addrspace(3)*)* @block_A_block_invoke to i8*) to i8 addrspace(4)*) }
+// COMMON-NOT: .str
+
+// COMMON-LABEL: define internal {{.*}}void @block_A_block_invoke(i8 addrspace(4)* %.block_descriptor, i8 addrspace(3)* %a)
void (^block_A)(local void *) = ^(local void *a) {
return;
};
+// COMMON-LABEL: define {{.*}}void @foo()
void foo(){
int i;
-// Checking for null instead of @_NSConcreteStackBlock symbol
-// COMMON: store i8* null, i8** %block.isa
+ // COMMON-NOT: %block.isa
+ // COMMON-NOT: %block.flags
+ // COMMON-NOT: %block.reserved
+ // COMMON-NOT: %block.descriptor
+ // COMMON: %[[block_size:.*]] = getelementptr inbounds <{ i32, i32, i8 addrspace(4)*, i32 }>, <{ i32, i32, i8 addrspace(4)*, i32 }>* %block, i32 0, i32 0
+ // SPIR: store i32 16, i32* %[[block_size]]
+ // AMD: store i32 20, i32* %[[block_size]]
+ // COMMON: %[[block_align:.*]] = getelementptr inbounds <{ i32, i32, i8 addrspace(4)*, i32 }>, <{ i32, i32, i8 addrspace(4)*, i32 }>* %block, i32 0, i32 1
+ // SPIR: store i32 4, i32* %[[block_align]]
+ // AMD: store i32 8, i32* %[[block_align]]
+ // COMMON: %[[block_invoke:.*]] = getelementptr inbounds <{ i32, i32, i8 addrspace(4)*, i32 }>, <{ i32, i32, i8 addrspace(4)*, i32 }>* %[[block:.*]], i32 0, i32 2
+ // COMMON: store i8 addrspace(4)* addrspacecast (i8* bitcast (i32 (i8 addrspace(4)*)* @__foo_block_invoke to i8*) to i8 addrspace(4)*), i8 addrspace(4)** %[[block_invoke]]
+ // COMMON: %[[block_captured:.*]] = getelementptr inbounds <{ i32, i32, i8 addrspace(4)*, i32 }>, <{ i32, i32, i8 addrspace(4)*, i32 }>* %[[block]], i32 0, i32 3
+ // COMMON: %[[i_value:.*]] = load i32, i32* %i
+ // COMMON: store i32 %[[i_value]], i32* %[[block_captured]],
+ // COMMON: %[[blk_ptr:.*]] = bitcast <{ i32, i32, i8 addrspace(4)*, i32 }>* %[[block]] to i32 ()*
+ // COMMON: %[[blk_gen_ptr:.*]] = addrspacecast i32 ()* %[[blk_ptr]] to i32 () addrspace(4)*
+ // COMMON: store i32 () addrspace(4)* %[[blk_gen_ptr]], i32 () addrspace(4)** %[[block_B:.*]],
+ // COMMON: %[[blk_gen_ptr:.*]] = load i32 () addrspace(4)*, i32 () addrspace(4)** %[[block_B]]
+ // COMMON: %[[block_literal:.*]] = bitcast i32 () addrspace(4)* %[[blk_gen_ptr]] to %struct.__opencl_block_literal_generic addrspace(4)*
+ // COMMON: %[[invoke_addr:.*]] = getelementptr inbounds %struct.__opencl_block_literal_generic, %struct.__opencl_block_literal_generic addrspace(4)* %[[block_literal]], i32 0, i32 2
+ // COMMON: %[[blk_gen_ptr:.*]] = bitcast %struct.__opencl_block_literal_generic addrspace(4)* %[[block_literal]] to i8 addrspace(4)*
+ // COMMON: %[[invoke_func_ptr:.*]] = load i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* %[[invoke_addr]]
+ // COMMON: %[[invoke_func:.*]] = addrspacecast i8 addrspace(4)* %[[invoke_func_ptr]] to i32 (i8 addrspace(4)*)*
+ // COMMON: call {{.*}}i32 %[[invoke_func]](i8 addrspace(4)* %[[blk_gen_ptr]])
+
int (^ block_B)(void) = ^{
return i;
};
+ block_B();
}
+
+// COMMON-LABEL: define internal {{.*}}i32 @__foo_block_invoke(i8 addrspace(4)* %.block_descriptor)
+// COMMON: %[[block:.*]] = bitcast i8 addrspace(4)* %.block_descriptor to <{ i32, i32, i8 addrspace(4)*, i32 }> addrspace(4)*
+// COMMON: %[[block_capture_addr:.*]] = getelementptr inbounds <{ i32, i32, i8 addrspace(4)*, i32 }>, <{ i32, i32, i8 addrspace(4)*, i32 }> addrspace(4)* %[[block]], i32 0, i32 3
+// COMMON: %[[block_capture:.*]] = load i32, i32 addrspace(4)* %[[block_capture_addr]]
+
+// COMMON-NOT: define{{.*}}@__foo_block_invoke_kernel
diff --git a/test/CodeGenOpenCL/builtins-amdgcn.cl b/test/CodeGenOpenCL/builtins-amdgcn.cl
index f75620ba603a..9f036547bf41 100644
--- a/test/CodeGenOpenCL/builtins-amdgcn.cl
+++ b/test/CodeGenOpenCL/builtins-amdgcn.cl
@@ -421,6 +421,25 @@ void test_read_exec(global ulong* out) {
// CHECK: declare i64 @llvm.read_register.i64(metadata) #[[NOUNWIND_READONLY:[0-9]+]]
+// CHECK-LABEL: @test_read_exec_lo(
+// CHECK: call i32 @llvm.read_register.i32(metadata ![[EXEC_LO:[0-9]+]]) #[[READ_EXEC_ATTRS]]
+void test_read_exec_lo(global uint* out) {
+ *out = __builtin_amdgcn_read_exec_lo();
+}
+
+// CHECK-LABEL: @test_read_exec_hi(
+// CHECK: call i32 @llvm.read_register.i32(metadata ![[EXEC_HI:[0-9]+]]) #[[READ_EXEC_ATTRS]]
+void test_read_exec_hi(global uint* out) {
+ *out = __builtin_amdgcn_read_exec_hi();
+}
+
+// CHECK-LABEL: @test_dispatch_ptr
+// CHECK: call i8 addrspace(2)* @llvm.amdgcn.dispatch.ptr()
+void test_dispatch_ptr(__attribute__((address_space(2))) unsigned char ** out)
+{
+ *out = __builtin_amdgcn_dispatch_ptr();
+}
+
// CHECK-LABEL: @test_kernarg_segment_ptr
// CHECK: call i8 addrspace(2)* @llvm.amdgcn.kernarg.segment.ptr()
void test_kernarg_segment_ptr(__attribute__((address_space(2))) unsigned char ** out)
@@ -492,3 +511,5 @@ void test_s_getpc(global ulong* out)
// CHECK-DAG: attributes #[[NOUNWIND_READONLY:[0-9]+]] = { nounwind readonly }
// CHECK-DAG: attributes #[[READ_EXEC_ATTRS]] = { convergent }
// CHECK-DAG: ![[EXEC]] = !{!"exec"}
+// CHECK-DAG: ![[EXEC_LO]] = !{!"exec_lo"}
+// CHECK-DAG: ![[EXEC_HI]] = !{!"exec_hi"}
diff --git a/test/CodeGenOpenCL/cl20-device-side-enqueue.cl b/test/CodeGenOpenCL/cl20-device-side-enqueue.cl
index def290661534..0bf87c25bd83 100644
--- a/test/CodeGenOpenCL/cl20-device-side-enqueue.cl
+++ b/test/CodeGenOpenCL/cl20-device-side-enqueue.cl
@@ -1,13 +1,35 @@
// RUN: %clang_cc1 %s -cl-std=CL2.0 -ffake-address-space-map -O0 -emit-llvm -o - -triple "spir-unknown-unknown" | FileCheck %s --check-prefix=COMMON --check-prefix=B32
// RUN: %clang_cc1 %s -cl-std=CL2.0 -ffake-address-space-map -O0 -emit-llvm -o - -triple "spir64-unknown-unknown" | FileCheck %s --check-prefix=COMMON --check-prefix=B64
+#pragma OPENCL EXTENSION cl_khr_subgroups : enable
+
typedef void (^bl_t)(local void *);
typedef struct {int a;} ndrange_t;
-// N.B. The check here only exists to set BL_GLOBAL
-// COMMON: @block_G = addrspace(1) constant void (i8 addrspace(3)*) addrspace(4)* addrspacecast (void (i8 addrspace(3)*) addrspace(1)* bitcast ({ i8**, i32, i32, i8*, %struct.__block_descriptor addrspace(2)* } addrspace(1)* [[BL_GLOBAL:@__block_literal_global(\.[0-9]+)?]] to void (i8 addrspace(3)*) addrspace(1)*) to void (i8 addrspace(3)*) addrspace(4)*)
+// COMMON: %struct.__opencl_block_literal_generic = type { i32, i32, i8 addrspace(4)* }
+
+// For a block global variable, first emit the block literal as a global variable, then emit the block variable itself.
+// COMMON: [[BL_GLOBAL:@__block_literal_global[^ ]*]] = internal addrspace(1) constant { i32, i32, i8 addrspace(4)* } { i32 {{[0-9]+}}, i32 {{[0-9]+}}, i8 addrspace(4)* addrspacecast (i8* bitcast (void (i8 addrspace(4)*, i8 addrspace(3)*)* [[INV_G:@[^ ]+]] to i8*) to i8 addrspace(4)*) }
+// COMMON: @block_G = addrspace(1) constant void (i8 addrspace(3)*) addrspace(4)* addrspacecast (void (i8 addrspace(3)*) addrspace(1)* bitcast ({ i32, i32, i8 addrspace(4)* } addrspace(1)* [[BL_GLOBAL]] to void (i8 addrspace(3)*) addrspace(1)*) to void (i8 addrspace(3)*) addrspace(4)*)
+
+// For anonymous blocks without captures, emit block literals as global variable.
+// COMMON: [[BLG1:@__block_literal_global[^ ]*]] = internal addrspace(1) constant { i32, i32, i8 addrspace(4)* } { i32 {{[0-9]+}}, i32 {{[0-9]+}}, i8 addrspace(4)* addrspacecast (i8* bitcast (void (i8 addrspace(4)*, i8 addrspace(3)*)* {{@[^ ]+}} to i8*) to i8 addrspace(4)*) }
+// COMMON: [[BLG2:@__block_literal_global[^ ]*]] = internal addrspace(1) constant { i32, i32, i8 addrspace(4)* } { i32 {{[0-9]+}}, i32 {{[0-9]+}}, i8 addrspace(4)* addrspacecast (i8* bitcast (void (i8 addrspace(4)*, i8 addrspace(3)*)* {{@[^ ]+}} to i8*) to i8 addrspace(4)*) }
+// COMMON: [[BLG3:@__block_literal_global[^ ]*]] = internal addrspace(1) constant { i32, i32, i8 addrspace(4)* } { i32 {{[0-9]+}}, i32 {{[0-9]+}}, i8 addrspace(4)* addrspacecast (i8* bitcast (void (i8 addrspace(4)*, i8 addrspace(3)*)* {{@[^ ]+}} to i8*) to i8 addrspace(4)*) }
+// COMMON: [[BLG4:@__block_literal_global[^ ]*]] = internal addrspace(1) constant { i32, i32, i8 addrspace(4)* } { i32 {{[0-9]+}}, i32 {{[0-9]+}}, i8 addrspace(4)* addrspacecast (i8* bitcast (void (i8 addrspace(4)*, i8 addrspace(3)*)* {{@[^ ]+}} to i8*) to i8 addrspace(4)*) }
+// COMMON: [[BLG5:@__block_literal_global[^ ]*]] = internal addrspace(1) constant { i32, i32, i8 addrspace(4)* } { i32 {{[0-9]+}}, i32 {{[0-9]+}}, i8 addrspace(4)* addrspacecast (i8* bitcast (void (i8 addrspace(4)*, i8 addrspace(3)*)* {{@[^ ]+}} to i8*) to i8 addrspace(4)*) }
+// COMMON: [[BLG6:@__block_literal_global[^ ]*]] = internal addrspace(1) constant { i32, i32, i8 addrspace(4)* } { i32 {{[0-9]+}}, i32 {{[0-9]+}}, i8 addrspace(4)* addrspacecast (i8* bitcast (void (i8 addrspace(4)*, i8 addrspace(3)*, i8 addrspace(3)*, i8 addrspace(3)*)* {{@[^ ]+}} to i8*) to i8 addrspace(4)*) }
+// COMMON: [[BLG7:@__block_literal_global[^ ]*]] = internal addrspace(1) constant { i32, i32, i8 addrspace(4)* } { i32 {{[0-9]+}}, i32 {{[0-9]+}}, i8 addrspace(4)* addrspacecast (i8* bitcast (void (i8 addrspace(4)*, i8 addrspace(3)*)* {{@[^ ]+}} to i8*) to i8 addrspace(4)*) }
+// COMMON: [[BLG8:@__block_literal_global[^ ]*]] = internal addrspace(1) constant { i32, i32, i8 addrspace(4)* } { i32 {{[0-9]+}}, i32 {{[0-9]+}}, i8 addrspace(4)* addrspacecast (i8* bitcast (void (i8 addrspace(4)*)* [[INVG8:@[^ ]+]] to i8*) to i8 addrspace(4)*) }
+// COMMON: [[BLG9:@__block_literal_global[^ ]*]] = internal addrspace(1) constant { i32, i32, i8 addrspace(4)* } { i32 {{[0-9]+}}, i32 {{[0-9]+}}, i8 addrspace(4)* addrspacecast (i8* bitcast (void (i8 addrspace(4)*, i8 addrspace(3)*)* [[INVG9:@[^ ]+]] to i8*) to i8 addrspace(4)*) }
+// COMMON: [[BLG10:@__block_literal_global[^ ]*]] = internal addrspace(1) constant { i32, i32, i8 addrspace(4)* } { i32 {{[0-9]+}}, i32 {{[0-9]+}}, i8 addrspace(4)* addrspacecast (i8* bitcast (void (i8 addrspace(4)*)* {{@[^ ]+}} to i8*) to i8 addrspace(4)*) }
+// COMMON: [[BLG11:@__block_literal_global[^ ]*]] = internal addrspace(1) constant { i32, i32, i8 addrspace(4)* } { i32 {{[0-9]+}}, i32 {{[0-9]+}}, i8 addrspace(4)* addrspacecast (i8* bitcast (void (i8 addrspace(4)*)* {{@[^ ]+}} to i8*) to i8 addrspace(4)*) }
+
+// Emits block literal [[BL_GLOBAL]], invoke function [[INV_G]] and global block variable @block_G
+// COMMON: define internal spir_func void [[INV_G]](i8 addrspace(4)* %{{.*}}, i8 addrspace(3)* %{{.*}})
const bl_t block_G = (bl_t) ^ (local void *a) {};
+// COMMON-LABEL: define spir_kernel void @device_side_enqueue(i32 addrspace(1)* %{{.*}}, i32 addrspace(1)* %b, i32 %i)
kernel void device_side_enqueue(global int *a, global int *b, int i) {
// COMMON: %default_queue = alloca %opencl.queue_t*
queue_t default_queue;
@@ -22,73 +44,125 @@ kernel void device_side_enqueue(global int *a, global int *b, int i) {
// COMMON: %event_wait_list2 = alloca [1 x %opencl.clk_event_t*]
clk_event_t event_wait_list2[] = {clk_event};
+ // Emits block literal on stack and block kernel [[INVLK1]].
// COMMON: [[NDR:%[a-z0-9]+]] = alloca %struct.ndrange_t, align 4
// COMMON: [[DEF_Q:%[0-9]+]] = load %opencl.queue_t{{.*}}*, %opencl.queue_t{{.*}}** %default_queue
// COMMON: [[FLAGS:%[0-9]+]] = load i32, i32* %flags
- // COMMON: [[BL:%[0-9]+]] = bitcast <{ i8*, i32, i32, i8*, %struct.__block_descriptor addrspace(2)*, i32{{.*}}, i32{{.*}}, i32{{.*}} }>* %block to void ()*
+ // COMMON: store i8 addrspace(4)* addrspacecast (i8* bitcast (void (i8 addrspace(4)*)* [[INVL1:@__device_side_enqueue_block_invoke[^ ]*]] to i8*) to i8 addrspace(4)*), i8 addrspace(4)** %block.invoke
+ // B32: [[BL:%[0-9]+]] = bitcast <{ i32, i32, i8 addrspace(4)*, i32 addrspace(1)*, i32, i32 addrspace(1)* }>* %block to void ()*
+ // B64: [[BL:%[0-9]+]] = bitcast <{ i32, i32, i8 addrspace(4)*, i32 addrspace(1)*, i32 addrspace(1)*, i32 }>* %block to void ()*
// COMMON: [[BL_I8:%[0-9]+]] = addrspacecast void ()* [[BL]] to i8 addrspace(4)*
- // COMMON: call i32 @__enqueue_kernel_basic(%opencl.queue_t{{.*}}* [[DEF_Q]], i32 [[FLAGS]], %struct.ndrange_t* byval [[NDR]]{{(.[0-9]+)?}}, i8 addrspace(4)* [[BL_I8]])
+ // COMMON-LABEL: call i32 @__enqueue_kernel_basic(
+ // COMMON-SAME: %opencl.queue_t{{.*}}* [[DEF_Q]], i32 [[FLAGS]], %struct.ndrange_t* byval [[NDR]]{{([0-9]+)?}},
+ // COMMON-SAME: i8 addrspace(4)* addrspacecast (i8* bitcast ({{.*}} [[INVLK1:[^ ]+_kernel]] to i8*) to i8 addrspace(4)*),
+ // COMMON-SAME: i8 addrspace(4)* [[BL_I8]])
enqueue_kernel(default_queue, flags, ndrange,
^(void) {
a[i] = b[i];
});
+ // Emits block literal on stack and block kernel [[INVLK2]].
// COMMON: [[DEF_Q:%[0-9]+]] = load %opencl.queue_t{{.*}}*, %opencl.queue_t{{.*}}** %default_queue
// COMMON: [[FLAGS:%[0-9]+]] = load i32, i32* %flags
// COMMON: [[WAIT_EVNT:%[0-9]+]] = addrspacecast %opencl.clk_event_t{{.*}}** %event_wait_list to %opencl.clk_event_t{{.*}}* addrspace(4)*
// COMMON: [[EVNT:%[0-9]+]] = addrspacecast %opencl.clk_event_t{{.*}}** %clk_event to %opencl.clk_event_t{{.*}}* addrspace(4)*
- // COMMON: [[BL:%[0-9]+]] = bitcast <{ i8*, i32, i32, i8*, %struct.__block_descriptor addrspace(2)*, i32{{.*}}, i32{{.*}}, i32{{.*}} }>* %block3 to void ()*
+ // COMMON: store i8 addrspace(4)* addrspacecast (i8* bitcast (void (i8 addrspace(4)*)* [[INVL2:@__device_side_enqueue_block_invoke[^ ]*]] to i8*) to i8 addrspace(4)*), i8 addrspace(4)** %block.invoke
+ // COMMON: [[BL:%[0-9]+]] = bitcast <{ i32, i32, i8 addrspace(4)*, i32{{.*}}, i32{{.*}}, i32{{.*}} }>* %block3 to void ()*
// COMMON: [[BL_I8:%[0-9]+]] = addrspacecast void ()* [[BL]] to i8 addrspace(4)*
- // COMMON: call i32 @__enqueue_kernel_basic_events(%opencl.queue_t{{.*}}* [[DEF_Q]], i32 [[FLAGS]], %struct.ndrange_t* {{.*}}, i32 2, %opencl.clk_event_t{{.*}}* addrspace(4)* [[WAIT_EVNT]], %opencl.clk_event_t{{.*}}* addrspace(4)* [[EVNT]], i8 addrspace(4)* [[BL_I8]])
+ // COMMON-LABEL: call i32 @__enqueue_kernel_basic_events
+ // COMMON-SAME: (%opencl.queue_t{{.*}}* [[DEF_Q]], i32 [[FLAGS]], %struct.ndrange_t* {{.*}}, i32 2, %opencl.clk_event_t{{.*}}* addrspace(4)* [[WAIT_EVNT]], %opencl.clk_event_t{{.*}}* addrspace(4)* [[EVNT]],
+ // COMMON-SAME: i8 addrspace(4)* addrspacecast (i8* bitcast ({{.*}} [[INVLK2:[^ ]+_kernel]] to i8*) to i8 addrspace(4)*),
+ // COMMON-SAME: i8 addrspace(4)* [[BL_I8]])
+
enqueue_kernel(default_queue, flags, ndrange, 2, &event_wait_list, &clk_event,
^(void) {
a[i] = b[i];
});
+ // Emits global block literal [[BLG1]] and block kernel [[INVGK1]].
// COMMON: [[DEF_Q:%[0-9]+]] = load %opencl.queue_t{{.*}}*, %opencl.queue_t{{.*}}** %default_queue
// COMMON: [[FLAGS:%[0-9]+]] = load i32, i32* %flags
- // B32: call i32 (%opencl.queue_t{{.*}}*, i32, %struct.ndrange_t*, i8 addrspace(4)*, i32, ...) @__enqueue_kernel_vaargs(%opencl.queue_t{{.*}}* [[DEF_Q]], i32 [[FLAGS]], %struct.ndrange_t* [[NDR]]{{(.[0-9]+)?}}, i8 addrspace(4)* addrspacecast (i8 addrspace(1)* bitcast ({ i8**, i32, i32, i8*, %struct.__block_descriptor addrspace(2)* } addrspace(1)* @__block_literal_global{{(.[0-9]+)?}} to i8 addrspace(1)*) to i8 addrspace(4)*), i32 1, i32 256)
- // B64: call i32 (%opencl.queue_t{{.*}}*, i32, %struct.ndrange_t*, i8 addrspace(4)*, i32, ...) @__enqueue_kernel_vaargs(%opencl.queue_t{{.*}}* [[DEF_Q]], i32 [[FLAGS]], %struct.ndrange_t* [[NDR]]{{(.[0-9]+)?}}, i8 addrspace(4)* addrspacecast (i8 addrspace(1)* bitcast ({ i8**, i32, i32, i8*, %struct.__block_descriptor addrspace(2)* } addrspace(1)* @__block_literal_global{{(.[0-9]+)?}} to i8 addrspace(1)*) to i8 addrspace(4)*), i32 1, i64 256)
+ // B32: %[[TMP:.*]] = alloca [1 x i32]
+ // B32: %[[TMP1:.*]] = getelementptr [1 x i32], [1 x i32]* %[[TMP]], i32 0, i32 0
+ // B32: store i32 256, i32* %[[TMP1]], align 4
+ // B64: %[[TMP:.*]] = alloca [1 x i64]
+ // B64: %[[TMP1:.*]] = getelementptr [1 x i64], [1 x i64]* %[[TMP]], i32 0, i32 0
+ // B64: store i64 256, i64* %[[TMP1]], align 8
+ // COMMON-LABEL: call i32 @__enqueue_kernel_vaargs(
+ // COMMON-SAME: %opencl.queue_t{{.*}}* [[DEF_Q]], i32 [[FLAGS]], %struct.ndrange_t* [[NDR]]{{([0-9]+)?}},
+ // COMMON-SAME: i8 addrspace(4)* addrspacecast (i8* bitcast ({{.*}} [[INVGK1:[^ ]+_kernel]] to i8*) to i8 addrspace(4)*),
+ // COMMON-SAME: i8 addrspace(4)* addrspacecast (i8 addrspace(1)* bitcast ({ i32, i32, i8 addrspace(4)* } addrspace(1)* [[BLG1]] to i8 addrspace(1)*) to i8 addrspace(4)*), i32 1,
+ // B32-SAME: i32* %[[TMP1]])
+ // B64-SAME: i64* %[[TMP1]])
enqueue_kernel(default_queue, flags, ndrange,
^(local void *p) {
return;
},
256);
char c;
+ // Emits global block literal [[BLG2]] and block kernel [[INVGK2]].
// COMMON: [[DEF_Q:%[0-9]+]] = load %opencl.queue_t{{.*}}*, %opencl.queue_t{{.*}}** %default_queue
// COMMON: [[FLAGS:%[0-9]+]] = load i32, i32* %flags
- // B32: [[SIZE:%[0-9]+]] = zext i8 {{%[0-9]+}} to i32
- // B32: call i32 (%opencl.queue_t{{.*}}*, i32, %struct.ndrange_t*, i8 addrspace(4)*, i32, ...) @__enqueue_kernel_vaargs(%opencl.queue_t{{.*}}* [[DEF_Q]], i32 [[FLAGS]], %struct.ndrange_t* [[NDR]]{{(.[0-9]+)?}}, i8 addrspace(4)* addrspacecast (i8 addrspace(1)* bitcast ({ i8**, i32, i32, i8*, %struct.__block_descriptor addrspace(2)* } addrspace(1)* @__block_literal_global{{(.[0-9]+)?}} to i8 addrspace(1)*) to i8 addrspace(4)*), i32 1, i32 [[SIZE]])
- // B64: [[SIZE:%[0-9]+]] = zext i8 {{%[0-9]+}} to i64
- // B64: call i32 (%opencl.queue_t{{.*}}*, i32, %struct.ndrange_t*, i8 addrspace(4)*, i32, ...) @__enqueue_kernel_vaargs(%opencl.queue_t{{.*}}* [[DEF_Q]], i32 [[FLAGS]], %struct.ndrange_t* [[NDR]]{{(.[0-9]+)?}}, i8 addrspace(4)* addrspacecast (i8 addrspace(1)* bitcast ({ i8**, i32, i32, i8*, %struct.__block_descriptor addrspace(2)* } addrspace(1)* @__block_literal_global{{(.[0-9]+)?}} to i8 addrspace(1)*) to i8 addrspace(4)*), i32 1, i64 [[SIZE]])
+ // B32: %[[TMP:.*]] = alloca [1 x i32]
+ // B32: %[[TMP1:.*]] = getelementptr [1 x i32], [1 x i32]* %[[TMP]], i32 0, i32 0
+ // B32: store i32 %{{.*}}, i32* %[[TMP1]], align 4
+ // B64: %[[TMP:.*]] = alloca [1 x i64]
+ // B64: %[[TMP1:.*]] = getelementptr [1 x i64], [1 x i64]* %[[TMP]], i32 0, i32 0
+ // B64: store i64 %{{.*}}, i64* %[[TMP1]], align 8
+ // COMMON-LABEL: call i32 @__enqueue_kernel_vaargs(
+ // COMMON-SAME: %opencl.queue_t{{.*}}* [[DEF_Q]], i32 [[FLAGS]], %struct.ndrange_t* [[NDR]]{{([0-9]+)?}},
+ // COMMON-SAME: i8 addrspace(4)* addrspacecast (i8* bitcast ({{.*}} [[INVGK2:[^ ]+_kernel]] to i8*) to i8 addrspace(4)*),
+ // COMMON-SAME: i8 addrspace(4)* addrspacecast (i8 addrspace(1)* bitcast ({ i32, i32, i8 addrspace(4)* } addrspace(1)* [[BLG2]] to i8 addrspace(1)*) to i8 addrspace(4)*), i32 1,
+ // B32-SAME: i32* %[[TMP1]])
+ // B64-SAME: i64* %[[TMP1]])
enqueue_kernel(default_queue, flags, ndrange,
^(local void *p) {
return;
},
c);
+ // Emits global block literal [[BLG3]] and block kernel [[INVGK3]].
// COMMON: [[DEF_Q:%[0-9]+]] = load %opencl.queue_t{{.*}}*, %opencl.queue_t{{.*}}** %default_queue
// COMMON: [[FLAGS:%[0-9]+]] = load i32, i32* %flags
// COMMON: [[AD:%arraydecay[0-9]*]] = getelementptr inbounds [1 x %opencl.clk_event_t*], [1 x %opencl.clk_event_t*]* %event_wait_list2, i32 0, i32 0
// COMMON: [[WAIT_EVNT:%[0-9]+]] = addrspacecast %opencl.clk_event_t{{.*}}** [[AD]] to %opencl.clk_event_t{{.*}}* addrspace(4)*
// COMMON: [[EVNT:%[0-9]+]] = addrspacecast %opencl.clk_event_t{{.*}}** %clk_event to %opencl.clk_event_t{{.*}}* addrspace(4)*
- // B32: call i32 (%opencl.queue_t{{.*}}*, i32, %struct.ndrange_t*, i32, %opencl.clk_event_t{{.*}}* addrspace(4)*, %opencl.clk_event_t{{.*}}* addrspace(4)*, i8 addrspace(4)*, i32, ...) @__enqueue_kernel_events_vaargs(%opencl.queue_t{{.*}}* [[DEF_Q]], i32 [[FLAGS]], %struct.ndrange_t* {{.*}}, i32 2, %opencl.clk_event_t{{.*}} [[WAIT_EVNT]], %opencl.clk_event_t{{.*}} [[EVNT]], i8 addrspace(4)* addrspacecast (i8 addrspace(1)* bitcast ({ i8**, i32, i32, i8*, %struct.__block_descriptor addrspace(2)* } addrspace(1)* @__block_literal_global{{(.[0-9]+)?}} to i8 addrspace(1)*) to i8 addrspace(4)*), i32 1, i32 256)
- // B64: call i32 (%opencl.queue_t{{.*}}*, i32, %struct.ndrange_t*, i32, %opencl.clk_event_t{{.*}}* addrspace(4)*, %opencl.clk_event_t{{.*}}* addrspace(4)*, i8 addrspace(4)*, i32, ...) @__enqueue_kernel_events_vaargs(%opencl.queue_t{{.*}}* [[DEF_Q]], i32 [[FLAGS]], %struct.ndrange_t* {{.*}}, i32 2, %opencl.clk_event_t{{.*}} [[WAIT_EVNT]], %opencl.clk_event_t{{.*}} [[EVNT]], i8 addrspace(4)* addrspacecast (i8 addrspace(1)* bitcast ({ i8**, i32, i32, i8*, %struct.__block_descriptor addrspace(2)* } addrspace(1)* @__block_literal_global{{(.[0-9]+)?}} to i8 addrspace(1)*) to i8 addrspace(4)*), i32 1, i64 256)
+ // B32: %[[TMP:.*]] = alloca [1 x i32]
+ // B32: %[[TMP1:.*]] = getelementptr [1 x i32], [1 x i32]* %[[TMP]], i32 0, i32 0
+ // B32: store i32 256, i32* %[[TMP1]], align 4
+ // B64: %[[TMP:.*]] = alloca [1 x i64]
+ // B64: %[[TMP1:.*]] = getelementptr [1 x i64], [1 x i64]* %[[TMP]], i32 0, i32 0
+ // B64: store i64 256, i64* %[[TMP1]], align 8
+ // COMMON-LABEL: call i32 @__enqueue_kernel_events_vaargs
+ // COMMON-SAME: (%opencl.queue_t{{.*}}* [[DEF_Q]], i32 [[FLAGS]], %struct.ndrange_t* {{.*}}, i32 2, %opencl.clk_event_t{{.*}} [[WAIT_EVNT]], %opencl.clk_event_t{{.*}} [[EVNT]],
+ // COMMON-SAME: i8 addrspace(4)* addrspacecast (i8* bitcast ({{.*}} [[INVGK3:[^ ]+_kernel]] to i8*) to i8 addrspace(4)*),
+ // COMMON-SAME: i8 addrspace(4)* addrspacecast (i8 addrspace(1)* bitcast ({ i32, i32, i8 addrspace(4)* } addrspace(1)* [[BLG3]] to i8 addrspace(1)*) to i8 addrspace(4)*), i32 1,
+ // B32-SAME: i32* %[[TMP1]])
+ // B64-SAME: i64* %[[TMP1]])
enqueue_kernel(default_queue, flags, ndrange, 2, event_wait_list2, &clk_event,
^(local void *p) {
return;
},
256);
+ // Emits global block literal [[BLG4]] and block kernel [[INVGK4]].
// COMMON: [[DEF_Q:%[0-9]+]] = load %opencl.queue_t{{.*}}*, %opencl.queue_t{{.*}}** %default_queue
// COMMON: [[FLAGS:%[0-9]+]] = load i32, i32* %flags
// COMMON: [[AD:%arraydecay[0-9]*]] = getelementptr inbounds [1 x %opencl.clk_event_t*], [1 x %opencl.clk_event_t*]* %event_wait_list2, i32 0, i32 0
// COMMON: [[WAIT_EVNT:%[0-9]+]] = addrspacecast %opencl.clk_event_t{{.*}}** [[AD]] to %opencl.clk_event_t{{.*}}* addrspace(4)*
// COMMON: [[EVNT:%[0-9]+]] = addrspacecast %opencl.clk_event_t{{.*}}** %clk_event to %opencl.clk_event_t{{.*}}* addrspace(4)*
- // B32: [[SIZE:%[0-9]+]] = zext i8 {{%[0-9]+}} to i32
- // B32: call i32 (%opencl.queue_t{{.*}}*, i32, %struct.ndrange_t*, i32, %opencl.clk_event_t{{.*}}* addrspace(4)*, %opencl.clk_event_t{{.*}}* addrspace(4)*, i8 addrspace(4)*, i32, ...) @__enqueue_kernel_events_vaargs(%opencl.queue_t{{.*}}* [[DEF_Q]], i32 [[FLAGS]], %struct.ndrange_t* {{.*}}, i32 2, %opencl.clk_event_t{{.*}}* addrspace(4)* [[WAIT_EVNT]], %opencl.clk_event_t{{.*}}* addrspace(4)* [[EVNT]], i8 addrspace(4)* addrspacecast (i8 addrspace(1)* bitcast ({ i8**, i32, i32, i8*, %struct.__block_descriptor addrspace(2)* } addrspace(1)* @__block_literal_global{{(.[0-9]+)?}} to i8 addrspace(1)*) to i8 addrspace(4)*), i32 1, i32 [[SIZE]])
- // B64: [[SIZE:%[0-9]+]] = zext i8 {{%[0-9]+}} to i64
- // B64: call i32 (%opencl.queue_t{{.*}}*, i32, %struct.ndrange_t*, i32, %opencl.clk_event_t{{.*}}* addrspace(4)*, %opencl.clk_event_t{{.*}}* addrspace(4)*, i8 addrspace(4)*, i32, ...) @__enqueue_kernel_events_vaargs(%opencl.queue_t{{.*}}* [[DEF_Q]], i32 [[FLAGS]], %struct.ndrange_t* {{.*}}, i32 2, %opencl.clk_event_t{{.*}}* addrspace(4)* [[WAIT_EVNT]], %opencl.clk_event_t{{.*}}* addrspace(4)* [[EVNT]], i8 addrspace(4)* addrspacecast (i8 addrspace(1)* bitcast ({ i8**, i32, i32, i8*, %struct.__block_descriptor addrspace(2)* } addrspace(1)* @__block_literal_global{{(.[0-9]+)?}} to i8 addrspace(1)*) to i8 addrspace(4)*), i32 1, i64 [[SIZE]])
+ // B32: %[[TMP:.*]] = alloca [1 x i32]
+ // B32: %[[TMP1:.*]] = getelementptr [1 x i32], [1 x i32]* %[[TMP]], i32 0, i32 0
+ // B32: store i32 %{{.*}}, i32* %[[TMP1]], align 4
+ // B64: %[[TMP:.*]] = alloca [1 x i64]
+ // B64: %[[TMP1:.*]] = getelementptr [1 x i64], [1 x i64]* %[[TMP]], i32 0, i32 0
+ // B64: store i64 %{{.*}}, i64* %[[TMP1]], align 8
+ // COMMON-LABEL: call i32 @__enqueue_kernel_events_vaargs
+ // COMMON-SAME: (%opencl.queue_t{{.*}}* [[DEF_Q]], i32 [[FLAGS]], %struct.ndrange_t* {{.*}}, i32 2, %opencl.clk_event_t{{.*}}* addrspace(4)* [[WAIT_EVNT]], %opencl.clk_event_t{{.*}}* addrspace(4)* [[EVNT]],
+ // COMMON-SAME: i8 addrspace(4)* addrspacecast (i8* bitcast ({{.*}} [[INVGK4:[^ ]+_kernel]] to i8*) to i8 addrspace(4)*),
+ // COMMON-SAME: i8 addrspace(4)* addrspacecast (i8 addrspace(1)* bitcast ({ i32, i32, i8 addrspace(4)* } addrspace(1)* [[BLG4]] to i8 addrspace(1)*) to i8 addrspace(4)*), i32 1,
+ // B32-SAME: i32* %[[TMP1]])
+ // B64-SAME: i64* %[[TMP1]])
enqueue_kernel(default_queue, flags, ndrange, 2, event_wait_list2, &clk_event,
^(local void *p) {
return;
@@ -96,46 +170,170 @@ kernel void device_side_enqueue(global int *a, global int *b, int i) {
c);
long l;
+ // Emits global block literal [[BLG5]] and block kernel [[INVGK5]].
// COMMON: [[DEF_Q:%[0-9]+]] = load %opencl.queue_t{{.*}}*, %opencl.queue_t{{.*}}** %default_queue
// COMMON: [[FLAGS:%[0-9]+]] = load i32, i32* %flags
- // B32: [[SIZE:%[0-9]+]] = trunc i64 {{%[0-9]+}} to i32
- // B32: call i32 (%opencl.queue_t{{.*}}*, i32, %struct.ndrange_t*, i8 addrspace(4)*, i32, ...) @__enqueue_kernel_vaargs(%opencl.queue_t{{.*}}* [[DEF_Q]], i32 [[FLAGS]], %struct.ndrange_t* [[NDR]]{{(.[0-9]+)?}}, i8 addrspace(4)* addrspacecast (i8 addrspace(1)* bitcast ({ i8**, i32, i32, i8*, %struct.__block_descriptor addrspace(2)* } addrspace(1)* @__block_literal_global{{(.[0-9]+)?}} to i8 addrspace(1)*) to i8 addrspace(4)*), i32 1, i32 [[SIZE]])
- // B64: [[SIZE:%[0-9]+]] = load i64, i64* %l
- // B64: call i32 (%opencl.queue_t{{.*}}*, i32, %struct.ndrange_t*, i8 addrspace(4)*, i32, ...) @__enqueue_kernel_vaargs(%opencl.queue_t{{.*}}* [[DEF_Q]], i32 [[FLAGS]], %struct.ndrange_t* [[NDR]]{{(.[0-9]+)?}}, i8 addrspace(4)* addrspacecast (i8 addrspace(1)* bitcast ({ i8**, i32, i32, i8*, %struct.__block_descriptor addrspace(2)* } addrspace(1)* @__block_literal_global{{(.[0-9]+)?}} to i8 addrspace(1)*) to i8 addrspace(4)*), i32 1, i64 [[SIZE]])
+ // B32: %[[TMP:.*]] = alloca [1 x i32]
+ // B32: %[[TMP1:.*]] = getelementptr [1 x i32], [1 x i32]* %[[TMP]], i32 0, i32 0
+ // B32: store i32 %{{.*}}, i32* %[[TMP1]], align 4
+ // B64: %[[TMP:.*]] = alloca [1 x i64]
+ // B64: %[[TMP1:.*]] = getelementptr [1 x i64], [1 x i64]* %[[TMP]], i32 0, i32 0
+ // B64: store i64 %{{.*}}, i64* %[[TMP1]], align 8
+ // COMMON-LABEL: call i32 @__enqueue_kernel_vaargs
+ // COMMON-SAME: (%opencl.queue_t{{.*}}* [[DEF_Q]], i32 [[FLAGS]], %struct.ndrange_t* [[NDR]]{{([0-9]+)?}},
+ // COMMON-SAME: i8 addrspace(4)* addrspacecast (i8* bitcast ({{.*}} [[INVGK5:[^ ]+_kernel]] to i8*) to i8 addrspace(4)*),
+ // COMMON-SAME: i8 addrspace(4)* addrspacecast (i8 addrspace(1)* bitcast ({ i32, i32, i8 addrspace(4)* } addrspace(1)* [[BLG5]] to i8 addrspace(1)*) to i8 addrspace(4)*), i32 1,
+ // B32-SAME: i32* %[[TMP1]])
+ // B64-SAME: i64* %[[TMP1]])
enqueue_kernel(default_queue, flags, ndrange,
^(local void *p) {
return;
},
l);
+ // Emits global block literal [[BLG6]] and block kernel [[INVGK6]].
+ // COMMON: [[DEF_Q:%[0-9]+]] = load %opencl.queue_t{{.*}}*, %opencl.queue_t{{.*}}** %default_queue
+ // COMMON: [[FLAGS:%[0-9]+]] = load i32, i32* %flags
+ // B32: %[[TMP:.*]] = alloca [3 x i32]
+ // B32: %[[TMP1:.*]] = getelementptr [3 x i32], [3 x i32]* %[[TMP]], i32 0, i32 0
+ // B32: store i32 1, i32* %[[TMP1]], align 4
+ // B32: %[[TMP2:.*]] = getelementptr [3 x i32], [3 x i32]* %[[TMP]], i32 0, i32 1
+ // B32: store i32 2, i32* %[[TMP2]], align 4
+ // B32: %[[TMP3:.*]] = getelementptr [3 x i32], [3 x i32]* %[[TMP]], i32 0, i32 2
+ // B32: store i32 4, i32* %[[TMP3]], align 4
+ // B64: %[[TMP:.*]] = alloca [3 x i64]
+ // B64: %[[TMP1:.*]] = getelementptr [3 x i64], [3 x i64]* %[[TMP]], i32 0, i32 0
+ // B64: store i64 1, i64* %[[TMP1]], align 8
+ // B64: %[[TMP2:.*]] = getelementptr [3 x i64], [3 x i64]* %[[TMP]], i32 0, i32 1
+ // B64: store i64 2, i64* %[[TMP2]], align 8
+ // B64: %[[TMP3:.*]] = getelementptr [3 x i64], [3 x i64]* %[[TMP]], i32 0, i32 2
+ // B64: store i64 4, i64* %[[TMP3]], align 8
+ // COMMON-LABEL: call i32 @__enqueue_kernel_vaargs
+ // COMMON-SAME: (%opencl.queue_t{{.*}}* [[DEF_Q]], i32 [[FLAGS]], %struct.ndrange_t* [[NDR]]{{([0-9]+)?}},
+ // COMMON-SAME: i8 addrspace(4)* addrspacecast (i8* bitcast ({{.*}} [[INVGK6:[^ ]+_kernel]] to i8*) to i8 addrspace(4)*),
+ // COMMON-SAME: i8 addrspace(4)* addrspacecast (i8 addrspace(1)* bitcast ({ i32, i32, i8 addrspace(4)* } addrspace(1)* [[BLG6]] to i8 addrspace(1)*) to i8 addrspace(4)*), i32 3,
+ // B32-SAME: i32* %[[TMP1]])
+ // B64-SAME: i64* %[[TMP1]])
+ enqueue_kernel(default_queue, flags, ndrange,
+ ^(local void *p1, local void *p2, local void *p3) {
+ return;
+ },
+ 1, 2, 4);
+
+ // Emits global block literal [[BLG7]] and block kernel [[INVGK7]].
// COMMON: [[DEF_Q:%[0-9]+]] = load %opencl.queue_t*, %opencl.queue_t** %default_queue
// COMMON: [[FLAGS:%[0-9]+]] = load i32, i32* %flags
- // B32: call i32 (%opencl.queue_t{{.*}}*, i32, %struct.ndrange_t*, i8 addrspace(4)*, i32, ...) @__enqueue_kernel_vaargs(%opencl.queue_t{{.*}}* [[DEF_Q]], i32 [[FLAGS]], %struct.ndrange_t* [[NDR]]{{(.[0-9]+)?}}, i8 addrspace(4)* addrspacecast (i8 addrspace(1)* bitcast ({ i8**, i32, i32, i8*, %struct.__block_descriptor addrspace(2)* } addrspace(1)* @__block_literal_global{{(.[0-9]+)?}} to i8 addrspace(1)*) to i8 addrspace(4)*), i32 1, i32 0)
- // B64: call i32 (%opencl.queue_t{{.*}}*, i32, %struct.ndrange_t*, i8 addrspace(4)*, i32, ...) @__enqueue_kernel_vaargs(%opencl.queue_t{{.*}}* [[DEF_Q]], i32 [[FLAGS]], %struct.ndrange_t* [[NDR]]{{(.[0-9]+)?}}, i8 addrspace(4)* addrspacecast (i8 addrspace(1)* bitcast ({ i8**, i32, i32, i8*, %struct.__block_descriptor addrspace(2)* } addrspace(1)* @__block_literal_global{{(.[0-9]+)?}} to i8 addrspace(1)*) to i8 addrspace(4)*), i32 1, i64 4294967296)
+ // B32: %[[TMP:.*]] = alloca [1 x i32]
+ // B32: %[[TMP1:.*]] = getelementptr [1 x i32], [1 x i32]* %[[TMP]], i32 0, i32 0
+ // B32: store i32 0, i32* %[[TMP1]], align 4
+ // B64: %[[TMP:.*]] = alloca [1 x i64]
+ // B64: %[[TMP1:.*]] = getelementptr [1 x i64], [1 x i64]* %[[TMP]], i32 0, i32 0
+ // B64: store i64 4294967296, i64* %[[TMP1]], align 8
+ // COMMON-LABEL: call i32 @__enqueue_kernel_vaargs
+ // COMMON-SAME: (%opencl.queue_t{{.*}}* [[DEF_Q]], i32 [[FLAGS]], %struct.ndrange_t* [[NDR]]{{([0-9]+)?}},
+ // COMMON-SAME: i8 addrspace(4)* addrspacecast (i8* bitcast ({{.*}} [[INVGK7:[^ ]+_kernel]] to i8*) to i8 addrspace(4)*),
+ // COMMON-SAME: i8 addrspace(4)* addrspacecast (i8 addrspace(1)* bitcast ({ i32, i32, i8 addrspace(4)* } addrspace(1)* [[BLG7]] to i8 addrspace(1)*) to i8 addrspace(4)*), i32 1,
+ // B32-SAME: i32* %[[TMP1]])
+ // B64-SAME: i64* %[[TMP1]])
enqueue_kernel(default_queue, flags, ndrange,
^(local void *p) {
return;
},
4294967296L);
+ // Emits global block literal [[BLG8]] and invoke function [[INVG8]].
// The full type of these expressions are long (and repeated elsewhere), so we
// capture it as part of the regex for convenience and clarity.
- // COMMON: store void () addrspace(4)* addrspacecast (void () addrspace(1)* bitcast ({ i8**, i32, i32, i8*, %struct.__block_descriptor addrspace(2)* } addrspace(1)* [[BL_A:@__block_literal_global(\.[0-9]+)?]] to void () addrspace(1)*) to void () addrspace(4)*), void () addrspace(4)** %block_A
+ // COMMON: store void () addrspace(4)* addrspacecast (void () addrspace(1)* bitcast ({ i32, i32, i8 addrspace(4)* } addrspace(1)* [[BLG8]] to void () addrspace(1)*) to void () addrspace(4)*), void () addrspace(4)** %block_A
void (^const block_A)(void) = ^{
return;
};
- // COMMON: store void (i8 addrspace(3)*) addrspace(4)* addrspacecast (void (i8 addrspace(3)*) addrspace(1)* bitcast ({ i8**, i32, i32, i8*, %struct.__block_descriptor addrspace(2)* } addrspace(1)* [[BL_B:@__block_literal_global(\.[0-9]+)?]] to void (i8 addrspace(3)*) addrspace(1)*) to void (i8 addrspace(3)*) addrspace(4)*), void (i8 addrspace(3)*) addrspace(4)** %block_B
+ // Emits global block literal [[BLG9]] and invoke function [[INVG9]].
+ // COMMON: store void (i8 addrspace(3)*) addrspace(4)* addrspacecast (void (i8 addrspace(3)*) addrspace(1)* bitcast ({ i32, i32, i8 addrspace(4)* } addrspace(1)* [[BLG9]] to void (i8 addrspace(3)*) addrspace(1)*) to void (i8 addrspace(3)*) addrspace(4)*), void (i8 addrspace(3)*) addrspace(4)** %block_B
void (^const block_B)(local void *) = ^(local void *a) {
return;
};
- // COMMON: call i32 @__get_kernel_work_group_size_impl(i8 addrspace(4)* addrspacecast (i8 addrspace(1)* bitcast ({ i8**, i32, i32, i8*, %struct.__block_descriptor addrspace(2)* } addrspace(1)* [[BL_A]] to i8 addrspace(1)*) to i8 addrspace(4)*))
+ // Uses global block literal [[BLG8]] and invoke function [[INVG8]].
+ // COMMON: [[r1:%.*]] = load i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* getelementptr inbounds (%struct.__opencl_block_literal_generic, %struct.__opencl_block_literal_generic addrspace(4)* addrspacecast (%struct.__opencl_block_literal_generic addrspace(1)* bitcast ({ i32, i32, i8 addrspace(4)* } addrspace(1)* [[BLG8]] to %struct.__opencl_block_literal_generic addrspace(1)*) to %struct.__opencl_block_literal_generic addrspace(4)*), i32 0, i32 2)
+ // COMMON: [[r2:%.*]] = addrspacecast i8 addrspace(4)* [[r1]] to void (i8 addrspace(4)*)*
+ // COMMON: call spir_func void [[r2]](i8 addrspace(4)* addrspacecast (i8 addrspace(1)* bitcast ({ i32, i32, i8 addrspace(4)* } addrspace(1)* [[BLG8]] to i8 addrspace(1)*) to i8 addrspace(4)*))
+ block_A();
+
+ // Emits global block literal [[BLG8]] and block kernel [[INVGK8]]. [[INVGK8]] calls [[INVG8]].
+ // COMMON: [[DEF_Q:%[0-9]+]] = load %opencl.queue_t{{.*}}*, %opencl.queue_t{{.*}}** %default_queue
+ // COMMON: [[FLAGS:%[0-9]+]] = load i32, i32* %flags
+ // COMMON-LABEL: call i32 @__enqueue_kernel_basic(
+ // COMMON-SAME: %opencl.queue_t{{.*}}* [[DEF_Q]], i32 [[FLAGS]], %struct.ndrange_t* byval [[NDR]]{{([0-9]+)?}},
+ // COMMON-SAME: i8 addrspace(4)* addrspacecast (i8* bitcast ({{.*}} [[INVGK8:[^ ]+_kernel]] to i8*) to i8 addrspace(4)*),
+ // COMMON-SAME: i8 addrspace(4)* addrspacecast (i8 addrspace(1)* bitcast ({ i32, i32, i8 addrspace(4)* } addrspace(1)* [[BLG8]] to i8 addrspace(1)*) to i8 addrspace(4)*))
+ enqueue_kernel(default_queue, flags, ndrange, block_A);
+
+ // Uses block kernel [[INVGK8]] and global block literal [[BLG8]].
+ // COMMON: call i32 @__get_kernel_work_group_size_impl(
+ // COMMON-SAME: i8 addrspace(4)* addrspacecast (i8* bitcast ({{.*}} [[INVGK8]] to i8*) to i8 addrspace(4)*),
+ // COMMON-SAME: i8 addrspace(4)* addrspacecast (i8 addrspace(1)* bitcast ({ i32, i32, i8 addrspace(4)* } addrspace(1)* [[BLG8]] to i8 addrspace(1)*) to i8 addrspace(4)*))
unsigned size = get_kernel_work_group_size(block_A);
- // COMMON: call i32 @__get_kernel_work_group_size_impl(i8 addrspace(4)* addrspacecast (i8 addrspace(1)* bitcast ({ i8**, i32, i32, i8*, %struct.__block_descriptor addrspace(2)* } addrspace(1)* [[BL_B]] to i8 addrspace(1)*) to i8 addrspace(4)*))
+
+ // Uses global block literal [[BLG8]] and invoke function [[INVG8]]. Make sure no redundant block literal and invoke functions are emitted.
+ // COMMON: [[r1:%.*]] = load i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* getelementptr inbounds (%struct.__opencl_block_literal_generic, %struct.__opencl_block_literal_generic addrspace(4)* addrspacecast (%struct.__opencl_block_literal_generic addrspace(1)* bitcast ({ i32, i32, i8 addrspace(4)* } addrspace(1)* [[BLG8]] to %struct.__opencl_block_literal_generic addrspace(1)*) to %struct.__opencl_block_literal_generic addrspace(4)*), i32 0, i32 2)
+ // COMMON: [[r2:%.*]] = addrspacecast i8 addrspace(4)* [[r1]] to void (i8 addrspace(4)*)*
+ // COMMON: call spir_func void [[r2]](i8 addrspace(4)* addrspacecast (i8 addrspace(1)* bitcast ({ i32, i32, i8 addrspace(4)* } addrspace(1)* [[BLG8]] to i8 addrspace(1)*) to i8 addrspace(4)*))
+ block_A();
+
+ // Emits global block literal [[BLG9]] and block kernel [[INVGK9]]. [[INVGK9]] calls [[INV9]].
+ // COMMON: call i32 @__get_kernel_work_group_size_impl(
+ // COMMON-SAME: i8 addrspace(4)* addrspacecast (i8* bitcast ({{.*}} [[INVGK9:[^ ]+_kernel]] to i8*) to i8 addrspace(4)*),
+ // COMMON-SAME: i8 addrspace(4)* addrspacecast (i8 addrspace(1)* bitcast ({ i32, i32, i8 addrspace(4)* } addrspace(1)* [[BLG9]] to i8 addrspace(1)*) to i8 addrspace(4)*))
size = get_kernel_work_group_size(block_B);
- // COMMON: call i32 @__get_kernel_preferred_work_group_multiple_impl(i8 addrspace(4)* addrspacecast (i8 addrspace(1)* bitcast ({ i8**, i32, i32, i8*, %struct.__block_descriptor addrspace(2)* } addrspace(1)* [[BL_A]] to i8 addrspace(1)*) to i8 addrspace(4)*))
+
+ // Uses global block literal [[BLG8]] and block kernel [[INVGK8]]. Make sure no redundant block literal ind invoke functions are emitted.
+ // COMMON: call i32 @__get_kernel_preferred_work_group_multiple_impl(
+ // COMMON-SAME: i8 addrspace(4)* addrspacecast (i8* bitcast ({{.*}} [[INVGK8]] to i8*) to i8 addrspace(4)*),
+ // COMMON-SAME: i8 addrspace(4)* addrspacecast (i8 addrspace(1)* bitcast ({ i32, i32, i8 addrspace(4)* } addrspace(1)* [[BLG8]] to i8 addrspace(1)*) to i8 addrspace(4)*))
size = get_kernel_preferred_work_group_size_multiple(block_A);
- // COMMON: call i32 @__get_kernel_preferred_work_group_multiple_impl(i8 addrspace(4)* addrspacecast (i8 addrspace(1)* bitcast ({ i8**, i32, i32, i8*, %struct.__block_descriptor addrspace(2)* } addrspace(1)* [[BL_GLOBAL]] to i8 addrspace(1)*) to i8 addrspace(4)*))
+
+ // Uses global block literal [[BL_GLOBAL]] and block kernel [[INV_G_K]]. [[INV_G_K]] calls [[INV_G]].
+ // COMMON: call i32 @__get_kernel_preferred_work_group_multiple_impl(
+ // COMMON-SAME: i8 addrspace(4)* addrspacecast (i8* bitcast ({{.*}} [[INV_G_K:[^ ]+_kernel]] to i8*) to i8 addrspace(4)*),
+ // COMMON-SAME: i8 addrspace(4)* addrspacecast (i8 addrspace(1)* bitcast ({ i32, i32, i8 addrspace(4)* } addrspace(1)* [[BL_GLOBAL]] to i8 addrspace(1)*) to i8 addrspace(4)*))
size = get_kernel_preferred_work_group_size_multiple(block_G);
+
+ // Emits global block literal [[BLG10]] and block kernel [[INVGK10]].
+ // COMMON: call i32 @__get_kernel_max_sub_group_size_for_ndrange_impl(%struct.ndrange_t* {{[^,]+}},
+ // COMMON-SAME: i8 addrspace(4)* addrspacecast (i8* bitcast ({{.*}} [[INVGK10:[^ ]+_kernel]] to i8*) to i8 addrspace(4)*),
+ // COMMON-SAME: i8 addrspace(4)* addrspacecast (i8 addrspace(1)* bitcast ({ i32, i32, i8 addrspace(4)* } addrspace(1)* [[BLG10]] to i8 addrspace(1)*) to i8 addrspace(4)*))
+ size = get_kernel_max_sub_group_size_for_ndrange(ndrange, ^(){});
+
+ // Emits global block literal [[BLG11]] and block kernel [[INVGK11]].
+ // COMMON: call i32 @__get_kernel_sub_group_count_for_ndrange_impl(%struct.ndrange_t* {{[^,]+}},
+ // COMMON-SAME: i8 addrspace(4)* addrspacecast (i8* bitcast ({{.*}} [[INVGK11:[^ ]+_kernel]] to i8*) to i8 addrspace(4)*),
+ // COMMON-SAME: i8 addrspace(4)* addrspacecast (i8 addrspace(1)* bitcast ({ i32, i32, i8 addrspace(4)* } addrspace(1)* [[BLG11]] to i8 addrspace(1)*) to i8 addrspace(4)*))
+ size = get_kernel_sub_group_count_for_ndrange(ndrange, ^(){});
}
+
+// COMMON: define internal spir_kernel void [[INVLK1]](i8 addrspace(4)*) #{{[0-9]+}} {
+// COMMON: entry:
+// COMMON: call void @__device_side_enqueue_block_invoke(i8 addrspace(4)* %0)
+// COMMON: ret void
+// COMMON: }
+// COMMON: define internal spir_kernel void [[INVLK2]](i8 addrspace(4)*{{.*}})
+// COMMON: define internal spir_kernel void [[INVGK1]](i8 addrspace(4)*{{.*}}, i8 addrspace(3)*{{.*}})
+// COMMON: define internal spir_kernel void [[INVGK2]](i8 addrspace(4)*{{.*}}, i8 addrspace(3)*{{.*}})
+// COMMON: define internal spir_kernel void [[INVGK3]](i8 addrspace(4)*{{.*}}, i8 addrspace(3)*{{.*}})
+// COMMON: define internal spir_kernel void [[INVGK4]](i8 addrspace(4)*{{.*}}, i8 addrspace(3)*{{.*}})
+// COMMON: define internal spir_kernel void [[INVGK5]](i8 addrspace(4)*{{.*}}, i8 addrspace(3)*{{.*}})
+// COMMON: define internal spir_kernel void [[INVGK6]](i8 addrspace(4)*, i8 addrspace(3)*, i8 addrspace(3)*, i8 addrspace(3)*) #{{[0-9]+}} {
+// COMMON: entry:
+// COMMON: call void @__device_side_enqueue_block_invoke_8(i8 addrspace(4)* %0, i8 addrspace(3)* %1, i8 addrspace(3)* %2, i8 addrspace(3)* %3)
+// COMMON: ret void
+// COMMON: }
+// COMMON: define internal spir_kernel void [[INVGK7]](i8 addrspace(4)*{{.*}}, i8 addrspace(3)*{{.*}})
+// COMMON: define internal spir_func void [[INVG8]](i8 addrspace(4)*{{.*}})
+// COMMON: define internal spir_func void [[INVG9]](i8 addrspace(4)*{{.*}}, i8 addrspace(3)* %{{.*}})
+// COMMON: define internal spir_kernel void [[INVGK8]](i8 addrspace(4)*{{.*}})
+// COMMON: define internal spir_kernel void [[INVGK9]](i8 addrspace(4)*{{.*}}, i8 addrspace(3)*{{.*}})
+// COMMON: define internal spir_kernel void [[INV_G_K]](i8 addrspace(4)*{{.*}}, i8 addrspace(3)*{{.*}})
+// COMMON: define internal spir_kernel void [[INVGK10]](i8 addrspace(4)*{{.*}})
+// COMMON: define internal spir_kernel void [[INVGK11]](i8 addrspace(4)*{{.*}})
diff --git a/test/CodeGenOpenCL/convergent.cl b/test/CodeGenOpenCL/convergent.cl
index c6bcb52a6d75..285b637ca687 100644
--- a/test/CodeGenOpenCL/convergent.cl
+++ b/test/CodeGenOpenCL/convergent.cl
@@ -1,9 +1,19 @@
-// RUN: %clang_cc1 -triple spir-unknown-unknown -emit-llvm %s -o - | opt -instnamer -S | FileCheck %s
+// RUN: %clang_cc1 -triple spir-unknown-unknown -emit-llvm %s -o - | opt -instnamer -S | FileCheck -enable-var-scope %s
+
+// This is initially assumed convergent, but can be deduced to not require it.
+
+// CHECK-LABEL: define spir_func void @non_convfun() local_unnamed_addr #0
+// CHECK: ret void
+__attribute__((noinline))
+void non_convfun(void) {
+ volatile int* p;
+ *p = 0;
+}
void convfun(void) __attribute__((convergent));
-void non_convfun(void);
void nodupfun(void) __attribute__((noduplicate));
+// External functions should be assumed convergent.
void f(void);
void g(void);
@@ -17,19 +27,23 @@ void g(void);
// non_convfun();
// }
//
-// CHECK: define spir_func void @test_merge_if(i32 %[[a:.+]])
-// CHECK: %[[tobool:.+]] = icmp eq i32 %[[a]], 0
+// CHECK-LABEL: define spir_func void @test_merge_if(i32 %a) local_unnamed_addr #1 {
+// CHECK: %[[tobool:.+]] = icmp eq i32 %a, 0
// CHECK: br i1 %[[tobool]], label %[[if_end3_critedge:.+]], label %[[if_then:.+]]
+
// CHECK: [[if_then]]:
// CHECK: tail call spir_func void @f()
// CHECK: tail call spir_func void @non_convfun()
// CHECK: tail call spir_func void @g()
+
// CHECK: br label %[[if_end3:.+]]
+
// CHECK: [[if_end3_critedge]]:
// CHECK: tail call spir_func void @non_convfun()
// CHECK: br label %[[if_end3]]
+
// CHECK: [[if_end3]]:
-// CHECK-LABEL: ret void
+// CHECK: ret void
void test_merge_if(int a) {
if (a) {
@@ -41,13 +55,13 @@ void test_merge_if(int a) {
}
}
-// CHECK-DAG: declare spir_func void @f()
-// CHECK-DAG: declare spir_func void @non_convfun()
-// CHECK-DAG: declare spir_func void @g()
+// CHECK-DAG: declare spir_func void @f() local_unnamed_addr #2
+// CHECK-DAG: declare spir_func void @g() local_unnamed_addr #2
+
// Test two if's are not merged.
-// CHECK: define spir_func void @test_no_merge_if(i32 %[[a:.+]])
-// CHECK: %[[tobool:.+]] = icmp eq i32 %[[a]], 0
+// CHECK-LABEL: define spir_func void @test_no_merge_if(i32 %a) local_unnamed_addr #1
+// CHECK: %[[tobool:.+]] = icmp eq i32 %a, 0
// CHECK: br i1 %[[tobool]], label %[[if_end:.+]], label %[[if_then:.+]]
// CHECK: [[if_then]]:
// CHECK: tail call spir_func void @f()
@@ -56,7 +70,7 @@ void test_merge_if(int a) {
// CHECK: br label %[[if_end]]
// CHECK: [[if_end]]:
// CHECK: %[[tobool_pr:.+]] = phi i1 [ true, %[[if_then]] ], [ false, %{{.+}} ]
-// CHECK: tail call spir_func void @convfun() #[[attr5:.+]]
+// CHECK: tail call spir_func void @convfun() #[[attr4:.+]]
// CHECK: br i1 %[[tobool_pr]], label %[[if_then2:.+]], label %[[if_end3:.+]]
// CHECK: [[if_then2]]:
// CHECK: tail call spir_func void @g()
@@ -74,20 +88,20 @@ void test_no_merge_if(int a) {
}
}
-// CHECK: declare spir_func void @convfun(){{[^#]*}} #[[attr2:[0-9]+]]
+// CHECK: declare spir_func void @convfun(){{[^#]*}} #2
// Test loop is unrolled for convergent function.
-// CHECK-LABEL: define spir_func void @test_unroll()
-// CHECK: tail call spir_func void @convfun() #[[attr5:[0-9]+]]
-// CHECK: tail call spir_func void @convfun() #[[attr5]]
-// CHECK: tail call spir_func void @convfun() #[[attr5]]
-// CHECK: tail call spir_func void @convfun() #[[attr5]]
-// CHECK: tail call spir_func void @convfun() #[[attr5]]
-// CHECK: tail call spir_func void @convfun() #[[attr5]]
-// CHECK: tail call spir_func void @convfun() #[[attr5]]
-// CHECK: tail call spir_func void @convfun() #[[attr5]]
-// CHECK: tail call spir_func void @convfun() #[[attr5]]
-// CHECK: tail call spir_func void @convfun() #[[attr5]]
+// CHECK-LABEL: define spir_func void @test_unroll() local_unnamed_addr #1
+// CHECK: tail call spir_func void @convfun() #[[attr4:[0-9]+]]
+// CHECK: tail call spir_func void @convfun() #[[attr4]]
+// CHECK: tail call spir_func void @convfun() #[[attr4]]
+// CHECK: tail call spir_func void @convfun() #[[attr4]]
+// CHECK: tail call spir_func void @convfun() #[[attr4]]
+// CHECK: tail call spir_func void @convfun() #[[attr4]]
+// CHECK: tail call spir_func void @convfun() #[[attr4]]
+// CHECK: tail call spir_func void @convfun() #[[attr4]]
+// CHECK: tail call spir_func void @convfun() #[[attr4]]
+// CHECK: tail call spir_func void @convfun() #[[attr4]]
// CHECK-LABEL: ret void
void test_unroll() {
@@ -101,7 +115,7 @@ void test_unroll() {
// CHECK: [[for_cond_cleanup:.+]]:
// CHECK: ret void
// CHECK: [[for_body]]:
-// CHECK: tail call spir_func void @nodupfun() #[[attr6:[0-9]+]]
+// CHECK: tail call spir_func void @nodupfun() #[[attr5:[0-9]+]]
// CHECK-NOT: call spir_func void @nodupfun()
// CHECK: br i1 %{{.+}}, label %[[for_body]], label %[[for_cond_cleanup]]
@@ -112,7 +126,16 @@ void test_not_unroll() {
// CHECK: declare spir_func void @nodupfun(){{[^#]*}} #[[attr3:[0-9]+]]
-// CHECK-DAG: attributes #[[attr2]] = { {{[^}]*}}convergent{{[^}]*}} }
-// CHECK-DAG: attributes #[[attr3]] = { {{[^}]*}}noduplicate{{[^}]*}} }
-// CHECK-DAG: attributes #[[attr5]] = { {{[^}]*}}convergent{{[^}]*}} }
-// CHECK-DAG: attributes #[[attr6]] = { {{[^}]*}}noduplicate{{[^}]*}} }
+// CHECK-LABEL: @assume_convergent_asm
+// CHECK: tail call void asm sideeffect "s_barrier", ""() #4
+kernel void assume_convergent_asm()
+{
+ __asm__ volatile("s_barrier");
+}
+
+// CHECK: attributes #0 = { noinline norecurse nounwind "
+// CHECK: attributes #1 = { {{[^}]*}}convergent{{[^}]*}} }
+// CHECK: attributes #2 = { {{[^}]*}}convergent{{[^}]*}} }
+// CHECK: attributes #3 = { {{[^}]*}}convergent noduplicate{{[^}]*}} }
+// CHECK: attributes #4 = { {{[^}]*}}convergent{{[^}]*}} }
+// CHECK: attributes #5 = { {{[^}]*}}convergent noduplicate{{[^}]*}} }
diff --git a/test/CodeGenOpenCL/func-call-dbg-loc.cl b/test/CodeGenOpenCL/func-call-dbg-loc.cl
new file mode 100644
index 000000000000..4ed082fa9f1c
--- /dev/null
+++ b/test/CodeGenOpenCL/func-call-dbg-loc.cl
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -triple amdgcn---amdgizcl -debug-info-kind=limited -O0 -emit-llvm -o - %s | FileCheck %s
+
+typedef struct
+{
+ int a;
+} Struct;
+
+Struct func1();
+
+void func2(Struct S);
+
+void func3()
+{
+ // CHECK: call i32 @func1() #{{[0-9]+}}, !dbg ![[LOC:[0-9]+]]
+ // CHECK: call void @func2(i32 %{{[0-9]+}}) #{{[0-9]+}}, !dbg ![[LOC]]
+ func2(func1());
+}
+
diff --git a/test/CodeGenOpenCL/kernel-arg-info.cl b/test/CodeGenOpenCL/kernel-arg-info.cl
index 463cc4451114..fa48ad28f767 100644
--- a/test/CodeGenOpenCL/kernel-arg-info.cl
+++ b/test/CodeGenOpenCL/kernel-arg-info.cl
@@ -78,6 +78,21 @@ kernel void foo5(myImage img1, write_only image1d_t img2) {
typedef char char16 __attribute__((ext_vector_type(16)));
__kernel void foo6(__global char16 arg[]) {}
// CHECK: !kernel_arg_type ![[MD61:[0-9]+]]
+// ARGINFO: !kernel_arg_name ![[MD62:[0-9]+]]
+
+typedef read_only image1d_t ROImage;
+typedef write_only image1d_t WOImage;
+typedef read_write image1d_t RWImage;
+kernel void foo7(ROImage ro, WOImage wo, RWImage rw) {
+}
+// CHECK: define spir_kernel void @foo7{{[^!]+}}
+// CHECK: !kernel_arg_addr_space ![[MD71:[0-9]+]]
+// CHECK: !kernel_arg_access_qual ![[MD72:[0-9]+]]
+// CHECK: !kernel_arg_type ![[MD73:[0-9]+]]
+// CHECK: !kernel_arg_base_type ![[MD74:[0-9]+]]
+// CHECK: !kernel_arg_type_qual ![[MD75:[0-9]+]]
+// CHECK-NOT: !kernel_arg_name
+// ARGINFO: !kernel_arg_name ![[MD76:[0-9]+]]
// CHECK: ![[MD11]] = !{i32 1, i32 1, i32 1, i32 1, i32 2, i32 2, i32 1, i32 1, i32 1, i32 1, i32 3, i32 3, i32 3, i32 3, i32 3, i32 3, i32 3, i32 3, i32 0, i32 0, i32 0, i32 0}
// CHECK: ![[MD12]] = !{!"none", !"none", !"none", !"none", !"none", !"none", !"none", !"none", !"none", !"none", !"none", !"none", !"none", !"none", !"none", !"none", !"none", !"none", !"none", !"none", !"none", !"none"}
@@ -105,4 +120,11 @@ __kernel void foo6(__global char16 arg[]) {}
// CHECK: ![[MD53]] = !{!"image1d_t", !"image1d_t"}
// ARGINFO: ![[MD54]] = !{!"img1", !"img2"}
// CHECK: ![[MD61]] = !{!"char16*"}
+// ARGINFO: ![[MD62]] = !{!"arg"}
+// CHECK: ![[MD71]] = !{i32 1, i32 1, i32 1}
+// CHECK: ![[MD72]] = !{!"read_only", !"write_only", !"read_write"}
+// CHECK: ![[MD73]] = !{!"ROImage", !"WOImage", !"RWImage"}
+// CHECK: ![[MD74]] = !{!"image1d_t", !"image1d_t", !"image1d_t"}
+// CHECK: ![[MD75]] = !{!"", !"", !""}
+// ARGINFO: ![[MD76]] = !{!"ro", !"wo", !"rw"}
diff --git a/test/CodeGenOpenCL/no-half.cl b/test/CodeGenOpenCL/no-half.cl
new file mode 100644
index 000000000000..aee8f678f01a
--- /dev/null
+++ b/test/CodeGenOpenCL/no-half.cl
@@ -0,0 +1,39 @@
+// RUN: %clang_cc1 %s -cl-std=cl2.0 -emit-llvm -o - -triple spir-unknown-unknown | FileCheck %s
+// RUN: %clang_cc1 %s -cl-std=cl1.2 -emit-llvm -o - -triple spir-unknown-unknown | FileCheck %s
+// RUN: %clang_cc1 %s -cl-std=cl1.1 -emit-llvm -o - -triple spir-unknown-unknown | FileCheck %s
+
+#pragma OPENCL EXTENSION cl_khr_fp64:enable
+
+// CHECK-LABEL: @test_store_float(float %foo, half addrspace({{.}}){{.*}} %bar)
+__kernel void test_store_float(float foo, __global half* bar)
+{
+ __builtin_store_halff(foo, bar);
+// CHECK: [[HALF_VAL:%.*]] = fptrunc float %foo to half
+// CHECK: store half [[HALF_VAL]], half addrspace({{.}})* %bar, align 2
+}
+
+// CHECK-LABEL: @test_store_double(double %foo, half addrspace({{.}}){{.*}} %bar)
+__kernel void test_store_double(double foo, __global half* bar)
+{
+ __builtin_store_half(foo, bar);
+// CHECK: [[HALF_VAL:%.*]] = fptrunc double %foo to half
+// CHECK: store half [[HALF_VAL]], half addrspace({{.}})* %bar, align 2
+}
+
+// CHECK-LABEL: @test_load_float(float addrspace({{.}}){{.*}} %foo, half addrspace({{.}}){{.*}} %bar)
+__kernel void test_load_float(__global float* foo, __global half* bar)
+{
+ foo[0] = __builtin_load_halff(bar);
+// CHECK: [[HALF_VAL:%.*]] = load half, half addrspace({{.}})* %bar
+// CHECK: [[FULL_VAL:%.*]] = fpext half [[HALF_VAL]] to float
+// CHECK: store float [[FULL_VAL]], float addrspace({{.}})* %foo
+}
+
+// CHECK-LABEL: @test_load_double(double addrspace({{.}}){{.*}} %foo, half addrspace({{.}}){{.*}} %bar)
+__kernel void test_load_double(__global double* foo, __global half* bar)
+{
+ foo[0] = __builtin_load_half(bar);
+// CHECK: [[HALF_VAL:%.*]] = load half, half addrspace({{.}})* %bar
+// CHECK: [[FULL_VAL:%.*]] = fpext half [[HALF_VAL]] to double
+// CHECK: store double [[FULL_VAL]], double addrspace({{.}})* %foo
+}
diff --git a/test/CodeGenOpenCL/opencl_types.cl b/test/CodeGenOpenCL/opencl_types.cl
index 73c57b73098f..3501f9fd34e9 100644
--- a/test/CodeGenOpenCL/opencl_types.cl
+++ b/test/CodeGenOpenCL/opencl_types.cl
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 %s -triple "spir-unknown-unknown" -emit-llvm -o - -O0 | FileCheck %s --check-prefix=CHECK-SPIR
-// RUN: %clang_cc1 %s -triple "amdgcn--amdhsa" -emit-llvm -o - -O0 | FileCheck %s --check-prefix=CHECK-AMDGCN
+// RUN: %clang_cc1 -cl-std=CL2.0 %s -triple "spir-unknown-unknown" -emit-llvm -o - -O0 | FileCheck %s --check-prefixes=CHECK-COM,CHECK-SPIR
+// RUN: %clang_cc1 -cl-std=CL2.0 %s -triple "amdgcn--amdhsa" -emit-llvm -o - -O0 | FileCheck %s --check-prefixes=CHECK-COM,CHECK-AMDGCN
#define CLK_ADDRESS_CLAMP_TO_EDGE 2
#define CLK_NORMALIZED_COORDS_TRUE 1
@@ -7,7 +7,7 @@
#define CLK_FILTER_LINEAR 0x20
constant sampler_t glb_smp = CLK_ADDRESS_CLAMP_TO_EDGE|CLK_NORMALIZED_COORDS_TRUE|CLK_FILTER_NEAREST;
-// CHECK-SPIR-NOT: constant i32
+// CHECK-COM-NOT: constant i32
void fnc1(image1d_t img) {}
// CHECK-SPIR: @fnc1(%opencl.image1d_ro_t addrspace(1)*
@@ -39,16 +39,29 @@ void fnc4smp(sampler_t s) {}
kernel void foo(image1d_t img) {
sampler_t smp = CLK_ADDRESS_CLAMP_TO_EDGE|CLK_NORMALIZED_COORDS_TRUE|CLK_FILTER_LINEAR;
- // CHECK-SPIR: alloca %opencl.sampler_t addrspace(2)*
+ // CHECK-COM: alloca %opencl.sampler_t addrspace(2)*
event_t evt;
- // CHECK-SPIR: alloca %opencl.event_t*
- // CHECK-SPIR: store %opencl.sampler_t addrspace(2)*
+ // CHECK-COM: alloca %opencl.event_t*
+ clk_event_t clk_evt;
+ // CHECK-SPIR: alloca %opencl.clk_event_t*
+ // CHECK-AMDGCN: alloca %opencl.clk_event_t addrspace(1)*
+ queue_t queue;
+ // CHECK-SPIR: alloca %opencl.queue_t*
+ // CHECK-AMDGCN: alloca %opencl.queue_t addrspace(1)*
+ reserve_id_t rid;
+ // CHECK-SPIR: alloca %opencl.reserve_id_t*
+ // CHECK-AMDGCN: alloca %opencl.reserve_id_t addrspace(1)*
+ // CHECK-COM: store %opencl.sampler_t addrspace(2)*
fnc4smp(smp);
- // CHECK-SPIR: call {{.*}}void @fnc4smp(%opencl.sampler_t addrspace(2)*
+ // CHECK-COM: call {{.*}}void @fnc4smp(%opencl.sampler_t addrspace(2)*
fnc4smp(glb_smp);
- // CHECK-SPIR: call {{.*}}void @fnc4smp(%opencl.sampler_t addrspace(2)*
+ // CHECK-COM: call {{.*}}void @fnc4smp(%opencl.sampler_t addrspace(2)*
}
+kernel void foo_pipe(read_only pipe int p) {}
+// CHECK-SPIR: @foo_pipe(%opencl.pipe_t addrspace(1)* %p)
+// CHECK_AMDGCN: @foo_pipe(%opencl.pipe_t addrspace(1)* %p)
+
void __attribute__((overloadable)) bad1(image1d_t b, image2d_t c, image2d_t d) {}
// CHECK-SPIR-LABEL: @{{_Z4bad114ocl_image1d_ro14ocl_image2d_roS0_|"\\01\?bad1@@\$\$J0YAXPAUocl_image1d_ro@@PAUocl_image2d_ro@@1@Z"}}
// CHECK-AMDGCN-LABEL: @{{_Z4bad114ocl_image1d_ro14ocl_image2d_roS0_|"\\01\?bad1@@\$\$J0YAXPAUocl_image1d_ro@@PAUocl_image2d_ro@@1@Z"}}(%opencl.image1d_ro_t addrspace(2)*{{.*}}%opencl.image2d_ro_t addrspace(2)*{{.*}}%opencl.image2d_ro_t addrspace(2)*{{.*}})
diff --git a/test/CodeGenOpenCL/pipe_builtin.cl b/test/CodeGenOpenCL/pipe_builtin.cl
index a9b4ab630cef..4b4b4ef97ab2 100644
--- a/test/CodeGenOpenCL/pipe_builtin.cl
+++ b/test/CodeGenOpenCL/pipe_builtin.cl
@@ -1,8 +1,10 @@
-// RUN: %clang_cc1 -emit-llvm -O0 -cl-std=CL2.0 -o - %s | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -cl-ext=+cl_khr_subgroups -O0 -cl-std=CL2.0 -o - %s | FileCheck %s
// CHECK: %opencl.pipe_t = type opaque
// CHECK: %opencl.reserve_id_t = type opaque
+#pragma OPENCL EXTENSION cl_khr_subgroups : enable
+
void test1(read_only pipe int p, global int *ptr) {
// CHECK: call i32 @__read_pipe_2(%opencl.pipe_t* %{{.*}}, i8* %{{.*}}, i32 4, i32 4)
read_pipe(p, ptr);
diff --git a/test/CodeGenOpenCL/sampler.cl b/test/CodeGenOpenCL/sampler.cl
index 3a7319cd78d2..22976c57665f 100644
--- a/test/CodeGenOpenCL/sampler.cl
+++ b/test/CodeGenOpenCL/sampler.cl
@@ -20,6 +20,8 @@
constant sampler_t glb_smp = CLK_ADDRESS_CLAMP_TO_EDGE | CLK_NORMALIZED_COORDS_TRUE | CLK_FILTER_LINEAR;
// CHECK-NOT: glb_smp
+int get_sampler_initializer(void);
+
void fnc4smp(sampler_t s) {}
// CHECK: define spir_func void @fnc4smp(%opencl.sampler_t addrspace(2)* %
@@ -58,4 +60,20 @@ kernel void foo(sampler_t smp_par) {
fnc4smp(5);
// CHECK: [[SAMP:%[0-9]+]] = call %opencl.sampler_t addrspace(2)* @__translate_sampler_initializer(i32 5)
// CHECK: call spir_func void @fnc4smp(%opencl.sampler_t addrspace(2)* [[SAMP]])
+
+ const sampler_t const_smp = CLK_ADDRESS_CLAMP_TO_EDGE | CLK_NORMALIZED_COORDS_TRUE | CLK_FILTER_LINEAR;
+ fnc4smp(const_smp);
+ // CHECK: [[CONST_SAMP:%[0-9]+]] = call %opencl.sampler_t addrspace(2)* @__translate_sampler_initializer(i32 35)
+ // CHECK: store %opencl.sampler_t addrspace(2)* [[CONST_SAMP]], %opencl.sampler_t addrspace(2)** [[CONST_SMP_PTR:%[a-zA-Z0-9]+]]
+ fnc4smp(const_smp);
+ // CHECK: [[SAMP:%[0-9]+]] = load %opencl.sampler_t addrspace(2)*, %opencl.sampler_t addrspace(2)** [[CONST_SMP_PTR]]
+ // CHECK: call spir_func void @fnc4smp(%opencl.sampler_t addrspace(2)* [[SAMP]])
+
+ constant sampler_t constant_smp = CLK_ADDRESS_CLAMP_TO_EDGE | CLK_NORMALIZED_COORDS_TRUE | CLK_FILTER_LINEAR;
+ fnc4smp(constant_smp);
+ // CHECK: [[SAMP:%[0-9]+]] = call %opencl.sampler_t addrspace(2)* @__translate_sampler_initializer(i32 35)
+ // CHECK: call spir_func void @fnc4smp(%opencl.sampler_t addrspace(2)* [[SAMP]])
+
+ // TODO: enable sampler initialization with non-constant integer.
+ //const sampler_t const_smp_func_init = get_sampler_initializer();
}
diff --git a/test/CodeGenOpenCL/vectorLoadStore.cl b/test/CodeGenOpenCL/vectorLoadStore.cl
index 44bc7bd25d45..cb35e6f4689b 100644
--- a/test/CodeGenOpenCL/vectorLoadStore.cl
+++ b/test/CodeGenOpenCL/vectorLoadStore.cl
@@ -1,9 +1,22 @@
-// RUN: %clang_cc1 %s -emit-llvm -O0 -o - | FileCheck %s
+// RUN: %clang_cc1 -cl-std=CL2.0 -triple "spir-unknown-unknown" %s -emit-llvm -O0 -o - | FileCheck %s
-typedef char char3 __attribute((ext_vector_type(3)));;
+typedef char char2 __attribute((ext_vector_type(2)));
+typedef char char3 __attribute((ext_vector_type(3)));
+typedef char char8 __attribute((ext_vector_type(8)));
+typedef float float4 __attribute((ext_vector_type(4)));
// Check for optimized vec3 load/store which treats vec3 as vec4.
void foo(char3 *P, char3 *Q) {
*P = *Q;
// CHECK: %{{.*}} = shufflevector <4 x i8> %{{.*}}, <4 x i8> undef, <3 x i32> <i32 0, i32 1, i32 2>
}
+
+// CHECK: define spir_func void @alignment()
+void alignment() {
+ __private char2 data_generic[100];
+ __private char8 data_private[100];
+
+ // CHECK: %{{.*}} = load <4 x float>, <4 x float> addrspace(4)* %{{.*}}, align 2
+ // CHECK: store <4 x float> %{{.*}}, <4 x float>* %{{.*}}, align 8
+ ((private float4 *)data_private)[1] = ((float4 *)data_generic)[2];
+}
diff --git a/test/Coverage/html-diagnostics.c b/test/Coverage/html-diagnostics.c
index 045943ae8b11..34b86cd98291 100644
--- a/test/Coverage/html-diagnostics.c
+++ b/test/Coverage/html-diagnostics.c
@@ -1,11 +1,18 @@
// RUN: rm -rf %t
// RUN: %clang_cc1 -analyze -analyzer-output=html -analyzer-checker=core -o %t %s
// RUN: find %t -name "*.html" -exec cat "{}" ";" | FileCheck %s
+//
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -analyze -analyzer-output=html-single-file -analyzer-checker=core -o %t %s
+// RUN: find %t -name "*.html" -exec cat "{}" ";" | FileCheck %s
// REQUIRES: staticanalyzer
// CHECK: <h3>Annotated Source Code</h3>
+// Make sure it's not generated as a multi-file HTML output
+// CHECK-NOT: <h4 class=FileName>{{.*}}
+
// Without tweaking expr, the expr would hit to the line below
// emitted to the output as comment.
// CHECK: {{[D]ereference of null pointer}}
diff --git a/test/Coverage/html-multifile-diagnostics.c b/test/Coverage/html-multifile-diagnostics.c
new file mode 100644
index 000000000000..abd54ae83938
--- /dev/null
+++ b/test/Coverage/html-multifile-diagnostics.c
@@ -0,0 +1,21 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -analyze -analyzer-output=html -analyzer-checker=core -o %t %s
+// RUN: find %t -name "*.html" -exec cat "{}" ";" | FileCheck %s
+
+// REQUIRES: staticanalyzer
+
+// CHECK: <h3>Annotated Source Code</h3>
+
+// Make sure it's generated as multi-file HTML output
+// CHECK: <h4 class=FileName>{{.*}}html-multifile-diagnostics.c</h4>
+// CHECK: <h4 class=FileName>{{.*}}html-multifile-diagnostics.h</h4>
+
+// Without tweaking expr, the expr would hit to the line below
+// emitted to the output as comment.
+// CHECK: {{[D]ereference of null pointer}}
+
+#include "html-multifile-diagnostics.h"
+
+void f0() {
+ f1((int*)0);
+}
diff --git a/test/Coverage/html-multifile-diagnostics.h b/test/Coverage/html-multifile-diagnostics.h
new file mode 100644
index 000000000000..4a99ff0df9cd
--- /dev/null
+++ b/test/Coverage/html-multifile-diagnostics.h
@@ -0,0 +1,3 @@
+void f1(int *ptr) {
+ *ptr = 0;
+}
diff --git a/test/CoverageMapping/Inputs/deferred-region-helper.h b/test/CoverageMapping/Inputs/deferred-region-helper.h
new file mode 100644
index 000000000000..c3e5c16e32a7
--- /dev/null
+++ b/test/CoverageMapping/Inputs/deferred-region-helper.h
@@ -0,0 +1,5 @@
+void included_func() {
+ if (false)
+ return;
+ return;
+}
diff --git a/test/CoverageMapping/abspath.cpp b/test/CoverageMapping/abspath.cpp
index 667172e32cf4..4b92a3773db0 100644
--- a/test/CoverageMapping/abspath.cpp
+++ b/test/CoverageMapping/abspath.cpp
@@ -4,7 +4,7 @@
// RMDOTS-NOT: Inputs
// RMDOTS: "
-// RUN: cd %T && mkdir -p test && cd test
+// RUN: mkdir -p %t/test && cd %t/test
// RUN: echo "void f1() {}" > f1.c
// RUN: %clang_cc1 -fprofile-instrument=clang -fcoverage-mapping -emit-llvm -main-file-name abspath.cpp ../test/f1.c -o - | FileCheck -check-prefix=RELPATH %s
diff --git a/test/CoverageMapping/break.c b/test/CoverageMapping/break.c
index ee41271b53fb..d42c1bd082d2 100644
--- a/test/CoverageMapping/break.c
+++ b/test/CoverageMapping/break.c
@@ -2,29 +2,29 @@
int main() { // CHECK: File 0, [[@LINE]]:12 -> {{[0-9]+}}:2 = #0
int cnt = 0; // CHECK-NEXT: File 0, [[@LINE+1]]:9 -> [[@LINE+1]]:18 = #0
- while(cnt < 100) { // CHECK-NEXT: File 0, [[@LINE]]:20 -> [[@LINE+3]]:4 = #1
+ while(cnt < 100) { // CHECK: File 0, [[@LINE]]:20 -> [[@LINE+3]]:4 = #1
break;
++cnt; // CHECK-NEXT: File 0, [[@LINE]]:5 -> [[@LINE+1]]:4 = 0
} // CHECK-NEXT: File 0, [[@LINE+1]]:9 -> [[@LINE+1]]:18 = #0
- while(cnt < 100) { // CHECK-NEXT: File 0, [[@LINE]]:20 -> [[@LINE+6]]:4 = #2
+ while(cnt < 100) { // CHECK: File 0, [[@LINE]]:20 -> [[@LINE+6]]:4 = #2
{
break;
++cnt; // CHECK-NEXT: File 0, [[@LINE]]:7 -> [[@LINE+3]]:4 = 0
}
++cnt;
} // CHECK-NEXT: File 0, [[@LINE+1]]:9 -> [[@LINE+1]]:18 = ((#0 + #3) - #4)
- while(cnt < 100) { // CHECK-NEXT: File 0, [[@LINE]]:20 -> [[@LINE+7]]:4 = #3
+ while(cnt < 100) { // CHECK: File 0, [[@LINE]]:20 -> [[@LINE+7]]:4 = #3
// CHECK-NEXT: File 0, [[@LINE+1]]:8 -> [[@LINE+1]]:16 = #3
- if(cnt == 0) { // CHECK-NEXT: File 0, [[@LINE]]:18 -> [[@LINE+3]]:6 = #4
+ if(cnt == 0) { // CHECK: File 0, [[@LINE]]:18 -> [[@LINE+3]]:6 = #4
break;
++cnt; // CHECK-NEXT: File 0, [[@LINE]]:7 -> [[@LINE+1]]:6 = 0
}
++cnt; // CHECK-NEXT: File 0, [[@LINE]]:5 -> [[@LINE+1]]:4 = (#3 - #4)
} // CHECK-NEXT: File 0, [[@LINE+1]]:9 -> [[@LINE+1]]:18 = (#0 + #6)
- while(cnt < 100) { // CHECK-NEXT: File 0, [[@LINE]]:20 -> [[@LINE+8]]:4 = #5
+ while(cnt < 100) { // CHECK: File 0, [[@LINE]]:20 -> [[@LINE+8]]:4 = #5
// CHECK-NEXT: File 0, [[@LINE+1]]:8 -> [[@LINE+1]]:16 = #5
- if(cnt == 0) { // CHECK-NEXT: File 0, [[@LINE]]:18 -> [[@LINE+2]]:6 = #6
- ++cnt;
+ if(cnt == 0) { // CHECK: File 0, [[@LINE]]:18 -> [[@LINE+2]]:6 = #6
+ ++cnt; // CHECK-NEXT: Gap,File 0, [[@LINE+1]]:6 -> [[@LINE+1]]:12 = (#5 - #6)
} else { // CHECK-NEXT: File 0, [[@LINE]]:12 -> [[@LINE+2]]:6 = (#5 - #6)
break;
}
diff --git a/test/CoverageMapping/casts.c b/test/CoverageMapping/casts.c
index d295f3159875..6f479fd58838 100644
--- a/test/CoverageMapping/casts.c
+++ b/test/CoverageMapping/casts.c
@@ -1,7 +1,7 @@
// RUN: %clang_cc1 -fprofile-instrument=clang -fcoverage-mapping -dump-coverage-mapping -emit-llvm-only -main-file-name casts.c %s | FileCheck %s
int main() { // CHECK: File 0, [[@LINE]]:12 -> [[@LINE+4]]:2 = #0
- // CHECK-NEXT: File 0, [[@LINE+1]]:41 -> [[@LINE+1]]:54 = #1
+ // CHECK: File 0, [[@LINE+1]]:41 -> [[@LINE+1]]:54 = #1
int window_size = (sizeof(int) <= 2 ? (unsigned)512 : 1024); // CHECK-NEXT: File 0, [[@LINE]]:57 -> [[@LINE]]:61 = (#0 - #1)
return 0;
}
diff --git a/test/CoverageMapping/continue.c b/test/CoverageMapping/continue.c
index 7ea03fb68624..9864c912f239 100644
--- a/test/CoverageMapping/continue.c
+++ b/test/CoverageMapping/continue.c
@@ -3,21 +3,21 @@
int main() { // CHECK: File 0, [[@LINE]]:12 -> [[@LINE+21]]:2 = #0
int j = 0; // CHECK-NEXT: File 0, [[@LINE+2]]:18 -> [[@LINE+2]]:24 = (#0 + #1)
// CHECK-NEXT: File 0, [[@LINE+1]]:26 -> [[@LINE+1]]:29 = #1
- for(int i = 0; i < 20; ++i) { // CHECK-NEXT: File 0, [[@LINE]]:31 -> [[@LINE+17]]:4 = #1
+ for(int i = 0; i < 20; ++i) { // CHECK: File 0, [[@LINE]]:31 -> [[@LINE+17]]:4 = #1
if(i < 10) { // CHECK: File 0, [[@LINE]]:16 -> [[@LINE+13]]:6 = #2
if(i < 5) { // CHECK: File 0, [[@LINE]]:17 -> [[@LINE+3]]:8 = #3
continue;
j = 1; // CHECK-NEXT: File 0, [[@LINE]]:9 -> [[@LINE+1]]:8 = 0
- } else { // CHECK-NEXT: File 0, [[@LINE]]:14 -> [[@LINE+2]]:8 = (#2 - #3)
+ } else { // CHECK: File 0, [[@LINE]]:14 -> [[@LINE+2]]:8 = (#2 - #3)
j = 2;
}
j = 3; // CHECK-NEXT: File 0, [[@LINE]]:7 -> [[@LINE+6]]:6 = (#2 - #3)
if(i < 7) { // CHECK: File 0, [[@LINE]]:17 -> [[@LINE+3]]:8 = #4
continue;
j = 4; // CHECK-NEXT: File 0, [[@LINE]]:9 -> [[@LINE+1]]:8 = 0
- } else j = 5; // CHECK-NEXT: File 0, [[@LINE]]:14 -> [[@LINE]]:19 = ((#2 - #3) - #4)
+ } else j = 5; // CHECK: File 0, [[@LINE]]:14 -> [[@LINE]]:19 = ((#2 - #3) - #4)
j = 6; // CHECK-NEXT: File 0, [[@LINE]]:7 -> [[@LINE+1]]:6 = ((#2 - #3) - #4)
- } else // CHECK-NEXT: File 0, [[@LINE+1]]:7 -> [[@LINE+1]]:12 = (#1 - #2)
+ } else // CHECK: File 0, [[@LINE+1]]:7 -> [[@LINE+1]]:12 = (#1 - #2)
j = 7;
j = 8; // CHECK-NEXT: File 0, [[@LINE]]:5 -> [[@LINE+1]]:4 = ((#1 - #3) - #4)
}
diff --git a/test/CoverageMapping/deferred-region.cpp b/test/CoverageMapping/deferred-region.cpp
new file mode 100644
index 000000000000..5a104f778979
--- /dev/null
+++ b/test/CoverageMapping/deferred-region.cpp
@@ -0,0 +1,204 @@
+// RUN: %clang_cc1 -std=c++11 -fprofile-instrument=clang -fcoverage-mapping -dump-coverage-mapping -fexceptions -fcxx-exceptions -emit-llvm-only -triple %itanium_abi_triple -main-file-name deferred-region.cpp -I %S/Inputs %s | FileCheck %s
+
+#define IF if
+#define STMT(S) S
+
+// CHECK-LABEL: _Z3fooi:
+void foo(int x) {
+ if (x == 0) {
+ return;
+ } // CHECK: Gap,File 0, [[@LINE]]:4 -> [[@LINE+2]]:2 = (#0 - #1)
+
+}
+
+// CHECK-NEXT: _Z4foooi:
+void fooo(int x) {
+ if (x == 0) {
+ return;
+ } // CHECK: Gap,File 0, [[@LINE]]:4 -> [[@LINE+2]]:3 = (#0 - #1)
+
+ if (x == 1) {
+ return;
+ } // CHECK: Gap,File 0, [[@LINE]]:4 -> [[@LINE+2]]:2 = ((#0 - #1) - #2)
+
+}
+
+// CHECK-LABEL: _Z3bazv:
+void baz() { // CHECK: [[@LINE]]:12 -> [[@LINE+2]]:2
+ return; // CHECK-NOT: File
+}
+
+// CHECK-LABEL: _Z3mazv:
+void maz() {
+ if (true)
+ return; // CHECK: Gap,File 0, [[@LINE]]:11 -> [[@LINE+2]]:3 = (#0 - #1)
+
+ return; // CHECK-NOT: Gap
+}
+
+// CHECK-LABEL: _Z4maazv:
+void maaz() {
+ if (true)
+ return; // CHECK: Gap,File 0, [[@LINE]]:11
+ else
+ return; // CHECK-NOT: Gap,File 0, [[@LINE]]
+}
+
+// CHECK-LABEL: _Z5maaazv:
+void maaaz() {
+ if (true) {
+ return;
+ } else { // CHECK: Gap,File 0, [[@LINE]]:4 -> [[@LINE]]:10
+ return; // CHECK-NOT: Gap,File 0, [[@LINE]]
+ }
+}
+
+// CHECK-LABEL: _Z3bari:
+void bar(int x) {
+ IF (x)
+ return; // CHECK: Gap,File 0, [[@LINE]]:11 -> [[@LINE+2]]:3 = (#0 - #1)
+
+ IF (!x)
+ return; // CHECK: Gap,File 0, [[@LINE]]:11 -> [[@LINE+2]]:3 = ((#0 - #1) - #2)
+
+ foo(x);
+}
+
+// CHECK-LABEL: _Z4quuxi:
+// Deferred regions are not emitted within macro expansions.
+void quux(int x) {
+ STMT(
+ if (x == 0)
+ return;)
+
+ // CHECK-NOT: [[@LINE-2]]:{{.*}} -> [[@LINE+2]]
+
+ if (x == 1)
+ STMT(return;)
+
+ // CHECK-NOT: [[@LINE-2]]:{{.*}} -> [[@LINE+3]]
+
+ STMT(
+ if (x == 2)
+ return;
+
+ // CHECK-NOT: [[@LINE-2]]:{{.*}} -> [[@LINE+2]]
+
+ if (x == 3)
+ return;
+ )
+}
+
+// CHECK-LABEL: _Z8weird_ifv:
+void weird_if() {
+ int i = 0;
+
+ if (false)
+ return; // CHECK: Gap,File 0, [[@LINE]]:11 -> [[@LINE+2]]:3 = (#0 - #1)
+
+ if (false)
+ i++;
+
+ if (i + 100 > 0) { // CHECK: [[@LINE]]:20 -> [[@LINE+6]]:4 = #3
+ if (false) // CHECK: [[@LINE+1]]:7 -> [[@LINE+1]]:13 = #4
+ return; // CHECK: Gap,File 0, [[@LINE]]:13 -> [[@LINE+2]]:5 = (#3 - #4)
+ // CHECK: [[@LINE+1]]:5 -> [[@LINE+3]]:4 = (#3 - #4)
+ return; // CHECK: Gap,File 0, [[@LINE]]:5 -> [[@LINE+4]]:3 = ((#0 - #1) - #3)
+
+ }
+
+ if (false)
+ return; // CHECK: Gap,File 0, [[@LINE]]:11 -> [[@LINE+1]]:2
+}
+
+// CHECK-LABEL: _Z8for_loopv:
+void for_loop() {
+ if (false)
+ return; // CHECK: Gap,File 0, [[@LINE]]:11 -> [[@LINE+2]]:3 = (#0 - #1)
+
+ for (int i = 0; i < 10; ++i) {
+ if (i % 2 == 0)
+ continue; // CHECK: Gap,File 0, [[@LINE]]:15 -> [[@LINE+2]]:5 = (#2 - #3)
+
+ if (i % 5 == 0)
+ break; // CHECK: Gap,File 0, [[@LINE]]:12 -> [[@LINE+2]]:5 = ((#2 - #3) - #4)
+
+ int x = i; // CHECK: [[@LINE]]:5 -> [[@LINE+3]]:4 = ((#2 - #3) - #4)
+ return; // CHECK-NOT: [[@LINE]]:11 -> [[@LINE+2]]
+
+ }
+}
+
+struct Error {};
+
+// CHECK-LABEL: _Z10while_loopv:
+void while_loop() {
+ if (false)
+ return; // CHECK: Gap,File 0, [[@LINE]]:11 -> [[@LINE+2]]:3 = (#0 - #1)
+
+ int x = 0;
+ while (++x < 10) {
+ if (x == 1)
+ continue; // CHECK: Gap,File 0, [[@LINE]]:15 -> [[@LINE+2]]:5 = (#2 - #3)
+
+ while (++x < 4) {
+ if (x == 3)
+ break; // CHECK: Gap,File 0, [[@LINE]]:14 -> [[@LINE+2]]:7 = (#4 - #5)
+
+ while (++x < 5) {}
+ }
+
+ if (x == 0)
+ throw Error(); // CHECK: Gap,File 0, [[@LINE]]:20 -> [[@LINE+2]]:5 = ((#2 - #3) - #7)
+
+ while (++x < 9) {
+ if (x == 0)
+ break; // CHECK-NOT: [[@LINE]]:14 -> [[@LINE+2]]
+
+ }
+ }
+}
+
+// CHECK-LABEL: _Z5gotosv:
+void gotos() {
+ if (false)
+ goto out; // CHECK: Gap,File 0, [[@LINE]]:13 -> [[@LINE+2]]:3 = (#0 - #1)
+
+ return; // CHECK: [[@LINE]]:3 -> [[@LINE+4]]:2 = (#0 - #1)
+
+out:
+ return; // CHECK: Gap,File 0, [[@LINE]]:8 -> [[@LINE+1]]:2 = 0
+}
+
+#include "deferred-region-helper.h"
+// CHECK-LABEL: _Z13included_funcv:
+// CHECK: Gap,File 0, 2:13 -> 3:5 = #1
+// CHECK: Gap,File 0, 3:11 -> 4:3 = (#0 - #1)
+
+// CHECK-LABEL: _Z7includev:
+void include() {
+ included_func();
+}
+
+int main() {
+ foo(0);
+ foo(1);
+ fooo(0);
+ fooo(1);
+ maz();
+ maaz();
+ maaaz();
+ baz();
+ bar(0);
+ bar(1);
+ quux(0);
+ quux(1);
+ quux(2);
+ quux(3);
+ weird_if();
+ for_loop();
+ while_loop();
+ gotos();
+ include();
+ return 0;
+}
diff --git a/test/CoverageMapping/header.cpp b/test/CoverageMapping/header.cpp
index 5e0b3111c1d3..d42c15444664 100644
--- a/test/CoverageMapping/header.cpp
+++ b/test/CoverageMapping/header.cpp
@@ -2,6 +2,9 @@
// RUN: FileCheck -input-file %tmapping %s --check-prefix=CHECK-FUNC
// RUN: FileCheck -input-file %tmapping %s --check-prefix=CHECK-STATIC-FUNC
// RUN: FileCheck -input-file %tmapping %s --check-prefix=CHECK-STATIC-FUNC2
+//
+// RUN: %clang_cc1 -fprofile-instrument=clang -fcoverage-mapping -mllvm -limited-coverage-experimental=true -dump-coverage-mapping -emit-llvm-only -main-file-name header.cpp %s > %tmapping.limited
+// RUN: FileCheck -input-file %tmapping.limited %s --check-prefix=CHECK-LIMITED
#include "Inputs/header1.h"
@@ -22,3 +25,5 @@ int main() {
// CHECK-STATIC-FUNC2: static_func2
// CHECK-STATIC-FUNC2: File 0, 21:33 -> 29:2 = 0
+
+// CHECK-LIMITED-NOT: static_func2
diff --git a/test/CoverageMapping/if.cpp b/test/CoverageMapping/if.cpp
index 95e6d8abe63e..e3d6f4e25e57 100644
--- a/test/CoverageMapping/if.cpp
+++ b/test/CoverageMapping/if.cpp
@@ -3,37 +3,50 @@
int nop() { return 0; }
// CHECK-LABEL: _Z3foov:
-void foo() { // CHECK-NEXT: [[@LINE]]:12 -> [[@LINE+5]]:2 = #0
+ // CHECK-NEXT: [[@LINE+1]]:12 -> [[@LINE+6]]:2 = #0
+void foo() { // CHECK-NEXT: Gap,File 0, [[@LINE+1]]:20 -> [[@LINE+1]]:22 = #2
if (int j = true ? nop() // CHECK-NEXT: [[@LINE]]:22 -> [[@LINE]]:27 = #2
: nop(); // CHECK-NEXT: [[@LINE]]:22 -> [[@LINE]]:27 = (#0 - #2)
j) // CHECK-NEXT: [[@LINE]]:7 -> [[@LINE]]:8 = #0
- ++j; // CHECK-NEXT: [[@LINE]]:5 -> [[@LINE]]:8 = #1
-}
+ ++j; // CHECK-NEXT: [[@LINE-1]]:9 -> [[@LINE]]:5 = #1
+} // CHECK-NEXT: [[@LINE-1]]:5 -> [[@LINE-1]]:8 = #1
// CHECK-LABEL: main:
int main() { // CHECK: File 0, [[@LINE]]:12 -> {{[0-9]+}}:2 = #0
int i = 0;
- // CHECK-NEXT: File 0, [[@LINE+1]]:6 -> [[@LINE+1]]:12 = #0
+ // CHECK-NEXT: File 0, [[@LINE+2]]:6 -> [[@LINE+2]]:12 = #0
+ // CHECK-NEXT: Gap,File 0, [[@LINE+1]]:13 -> [[@LINE+1]]:14 = #1
if(i == 0) i = 1; // CHECK-NEXT: File 0, [[@LINE]]:14 -> [[@LINE]]:19 = #1
+
// CHECK-NEXT: File 0, [[@LINE+1]]:6 -> [[@LINE+1]]:12 = #0
- if(i == 1)
+ if(i == 1) // CHECK-NEXT: Gap,File 0, [[@LINE]]:13 -> [[@LINE+1]]:5 = #2
i = 2; // CHECK-NEXT: File 0, [[@LINE]]:5 -> [[@LINE]]:10 = #2
+
// CHECK-NEXT: File 0, [[@LINE+1]]:6 -> [[@LINE+1]]:12 = #0
- if(i == 0) { i = 1; // CHECK-NEXT: File 0, [[@LINE]]:14 -> [[@LINE+2]]:4 = #3
- i = 2;
+ if(i == 0) { i = 1; // CHECK-NEXT: Gap,File 0, [[@LINE]]:13 -> [[@LINE]]:14 = #3
+ i = 2; // CHECK-NEXT: File 0, [[@LINE-1]]:14 -> [[@LINE+1]]:4 = #3
}
// CHECK-NEXT: File 0, [[@LINE+1]]:6 -> [[@LINE+1]]:12 = #0
- if(i != 0) { // CHECK-NEXT: File 0, [[@LINE]]:14 -> [[@LINE+2]]:4 = #4
- i = 1;
- } else { // CHECK-NEXT: File 0, [[@LINE]]:10 -> [[@LINE+2]]:4 = (#0 - #4)
- i = 3;
+ if(i != 0) { // CHECK-NEXT: Gap,File 0, [[@LINE]]:13 -> [[@LINE]]:14 = #4
+ i = 1; // CHECK-NEXT: File 0, [[@LINE-1]]:14 -> [[@LINE+1]]:4 = #4
+ } else { // CHECK-NEXT: Gap,File 0, [[@LINE]]:4 -> [[@LINE]]:10 = (#0 - #4)
+ i = 3; // CHECK-NEXT: File 0, [[@LINE-1]]:10 -> [[@LINE+1]]:4 = (#0 - #4)
}
- i = i == 0?
+ i = i == 0? // CHECK-NEXT: Gap,File 0, [[@LINE]]:13 -> [[@LINE+1]]:9 = #5
i + 1 : // CHECK-NEXT: File 0, [[@LINE]]:9 -> [[@LINE]]:14 = #5
i + 2; // CHECK-NEXT: File 0, [[@LINE]]:9 -> [[@LINE]]:14 = (#0 - #5)
+
+ // CHECK-NEXT: Gap,File 0, [[@LINE+2]]:13 -> [[@LINE+2]]:14 = #6
// CHECK-NEXT: File 0, [[@LINE+1]]:14 -> [[@LINE+1]]:20 = #6
i = i == 0?i + 12:i + 10; // CHECK-NEXT: File 0, [[@LINE]]:21 -> [[@LINE]]:27 = (#0 - #6)
return 0;
}
+
+#define FOO true
+
+// CHECK-LABEL: _Z7ternaryv:
+void ternary() {
+ true ? FOO : FOO; // CHECK-NOT: Gap,{{.*}}, [[@LINE]]:8 ->
+}
diff --git a/test/CoverageMapping/includehell.cpp b/test/CoverageMapping/includehell.cpp
index 9ad3683abe11..fd08d6af7f3d 100644
--- a/test/CoverageMapping/includehell.cpp
+++ b/test/CoverageMapping/includehell.cpp
@@ -37,43 +37,43 @@ int main() {
// CHECK-MAIN-NEXT: File [[MAIN]], 16:35 -> 17:33 = #9
// CHECK-MAIN-NEXT: Expansion,File [[MAIN]], 17:12 -> 17:33 = #9
-// CHECK-START: File [[START1:[0-9]]], 1:1 -> 5:1 = #0
-// CHECK-START-NEXT: File [[START1]], 4:17 -> 4:22 = (#0 + #1)
-// CHECK-START-NEXT: File [[START1]], 4:24 -> 4:27 = #1
-// CHECK-START-NEXT: File [[START1]], 4:29 -> 5:1 = #1
-// CHECK-START: File [[START2:[0-9]]], 1:1 -> 5:1 = #0
-// CHECK-START-NEXT: File [[START2]], 4:17 -> 4:22 = (#0 + #5)
-// CHECK-START-NEXT: File [[START2]], 4:24 -> 4:27 = #5
-// CHECK-START-NEXT: File [[START2]], 4:29 -> 5:1 = #5
-// CHECK-START: File [[START3:[0-9]]], 1:1 -> 5:1 = #0
-// CHECK-START-NEXT: File [[START3]], 4:17 -> 4:22 = (#0 + #9)
-// CHECK-START-NEXT: File [[START3]], 4:24 -> 4:27 = #9
-// CHECK-START-NEXT: File [[START3]], 4:29 -> 5:1 = #9
+// CHECK-START: File [[START1:[0-9]]], 1:1 -> 5:1 = #0
+// CHECK-START: File [[START1]], 4:17 -> 4:22 = (#0 + #1)
+// CHECK-START: File [[START1]], 4:24 -> 4:27 = #1
+// CHECK-START: File [[START1]], 4:29 -> 5:1 = #1
+// CHECK-START: File [[START2:[0-9]]], 1:1 -> 5:1 = #0
+// CHECK-START: File [[START2]], 4:17 -> 4:22 = (#0 + #5)
+// CHECK-START: File [[START2]], 4:24 -> 4:27 = #5
+// CHECK-START: File [[START2]], 4:29 -> 5:1 = #5
+// CHECK-START: File [[START3:[0-9]]], 1:1 -> 5:1 = #0
+// CHECK-START: File [[START3]], 4:17 -> 4:22 = (#0 + #9)
+// CHECK-START: File [[START3]], 4:24 -> 4:27 = #9
+// CHECK-START: File [[START3]], 4:29 -> 5:1 = #9
// CHECK-CODE: File [[CODE1:[0-9]]], 1:1 -> 14:1 = #1
// CHECK-CODE-NEXT: File [[CODE1]], 4:5 -> 4:11 = #1
-// CHECK-CODE-NEXT: File [[CODE1]], 4:13 -> 6:2 = #2
-// CHECK-CODE-NEXT: File [[CODE1]], 6:8 -> 8:2 = (#1 - #2)
+// CHECK-CODE: File [[CODE1]], 4:13 -> 6:2 = #2
+// CHECK-CODE: File [[CODE1]], 6:8 -> 8:2 = (#1 - #2)
// CHECK-CODE-NEXT: File [[CODE1]], 9:5 -> 9:9 = #1
-// CHECK-CODE-NEXT: File [[CODE1]], 9:11 -> 11:2 = #3
-// CHECK-CODE-NEXT: File [[CODE1]], 11:8 -> 13:2 = (#1 - #3)
+// CHECK-CODE: File [[CODE1]], 9:11 -> 11:2 = #3
+// CHECK-CODE: File [[CODE1]], 11:8 -> 13:2 = (#1 - #3)
// CHECK-CODE: File [[CODE2:[0-9]]], 1:1 -> 14:1 = #5
// CHECK-CODE-NEXT: File [[CODE2]], 4:5 -> 4:11 = #5
-// CHECK-CODE-NEXT: File [[CODE2]], 4:13 -> 6:2 = #6
-// CHECK-CODE-NEXT: File [[CODE2]], 6:8 -> 8:2 = (#5 - #6)
+// CHECK-CODE: File [[CODE2]], 4:13 -> 6:2 = #6
+// CHECK-CODE: File [[CODE2]], 6:8 -> 8:2 = (#5 - #6)
// CHECK-CODE-NEXT: File [[CODE2]], 9:5 -> 9:9 = #5
-// CHECK-CODE-NEXT: File [[CODE2]], 9:11 -> 11:2 = #7
-// CHECK-CODE-NEXT: File [[CODE2]], 11:8 -> 13:2 = (#5 - #7)
+// CHECK-CODE: File [[CODE2]], 9:11 -> 11:2 = #7
+// CHECK-CODE: File [[CODE2]], 11:8 -> 13:2 = (#5 - #7)
-// CHECK-END: File [[END1:[0-9]]], 1:1 -> 3:2 = #1
-// CHECK-END-NEXT: File [[END1]], 1:1 -> 6:1 = #0
-// CHECK-END-NEXT: File [[END1]], 5:5 -> 5:9 = #0
-// CHECK-END-NEXT: File [[END1]], 5:11 -> 5:16 = #4
-// CHECK-END: File [[END2:[0-9]]], 1:1 -> 3:2 = #5
-// CHECK-END-NEXT: File [[END2]], 1:1 -> 6:1 = #0
-// CHECK-END-NEXT: File [[END2]], 5:5 -> 5:9 = #0
-// CHECK-END-NEXT: File [[END2]], 5:11 -> 5:16 = #8
-// CHECK-END: File [[END3:[0-9]]], 1:1 -> 3:2 = #9
-// CHECK-END-NEXT: File [[END3]], 1:1 -> 6:1 = #0
-// CHECK-END-NEXT: File [[END3]], 5:5 -> 5:9 = #0
-// CHECK-END-NEXT: File [[END3]], 5:11 -> 5:16 = #10
+// CHECK-END: File [[END1:[0-9]]], 1:1 -> 3:2 = #1
+// CHECK-END: File [[END1]], 1:1 -> 6:1 = #0
+// CHECK-END: File [[END1]], 5:5 -> 5:9 = #0
+// CHECK-END: File [[END1]], 5:11 -> 5:16 = #4
+// CHECK-END: File [[END2:[0-9]]], 1:1 -> 3:2 = #5
+// CHECK-END: File [[END2]], 1:1 -> 6:1 = #0
+// CHECK-END: File [[END2]], 5:5 -> 5:9 = #0
+// CHECK-END: File [[END2]], 5:11 -> 5:16 = #8
+// CHECK-END: File [[END3:[0-9]]], 1:1 -> 3:2 = #9
+// CHECK-END: File [[END3]], 1:1 -> 6:1 = #0
+// CHECK-END: File [[END3]], 5:5 -> 5:9 = #0
+// CHECK-END: File [[END3]], 5:11 -> 5:16 = #10
diff --git a/test/CoverageMapping/label.cpp b/test/CoverageMapping/label.cpp
index 1c5111a675a1..8cac5b0cbe76 100644
--- a/test/CoverageMapping/label.cpp
+++ b/test/CoverageMapping/label.cpp
@@ -4,29 +4,32 @@
void func() { // CHECK-NEXT: File 0, [[@LINE]]:13 -> {{[0-9]+}}:2 = #0
int i = 0; // CHECK-NEXT: File 0, [[@LINE+2]]:14 -> [[@LINE+2]]:20 = (#0 + #3)
// CHECK-NEXT: File 0, [[@LINE+1]]:22 -> [[@LINE+1]]:25 = #3
- for(i = 0; i < 10; ++i) { // CHECK-NEXT: File 0, [[@LINE]]:27 -> [[@LINE+11]]:4 = #1
+ for(i = 0; i < 10; ++i) { // CHECK: File 0, [[@LINE]]:27 -> [[@LINE+11]]:4 = #1
// CHECK-NEXT: File 0, [[@LINE+1]]:8 -> [[@LINE+1]]:13 = #1
- if(i < 5) { // CHECK-NEXT: File 0, [[@LINE]]:15 -> [[@LINE+6]]:6 = #2
+ if(i < 5) { // CHECK: File 0, [[@LINE]]:15 -> [[@LINE+6]]:6 = #2
{
x: // CHECK-NEXT: File 0, [[@LINE]]:9 -> [[@LINE+4]]:6 = #3
int j = 1;
}
int m = 2;
} else
- goto x; // CHECK-NEXT: File 0, [[@LINE]]:7 -> [[@LINE]]:13 = (#1 - #2)
- int k = 3; // CHECK-NEXT: File 0, [[@LINE]]:5 -> [[@LINE+1]]:4 = #3
- }
- static int j = 0; // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+4]]:2 = ((#0 + #3) - #1)
+ goto x; // CHECK: File 0, [[@LINE]]:7 -> [[@LINE]]:13 = (#1 - #2)
+ int k = 3; // CHECK-NEXT: File 0, [[@LINE-1]]:13 -> [[@LINE]]:5 = #3
+ } // CHECK-NEXT: File 0, [[@LINE-1]]:5 -> [[@LINE]]:4 = #3
+ static int j = 0; // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+5]]:2 = ((#0 + #3) - #1)
++j;
if(j == 1) // CHECK-NEXT: File 0, [[@LINE]]:6 -> [[@LINE]]:12 = ((#0 + #3) - #1)
- goto x; // CHECK-NEXT: File 0, [[@LINE]]:5 -> [[@LINE]]:11 = #4
+ goto x; // CHECK: File 0, [[@LINE]]:5 -> [[@LINE]]:11 = #4
+ // CHECK-NEXT: File 0, [[@LINE-1]]:11 -> [[@LINE+1]]:2 = (((#0 + #3) - #1) - #4)
}
// CHECK-NEXT: test1
void test1(int x) { // CHECK-NEXT: File 0, [[@LINE]]:19 -> {{[0-9]+}}:2 = #0
if(x == 0) // CHECK-NEXT: File 0, [[@LINE]]:6 -> [[@LINE]]:12 = #0
- goto a; // CHECK-NEXT: File 0, [[@LINE]]:5 -> [[@LINE]]:11 = #1
- goto b; // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE]]:9 = (#0 - #1)
+ goto a; // CHECK: File 0, [[@LINE]]:5 -> [[@LINE]]:11 = #1
+ // CHECK-NEXT: File 0, [[@LINE-1]]:11 -> [[@LINE+1]]:3 = (#0 - #1)
+ goto b; // CHECK: Gap,File 0, [[@LINE]]:3 -> [[@LINE+5]]:2 = #3
+ // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:9 -> [[@LINE+1]]:1 = #2
a: // CHECK-NEXT: File 0, [[@LINE]]:1 -> [[@LINE+3]]:2 = #2
b: // CHECK-NEXT: File 0, [[@LINE]]:1 -> [[@LINE+2]]:2 = #3
x = x + 1;
@@ -35,10 +38,12 @@ b: // CHECK-NEXT: File 0, [[@LINE]]:1 -> [[@LINE+2]]:2
// CHECK-NEXT: test2
void test2(int x) { // CHECK-NEXT: File 0, [[@LINE]]:19 -> {{[0-9]+}}:2 = #0
if(x == 0) // CHECK-NEXT: File 0, [[@LINE]]:6 -> [[@LINE]]:12 = #0
- goto a; // CHECK-NEXT: File 0, [[@LINE]]:5 -> [[@LINE]]:11 = #1
- // CHECK-NEXT: File 0, [[@LINE+2]]:8 -> [[@LINE+2]]:25 = (#0 - #1)
+ goto a; // CHECK: File 0, [[@LINE]]:5 -> [[@LINE]]:11 = #1
+ // CHECK: Gap,File 0, [[@LINE-1]]:12 -> [[@LINE+3]]:8 = (#0 - #1)
+ // CHECK-NEXT: File 0, [[@LINE+2]]:8 -> [[@LINE+3]]:11 = (#0 - #1)
// CHECK-NEXT: File 0, [[@LINE+1]]:11 -> [[@LINE+1]]:17 = (#0 - #1)
- else if(x == 1) goto b; // CHECK-NEXT: File 0, [[@LINE]]:19 -> [[@LINE]]:25 = #2
+ else if(x == 1) // CHECK: File 0, [[@LINE+1]]:5 -> [[@LINE+1]]:11 = #2
+ goto b; // CHECK-NEXT: File 0, [[@LINE]]:11 -> [[@LINE+1]]:1 = #3
a: // CHECK-NEXT: File 0, [[@LINE]]:1 -> [[@LINE+3]]:2 = #3
b: // CHECK-NEXT: File 0, [[@LINE]]:1 -> [[@LINE+2]]:2 = #4
x = x + 1;
@@ -47,11 +52,13 @@ b: // CHECK-NEXT: File 0, [[@LINE]]:1 -> [[@LINE+2]]:2
// CHECK-NEXT: main
int main() { // CHECK-NEXT: File 0, [[@LINE]]:12 -> {{[0-9]+}}:2 = #0
int j = 0;
- for(int i = 0; i < 10; ++i) { // CHECK: File 0, [[@LINE]]:31 -> [[@LINE+11]]:4 = #1
- a: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+10]]:4 = #2
+ for(int i = 0; i < 10; ++i) { // CHECK: File 0, [[@LINE]]:31 -> [[@LINE+13]]:4 = #1
+ a: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+12]]:4 = #2
if(i < 3) // CHECK-NEXT: File 0, [[@LINE]]:8 -> [[@LINE]]:13 = #2
- goto e; // CHECK-NEXT: File 0, [[@LINE]]:7 -> [[@LINE]]:13 = #3
- goto c; // CHECK-NEXT: File 0, [[@LINE]]:5 -> [[@LINE]]:11 = (#2 - #3)
+ goto e; // CHECK: File 0, [[@LINE]]:7 -> [[@LINE]]:13 = #3
+ // CHECK-NEXT: File 0, [[@LINE-1]]:13 -> [[@LINE+1]]:5 = (#2 - #3)
+ goto c; // CHECK-NEXT: File 0, [[@LINE]]:5 -> [[@LINE+8]]:4 = (#2 - #3)
+ // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:11 -> [[@LINE+1]]:3 = #4
b: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+6]]:4 = #4
j = 2;
c: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+4]]:4 = #5
diff --git a/test/CoverageMapping/logical.cpp b/test/CoverageMapping/logical.cpp
index 198cc60d99b6..bc7c785b7b55 100644
--- a/test/CoverageMapping/logical.cpp
+++ b/test/CoverageMapping/logical.cpp
@@ -1,13 +1,18 @@
// RUN: %clang_cc1 -fprofile-instrument=clang -fcoverage-mapping -dump-coverage-mapping -emit-llvm-only -main-file-name logical.cpp %s | FileCheck %s
-int main() { // CHECK: File 0, [[@LINE]]:12 -> [[@LINE+10]]:2 = #0
+int main() { // CHECK: File 0, [[@LINE]]:12 -> [[@LINE+15]]:2 = #0
bool bt = true;
bool bf = false;
- bool a = bt && bf; // CHECK-NEXT: File 0, [[@LINE]]:18 -> [[@LINE]]:20 = #1
- a = bt &&
+ bool a = bt && bf; // CHECK-NEXT: File 0, [[@LINE]]:12 -> [[@LINE]]:14 = #0
+ // CHECK-NEXT: File 0, [[@LINE-1]]:18 -> [[@LINE-1]]:20 = #1
+
+ a = bt && // CHECK-NEXT: File 0, [[@LINE]]:7 -> [[@LINE]]:9 = #0
bf; // CHECK-NEXT: File 0, [[@LINE]]:7 -> [[@LINE]]:9 = #2
- a = bf || bt; // CHECK-NEXT: File 0, [[@LINE]]:13 -> [[@LINE]]:15 = #3
- a = bf ||
+
+ a = bf || bt; // CHECK-NEXT: File 0, [[@LINE]]:7 -> [[@LINE]]:9 = #0
+ // CHECK-NEXT: File 0, [[@LINE-1]]:13 -> [[@LINE-1]]:15 = #3
+
+ a = bf || // CHECK-NEXT: File 0, [[@LINE]]:7 -> [[@LINE]]:9 = #0
bt; // CHECK-NEXT: File 0, [[@LINE]]:7 -> [[@LINE]]:9 = #4
return 0;
}
diff --git a/test/CoverageMapping/loops.cpp b/test/CoverageMapping/loops.cpp
index cb7d777f86b6..ff7aafd66d94 100644
--- a/test/CoverageMapping/loops.cpp
+++ b/test/CoverageMapping/loops.cpp
@@ -3,7 +3,7 @@
// CHECK: rangedFor
void rangedFor() { // CHECK-NEXT: File 0, [[@LINE]]:18 -> {{[0-9]+}}:2 = #0
int arr[] = { 1, 2, 3, 4, 5 };
- int sum = 0;
+ int sum = 0; // CHECK: Gap,File 0, [[@LINE+1]]:20 -> [[@LINE+1]]:21 = #1
for(auto i : arr) { // CHECK: File 0, [[@LINE]]:21 -> [[@LINE+6]]:4 = #1
if (i == 3)
continue; // CHECK: File 0, [[@LINE]]:7 -> [[@LINE]]:15 = #2
@@ -17,24 +17,27 @@ void rangedFor() { // CHECK-NEXT: File 0, [[@LINE]]:18 -> {{[0-
}
// CHECK: main:
-int main() { // CHECK-NEXT: File 0, [[@LINE]]:12 -> [[@LINE+24]]:2 = #0
+int main() { // CHECK-NEXT: File 0, [[@LINE]]:12 -> {{.*}}:2 = #0
// CHECK-NEXT: File 0, [[@LINE+1]]:18 -> [[@LINE+1]]:24 = (#0 + #1)
for(int i = 0; i < 10; ++i) // CHECK-NEXT: File 0, [[@LINE]]:26 -> [[@LINE]]:29 = #1
- ; // CHECK-NEXT: File 0, [[@LINE]]:6 -> [[@LINE]]:7 = #1
+ ; // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:30 -> [[@LINE]]:6 = #1
+ // CHECK-NEXT: File 0, [[@LINE-1]]:6 -> [[@LINE-1]]:7 = #1
for(int i = 0;
i < 10; // CHECK-NEXT: File 0, [[@LINE]]:7 -> [[@LINE]]:13 = (#0 + #2)
++i) // CHECK-NEXT: File 0, [[@LINE]]:7 -> [[@LINE]]:10 = #2
- { // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+2]]:4 = #2
- int x = 0;
+ { // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:11 -> [[@LINE]]:3 = #2
+ int x = 0; // CHECK-NEXT: File 0, [[@LINE-1]]:3 -> [[@LINE+1]]:4 = #2
}
int j = 0; // CHECK-NEXT: File 0, [[@LINE+1]]:9 -> [[@LINE+1]]:14 = (#0 + #3)
- while(j < 5) ++j; // CHECK-NEXT: File 0, [[@LINE]]:16 -> [[@LINE]]:19 = #3
+ while(j < 5) ++j; // CHECK-NEXT: Gap,File 0, [[@LINE]]:15 -> [[@LINE]]:16 = #3
+ // CHECK-NEXT: File 0, [[@LINE-1]]:16 -> [[@LINE-1]]:19 = #3
+
do { // CHECK-NEXT: File 0, [[@LINE]]:6 -> [[@LINE+2]]:4 = (#0 + #4)
++j;
} while(j < 10); // CHECK-NEXT: File 0, [[@LINE]]:11 -> [[@LINE]]:17 = (#0 + #4)
j = 0;
- while
- (j < 5) // CHECK-NEXT: File 0, [[@LINE]]:5 -> [[@LINE]]:10 = (#0 + #5)
+ while // CHECK-NEXT: File 0, [[@LINE+1]]:5 -> [[@LINE+1]]:10 = (#0 + #5)
+ (j < 5) // CHECK-NEXT: Gap,File 0, [[@LINE]]:11 -> [[@LINE+1]]:6 = #5
++j; // CHECK-NEXT: File 0, [[@LINE]]:6 -> [[@LINE]]:9 = #5
do
++j; // CHECK-NEXT: File 0, [[@LINE]]:5 -> [[@LINE]]:8 = (#0 + #6)
diff --git a/test/CoverageMapping/macro-expansion.c b/test/CoverageMapping/macro-expansion.c
index 3fca97584aa8..1e4a28b32d88 100644
--- a/test/CoverageMapping/macro-expansion.c
+++ b/test/CoverageMapping/macro-expansion.c
@@ -4,18 +4,18 @@
// CHECK: File 1, [[@LINE+5]]:12 -> [[@LINE+5]]:38 = #0
// CHECK-NEXT: File 1, [[@LINE+4]]:15 -> [[@LINE+4]]:28 = (#0 + #2)
// CHECK-NEXT: File 1, [[@LINE+3]]:21 -> [[@LINE+3]]:22 = (#0 + #2)
-// CHECK-NEXT: File 1, [[@LINE+2]]:24 -> [[@LINE+2]]:26 = #3
+// CHECK: File 1, [[@LINE+2]]:24 -> [[@LINE+2]]:26 = #3
// CHECK-NEXT: File 1, [[@LINE+1]]:36 -> [[@LINE+1]]:37 = (#0 + #2)
#define M1 do { if (0) {} } while (0)
// CHECK-NEXT: File 2, [[@LINE+10]]:15 -> [[@LINE+10]]:41 = #0
// CHECK-NEXT: File 2, [[@LINE+9]]:18 -> [[@LINE+9]]:31 = (#0 + #4)
// CHECK-NEXT: File 2, [[@LINE+8]]:24 -> [[@LINE+8]]:25 = (#0 + #4)
-// CHECK-NEXT: File 2, [[@LINE+7]]:27 -> [[@LINE+7]]:29 = #5
+// CHECK: File 2, [[@LINE+7]]:27 -> [[@LINE+7]]:29 = #5
// CHECK-NEXT: File 2, [[@LINE+6]]:39 -> [[@LINE+6]]:40 = (#0 + #4)
// CHECK-NEXT: File 3, [[@LINE+5]]:15 -> [[@LINE+5]]:41 = #0
// CHECK-NEXT: File 3, [[@LINE+4]]:18 -> [[@LINE+4]]:31 = (#0 + #6)
// CHECK-NEXT: File 3, [[@LINE+3]]:24 -> [[@LINE+3]]:25 = (#0 + #6)
-// CHECK-NEXT: File 3, [[@LINE+2]]:27 -> [[@LINE+2]]:29 = #7
+// CHECK: File 3, [[@LINE+2]]:27 -> [[@LINE+2]]:29 = #7
// CHECK-NEXT: File 3, [[@LINE+1]]:39 -> [[@LINE+1]]:40 = (#0 + #6)
#define M2(x) do { if (x) {} } while (0)
// CHECK-NEXT: File 4, [[@LINE+4]]:15 -> [[@LINE+4]]:38 = #0
@@ -23,10 +23,12 @@
// CHECK-NEXT: Expansion,File 4, [[@LINE+2]]:20 -> [[@LINE+2]]:22 = (#0 + #8)
// CHECK-NEXT: File 4, [[@LINE+1]]:36 -> [[@LINE+1]]:37 = (#0 + #8)
#define M3(x) do { M2(x); } while (0)
-// CHECK-NEXT: File 5, [[@LINE+2]]:15 -> [[@LINE+2]]:27 = #0
+// CHECK-NEXT: File 5, [[@LINE+3]]:15 -> [[@LINE+3]]:27 = #0
+// CHECK-NEXT: File 5, [[@LINE+2]]:16 -> [[@LINE+2]]:19 = #0
// CHECK-NEXT: File 5, [[@LINE+1]]:23 -> [[@LINE+1]]:26 = #12
#define M4(x) ((x) && (x))
-// CHECK-NEXT: File 6, [[@LINE+2]]:15 -> [[@LINE+2]]:27 = #0
+// CHECK-NEXT: File 6, [[@LINE+3]]:15 -> [[@LINE+3]]:27 = #0
+// CHECK-NEXT: File 6, [[@LINE+2]]:16 -> [[@LINE+2]]:19 = #0
// CHECK-NEXT: File 6, [[@LINE+1]]:23 -> [[@LINE+1]]:26 = #14
#define M5(x) ((x) || (x))
// CHECK-NEXT: File 7, [[@LINE+1]]:15 -> [[@LINE+1]]:26 = #0
@@ -38,7 +40,7 @@
// CHECK-NEXT: File 9, {{[0-9]+}}:15 -> {{[0-9]+}}:41 = (#0 + #8)
// CHECK-NEXT: File 9, {{[0-9]+}}:18 -> {{[0-9]+}}:31 = ((#0 + #8) + #9)
// CHECK-NEXT: File 9, {{[0-9]+}}:24 -> {{[0-9]+}}:25 = ((#0 + #8) + #9)
-// CHECK-NEXT: File 9, {{[0-9]+}}:27 -> {{[0-9]+}}:29 = #10
+// CHECK: File 9, {{[0-9]+}}:27 -> {{[0-9]+}}:29 = #10
// CHECK-NEXT: File 9, {{[0-9]+}}:39 -> {{[0-9]+}}:40 = ((#0 + #8) + #9)
void func(int x) {
diff --git a/test/CoverageMapping/macro-expressions.cpp b/test/CoverageMapping/macro-expressions.cpp
index 3eba86949a76..26d70c67fca0 100644
--- a/test/CoverageMapping/macro-expressions.cpp
+++ b/test/CoverageMapping/macro-expressions.cpp
@@ -54,19 +54,19 @@ void STMT(fn3)() {
// CHECK-NEXT: File 0, [[@LINE+1]]:17 -> {{[0-9]+}}:2 = #0
void foo(int i) {
// CHECK-NEXT: File 0, [[@LINE+2]]:7 -> [[@LINE+2]]:8 = #0
- // CHECK-NEXT: File 0, [[@LINE+1]]:10 -> [[@LINE+1]]:12 = #1
+ // CHECK: File 0, [[@LINE+1]]:10 -> [[@LINE+1]]:12 = #1
if (0) {}
// CHECK-NEXT: Expansion,File 0, [[@LINE+2]]:7 -> [[@LINE+2]]:11 = #0
// CHECK-NEXT: File 0, [[@LINE+1]]:16 -> [[@LINE+1]]:18 = #2
if (EXPR(i)) {}
// CHECK-NEXT: Expansion,File 0, [[@LINE+2]]:9 -> [[@LINE+2]]:14 = (#0 + #3)
- // CHECK-NEXT: File 0, [[@LINE+1]]:20 -> [[@LINE+1]]:22 = #3
+ // CHECK: File 0, [[@LINE+1]]:20 -> [[@LINE+1]]:22 = #3
for (;NEXPR(i);) {}
// CHECK-NEXT: Expansion,File 0, [[@LINE+4]]:8 -> [[@LINE+4]]:14 = #0
// CHECK-NEXT: Expansion,File 0, [[@LINE+3]]:33 -> [[@LINE+3]]:35 = (#0 + #4)
// CHECK-NEXT: Expansion,File 0, [[@LINE+2]]:43 -> [[@LINE+2]]:46 = #4
- // CHECK-NEXT: File 0, [[@LINE+1]]:51 -> [[@LINE+1]]:53 = #4
+ // CHECK: File 0, [[@LINE+1]]:51 -> [[@LINE+1]]:53 = #4
for (ASSIGN(DECL(int, j), 0); LT(j, i); INC(j)) {}
// CHECK-NEXT: Expansion,File 0, [[@LINE+1]]:3 -> [[@LINE+1]]:9 = #0
ASSIGN(DECL(int, k), 0);
@@ -79,17 +79,17 @@ void foo(int i) {
do {} while (NEXPR(i));
// CHECK-NEXT: Expansion,File 0, [[@LINE+3]]:8 -> [[@LINE+3]]:12 = #0
// CHECK-NEXT: Expansion,File 0, [[@LINE+2]]:23 -> [[@LINE+2]]:26 = #0
- // CHECK-NEXT: File 0, [[@LINE+1]]:42 -> [[@LINE+1]]:44 = #7
+ // CHECK: File 0, [[@LINE+1]]:42 -> [[@LINE+1]]:44 = #7
for (DECL(int, j) : ARR(int, 1, 2, 3)) {}
// CHECK-NEXT: Expansion,File 0, [[@LINE+2]]:14 -> [[@LINE+2]]:20 = #0
// CHECK-NEXT: Expansion,File 0, [[@LINE+1]]:23 -> [[@LINE+1]]:29 = #0
(void)(i ? PRIo64 : PRIu64);
- // CHECK-NEXT: File 0, [[@LINE+5]]:14 -> [[@LINE+5]]:15 = #9
+ // CHECK: File 0, [[@LINE+5]]:14 -> [[@LINE+5]]:15 = #9
// CHECK-NEXT: Expansion,File 0, [[@LINE+4]]:18 -> [[@LINE+4]]:22 = (#0 - #9)
// CHECK-NEXT: File 0, [[@LINE+3]]:22 -> [[@LINE+3]]:33 = (#0 - #9)
- // CHECK-NEXT: File 0, [[@LINE+2]]:28 -> [[@LINE+2]]:29 = #10
+ // CHECK: File 0, [[@LINE+2]]:28 -> [[@LINE+2]]:29 = #10
// CHECK-NEXT: File 0, [[@LINE+1]]:32 -> [[@LINE+1]]:33 = ((#0 - #9) - #10)
(void)(i ? i : EXPR(i) ? i : 0);
// CHECK-NEXT: Expansion,File 0, [[@LINE+3]]:15 -> [[@LINE+3]]:19 = (#0 - #11)
diff --git a/test/CoverageMapping/macros.c b/test/CoverageMapping/macros.c
index 60164be91d7c..95fe37ed7e8d 100644
--- a/test/CoverageMapping/macros.c
+++ b/test/CoverageMapping/macros.c
@@ -40,7 +40,7 @@ void func3() { // CHECK-NEXT: File 0, [[@LINE]]:14 -> [[@LINE+3]]:2 = #0
void func4() { // CHECK-NEXT: File 0, [[@LINE]]:14 -> [[@LINE+6]]:2 = #0
int i = 0;
while (i++ < 10) // CHECK-NEXT: File 0, [[@LINE]]:10 -> [[@LINE]]:18 = (#0 + #1)
- if (i < 5) // CHECK-NEXT: File 0, [[@LINE]]:5 -> [[@LINE+2]]:14 = #1
+ if (i < 5) // CHECK: File 0, [[@LINE]]:5 -> [[@LINE+2]]:14 = #1
// CHECK-NEXT: File 0, [[@LINE-1]]:9 -> [[@LINE-1]]:14 = #1
MACRO_2; // CHECK-NEXT: Expansion,File 0, [[@LINE]]:7 -> [[@LINE]]:14 = #2
}
diff --git a/test/CoverageMapping/macroscopes.cpp b/test/CoverageMapping/macroscopes.cpp
index f5fd55c73177..3f5f65e5ad7b 100644
--- a/test/CoverageMapping/macroscopes.cpp
+++ b/test/CoverageMapping/macroscopes.cpp
@@ -89,10 +89,10 @@ int main() {
// CHECK-NEXT: File 1, 3:52 -> 3:53 = #1
// CHECK-NEXT: File 2, 10:3 -> 20:4 = #1
// CHECK-NEXT: File 2, 11:7 -> 11:13 = #1
-// CHECK-NEXT: File 2, 11:15 -> 13:4 = #2
+// CHECK: File 2, 11:15 -> 13:4 = #2
// CHECK-NEXT: File 2, 13:10 -> 15:4 = (#1 - #2)
// CHECK-NEXT: File 2, 16:7 -> 16:11 = #1
-// CHECK-NEXT: File 2, 16:13 -> 18:4 = #3
+// CHECK: File 2, 16:13 -> 18:4 = #3
// CHECK-NEXT: File 2, 18:10 -> 20:4 = (#1 - #3)
// CHECK-NEXT: File 3, 6:3 -> 7:4 = #1
// CHECK-NEXT: File 4, 3:24 -> 3:53 = #0
@@ -101,10 +101,10 @@ int main() {
// CHECK-NEXT: File 4, 3:52 -> 3:53 = #4
// CHECK-NEXT: File 5, 10:3 -> 20:4 = #4
// CHECK-NEXT: File 5, 11:7 -> 11:13 = #4
-// CHECK-NEXT: File 5, 11:15 -> 13:4 = #5
+// CHECK: File 5, 11:15 -> 13:4 = #5
// CHECK-NEXT: File 5, 13:10 -> 15:4 = (#4 - #5)
// CHECK-NEXT: File 5, 16:7 -> 16:11 = #4
-// CHECK-NEXT: File 5, 16:13 -> 18:4 = #6
+// CHECK: File 5, 16:13 -> 18:4 = #6
// CHECK-NEXT: File 5, 18:10 -> 20:4 = (#4 - #6)
// CHECK-NEXT: File 6, 6:3 -> 7:4 = #4
// CHECK-NEXT: File 7, 3:24 -> 3:53 = #0
diff --git a/test/CoverageMapping/md.cpp b/test/CoverageMapping/md.cpp
index 20c696c7dfbb..5f2b2d61224f 100644
--- a/test/CoverageMapping/md.cpp
+++ b/test/CoverageMapping/md.cpp
@@ -27,6 +27,17 @@ void foo(MD i) {
#include "Inputs/md.def"
}
+// CHECK: bar
+// CHECK-NEXT: File 0, [[@LINE+3]]:12 -> [[@LINE+8]]:2 = #0
+bool isVal1();
+bool isVal2();
+bool bar() {
+ #define HANDLE_MD(X) is##X() ||
+ return
+#include "Inputs/md.def"
+ 0;
+}
+
int main(int argc, const char *argv[]) {
foo(MD::Val1);
return 0;
diff --git a/test/CoverageMapping/moremacros.c b/test/CoverageMapping/moremacros.c
index 56662270d073..88411f3ba916 100644
--- a/test/CoverageMapping/moremacros.c
+++ b/test/CoverageMapping/moremacros.c
@@ -7,7 +7,7 @@
// CHECK-NEXT: File 0, [[@LINE+1]]:40 -> {{[0-9]+}}:2 = #0
int main(int argc, const char *argv[]) {
// CHECK-NEXT: File 0, [[@LINE+1]]:7 -> [[@LINE+1]]:12 = #0
- if (!argc) {} // CHECK-NEXT: File 0, [[@LINE]]:14 -> [[@LINE]]:16 = #1
+ if (!argc) {} // CHECK: File 0, [[@LINE]]:14 -> [[@LINE]]:16 = #1
// CHECK-NEXT: File 0, [[@LINE+3]]:7 -> [[@LINE+3]]:12 = #0
// CHECK-NEXT: Expansion,File 0, [[@LINE+2]]:14 -> [[@LINE+2]]:19 = #2
@@ -15,7 +15,7 @@ int main(int argc, const char *argv[]) {
if (!argc) LBRAC
return 0;
// CHECK-NEXT: Expansion,File 0, [[@LINE+1]]:3 -> [[@LINE+1]]:8 = #2
- RBRAC
+ RBRAC // CHECK-NEXT: [[@LINE]]:8 -> [[@LINE+6]]:3 = (#0 - #2)
// CHECK-NEXT: File 0, [[@LINE+4]]:3 -> [[@LINE+15]]:2 = (#0 - #2)
// CHECK-NEXT: File 0, [[@LINE+3]]:7 -> [[@LINE+3]]:12 = (#0 - #2)
@@ -23,15 +23,15 @@ int main(int argc, const char *argv[]) {
// CHECK-NEXT: File 0, [[@LINE+1]]:19 -> [[@LINE+3]]:4 = #3
if (!argc) LBRAC
return 0;
- }
+ } // CHECK-NEXT: [[@LINE]]:4 -> [[@LINE+5]]:3 = ((#0 - #2) - #3)
// CHECK-NEXT: File 0, [[@LINE+3]]:3 -> [[@LINE+7]]:2 = ((#0 - #2) - #3)
// CHECK-NEXT: File 0, [[@LINE+2]]:7 -> [[@LINE+2]]:12 = ((#0 - #2) - #3)
- // CHECK-NEXT: File 0, [[@LINE+1]]:14 -> [[@LINE+4]]:8 = #4
+ // CHECK: File 0, [[@LINE+1]]:14 -> [[@LINE+4]]:8 = #4
if (!argc) {
return 0;
// CHECK-NEXT: Expansion,File 0, [[@LINE+1]]:3 -> [[@LINE+1]]:8 = #4
- RBRAC
+ RBRAC // CHECK-NEXT: [[@LINE]]:8 -> [[@LINE+1]]:2 = (((#0 - #2) - #3) - #4)
}
// CHECK-NEXT: File 1, 3:15 -> 3:16 = #2
diff --git a/test/CoverageMapping/objc.m b/test/CoverageMapping/objc.m
index 55c7545370cc..4e4c184f0a88 100644
--- a/test/CoverageMapping/objc.m
+++ b/test/CoverageMapping/objc.m
@@ -7,7 +7,7 @@
// CHECK: func
void func(A *a) { // CHECK-NEXT: File 0, [[@LINE]]:17 -> [[@LINE+3]]:2 = #0
if (a) // CHECK-NEXT: File 0, [[@LINE]]:7 -> [[@LINE]]:8 = #0
- [a bork: 20 ]; // CHECK-NEXT: File 0, [[@LINE]]:5 -> [[@LINE]]:20 = #1
+ [a bork: 20 ]; // CHECK: File 0, [[@LINE]]:5 -> [[@LINE]]:20 = #1
}
@interface NSArray
@@ -17,12 +17,12 @@ void func(A *a) { // CHECK-NEXT: File 0, [[@LINE]]:17 -> [[@LINE+3]]:2 = #0
// CHECK: func2
void func2(NSArray *array) { // CHECK-NEXT: File 0, [[@LINE]]:28 -> {{[0-9]+}}:2 = #0
- int i = 0;
+ int i = 0; // CHECK-NEXT: Gap,File 0, [[@LINE+1]]:28 -> [[@LINE+1]]:29 = #1
for (NSArray *x in array) { // CHECK-NEXT: File 0, [[@LINE]]:29 -> [[@LINE+7]]:4 = #1
// CHECK-NEXT: File 0, [[@LINE+1]]:9 -> [[@LINE+1]]:10 = #1
- if (x) { // CHECK-NEXT: File 0, [[@LINE]]:12 -> [[@LINE+2]]:6 = #2
+ if (x) { // CHECK: File 0, [[@LINE]]:12 -> [[@LINE+2]]:6 = #2
i = 1;
- } else { // CHECK-NEXT: File 0, [[@LINE]]:12 -> [[@LINE+2]]:6 = (#1 - #2)
+ } else { // CHECK: File 0, [[@LINE]]:12 -> [[@LINE+2]]:6 = (#1 - #2)
i = -1;
}
}
diff --git a/test/CoverageMapping/preprocessor.c b/test/CoverageMapping/preprocessor.c
index bd82b3939ed5..b3ebc7bd4ec0 100644
--- a/test/CoverageMapping/preprocessor.c
+++ b/test/CoverageMapping/preprocessor.c
@@ -3,36 +3,69 @@
// CHECK: func
void func() { // CHECK: File 0, [[@LINE]]:13 -> [[@LINE+5]]:2 = #0
int i = 0;
-#ifdef MACRO // CHECK-NEXT: Skipped,File 0, [[@LINE]]:2 -> [[@LINE+2]]:2 = 0
+#ifdef MACRO // CHECK-NEXT: Skipped,File 0, [[@LINE]]:1 -> [[@LINE+3]]:1 = 0
int x = i;
#endif
}
-#if 0
- int g = 0;
-
- void bar() { }
-#endif
-
// CHECK: main
int main() { // CHECK-NEXT: File 0, [[@LINE]]:12 -> {{[0-9]+}}:2 = #0
int i = 0;
-#if 0 // CHECK-NEXT: Skipped,File 0, [[@LINE]]:2 -> [[@LINE+4]]:2 = 0
+# if 0 // CHECK-NEXT: Skipped,File 0, [[@LINE]]:1 -> [[@LINE+5]]:1 = 0
if(i == 0) {
i = 1;
}
-#endif
+# endif // Mark me skipped!
#if 1
// CHECK-NEXT: File 0, [[@LINE+1]]:6 -> [[@LINE+1]]:12 = #0
- if(i == 0) { // CHECK-NEXT: File 0, [[@LINE]]:14 -> [[@LINE+2]]:4 = #1
+ if(i == 0) { // CHECK: File 0, [[@LINE]]:14 -> [[@LINE+2]]:4 = #1
i = 1;
}
-#else // CHECK-NEXT: Skipped,File 0, [[@LINE]]:2 -> [[@LINE+5]]:2 = 0
+#else // CHECK-NEXT: Skipped,File 0, [[@LINE]]:1 -> [[@LINE+6]]:1 = 0
if(i == 1) {
i = 0;
}
}
#endif
+
+ // CHECK-NEXT: Skipped,File 0, [[@LINE+1]]:1 -> [[@LINE+5]]:1
+#\
+ if 0
+#\
+ endif // also skipped
+
+#if 1
+ // CHECK-NEXT: Skipped,File 0, [[@LINE+1]]:1 -> [[@LINE+4]]:1
+#\
+ elif 0
+#endif
+
+#if 1
+ // CHECK-NEXT: Skipped,File 0, [[@LINE+1]]:1 -> [[@LINE+4]]:1
+#\
+ else
+#endif
+
+ // CHECK-NEXT: Skipped,File 0, [[@LINE+1]]:1 -> [[@LINE+5]]:1
+#\
+ ifdef NOT_DEFINED
+#\
+ endif
+
+ // CHECK-NEXT: Skipped,File 0, [[@LINE+1]]:1 -> [[@LINE+5]]:1
+#\
+ ifndef __FILE__
+#\
+ endif
+
+ // CHECK-NEXT: Skipped,File 0, [[@LINE+1]]:1 -> [[@LINE+7]]:1
+#\
+ ifdef NOT_DEFINED
+#\
+ \
+ \
+ endif // also skipped
+
return 0;
}
diff --git a/test/CoverageMapping/return.c b/test/CoverageMapping/return.c
index 1b190b0eb733..440acb569b8f 100644
--- a/test/CoverageMapping/return.c
+++ b/test/CoverageMapping/return.c
@@ -10,15 +10,15 @@ void func() { // CHECK: File 0, [[@LINE]]:13 -> [[@LINE+3]]:2
void func2() { // CHECK-NEXT: File 0, [[@LINE]]:14 -> {{[0-9]+}}:2 = #0
// CHECK-NEXT: File 0, [[@LINE+2]]:18 -> [[@LINE+2]]:24 = ((#0 + #1) - #2)
// CHECK-NEXT: File 0, [[@LINE+1]]:26 -> [[@LINE+1]]:29 = (#1 - #2)
- for(int i = 0; i < 10; ++i) { // CHECK-NEXT: File 0, [[@LINE]]:31 -> {{[0-9]+}}:4 = #1
+ for(int i = 0; i < 10; ++i) { // CHECK: File 0, [[@LINE]]:31 -> {{[0-9]+}}:4 = #1
// CHECK-NEXT: File 0, [[@LINE+1]]:8 -> [[@LINE+1]]:13 = #1
- if(i > 2) { // CHECK-NEXT: File 0, [[@LINE]]:15 -> [[@LINE+2]]:6 = #2
- return;
+ if(i > 2) { // CHECK: File 0, [[@LINE]]:15 -> [[@LINE+2]]:6 = #2
+ return; // CHECK-NEXT: File 0, [[@LINE+1]]:6 -> [[@LINE+3]]:5 = (#1 - #2)
} // CHECK-NEXT: File 0, [[@LINE+2]]:5 -> {{[0-9]+}}:4 = (#1 - #2)
// CHECK-NEXT: File 0, [[@LINE+1]]:8 -> [[@LINE+1]]:14 = (#1 - #2)
- if(i == 3) { // CHECK-NEXT: File 0, [[@LINE]]:16 -> [[@LINE+2]]:6 = #3
+ if(i == 3) { // CHECK: File 0, [[@LINE]]:16 -> [[@LINE+2]]:6 = #3
int j = 1;
- } else { // CHECK-NEXT: File 0, [[@LINE]]:12 -> [[@LINE+2]]:6 = ((#1 - #2) - #3)
+ } else { // CHECK: File 0, [[@LINE]]:12 -> [[@LINE+2]]:6 = ((#1 - #2) - #3)
int j = 2;
}
}
@@ -27,9 +27,9 @@ void func2() { // CHECK-NEXT: File 0, [[@LINE]]:14 -> {{[0-9]+}
// CHECK-NEXT: func3
void func3(int x) { // CHECK-NEXT: File 0, [[@LINE]]:19 -> {{[0-9]+}}:2 = #0
// CHECK-NEXT: File 0, [[@LINE+1]]:6 -> [[@LINE+1]]:11 = #0
- if(x > 5) { // CHECK-NEXT: File 0, [[@LINE]]:13 -> [[@LINE+6]]:4 = #1
+ if(x > 5) { // CHECK: File 0, [[@LINE]]:13 -> [[@LINE+6]]:4 = #1
while(x >= 9) { // CHECK-NEXT: File 0, [[@LINE]]:11 -> [[@LINE]]:17 = #1
- return; // CHECK-NEXT: File 0, [[@LINE-1]]:19 -> [[@LINE+2]]:6 = #2
+ return; // CHECK: File 0, [[@LINE-1]]:19 -> [[@LINE+2]]:6 = #2
--x; // CHECK-NEXT: File 0, [[@LINE]]:7 -> [[@LINE+1]]:6 = 0
}
int i = 0; // CHECK-NEXT: File 0, [[@LINE]]:5 -> [[@LINE+1]]:4 = (#1 - #2)
diff --git a/test/CoverageMapping/switch.cpp b/test/CoverageMapping/switch.cpp
index 312f26ca16e4..30c64922201f 100644
--- a/test/CoverageMapping/switch.cpp
+++ b/test/CoverageMapping/switch.cpp
@@ -3,10 +3,10 @@
// CHECK: foo
void foo(int i) { // CHECK-NEXT: File 0, [[@LINE]]:17 -> [[@LINE+8]]:2 = #0
switch(i) {
- case 1: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+3]]:10 = #2
+ case 1: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+1]]:11 = #2
return;
case 2: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+1]]:10 = #3
- break;
+ break; // CHECK-NEXT: File 0, [[@LINE]]:10 -> [[@LINE+2]]:3 = #1
}
int x = 0; // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+1]]:2 = #1
}
@@ -38,7 +38,7 @@ void bar(int i) { // CHECK-NEXT: File 0, [[@LINE]]:17 -> [[@LINE+20]]:2 = #0
// CHECK: baz
void baz() { // CHECK-NEXT: File 0, [[@LINE]]:12 -> [[@LINE+5]]:2 = #0
- switch (int i = true ? nop() // CHECK-NEXT: [[@LINE]]:26 -> [[@LINE]]:31 = #2
+ switch (int i = true ? nop() // CHECK: [[@LINE]]:26 -> [[@LINE]]:31 = #2
: nop(); // CHECK-NEXT: [[@LINE]]:26 -> [[@LINE]]:31 = (#0 - #2)
i) {}
nop(); // CHECK-NEXT: [[@LINE]]:3 -> [[@LINE+1]]:2 = #1
@@ -48,23 +48,23 @@ void baz() { // CHECK-NEXT: File 0, [[@LINE]]:12 -> [[@LINE+5]]:2 = #0
int main() { // CHECK-NEXT: File 0, [[@LINE]]:12 -> [[@LINE+35]]:2 = #0
int i = 0;
switch(i) {
- case 0: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+7]]:10 = #2
+ case 0: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+2]]:10 = #2
i = 1;
break;
case 1: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+2]]:10 = #3
i = 2;
break;
default: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+1]]:10 = #4
- break;
+ break; // CHECK-NEXT: File 0, [[@LINE]]:10 -> [[@LINE+2]]:3 = #1
}
switch(i) { // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+23]]:2 = #1
- case 0: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+6]]:10 = #6
+ case 0: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+2]]:10 = #6
i = 1;
break;
case 1: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+3]]:10 = #7
i = 2;
default: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+1]]:10 = (#7 + #8)
- break;
+ break; // CHECK-NEXT: File 0, [[@LINE]]:10 -> [[@LINE+3]]:3 = #5
}
switch(i) { // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+13]]:2 = #5
@@ -81,3 +81,32 @@ int main() { // CHECK-NEXT: File 0, [[@LINE]]:12 -> [[@LINE+35]]:2 = #0
baz();
return 0;
}
+
+// FIXME: End location for "case 1" shouldn't point at the end of the switch.
+ // CHECK: fallthrough
+int fallthrough(int i) { // CHECK-NEXT: File 0, [[@LINE]]:24 -> [[@LINE+12]]:2 = #0
+ switch(i) {
+ case 1: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+8]]:10 = #2
+ i = 23;
+ case 2: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+2]]:10 = (#2 + #3)
+ i = 11;
+ break;
+ case 3: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+3]]:10 = #4
+ case 4: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+2]]:10 = (#4 + #5)
+ i = 99;
+ break;
+ }
+}
+
+void abort(void) __attribute((noreturn));
+ // CHECK: noret
+int noret(int x) { // CHECK-NEXT: File 0, [[@LINE]]:18 -> [[@LINE+9]]:2
+ switch (x) {
+ default: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+1]]:12
+ abort();
+ case 1: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+1]]:13
+ return 5;
+ case 2: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+1]]:14
+ return 10;
+ }
+}
diff --git a/test/CoverageMapping/switchmacro.c b/test/CoverageMapping/switchmacro.c
index 55f93d8f60c0..f4c14f798f0b 100644
--- a/test/CoverageMapping/switchmacro.c
+++ b/test/CoverageMapping/switchmacro.c
@@ -7,12 +7,13 @@ int foo(int i) { // CHECK-NEXT: File 0, [[@LINE]]:16 -> {{[0-9]+}}:2 = #0
switch (i) {
default: // CHECK-NEXT: File 0, [[@LINE]]:3 -> {{[0-9]+}}:11 = #2
if (i == 1) // CHECK-NEXT: File 0, [[@LINE]]:9 -> [[@LINE]]:15 = #2
- return 0; // CHECK-NEXT: File 0, [[@LINE]]:7 -> [[@LINE]]:15 = #3
+ return 0; // CHECK: File 0, [[@LINE]]:7 -> [[@LINE]]:15 = #3
+ // CHECK-NEXT: File 0, [[@LINE-1]]:15 -> [[@LINE+3]]:5 = (#2 - #3)
// CHECK-NEXT: Expansion,File 0, [[@LINE+2]]:5 -> [[@LINE+2]]:8 = (#2 - #3) (Expanded file = 1)
// CHECK-NEXT: File 0, [[@LINE+1]]:8 -> {{[0-9]+}}:11 = (#2 - #3)
FOO(1);
case 0: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+1]]:13 = ((#2 + #4) - #3)
- return 2;
+ return 2; // CHECK-NEXT: Gap,File 0, [[@LINE]]:13 -> [[@LINE+6]]:3 = #5
// CHECK-NEXT: Expansion,File 0, [[@LINE+2]]:3 -> [[@LINE+2]]:6 = 0
// CHECK-NEXT: File 0, [[@LINE+1]]:6 -> {{[0-9]+}}:11 = 0
diff --git a/test/CoverageMapping/test.c b/test/CoverageMapping/test.c
index 5affbaadfd1d..ae73fcb3bbab 100644
--- a/test/CoverageMapping/test.c
+++ b/test/CoverageMapping/test.c
@@ -7,7 +7,7 @@ static void static_func();
int main() { // CHECK-NEXT: File 0, [[@LINE]]:12 -> [[@LINE+7]]:2 = #0
// CHECK-NEXT: File 0, [[@LINE+1]]:18 -> [[@LINE+1]]:24 = (#0 + #1)
for(int i = 0; i < 10; ++i) { // CHECK-NEXT: File 0, [[@LINE]]:26 -> [[@LINE]]:29 = #1
- bar(); // CHECK-NEXT: File 0, [[@LINE-1]]:31 -> [[@LINE+1]]:4 = #1
+ bar(); // CHECK: File 0, [[@LINE-1]]:31 -> [[@LINE+1]]:4 = #1
}
static_func();
return 0;
@@ -16,7 +16,7 @@ int main() { // CHECK-NEXT: File 0, [[@LINE]]:12 -> [[@LINE+
// CHECK-NEXT: foo
void foo() { // CHECK-NEXT: File 0, [[@LINE]]:12 -> [[@LINE+5]]:2 = #0
// CHECK-NEXT: File 0, [[@LINE+1]]:6 -> [[@LINE+1]]:7 = #0
- if(1) { // CHECK-NEXT: File 0, [[@LINE]]:9 -> [[@LINE+2]]:4 = #1
+ if(1) { // CHECK: File 0, [[@LINE]]:9 -> [[@LINE+2]]:4 = #1
int i = 0;
}
}
diff --git a/test/CoverageMapping/trycatch.cpp b/test/CoverageMapping/trycatch.cpp
index 01d8fb930740..560354320912 100644
--- a/test/CoverageMapping/trycatch.cpp
+++ b/test/CoverageMapping/trycatch.cpp
@@ -12,13 +12,13 @@ class Warning {
// CHECK: func
void func(int i) { // CHECK-NEXT: File 0, [[@LINE]]:18 -> {{[0-9]+}}:2 = #0
// CHECK-NEXT: File 0, [[@LINE+1]]:6 -> [[@LINE+1]]:11 = #0
- if(i % 2) { // CHECK-NEXT: File 0, [[@LINE]]:13 -> [[@LINE+4]]:4 = #1
+ if(i % 2) { // CHECK: File 0, [[@LINE]]:13 -> [[@LINE+4]]:4 = #1
throw Error();
int j = 0; // CHECK-NEXT: File 0, [[@LINE]]:5 -> [[@LINE+2]]:4 = 0
- // CHECK-NEXT: File 0, [[@LINE+1]]:10 -> [[@LINE+2]]:27 = (#0 - #1)
+ // CHECK: File 0, [[@LINE+1]]:10 -> [[@LINE+2]]:27 = (#0 - #1)
} else if(i == 8) // CHECK-NEXT: File 0, [[@LINE]]:13 -> [[@LINE]]:19 = (#0 - #1)
- throw ImportantError(); // CHECK-NEXT: File 0, [[@LINE]]:5 -> [[@LINE]]:27 = #2
-}
+ throw ImportantError(); // CHECK: File 0, [[@LINE]]:5 -> [[@LINE]]:27 = #2
+} // CHECK-NEXT: File 0, [[@LINE-1]]:27 -> [[@LINE]]:2 = ((#0 - #1) - #2)
// CHECK-NEXT: main
int main() { // CHECK-NEXT: File 0, [[@LINE]]:12 -> [[@LINE+13]]:2 = #0
diff --git a/test/CoverageMapping/while.c b/test/CoverageMapping/while.c
index 7f09e4b0d727..616ecf69020d 100644
--- a/test/CoverageMapping/while.c
+++ b/test/CoverageMapping/while.c
@@ -3,10 +3,10 @@
// CHECK: main
int main() { // CHECK-NEXT: File 0, [[@LINE]]:12 -> [[@LINE+8]]:2 = #0
int j = 0; // CHECK-NEXT: File 0, [[@LINE+1]]:9 -> [[@LINE+1]]:14 = (#0 + #1)
- while(j < 5) ++j; // CHECK-NEXT: File 0, [[@LINE]]:16 -> [[@LINE]]:19 = #1
- j = 0;
- while
- (j < 5) // CHECK-NEXT: File 0, [[@LINE]]:5 -> [[@LINE]]:10 = (#0 + #2)
+ while(j < 5) ++j; // CHECK-NEXT: File 0, [[@LINE]]:15 -> [[@LINE]]:16 = #1
+ j = 0; // CHECK-NEXT: File 0, [[@LINE-1]]:16 -> [[@LINE-1]]:19 = #1
+ while // CHECK-NEXT: File 0, [[@LINE+1]]:5 -> [[@LINE+1]]:10 = (#0 + #2)
+ (j < 5) // CHECK-NEXT: Gap,File 0, [[@LINE]]:11 -> [[@LINE+1]]:6 = #2
++j; // CHECK-NEXT: File 0, [[@LINE]]:6 -> [[@LINE]]:9 = #2
return 0;
}
diff --git a/test/Driver/Inputs/CUDA-nolibdevice/usr/local/cuda/bin/.keep b/test/Driver/Inputs/CUDA-nolibdevice/usr/local/cuda/bin/.keep
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/test/Driver/Inputs/CUDA-nolibdevice/usr/local/cuda/bin/.keep
diff --git a/test/Driver/Inputs/CUDA-nolibdevice/usr/local/cuda/include/.keep b/test/Driver/Inputs/CUDA-nolibdevice/usr/local/cuda/include/.keep
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/test/Driver/Inputs/CUDA-nolibdevice/usr/local/cuda/include/.keep
diff --git a/test/Driver/Inputs/CUDA-nolibdevice/usr/local/cuda/lib/.keep b/test/Driver/Inputs/CUDA-nolibdevice/usr/local/cuda/lib/.keep
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/test/Driver/Inputs/CUDA-nolibdevice/usr/local/cuda/lib/.keep
diff --git a/test/Driver/Inputs/CUDA-nolibdevice/usr/local/cuda/lib64/.keep b/test/Driver/Inputs/CUDA-nolibdevice/usr/local/cuda/lib64/.keep
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/test/Driver/Inputs/CUDA-nolibdevice/usr/local/cuda/lib64/.keep
diff --git a/test/Driver/Inputs/CUDA_90/usr/local/cuda/bin/.keep b/test/Driver/Inputs/CUDA_90/usr/local/cuda/bin/.keep
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/test/Driver/Inputs/CUDA_90/usr/local/cuda/bin/.keep
diff --git a/test/Driver/Inputs/CUDA_90/usr/local/cuda/include/.keep b/test/Driver/Inputs/CUDA_90/usr/local/cuda/include/.keep
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/test/Driver/Inputs/CUDA_90/usr/local/cuda/include/.keep
diff --git a/test/Driver/Inputs/CUDA_90/usr/local/cuda/lib/.keep b/test/Driver/Inputs/CUDA_90/usr/local/cuda/lib/.keep
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/test/Driver/Inputs/CUDA_90/usr/local/cuda/lib/.keep
diff --git a/test/Driver/Inputs/CUDA_90/usr/local/cuda/lib64/.keep b/test/Driver/Inputs/CUDA_90/usr/local/cuda/lib64/.keep
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/test/Driver/Inputs/CUDA_90/usr/local/cuda/lib64/.keep
diff --git a/test/Driver/Inputs/CUDA_90/usr/local/cuda/nvvm/libdevice/libdevice.10.bc b/test/Driver/Inputs/CUDA_90/usr/local/cuda/nvvm/libdevice/libdevice.10.bc
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/test/Driver/Inputs/CUDA_90/usr/local/cuda/nvvm/libdevice/libdevice.10.bc
diff --git a/test/Driver/Inputs/CUDA_90/usr/local/cuda/version.txt b/test/Driver/Inputs/CUDA_90/usr/local/cuda/version.txt
new file mode 100644
index 000000000000..24e1fd4ece78
--- /dev/null
+++ b/test/Driver/Inputs/CUDA_90/usr/local/cuda/version.txt
@@ -0,0 +1 @@
+CUDA Version 9.0.103
diff --git a/test/Driver/Inputs/Windows/usr/bin/ld.bfd b/test/Driver/Inputs/Windows/usr/bin/ld.bfd
new file mode 100755
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/test/Driver/Inputs/Windows/usr/bin/ld.bfd
diff --git a/test/Driver/Inputs/basic_linux_tree/usr/i686-unknown-linux/lib/.keep b/test/Driver/Inputs/basic_linux_tree/usr/i686-unknown-linux/lib/.keep
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/test/Driver/Inputs/basic_linux_tree/usr/i686-unknown-linux/lib/.keep
diff --git a/test/Driver/Inputs/basic_linux_tree/usr/lib/gcc/i686-unknown-linux/4.6.0/crtbegin.o b/test/Driver/Inputs/basic_linux_tree/usr/lib/gcc/i686-unknown-linux/4.6.0/crtbegin.o
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/test/Driver/Inputs/basic_linux_tree/usr/lib/gcc/i686-unknown-linux/4.6.0/crtbegin.o
diff --git a/test/Driver/Inputs/resource_dir/hwasan_blacklist.txt b/test/Driver/Inputs/resource_dir/hwasan_blacklist.txt
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/test/Driver/Inputs/resource_dir/hwasan_blacklist.txt
diff --git a/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.hwasan-aarch64.a.syms b/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.hwasan-aarch64.a.syms
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.hwasan-aarch64.a.syms
diff --git a/test/Driver/Inputs/resource_dir/ubsan_blacklist.txt b/test/Driver/Inputs/resource_dir/ubsan_blacklist.txt
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/test/Driver/Inputs/resource_dir/ubsan_blacklist.txt
diff --git a/test/Driver/XRay/lit.local.cfg b/test/Driver/XRay/lit.local.cfg
index 34040d226150..7cc6c70dcb22 100644
--- a/test/Driver/XRay/lit.local.cfg
+++ b/test/Driver/XRay/lit.local.cfg
@@ -1,2 +1,24 @@
target_triple_components = config.target_triple.split('-')
config.available_features.update(target_triple_components)
+
+# Only run the tests in platforms where XRay instrumentation is supported.
+supported_targets = [
+ 'x86_64', 'x86_64h', 'arm', 'aarch64', 'arm64', 'powerpc64le', 'mips',
+ 'mipsel', 'mips64', 'mips64el'
+]
+
+# Only on platforms we support.
+supported_oses = [
+ 'linux'
+]
+
+triple_set = set(target_triple_components)
+if len(triple_set.intersection(supported_targets)) == 0:
+ config.unsupported = True
+
+# Do not run for 'android' despite being linux.
+if len(triple_set.intersection(supported_oses)) == 0 or 'android' in triple_set:
+ config.unsupported = True
+
+if config.enable_shared:
+ config.available_features.update(['enable_shared'])
diff --git a/test/Driver/XRay/xray-shared-noxray.cpp b/test/Driver/XRay/xray-shared-noxray.cpp
new file mode 100644
index 000000000000..c279f93f3f3d
--- /dev/null
+++ b/test/Driver/XRay/xray-shared-noxray.cpp
@@ -0,0 +1,16 @@
+// RUN: %clangxx -shared -o /dev/null -v -fxray-instrument %s -###
+// RUN: %clangxx -shared -o /dev/null -v -fxray-instrument %s -### 2>&1 | \
+// RUN: FileCheck %s --check-prefix=SHARED
+// RUN: %clangxx -static -o /dev/null -v -fxray-instrument %s -### -DMAIN
+// RUN: %clangxx -static -o /dev/null -v -fxray-instrument %s -### 2>&1 -DMAIN \
+// RUN: | FileCheck %s --check-prefix=STATIC
+//
+// SHARED-NOT: {{clang_rt\.xray-}}
+// STATIC: {{clang_rt\.xray-}}
+//
+// REQUIRES: linux, enable_shared
+int foo() { return 42; }
+
+#ifdef MAIN
+int main() { return foo(); }
+#endif
diff --git a/test/Driver/aarch64-cpus.c b/test/Driver/aarch64-cpus.c
index 4c42e50e42da..229484b2577b 100644
--- a/test/Driver/aarch64-cpus.c
+++ b/test/Driver/aarch64-cpus.c
@@ -21,138 +21,188 @@
// RUN: %clang -target aarch64 -mcpu=cortex-a35 -### -c %s 2>&1 | FileCheck -check-prefix=CA35 %s
// RUN: %clang -target aarch64 -mlittle-endian -mcpu=cortex-a35 -### -c %s 2>&1 | FileCheck -check-prefix=CA35 %s
// RUN: %clang -target aarch64_be -mlittle-endian -mcpu=cortex-a35 -### -c %s 2>&1 | FileCheck -check-prefix=CA35 %s
-// RUN: %clang -target aarch64 -mtune=cortex-a35 -### -c %s 2>&1 | FileCheck -check-prefix=CA35 %s
-// RUN: %clang -target aarch64 -mlittle-endian -mtune=cortex-a35 -### -c %s 2>&1 | FileCheck -check-prefix=CA35 %s
-// RUN: %clang -target aarch64_be -mlittle-endian -mtune=cortex-a35 -### -c %s 2>&1 | FileCheck -check-prefix=CA35 %s
+// RUN: %clang -target aarch64 -mtune=cortex-a35 -### -c %s 2>&1 | FileCheck -check-prefix=CA35-TUNE %s
+// RUN: %clang -target aarch64 -mlittle-endian -mtune=cortex-a35 -### -c %s 2>&1 | FileCheck -check-prefix=CA35-TUNE %s
+// RUN: %clang -target aarch64_be -mlittle-endian -mtune=cortex-a35 -### -c %s 2>&1 | FileCheck -check-prefix=CA35-TUNE %s
// CA35: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "cortex-a35"
+// CA35-TUNE: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic"
// RUN: %clang -target arm64 -mcpu=cortex-a35 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-CA35 %s
// RUN: %clang -target arm64 -mlittle-endian -mcpu=cortex-a35 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-CA35 %s
-// RUN: %clang -target arm64 -mtune=cortex-a35 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-CA35 %s
-// RUN: %clang -target arm64 -mlittle-endian -mtune=cortex-a35 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-CA35 %s
+// RUN: %clang -target arm64 -mtune=cortex-a35 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-CA35-TUNE %s
+// RUN: %clang -target arm64 -mlittle-endian -mtune=cortex-a35 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-CA35-TUNE %s
// ARM64-CA35: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "cortex-a35"
-
+// ARM64-CA35-TUNE: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "generic"
// RUN: %clang -target aarch64 -mcpu=cortex-a53 -### -c %s 2>&1 | FileCheck -check-prefix=CA53 %s
// RUN: %clang -target aarch64 -mlittle-endian -mcpu=cortex-a53 -### -c %s 2>&1 | FileCheck -check-prefix=CA53 %s
// RUN: %clang -target aarch64_be -mlittle-endian -mcpu=cortex-a53 -### -c %s 2>&1 | FileCheck -check-prefix=CA53 %s
-// RUN: %clang -target aarch64 -mtune=cortex-a53 -### -c %s 2>&1 | FileCheck -check-prefix=CA53 %s
-// RUN: %clang -target aarch64_be -mlittle-endian -mtune=cortex-a53 -### -c %s 2>&1 | FileCheck -check-prefix=CA53 %s
+// RUN: %clang -target aarch64 -mtune=cortex-a53 -### -c %s 2>&1 | FileCheck -check-prefix=CA53-TUNE %s
+// RUN: %clang -target aarch64_be -mlittle-endian -mtune=cortex-a53 -### -c %s 2>&1 | FileCheck -check-prefix=CA53-TUNE %s
// CA53: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "cortex-a53"
+// CA53-TUNE: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic"
// RUN: %clang -target arm64 -mcpu=cortex-a53 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-CA53 %s
// RUN: %clang -target arm64 -mlittle-endian -mcpu=cortex-a53 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-CA53 %s
-// RUN: %clang -target arm64 -mtune=cortex-a53 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-CA53 %s
-// RUN: %clang -target arm64 -mlittle-endian -mtune=cortex-a53 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-CA53 %s
+// RUN: %clang -target arm64 -mtune=cortex-a53 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-CA53-TUNE %s
+// RUN: %clang -target arm64 -mlittle-endian -mtune=cortex-a53 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-CA53-TUNE %s
// ARM64-CA53: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "cortex-a53"
+// ARM64-CA53-TUNE: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "generic"
+
+// RUN: %clang -target aarch64 -mcpu=cortex-a55 -### -c %s 2>&1 | FileCheck -check-prefix=CA55 %s
+// RUN: %clang -target aarch64 -mlittle-endian -mcpu=cortex-a55 -### -c %s 2>&1 | FileCheck -check-prefix=CA55 %s
+// RUN: %clang -target aarch64_be -mlittle-endian -mcpu=cortex-a55 -### -c %s 2>&1 | FileCheck -check-prefix=CA55 %s
+// RUN: %clang -target aarch64 -mtune=cortex-a55 -### -c %s 2>&1 | FileCheck -check-prefix=CA55-TUNE %s
+// RUN: %clang -target aarch64_be -mlittle-endian -mtune=cortex-a55 -### -c %s 2>&1 | FileCheck -check-prefix=CA55-TUNE %s
+// CA55: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "cortex-a55"
+// CA55-TUNE: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic"
+
+// RUN: %clang -target arm64 -mcpu=cortex-a55 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-CA55 %s
+// RUN: %clang -target arm64 -mlittle-endian -mcpu=cortex-a55 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-CA55 %s
+// RUN: %clang -target arm64 -mtune=cortex-a55 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-CA55-TUNE %s
+// RUN: %clang -target arm64 -mlittle-endian -mtune=cortex-a55 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-CA55-TUNE %s
+// ARM64-CA55: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "cortex-a55"
+// ARM64-CA55-TUNE: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "generic"
// RUN: %clang -target aarch64 -mcpu=cortex-a57 -### -c %s 2>&1 | FileCheck -check-prefix=CA57 %s
// RUN: %clang -target aarch64 -mlittle-endian -mcpu=cortex-a57 -### -c %s 2>&1 | FileCheck -check-prefix=CA57 %s
// RUN: %clang -target aarch64_be -mlittle-endian -mcpu=cortex-a57 -### -c %s 2>&1 | FileCheck -check-prefix=CA57 %s
-// RUN: %clang -target aarch64 -mtune=cortex-a57 -### -c %s 2>&1 | FileCheck -check-prefix=CA57 %s
-// RUN: %clang -target aarch64 -mlittle-endian -mtune=cortex-a57 -### -c %s 2>&1 | FileCheck -check-prefix=CA57 %s
-// RUN: %clang -target aarch64_be -mlittle-endian -mtune=cortex-a57 -### -c %s 2>&1 | FileCheck -check-prefix=CA57 %s
+// RUN: %clang -target aarch64 -mtune=cortex-a57 -### -c %s 2>&1 | FileCheck -check-prefix=CA57-TUNE %s
+// RUN: %clang -target aarch64 -mlittle-endian -mtune=cortex-a57 -### -c %s 2>&1 | FileCheck -check-prefix=CA57-TUNE %s
+// RUN: %clang -target aarch64_be -mlittle-endian -mtune=cortex-a57 -### -c %s 2>&1 | FileCheck -check-prefix=CA57-TUNE %s
// CA57: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "cortex-a57"
+// CA57-TUNE: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic"
// RUN: %clang -target arm64 -mcpu=cortex-a57 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-CA57 %s
// RUN: %clang -target arm64 -mlittle-endian -mcpu=cortex-a57 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-CA57 %s
-// RUN: %clang -target arm64 -mtune=cortex-a57 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-CA57 %s
-// RUN: %clang -target arm64 -mlittle-endian -mtune=cortex-a57 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-CA57 %s
+// RUN: %clang -target arm64 -mtune=cortex-a57 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-CA57-TUNE %s
+// RUN: %clang -target arm64 -mlittle-endian -mtune=cortex-a57 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-CA57-TUNE %s
// ARM64-CA57: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "cortex-a57"
+// ARM64-CA57-TUNE: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "generic"
// RUN: %clang -target aarch64 -mcpu=cortex-a72 -### -c %s 2>&1 | FileCheck -check-prefix=CA72 %s
// RUN: %clang -target aarch64 -mlittle-endian -mcpu=cortex-a72 -### -c %s 2>&1 | FileCheck -check-prefix=CA72 %s
// RUN: %clang -target aarch64_be -mlittle-endian -mcpu=cortex-a72 -### -c %s 2>&1 | FileCheck -check-prefix=CA72 %s
-// RUN: %clang -target aarch64 -mtune=cortex-a72 -### -c %s 2>&1 | FileCheck -check-prefix=CA72 %s
-// RUN: %clang -target aarch64 -mlittle-endian -mtune=cortex-a72 -### -c %s 2>&1 | FileCheck -check-prefix=CA72 %s
-// RUN: %clang -target aarch64_be -mlittle-endian -mtune=cortex-a72 -### -c %s 2>&1 | FileCheck -check-prefix=CA72 %s
+// RUN: %clang -target aarch64 -mtune=cortex-a72 -### -c %s 2>&1 | FileCheck -check-prefix=CA72-TUNE %s
+// RUN: %clang -target aarch64 -mlittle-endian -mtune=cortex-a72 -### -c %s 2>&1 | FileCheck -check-prefix=CA72-TUNE %s
+// RUN: %clang -target aarch64_be -mlittle-endian -mtune=cortex-a72 -### -c %s 2>&1 | FileCheck -check-prefix=CA72-TUNE %s
// CA72: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "cortex-a72"
+// CA72-TUNE: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic"
// RUN: %clang -target arm64 -mcpu=cortex-a72 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-CA72 %s
// RUN: %clang -target arm64 -mlittle-endian -mcpu=cortex-a72 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-CA72 %s
-// RUN: %clang -target arm64 -mtune=cortex-a72 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-CA72 %s
-// RUN: %clang -target arm64 -mlittle-endian -mtune=cortex-a72 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-CA72 %s
+// RUN: %clang -target arm64 -mtune=cortex-a72 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-CA72-TUNE %s
+// RUN: %clang -target arm64 -mlittle-endian -mtune=cortex-a72 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-CA72-TUNE %s
// ARM64-CA72: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "cortex-a72"
+// ARM64-CA72-TUNE: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "generic"
// RUN: %clang -target aarch64 -mcpu=cortex-a73 -### -c %s 2>&1 | FileCheck -check-prefix=CORTEX-A73 %s
// RUN: %clang -target aarch64 -mlittle-endian -mcpu=cortex-a73 -### -c %s 2>&1 | FileCheck -check-prefix=CORTEX-A73 %s
// RUN: %clang -target aarch64_be -mlittle-endian -mcpu=cortex-a73 -### -c %s 2>&1 | FileCheck -check-prefix=CORTEX-A73 %s
-// RUN: %clang -target aarch64 -mtune=cortex-a73 -### -c %s 2>&1 | FileCheck -check-prefix=CORTEX-A73 %s
-// RUN: %clang -target aarch64 -mlittle-endian -mtune=cortex-a73 -### -c %s 2>&1 | FileCheck -check-prefix=CORTEX-A73 %s
-// RUN: %clang -target aarch64_be -mlittle-endian -mtune=cortex-a73 -### -c %s 2>&1 | FileCheck -check-prefix=CORTEX-A73 %s
+// RUN: %clang -target aarch64 -mtune=cortex-a73 -### -c %s 2>&1 | FileCheck -check-prefix=CORTEX-A73-TUNE %s
+// RUN: %clang -target aarch64 -mlittle-endian -mtune=cortex-a73 -### -c %s 2>&1 | FileCheck -check-prefix=CORTEX-A73-TUNE %s
+// RUN: %clang -target aarch64_be -mlittle-endian -mtune=cortex-a73 -### -c %s 2>&1 | FileCheck -check-prefix=CORTEX-A73-TUNE %s
// CORTEX-A73: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "cortex-a73"
+// CORTEX-A73-TUNE: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic"
// RUN: %clang -target arm64 -mcpu=cortex-a73 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-CORTEX-A73 %s
// RUN: %clang -target arm64 -mlittle-endian -mcpu=cortex-a73 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-CORTEX-A73 %s
-// RUN: %clang -target arm64 -mtune=cortex-a73 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-CORTEX-A73 %s
-// RUN: %clang -target arm64 -mlittle-endian -mtune=cortex-a73 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-CORTEX-A73 %s
+// RUN: %clang -target arm64 -mtune=cortex-a73 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-CORTEX-A73-TUNE %s
+// RUN: %clang -target arm64 -mlittle-endian -mtune=cortex-a73 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-CORTEX-A73-TUNE %s
// ARM64-CORTEX-A73: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "cortex-a73"
+// ARM64-CORTEX-A73-TUNE: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "generic"
+
+// RUN: %clang -target aarch64 -mcpu=cortex-a75 -### -c %s 2>&1 | FileCheck -check-prefix=CORTEX-A75 %s
+// RUN: %clang -target aarch64 -mlittle-endian -mcpu=cortex-a75 -### -c %s 2>&1 | FileCheck -check-prefix=CORTEX-A75 %s
+// RUN: %clang -target aarch64_be -mlittle-endian -mcpu=cortex-a75 -### -c %s 2>&1 | FileCheck -check-prefix=CORTEX-A75 %s
+// RUN: %clang -target aarch64 -mtune=cortex-a75 -### -c %s 2>&1 | FileCheck -check-prefix=CORTEX-A75-TUNE %s
+// RUN: %clang -target aarch64 -mlittle-endian -mtune=cortex-a75 -### -c %s 2>&1 | FileCheck -check-prefix=CORTEX-A75-TUNE %s
+// RUN: %clang -target aarch64_be -mlittle-endian -mtune=cortex-a75 -### -c %s 2>&1 | FileCheck -check-prefix=CORTEX-A75-TUNE %s
+// CORTEX-A75: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "cortex-a75"
+// CORTEX-A75-TUNE: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic"
+
+// RUN: %clang -target arm64 -mcpu=cortex-a75 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-CORTEX-A75 %s
+// RUN: %clang -target arm64 -mlittle-endian -mcpu=cortex-a75 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-CORTEX-A75 %s
+// RUN: %clang -target arm64 -mtune=cortex-a75 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-CORTEX-A75-TUNE %s
+// RUN: %clang -target arm64 -mlittle-endian -mtune=cortex-a75 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-CORTEX-A75-TUNE %s
+// ARM64-CORTEX-A75: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "cortex-a75"
+// ARM64-CORTEX-A75-TUNE: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "generic"
// RUN: %clang -target aarch64 -mcpu=exynos-m1 -### -c %s 2>&1 | FileCheck -check-prefix=M1 %s
// RUN: %clang -target aarch64 -mlittle-endian -mcpu=exynos-m1 -### -c %s 2>&1 | FileCheck -check-prefix=M1 %s
// RUN: %clang -target aarch64_be -mlittle-endian -mcpu=exynos-m1 -### -c %s 2>&1 | FileCheck -check-prefix=M1 %s
-// RUN: %clang -target aarch64 -mtune=exynos-m1 -### -c %s 2>&1 | FileCheck -check-prefix=M1 %s
-// RUN: %clang -target aarch64 -mlittle-endian -mtune=exynos-m1 -### -c %s 2>&1 | FileCheck -check-prefix=M1 %s
-// RUN: %clang -target aarch64_be -mlittle-endian -mtune=exynos-m1 -### -c %s 2>&1 | FileCheck -check-prefix=M1 %s
+// RUN: %clang -target aarch64 -mtune=exynos-m1 -### -c %s 2>&1 | FileCheck -check-prefix=M1-TUNE %s
+// RUN: %clang -target aarch64 -mlittle-endian -mtune=exynos-m1 -### -c %s 2>&1 | FileCheck -check-prefix=M1-TUNE %s
+// RUN: %clang -target aarch64_be -mlittle-endian -mtune=exynos-m1 -### -c %s 2>&1 | FileCheck -check-prefix=M1-TUNE %s
// M1: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "exynos-m1"
+// M1-TUNE: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic"
// RUN: %clang -target aarch64 -mcpu=exynos-m2 -### -c %s 2>&1 | FileCheck -check-prefix=M2 %s
// RUN: %clang -target aarch64 -mlittle-endian -mcpu=exynos-m2 -### -c %s 2>&1 | FileCheck -check-prefix=M2 %s
// RUN: %clang -target aarch64_be -mlittle-endian -mcpu=exynos-m2 -### -c %s 2>&1 | FileCheck -check-prefix=M2 %s
-// RUN: %clang -target aarch64 -mtune=exynos-m2 -### -c %s 2>&1 | FileCheck -check-prefix=M2 %s
-// RUN: %clang -target aarch64 -mlittle-endian -mtune=exynos-m2 -### -c %s 2>&1 | FileCheck -check-prefix=M2 %s
-// RUN: %clang -target aarch64_be -mlittle-endian -mtune=exynos-m2 -### -c %s 2>&1 | FileCheck -check-prefix=M2 %s
+// RUN: %clang -target aarch64 -mtune=exynos-m2 -### -c %s 2>&1 | FileCheck -check-prefix=M2-TUNE %s
+// RUN: %clang -target aarch64 -mlittle-endian -mtune=exynos-m2 -### -c %s 2>&1 | FileCheck -check-prefix=M2-TUNE %s
+// RUN: %clang -target aarch64_be -mlittle-endian -mtune=exynos-m2 -### -c %s 2>&1 | FileCheck -check-prefix=M2-TUNE %s
// M2: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "exynos-m2"
+// M2-TUNE: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic"
// RUN: %clang -target aarch64_be -mcpu=exynos-m3 -### -c %s 2>&1 | FileCheck -check-prefix=M3 %s
// RUN: %clang -target aarch64 -mbig-endian -mcpu=exynos-m3 -### -c %s 2>&1 | FileCheck -check-prefix=M3 %s
// RUN: %clang -target aarch64_be -mbig-endian -mcpu=exynos-m3 -### -c %s 2>&1 | FileCheck -check-prefix=M3 %s
-// RUN: %clang -target aarch64_be -mtune=exynos-m3 -### -c %s 2>&1 | FileCheck -check-prefix=M3 %s
-// RUN: %clang -target aarch64 -mbig-endian -mtune=exynos-m3 -### -c %s 2>&1 | FileCheck -check-prefix=M3 %s
-// RUN: %clang -target aarch64_be -mbig-endian -mtune=exynos-m3 -### -c %s 2>&1 | FileCheck -check-prefix=M3 %s
+// RUN: %clang -target aarch64_be -mtune=exynos-m3 -### -c %s 2>&1 | FileCheck -check-prefix=M3-TUNE %s
+// RUN: %clang -target aarch64 -mbig-endian -mtune=exynos-m3 -### -c %s 2>&1 | FileCheck -check-prefix=M3-TUNE %s
+// RUN: %clang -target aarch64_be -mbig-endian -mtune=exynos-m3 -### -c %s 2>&1 | FileCheck -check-prefix=M3-TUNE %s
// M3: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "exynos-m3"
+// M3-TUNE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "generic"
// RUN: %clang -target arm64 -mcpu=exynos-m1 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-M1 %s
// RUN: %clang -target arm64 -mlittle-endian -mcpu=exynos-m1 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-M1 %s
-// RUN: %clang -target arm64 -mtune=exynos-m1 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-M1 %s
-// RUN: %clang -target arm64 -mlittle-endian -mtune=exynos-m1 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-M1 %s
+// RUN: %clang -target arm64 -mtune=exynos-m1 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-M1-TUNE %s
+// RUN: %clang -target arm64 -mlittle-endian -mtune=exynos-m1 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-M1-TUNE %s
// ARM64-M1: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "exynos-m1"
+// ARM64-M1-TUNE: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "generic"
// RUN: %clang -target arm64 -mcpu=exynos-m2 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-M2 %s
// RUN: %clang -target arm64 -mlittle-endian -mcpu=exynos-m2 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-M2 %s
-// RUN: %clang -target arm64 -mtune=exynos-m2 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-M2 %s
-// RUN: %clang -target arm64 -mlittle-endian -mtune=exynos-m2 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-M2 %s
+// RUN: %clang -target arm64 -mtune=exynos-m2 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-M2-TUNE %s
+// RUN: %clang -target arm64 -mlittle-endian -mtune=exynos-m2 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-M2-TUNE %s
// ARM64-M2: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "exynos-m2"
+// ARM64-M2-TUNE: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "generic"
// RUN: %clang -target arm64 -mcpu=exynos-m3 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-M3 %s
// RUN: %clang -target arm64 -mlittle-endian -mcpu=exynos-m3 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-M3 %s
-// RUN: %clang -target arm64 -mtune=exynos-m3 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-M3 %s
-// RUN: %clang -target arm64 -mlittle-endian -mtune=exynos-m3 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-M3 %s
+// RUN: %clang -target arm64 -mtune=exynos-m3 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-M3-TUNE %s
+// RUN: %clang -target arm64 -mlittle-endian -mtune=exynos-m3 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-M3-TUNE %s
// ARM64-M3: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "exynos-m3"
+// ARM64-M3-TUNE: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "generic"
// RUN: %clang -target aarch64 -mcpu=falkor -### -c %s 2>&1 | FileCheck -check-prefix=FALKOR %s
// RUN: %clang -target aarch64 -mlittle-endian -mcpu=falkor -### -c %s 2>&1 | FileCheck -check-prefix=FALKOR %s
-// RUN: %clang -target aarch64 -mtune=falkor -### -c %s 2>&1 | FileCheck -check-prefix=FALKOR %s
-// RUN: %clang -target aarch64 -mlittle-endian -mtune=falkor -### -c %s 2>&1 | FileCheck -check-prefix=FALKOR %s
+// RUN: %clang -target aarch64 -mtune=falkor -### -c %s 2>&1 | FileCheck -check-prefix=FALKOR-TUNE %s
+// RUN: %clang -target aarch64 -mlittle-endian -mtune=falkor -### -c %s 2>&1 | FileCheck -check-prefix=FALKOR-TUNE %s
// FALKOR: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "falkor"
+// FALKOR-TUNE: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic"
// RUN: %clang -target arm64 -mcpu=falkor -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-FALKOR %s
// RUN: %clang -target arm64 -mlittle-endian -mcpu=falkor -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-FALKOR %s
-// RUN: %clang -target arm64 -mtune=falkor -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-FALKOR %s
-// RUN: %clang -target arm64 -mlittle-endian -mtune=falkor -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-FALKOR %s
+// RUN: %clang -target arm64 -mtune=falkor -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-FALKOR-TUNE %s
+// RUN: %clang -target arm64 -mlittle-endian -mtune=falkor -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-FALKOR-TUNE %s
// ARM64-FALKOR: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "falkor"
+// ARM64-FALKOR-TUNE: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "generic"
// RUN: %clang -target aarch64 -mcpu=kryo -### -c %s 2>&1 | FileCheck -check-prefix=KRYO %s
// RUN: %clang -target aarch64 -mlittle-endian -mcpu=kryo -### -c %s 2>&1 | FileCheck -check-prefix=KRYO %s
-// RUN: %clang -target aarch64 -mtune=kryo -### -c %s 2>&1 | FileCheck -check-prefix=KRYO %s
-// RUN: %clang -target aarch64 -mlittle-endian -mtune=kryo -### -c %s 2>&1 | FileCheck -check-prefix=KRYO %s
+// RUN: %clang -target aarch64 -mtune=kryo -### -c %s 2>&1 | FileCheck -check-prefix=KRYO-TUNE %s
+// RUN: %clang -target aarch64 -mlittle-endian -mtune=kryo -### -c %s 2>&1 | FileCheck -check-prefix=KRYO-TUNE %s
// KRYO: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "kryo"
+// KRYO-TUNE: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic"
// RUN: %clang -target arm64 -mcpu=kryo -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-KRYO %s
// RUN: %clang -target arm64 -mlittle-endian -mcpu=kryo -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-KRYO %s
-// RUN: %clang -target arm64 -mtune=kryo -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-KRYO %s
-// RUN: %clang -target arm64 -mlittle-endian -mtune=kryo -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-KRYO %s
+// RUN: %clang -target arm64 -mtune=kryo -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-KRYO-TUNE %s
+// RUN: %clang -target arm64 -mlittle-endian -mtune=kryo -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-KRYO-TUNE %s
// ARM64-KRYO: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "kryo"
+// ARM64-KRYO-TUNE: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "generic"
// RUN: %clang -target aarch64 -mcpu=thunderx2t99 -### -c %s 2>&1 | FileCheck -check-prefix=THUNDERX2T99 %s
// RUN: %clang -target aarch64 -mlittle-endian -mcpu=thunderx2t99 -### -c %s 2>&1 | FileCheck -check-prefix=THUNDERX2T99 %s
@@ -161,7 +211,7 @@
// RUN: %clang -target aarch64 -mlittle-endian -mtune=thunderx2t99 -### -c %s 2>&1 | FileCheck -check-prefix=THUNDERX2T99-TUNE %s
// RUN: %clang -target aarch64_be -mlittle-endian -mtune=thunderx2t99 -### -c %s 2>&1 | FileCheck -check-prefix=THUNDERX2T99-TUNE %s
// THUNDERX2T99: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "thunderx2t99" "-target-feature" "+v8.1a"
-// THUNDERX2T99-TUNE: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "thunderx2t99"
+// THUNDERX2T99-TUNE: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic"
// THUNDERX2T99-TUNE-NOT: +v8.1a
// RUN: %clang -target arm64 -mcpu=thunderx2t99 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-THUNDERX2T99 %s
@@ -169,7 +219,7 @@
// RUN: %clang -target arm64 -mtune=thunderx2t99 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-THUNDERX2T99-TUNE %s
// RUN: %clang -target arm64 -mlittle-endian -mtune=thunderx2t99 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-THUNDERX2T99-TUNE %s
// ARM64-THUNDERX2T99: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "thunderx2t99" "-target-feature" "+v8.1a"
-// ARM64-THUNDERX2T99-TUNE: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "thunderx2t99"
+// ARM64-THUNDERX2T99-TUNE: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "generic"
// ARM64-THUNDERX2T99-TUNE-NOT: +v8.1a
// RUN: %clang -target aarch64_be -### -c %s 2>&1 | FileCheck -check-prefix=GENERIC-BE %s
@@ -180,83 +230,104 @@
// RUN: %clang -target aarch64_be -mcpu=cortex-a35 -### -c %s 2>&1 | FileCheck -check-prefix=CA35-BE %s
// RUN: %clang -target aarch64 -mbig-endian -mcpu=cortex-a35 -### -c %s 2>&1 | FileCheck -check-prefix=CA35-BE %s
// RUN: %clang -target aarch64_be -mbig-endian -mcpu=cortex-a35 -### -c %s 2>&1 | FileCheck -check-prefix=CA35-BE %s
-// RUN: %clang -target aarch64_be -mtune=cortex-a35 -### -c %s 2>&1 | FileCheck -check-prefix=CA35-BE %s
-// RUN: %clang -target aarch64 -mbig-endian -mtune=cortex-a35 -### -c %s 2>&1 | FileCheck -check-prefix=CA35-BE %s
-// RUN: %clang -target aarch64_be -mbig-endian -mtune=cortex-a35 -### -c %s 2>&1 | FileCheck -check-prefix=CA35-BE %s
+// RUN: %clang -target aarch64_be -mtune=cortex-a35 -### -c %s 2>&1 | FileCheck -check-prefix=CA35-BE-TUNE %s
+// RUN: %clang -target aarch64 -mbig-endian -mtune=cortex-a35 -### -c %s 2>&1 | FileCheck -check-prefix=CA35-BE-TUNE %s
+// RUN: %clang -target aarch64_be -mbig-endian -mtune=cortex-a35 -### -c %s 2>&1 | FileCheck -check-prefix=CA35-BE-TUNE %s
// CA35-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "cortex-a35"
+// CA35-BE-TUNE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "generic"
// RUN: %clang -target aarch64_be -mcpu=cortex-a53 -### -c %s 2>&1 | FileCheck -check-prefix=CA53-BE %s
// RUN: %clang -target aarch64 -mbig-endian -mcpu=cortex-a53 -### -c %s 2>&1 | FileCheck -check-prefix=CA53-BE %s
// RUN: %clang -target aarch64_be -mbig-endian -mcpu=cortex-a53 -### -c %s 2>&1 | FileCheck -check-prefix=CA53-BE %s
-// RUN: %clang -target aarch64_be -mtune=cortex-a53 -### -c %s 2>&1 | FileCheck -check-prefix=CA53-BE %s
-// RUN: %clang -target aarch64 -mbig-endian -mtune=cortex-a53 -### -c %s 2>&1 | FileCheck -check-prefix=CA53-BE %s
-// RUN: %clang -target aarch64_be -mbig-endian -mtune=cortex-a53 -### -c %s 2>&1 | FileCheck -check-prefix=CA53-BE %s
+// RUN: %clang -target aarch64_be -mtune=cortex-a53 -### -c %s 2>&1 | FileCheck -check-prefix=CA53-BE-TUNE %s
+// RUN: %clang -target aarch64 -mbig-endian -mtune=cortex-a53 -### -c %s 2>&1 | FileCheck -check-prefix=CA53-BE-TUNE %s
+// RUN: %clang -target aarch64_be -mbig-endian -mtune=cortex-a53 -### -c %s 2>&1 | FileCheck -check-prefix=CA53-BE-TUNE %s
// CA53-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "cortex-a53"
+// CA53-BE-TUNE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "generic"
+
+// RUN: %clang -target aarch64_be -mcpu=cortex-a55 -### -c %s 2>&1 | FileCheck -check-prefix=CA55-BE %s
+// RUN: %clang -target aarch64 -mbig-endian -mcpu=cortex-a55 -### -c %s 2>&1 | FileCheck -check-prefix=CA55-BE %s
+// RUN: %clang -target aarch64_be -mbig-endian -mcpu=cortex-a55 -### -c %s 2>&1 | FileCheck -check-prefix=CA55-BE %s
+// RUN: %clang -target aarch64_be -mtune=cortex-a55 -### -c %s 2>&1 | FileCheck -check-prefix=CA55-BE-TUNE %s
+// RUN: %clang -target aarch64 -mbig-endian -mtune=cortex-a55 -### -c %s 2>&1 | FileCheck -check-prefix=CA55-BE-TUNE %s
+// RUN: %clang -target aarch64_be -mbig-endian -mtune=cortex-a55 -### -c %s 2>&1 | FileCheck -check-prefix=CA55-BE-TUNE %s
+// CA55-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "cortex-a55"
+// CA55-BE-TUNE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "generic"
// RUN: %clang -target aarch64_be -mcpu=cortex-a57 -### -c %s 2>&1 | FileCheck -check-prefix=CA57-BE %s
// RUN: %clang -target aarch64 -mbig-endian -mcpu=cortex-a57 -### -c %s 2>&1 | FileCheck -check-prefix=CA57-BE %s
// RUN: %clang -target aarch64_be -mbig-endian -mcpu=cortex-a57 -### -c %s 2>&1 | FileCheck -check-prefix=CA57-BE %s
-// RUN: %clang -target aarch64_be -mtune=cortex-a57 -### -c %s 2>&1 | FileCheck -check-prefix=CA57-BE %s
-// RUN: %clang -target aarch64 -mbig-endian -mtune=cortex-a57 -### -c %s 2>&1 | FileCheck -check-prefix=CA57-BE %s
-// RUN: %clang -target aarch64_be -mbig-endian -mtune=cortex-a57 -### -c %s 2>&1 | FileCheck -check-prefix=CA57-BE %s
+// RUN: %clang -target aarch64_be -mtune=cortex-a57 -### -c %s 2>&1 | FileCheck -check-prefix=CA57-BE-TUNE %s
+// RUN: %clang -target aarch64 -mbig-endian -mtune=cortex-a57 -### -c %s 2>&1 | FileCheck -check-prefix=CA57-BE-TUNE %s
+// RUN: %clang -target aarch64_be -mbig-endian -mtune=cortex-a57 -### -c %s 2>&1 | FileCheck -check-prefix=CA57-BE-TUNE %s
// CA57-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "cortex-a57"
+// CA57-BE-TUNE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "generic"
// RUN: %clang -target aarch64_be -mcpu=cortex-a72 -### -c %s 2>&1 | FileCheck -check-prefix=CA72-BE %s
// RUN: %clang -target aarch64 -mbig-endian -mcpu=cortex-a72 -### -c %s 2>&1 | FileCheck -check-prefix=CA72-BE %s
// RUN: %clang -target aarch64_be -mbig-endian -mcpu=cortex-a72 -### -c %s 2>&1 | FileCheck -check-prefix=CA72-BE %s
-// RUN: %clang -target aarch64_be -mtune=cortex-a72 -### -c %s 2>&1 | FileCheck -check-prefix=CA72-BE %s
-// RUN: %clang -target aarch64 -mbig-endian -mtune=cortex-a72 -### -c %s 2>&1 | FileCheck -check-prefix=CA72-BE %s
-// RUN: %clang -target aarch64_be -mbig-endian -mtune=cortex-a72 -### -c %s 2>&1 | FileCheck -check-prefix=CA72-BE %s
+// RUN: %clang -target aarch64_be -mtune=cortex-a72 -### -c %s 2>&1 | FileCheck -check-prefix=CA72-BE-TUNE %s
+// RUN: %clang -target aarch64 -mbig-endian -mtune=cortex-a72 -### -c %s 2>&1 | FileCheck -check-prefix=CA72-BE-TUNE %s
+// RUN: %clang -target aarch64_be -mbig-endian -mtune=cortex-a72 -### -c %s 2>&1 | FileCheck -check-prefix=CA72-BE-TUNE %s
// CA72-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "cortex-a72"
+// CA72-BE-TUNE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "generic"
// RUN: %clang -target aarch64_be -mcpu=cortex-a73 -### -c %s 2>&1 | FileCheck -check-prefix=CORTEX-A73-BE %s
// RUN: %clang -target aarch64 -mbig-endian -mcpu=cortex-a73 -### -c %s 2>&1 | FileCheck -check-prefix=CORTEX-A73-BE %s
// RUN: %clang -target aarch64_be -mbig-endian -mcpu=cortex-a73 -### -c %s 2>&1 | FileCheck -check-prefix=CORTEX-A73-BE %s
-// RUN: %clang -target aarch64_be -mtune=cortex-a73 -### -c %s 2>&1 | FileCheck -check-prefix=CORTEX-A73-BE %s
-// RUN: %clang -target aarch64 -mbig-endian -mtune=cortex-a73 -### -c %s 2>&1 | FileCheck -check-prefix=CORTEX-A73-BE %s
-// RUN: %clang -target aarch64_be -mbig-endian -mtune=cortex-a73 -### -c %s 2>&1 | FileCheck -check-prefix=CORTEX-A73-BE %s
+// RUN: %clang -target aarch64_be -mtune=cortex-a73 -### -c %s 2>&1 | FileCheck -check-prefix=CORTEX-A73-BE-TUNE %s
+// RUN: %clang -target aarch64 -mbig-endian -mtune=cortex-a73 -### -c %s 2>&1 | FileCheck -check-prefix=CORTEX-A73-BE-TUNE %s
+// RUN: %clang -target aarch64_be -mbig-endian -mtune=cortex-a73 -### -c %s 2>&1 | FileCheck -check-prefix=CORTEX-A73-BE-TUNE %s
// CORTEX-A73-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "cortex-a73"
+// CORTEX-A73-BE-TUNE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "generic"
// RUN: %clang -target aarch64_be -mcpu=exynos-m1 -### -c %s 2>&1 | FileCheck -check-prefix=M1-BE %s
// RUN: %clang -target aarch64 -mbig-endian -mcpu=exynos-m1 -### -c %s 2>&1 | FileCheck -check-prefix=M1-BE %s
// RUN: %clang -target aarch64_be -mbig-endian -mcpu=exynos-m1 -### -c %s 2>&1 | FileCheck -check-prefix=M1-BE %s
-// RUN: %clang -target aarch64_be -mtune=exynos-m1 -### -c %s 2>&1 | FileCheck -check-prefix=M1-BE %s
-// RUN: %clang -target aarch64 -mbig-endian -mtune=exynos-m1 -### -c %s 2>&1 | FileCheck -check-prefix=M1-BE %s
-// RUN: %clang -target aarch64_be -mbig-endian -mtune=exynos-m1 -### -c %s 2>&1 | FileCheck -check-prefix=M1-BE %s
+// RUN: %clang -target aarch64_be -mtune=exynos-m1 -### -c %s 2>&1 | FileCheck -check-prefix=M1-BE-TUNE %s
+// RUN: %clang -target aarch64 -mbig-endian -mtune=exynos-m1 -### -c %s 2>&1 | FileCheck -check-prefix=M1-BE-TUNE %s
+// RUN: %clang -target aarch64_be -mbig-endian -mtune=exynos-m1 -### -c %s 2>&1 | FileCheck -check-prefix=M1-BE-TUNE %s
// M1-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "exynos-m1"
+// M1-BE-TUNE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "generic"
// RUN: %clang -target aarch64_be -mcpu=exynos-m2 -### -c %s 2>&1 | FileCheck -check-prefix=M2-BE %s
// RUN: %clang -target aarch64 -mbig-endian -mcpu=exynos-m2 -### -c %s 2>&1 | FileCheck -check-prefix=M2-BE %s
// RUN: %clang -target aarch64_be -mbig-endian -mcpu=exynos-m2 -### -c %s 2>&1 | FileCheck -check-prefix=M2-BE %s
-// RUN: %clang -target aarch64_be -mtune=exynos-m2 -### -c %s 2>&1 | FileCheck -check-prefix=M2-BE %s
-// RUN: %clang -target aarch64 -mbig-endian -mtune=exynos-m2 -### -c %s 2>&1 | FileCheck -check-prefix=M2-BE %s
-// RUN: %clang -target aarch64_be -mbig-endian -mtune=exynos-m2 -### -c %s 2>&1 | FileCheck -check-prefix=M2-BE %s
+// RUN: %clang -target aarch64_be -mtune=exynos-m2 -### -c %s 2>&1 | FileCheck -check-prefix=M2-BE-TUNE %s
+// RUN: %clang -target aarch64 -mbig-endian -mtune=exynos-m2 -### -c %s 2>&1 | FileCheck -check-prefix=M2-BE-TUNE %s
+// RUN: %clang -target aarch64_be -mbig-endian -mtune=exynos-m2 -### -c %s 2>&1 | FileCheck -check-prefix=M2-BE-TUNE %s
// M2-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "exynos-m2"
+// M2-BE-TUNE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "generic"
// RUN: %clang -target aarch64_be -mcpu=exynos-m3 -### -c %s 2>&1 | FileCheck -check-prefix=M3-BE %s
// RUN: %clang -target aarch64 -mbig-endian -mcpu=exynos-m3 -### -c %s 2>&1 | FileCheck -check-prefix=M3-BE %s
// RUN: %clang -target aarch64_be -mbig-endian -mcpu=exynos-m3 -### -c %s 2>&1 | FileCheck -check-prefix=M3-BE %s
-// RUN: %clang -target aarch64_be -mtune=exynos-m3 -### -c %s 2>&1 | FileCheck -check-prefix=M3-BE %s
-// RUN: %clang -target aarch64 -mbig-endian -mtune=exynos-m3 -### -c %s 2>&1 | FileCheck -check-prefix=M3-BE %s
-// RUN: %clang -target aarch64_be -mbig-endian -mtune=exynos-m3 -### -c %s 2>&1 | FileCheck -check-prefix=M3-BE %s
+// RUN: %clang -target aarch64_be -mtune=exynos-m3 -### -c %s 2>&1 | FileCheck -check-prefix=M3-BE-TUNE %s
+// RUN: %clang -target aarch64 -mbig-endian -mtune=exynos-m3 -### -c %s 2>&1 | FileCheck -check-prefix=M3-BE-TUNE %s
+// RUN: %clang -target aarch64_be -mbig-endian -mtune=exynos-m3 -### -c %s 2>&1 | FileCheck -check-prefix=M3-BE-TUNE %s
// M3-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "exynos-m3"
+// M3-BE-TUNE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "generic"
// RUN: %clang -target aarch64_be -mcpu=thunderx2t99 -### -c %s 2>&1 | FileCheck -check-prefix=THUNDERX2T99-BE %s
// RUN: %clang -target aarch64 -mbig-endian -mcpu=thunderx2t99 -### -c %s 2>&1 | FileCheck -check-prefix=THUNDERX2T99-BE %s
// RUN: %clang -target aarch64_be -mbig-endian -mcpu=thunderx2t99 -### -c %s 2>&1 | FileCheck -check-prefix=THUNDERX2T99-BE %s
-// RUN: %clang -target aarch64_be -mtune=thunderx2t99 -### -c %s 2>&1 | FileCheck -check-prefix=THUNDERX2T99-BE %s
-// RUN: %clang -target aarch64 -mbig-endian -mtune=thunderx2t99 -### -c %s 2>&1 | FileCheck -check-prefix=THUNDERX2T99-BE %s
-// RUN: %clang -target aarch64_be -mbig-endian -mtune=thunderx2t99 -### -c %s 2>&1 | FileCheck -check-prefix=THUNDERX2T99-BE %s
+// RUN: %clang -target aarch64_be -mtune=thunderx2t99 -### -c %s 2>&1 | FileCheck -check-prefix=THUNDERX2T99-BE-TUNE %s
+// RUN: %clang -target aarch64 -mbig-endian -mtune=thunderx2t99 -### -c %s 2>&1 | FileCheck -check-prefix=THUNDERX2T99-BE-TUNE %s
+// RUN: %clang -target aarch64_be -mbig-endian -mtune=thunderx2t99 -### -c %s 2>&1 | FileCheck -check-prefix=THUNDERX2T99-BE-TUNE %s
// THUNDERX2T99-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "thunderx2t99"
-
-// RUN: %clang -target aarch64 -mcpu=cortex-a57 -mtune=cortex-a53 -### -c %s 2>&1 | FileCheck -check-prefix=MCPU-MTUNE %s
-// RUN: %clang -target aarch64 -mtune=cortex-a53 -mcpu=cortex-a57 -### -c %s 2>&1 | FileCheck -check-prefix=MCPU-MTUNE %s
-// RUN: %clang -target aarch64 -mcpu=cortex-a72 -mtune=cortex-a53 -### -c %s 2>&1 | FileCheck -check-prefix=MCPU-MTUNE %s
-// RUN: %clang -target aarch64 -mtune=cortex-a53 -mcpu=cortex-a72 -### -c %s 2>&1 | FileCheck -check-prefix=MCPU-MTUNE %s
-// RUN: %clang -target aarch64 -mtune=cortex-a53 -mcpu=cortex-a73 -### -c %s 2>&1 | FileCheck -check-prefix=MCPU-MTUNE %s
-// RUN: %clang -target aarch64 -mcpu=thunderx2t99 -mtune=cortex-a53 -### -c %s 2>&1 | FileCheck -check-prefix=MCPU-MTUNE %s
-// RUN: %clang -target aarch64 -mtune=cortex-a53 -mcpu=thunderx2t99 -### -c %s 2>&1 | FileCheck -check-prefix=MCPU-MTUNE %s
-// MCPU-MTUNE: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "cortex-a53"
+// THUNDERX2T99-BE-TUNE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "generic"
+
+// RUN: %clang -target aarch64 -mcpu=cortex-a57 -mtune=cortex-a53 -### -c %s 2>&1 | FileCheck -check-prefix=MCPU-MTUNE-A57 %s
+// RUN: %clang -target aarch64 -mtune=cortex-a53 -mcpu=cortex-a57 -### -c %s 2>&1 | FileCheck -check-prefix=MCPU-MTUNE-A57 %s
+// RUN: %clang -target aarch64 -mcpu=cortex-a72 -mtune=cortex-a53 -### -c %s 2>&1 | FileCheck -check-prefix=MCPU-MTUNE-A72 %s
+// RUN: %clang -target aarch64 -mtune=cortex-a53 -mcpu=cortex-a72 -### -c %s 2>&1 | FileCheck -check-prefix=MCPU-MTUNE-A72 %s
+// RUN: %clang -target aarch64 -mtune=cortex-a53 -mcpu=cortex-a73 -### -c %s 2>&1 | FileCheck -check-prefix=MCPU-MTUNE-A73 %s
+// RUN: %clang -target aarch64 -mcpu=thunderx2t99 -mtune=cortex-a53 -### -c %s 2>&1 | FileCheck -check-prefix=MCPU-MTUNE-THUNDERX2T99 %s
+// RUN: %clang -target aarch64 -mtune=cortex-a53 -mcpu=thunderx2t99 -### -c %s 2>&1 | FileCheck -check-prefix=MCPU-MTUNE-THUNDERX2T99 %s
+// MCPU-MTUNE-A57: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "cortex-a57"
+// MCPU-MTUNE-A72: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "cortex-a72"
+// MCPU-MTUNE-A73: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "cortex-a73"
+// MCPU-MTUNE-THUNDERX2T99: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "thunderx2t99"
// RUN: %clang -target aarch64 -march=armv8.1a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV81A %s
// RUN: %clang -target aarch64 -march=armv8.1-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV81A %s
@@ -307,17 +378,21 @@
// ================== Check whether -mcpu and -mtune accept mixed-case values.
// RUN: %clang -target aarch64 -mcpu=Cortex-a53 -### -c %s 2>&1 | FileCheck -check-prefix=CASE-INSENSITIVE-CA53 %s
-// RUN: %clang -target aarch64 -mtune=Cortex-a53 -### -c %s 2>&1 | FileCheck -check-prefix=CASE-INSENSITIVE-CA53 %s
+// RUN: %clang -target aarch64 -mtune=Cortex-a53 -### -c %s 2>&1 | FileCheck -check-prefix=CASE-INSENSITIVE-CA53-TUNE %s
// CASE-INSENSITIVE-CA53: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "cortex-a53"
+// CASE-INSENSITIVE-CA53-TUNE: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic"
// RUN: %clang -target arm64 -mcpu=cortex-A53 -### -c %s 2>&1 | FileCheck -check-prefix=CASE-INSENSITIVE-ARM64-CA53 %s
-// RUN: %clang -target arm64 -mtune=cortex-A53 -### -c %s 2>&1 | FileCheck -check-prefix=CASE-INSENSITIVE-ARM64-CA53 %s
+// RUN: %clang -target arm64 -mtune=cortex-A53 -### -c %s 2>&1 | FileCheck -check-prefix=CASE-INSENSITIVE-ARM64-CA53-TUNE %s
// CASE-INSENSITIVE-ARM64-CA53: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "cortex-a53"
+// CASE-INSENSITIVE-ARM64-CA53-TUNE: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "generic"
// RUN: %clang -target aarch64 -mcpu=CORTEX-A57 -### -c %s 2>&1 | FileCheck -check-prefix=CASE-INSENSITIVE-CA57 %s
-// RUN: %clang -target aarch64 -mtune=CORTEX-A57 -### -c %s 2>&1 | FileCheck -check-prefix=CASE-INSENSITIVE-CA57 %s
+// RUN: %clang -target aarch64 -mtune=CORTEX-A57 -### -c %s 2>&1 | FileCheck -check-prefix=CASE-INSENSITIVE-CA57-TUNE %s
// CASE-INSENSITIVE-CA57: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "cortex-a57"
+// CASE-INSENSITIVE-CA57-TUNE: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic"
// RUN: %clang -target arm64 -mcpu=Cortex-A57 -### -c %s 2>&1 | FileCheck -check-prefix=CASE-INSENSITIVE-ARM64-CA57 %s
-// RUN: %clang -target arm64 -mtune=Cortex-A57 -### -c %s 2>&1 | FileCheck -check-prefix=CASE-INSENSITIVE-ARM64-CA57 %s
+// RUN: %clang -target arm64 -mtune=Cortex-A57 -### -c %s 2>&1 | FileCheck -check-prefix=CASE-INSENSITIVE-ARM64-CA57-TUNE %s
// CASE-INSENSITIVE-ARM64-CA57: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "cortex-a57"
+// CASE-INSENSITIVE-ARM64-CA57-TUNE: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "generic"
diff --git a/test/Driver/aarch64-dotprod.c b/test/Driver/aarch64-dotprod.c
new file mode 100644
index 000000000000..0262cc75b77c
--- /dev/null
+++ b/test/Driver/aarch64-dotprod.c
@@ -0,0 +1,11 @@
+// RUN: %clang -### -target aarch64 %s 2>&1 | FileCheck %s --check-prefix=CHECK-NONE
+// RUN: %clang -### -target aarch64 -march=armv8.1a %s 2>&1 | FileCheck %s --check-prefix=CHECK-NONE
+// RUN: %clang -### -target aarch64 -march=armv8.2a %s 2>&1 | FileCheck %s --check-prefix=CHECK-NONE
+// RUN: %clang -### -target aarch64 -march=armv8.3a %s 2>&1 | FileCheck %s --check-prefix=CHECK-NONE
+// CHECK-NONE-NOT: "-target-feature" "+dotprod"
+
+// RUN: %clang -### -target aarch64 -march=armv8.2a+dotprod %s 2>&1 | FileCheck %s
+// RUN: %clang -### -target aarch64 -march=armv8.3a+dotprod %s 2>&1 | FileCheck %s
+// RUN: %clang -### -target aarch64 -mcpu=cortex-a75 %s 2>&1 | FileCheck %s
+// RUN: %clang -### -target aarch64 -mcpu=cortex-a55 %s 2>&1 | FileCheck %s
+// CHECK: "+dotprod"
diff --git a/test/Driver/aarch64-ras.c b/test/Driver/aarch64-ras.c
index fe038eaf159e..d4663a2f893d 100644
--- a/test/Driver/aarch64-ras.c
+++ b/test/Driver/aarch64-ras.c
@@ -1,5 +1,7 @@
// RUN: %clang -target aarch64-none-none-eabi -march=armv8a+ras -### -c %s 2>&1 | FileCheck --check-prefix=CHECK-RAS %s
// RUN: %clang -target aarch64-none-none-eabi -mcpu=generic+ras -### -c %s 2>&1 | FileCheck --check-prefix=CHECK-RAS %s
+// RUN: %clang -target aarch64-none-none-eabi -mcpu=cortex-a75 -### -c %s 2>&1 | FileCheck --check-prefix=CHECK-RAS %s
+// RUN: %clang -target aarch64-none-none-eabi -mcpu=cortex-a55 -### -c %s 2>&1 | FileCheck --check-prefix=CHECK-RAS %s
// CHECK-RAS: "-target-feature" "+ras"
// RUN: %clang -target aarch64-none-none-eabi -march=armv8a+noras -### -c %s 2>&1 | FileCheck --check-prefix=CHECK-NORAS %s
diff --git a/test/Driver/aarch64-rcpc.s b/test/Driver/aarch64-rcpc.s
new file mode 100644
index 000000000000..a3ddf69bd105
--- /dev/null
+++ b/test/Driver/aarch64-rcpc.s
@@ -0,0 +1,14 @@
+// RUN: %clang -### -target aarch64 %s 2>&1 | FileCheck --check-prefix=CHECK-NONE %s
+// RUN: %clang -### -target aarch64 -march=armv8.1a %s 2>&1 | FileCheck --check-prefix=CHECK-NONE %s
+// RUN: %clang -### -target aarch64 -march=armv8.2a %s 2>&1 | FileCheck --check-prefix=CHECK-NONE %s
+// CHECK-NONE-NOT: "-target-feature" "+rcpc"
+
+// RUN: %clang -### -target aarch64 -march=armv8.2a+rcpc %s 2>&1 | FileCheck %s
+// RUN: %clang -### -target aarch64 -march=armv8.3a+rcpc %s 2>&1 | FileCheck %s
+// RUN: %clang -### -target aarch64 -mcpu=cortex-a75 %s 2>&1 | FileCheck %s
+// RUN: %clang -### -target aarch64 -mcpu=cortex-a55 %s 2>&1 | FileCheck %s
+// CHECK: "-target-feature" "+rcpc"
+
+// RUN: %clang -### -target aarch64 -mcpu=cortex-a75+norcpc %s 2>&1 | FileCheck --check-prefix=CHECK-NO-RCPC %s
+// RUN: %clang -### -target aarch64 -mcpu=cortex-a55+norcpc %s 2>&1 | FileCheck --check-prefix=CHECK-NO-RCPC %s
+// CHECK-NO-RCPC: "-rcpc"
diff --git a/test/Driver/aarch64-rdm.c b/test/Driver/aarch64-rdm.c
new file mode 100644
index 000000000000..4f6fb24b687b
--- /dev/null
+++ b/test/Driver/aarch64-rdm.c
@@ -0,0 +1,9 @@
+// RUN: %clang -target aarch64-none-none-eabi -march=armv8a+rdm -### -c %s 2>&1 | FileCheck --check-prefix=CHECK-RDM %s
+// RUN: %clang -target aarch64-none-none-eabi -mcpu=generic+rdm -### -c %s 2>&1 | FileCheck --check-prefix=CHECK-RDM %s
+// RUN: %clang -target aarch64-none-none-eabi -mcpu=falkor -### -c %s 2>&1 | FileCheck --check-prefix=CHECK-RDM %s
+// RUN: %clang -target aarch64-none-none-eabi -mcpu=thunderx2t99 -### -c %s 2>&1 | FileCheck --check-prefix=CHECK-RDM %s
+// CHECK-RDM: "-target-feature" "+rdm"
+
+// RUN: %clang -target aarch64-none-none-eabi -march=armv8a+nordm -### -c %s 2>&1 | FileCheck --check-prefix=CHECK-NORDM %s
+// RUN: %clang -target aarch64-none-none-eabi -mcpu=generic+nordm -### -c %s 2>&1 | FileCheck --check-prefix=CHECK-NORDM %s
+// CHECK-NORDM: "-target-feature" "-rdm"
diff --git a/test/Driver/amdgpu-features.c b/test/Driver/amdgpu-features.c
index 495cadb11952..23ba72b26df5 100644
--- a/test/Driver/amdgpu-features.c
+++ b/test/Driver/amdgpu-features.c
@@ -5,3 +5,9 @@
// RUN: %clang -### -target amdgcn -x cl -S -emit-llvm -mcpu=kaveri -mamdgpu-debugger-abi=1.0 %s -o - 2>&1 \
// RUN: | FileCheck --check-prefix=CHECK-MAMDGPU-DEBUGGER-ABI-1-0 %s
// CHECK-MAMDGPU-DEBUGGER-ABI-1-0: "-target-feature" "+amdgpu-debugger-insert-nops" "-target-feature" "+amdgpu-debugger-reserve-regs" "-target-feature" "+amdgpu-debugger-emit-prologue"
+
+// RUN: %clang -### -target amdgcn -mcpu=gfx700 -mxnack %s 2>&1 | FileCheck --check-prefix=XNACK %s
+// XNACK: "-target-feature" "+xnack"
+
+// RUN: %clang -### -target amdgcn -mcpu=gfx700 -mno-xnack %s 2>&1 | FileCheck --check-prefix=NO-XNACK %s
+// NO-XNACK: "-target-feature" "-xnack"
diff --git a/test/Driver/r600-mcpu.cl b/test/Driver/amdgpu-mcpu.cl
index b99cac3bd7d8..26137ac68aef 100644
--- a/test/Driver/r600-mcpu.cl
+++ b/test/Driver/amdgpu-mcpu.cl
@@ -26,22 +26,6 @@ t// Check that -mcpu works for all supported GPUs
// RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=caicos %s -o - 2>&1 | FileCheck --check-prefix=CAICOS-CHECK %s
// RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=cayman %s -o - 2>&1 | FileCheck --check-prefix=CAYMAN-CHECK %s
// RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=aruba %s -o - 2>&1 | FileCheck --check-prefix=CAYMAN-CHECK %s
-// RUN: %clang -### -target amdgcn -x cl -S -emit-llvm -mcpu=tahiti %s -o - 2>&1 | FileCheck --check-prefix=TAHITI-CHECK %s
-// RUN: %clang -### -target amdgcn -x cl -S -emit-llvm -mcpu=pitcairn %s -o - 2>&1 | FileCheck --check-prefix=PITCAIRN-CHECK %s
-// RUN: %clang -### -target amdgcn -x cl -S -emit-llvm -mcpu=verde %s -o - 2>&1 | FileCheck --check-prefix=VERDE-CHECK %s
-// RUN: %clang -### -target amdgcn -x cl -S -emit-llvm -mcpu=oland %s -o - 2>&1 | FileCheck --check-prefix=OLAND-CHECK %s
-// RUN: %clang -### -target amdgcn -x cl -S -emit-llvm -mcpu=bonaire %s -o - 2>&1 | FileCheck --check-prefix=BONAIRE-CHECK %s
-// RUN: %clang -### -target amdgcn -x cl -S -emit-llvm -mcpu=kabini %s -o - 2>&1 | FileCheck --check-prefix=KABINI-CHECK %s
-// RUN: %clang -### -target amdgcn -x cl -S -emit-llvm -mcpu=kaveri %s -o - 2>&1 | FileCheck --check-prefix=KAVERI-CHECK %s
-// RUN: %clang -### -target amdgcn -x cl -S -emit-llvm -mcpu=hawaii %s -o - 2>&1 | FileCheck --check-prefix=HAWAII-CHECK %s
-// RUN: %clang -### -target amdgcn -x cl -S -emit-llvm -mcpu=mullins %s -o - 2>&1 | FileCheck --check-prefix=MULLINS-CHECK %s
-// RUN: %clang -### -target amdgcn -x cl -S -emit-llvm -mcpu=tonga %s -o - 2>&1 | FileCheck --check-prefix=TONGA-CHECK %s
-// RUN: %clang -### -target amdgcn -x cl -S -emit-llvm -mcpu=iceland %s -o - 2>&1 | FileCheck --check-prefix=ICELAND-CHECK %s
-// RUN: %clang -### -target amdgcn -x cl -S -emit-llvm -mcpu=carrizo %s -o - 2>&1 | FileCheck --check-prefix=CARRIZO-CHECK %s
-// RUN: %clang -### -target amdgcn -x cl -S -emit-llvm -mcpu=fiji %s -o - 2>&1 | FileCheck --check-prefix=FIJI-CHECK %s
-// RUN: %clang -### -target amdgcn -x cl -S -emit-llvm -mcpu=stoney %s -o - 2>&1 | FileCheck --check-prefix=STONEY-CHECK %s
-// RUN: %clang -### -target amdgcn -x cl -S -emit-llvm -mcpu=gfx900 %s -o - 2>&1 | FileCheck --check-prefix=GFX900-CHECK %s
-// RUN: %clang -### -target amdgcn -x cl -S -emit-llvm -mcpu=gfx901 %s -o - 2>&1 | FileCheck --check-prefix=GFX901-CHECK %s
// R600-CHECK: "-target-cpu" "r600"
// RS880-CHECK: "-target-cpu" "rs880"
@@ -58,19 +42,71 @@ t// Check that -mcpu works for all supported GPUs
// TURKS-CHECK: "-target-cpu" "turks"
// CAICOS-CHECK: "-target-cpu" "caicos"
// CAYMAN-CHECK: "-target-cpu" "cayman"
+
+// RUN: %clang -### -target amdgcn -x cl -S -emit-llvm -mcpu=gfx600 %s -o - 2>&1 | FileCheck --check-prefix=GFX600-CHECK %s
+// RUN: %clang -### -target amdgcn -x cl -S -emit-llvm -mcpu=tahiti %s -o - 2>&1 | FileCheck --check-prefix=TAHITI-CHECK %s
+// RUN: %clang -### -target amdgcn -x cl -S -emit-llvm -mcpu=gfx601 %s -o - 2>&1 | FileCheck --check-prefix=GFX601-CHECK %s
+// RUN: %clang -### -target amdgcn -x cl -S -emit-llvm -mcpu=pitcairn %s -o - 2>&1 | FileCheck --check-prefix=PITCAIRN-CHECK %s
+// RUN: %clang -### -target amdgcn -x cl -S -emit-llvm -mcpu=verde %s -o - 2>&1 | FileCheck --check-prefix=VERDE-CHECK %s
+// RUN: %clang -### -target amdgcn -x cl -S -emit-llvm -mcpu=oland %s -o - 2>&1 | FileCheck --check-prefix=OLAND-CHECK %s
+// RUN: %clang -### -target amdgcn -x cl -S -emit-llvm -mcpu=hainan %s -o - 2>&1 | FileCheck --check-prefix=HAINAN-CHECK %s
+// RUN: %clang -### -target amdgcn -x cl -S -emit-llvm -mcpu=gfx700 %s -o - 2>&1 | FileCheck --check-prefix=GFX700-CHECK %s
+// RUN: %clang -### -target amdgcn -x cl -S -emit-llvm -mcpu=bonaire %s -o - 2>&1 | FileCheck --check-prefix=BONAIRE-CHECK %s
+// RUN: %clang -### -target amdgcn -x cl -S -emit-llvm -mcpu=kaveri %s -o - 2>&1 | FileCheck --check-prefix=KAVERI-CHECK %s
+// RUN: %clang -### -target amdgcn -x cl -S -emit-llvm -mcpu=gfx701 %s -o - 2>&1 | FileCheck --check-prefix=GFX701-CHECK %s
+// RUN: %clang -### -target amdgcn -x cl -S -emit-llvm -mcpu=hawaii %s -o - 2>&1 | FileCheck --check-prefix=HAWAII-CHECK %s
+// RUN: %clang -### -target amdgcn -x cl -S -emit-llvm -mcpu=gfx702 %s -o - 2>&1 | FileCheck --check-prefix=GFX702-CHECK %s
+// RUN: %clang -### -target amdgcn -x cl -S -emit-llvm -mcpu=gfx703 %s -o - 2>&1 | FileCheck --check-prefix=GFX703-CHECK %s
+// RUN: %clang -### -target amdgcn -x cl -S -emit-llvm -mcpu=kabini %s -o - 2>&1 | FileCheck --check-prefix=KABINI-CHECK %s
+// RUN: %clang -### -target amdgcn -x cl -S -emit-llvm -mcpu=mullins %s -o - 2>&1 | FileCheck --check-prefix=MULLINS-CHECK %s
+// RUN: %clang -### -target amdgcn -x cl -S -emit-llvm -mcpu=gfx800 %s -o - 2>&1 | FileCheck --check-prefix=GFX800-CHECK %s
+// RUN: %clang -### -target amdgcn -x cl -S -emit-llvm -mcpu=iceland %s -o - 2>&1 | FileCheck --check-prefix=ICELAND-CHECK %s
+// RUN: %clang -### -target amdgcn -x cl -S -emit-llvm -mcpu=gfx801 %s -o - 2>&1 | FileCheck --check-prefix=GFX801-CHECK %s
+// RUN: %clang -### -target amdgcn -x cl -S -emit-llvm -mcpu=carrizo %s -o - 2>&1 | FileCheck --check-prefix=CARRIZO-CHECK %s
+// RUN: %clang -### -target amdgcn -x cl -S -emit-llvm -mcpu=gfx802 %s -o - 2>&1 | FileCheck --check-prefix=GFX802-CHECK %s
+// RUN: %clang -### -target amdgcn -x cl -S -emit-llvm -mcpu=tonga %s -o - 2>&1 | FileCheck --check-prefix=TONGA-CHECK %s
+// RUN: %clang -### -target amdgcn -x cl -S -emit-llvm -mcpu=gfx803 %s -o - 2>&1 | FileCheck --check-prefix=GFX803-CHECK %s
+// RUN: %clang -### -target amdgcn -x cl -S -emit-llvm -mcpu=fiji %s -o - 2>&1 | FileCheck --check-prefix=FIJI-CHECK %s
+// RUN: %clang -### -target amdgcn -x cl -S -emit-llvm -mcpu=polaris10 %s -o - 2>&1 | FileCheck --check-prefix=POLARIS10-CHECK %s
+// RUN: %clang -### -target amdgcn -x cl -S -emit-llvm -mcpu=polaris11 %s -o - 2>&1 | FileCheck --check-prefix=POLARIS11-CHECK %s
+// RUN: %clang -### -target amdgcn -x cl -S -emit-llvm -mcpu=gfx804 %s -o - 2>&1 | FileCheck --check-prefix=GFX804-CHECK %s
+// RUN: %clang -### -target amdgcn -x cl -S -emit-llvm -mcpu=gfx810 %s -o - 2>&1 | FileCheck --check-prefix=GFX810-CHECK %s
+// RUN: %clang -### -target amdgcn -x cl -S -emit-llvm -mcpu=stoney %s -o - 2>&1 | FileCheck --check-prefix=STONEY-CHECK %s
+// RUN: %clang -### -target amdgcn -x cl -S -emit-llvm -mcpu=gfx900 %s -o - 2>&1 | FileCheck --check-prefix=GFX900-CHECK %s
+// RUN: %clang -### -target amdgcn -x cl -S -emit-llvm -mcpu=gfx901 %s -o - 2>&1 | FileCheck --check-prefix=GFX901-CHECK %s
+// RUN: %clang -### -target amdgcn -x cl -S -emit-llvm -mcpu=gfx902 %s -o - 2>&1 | FileCheck --check-prefix=GFX902-CHECK %s
+// RUN: %clang -### -target amdgcn -x cl -S -emit-llvm -mcpu=gfx903 %s -o - 2>&1 | FileCheck --check-prefix=GFX903-CHECK %s
+
+// GFX600-CHECK: "-target-cpu" "gfx600"
// TAHITI-CHECK: "-target-cpu" "tahiti"
+// GFX601-CHECK: "-target-cpu" "gfx601"
// PITCAIRN-CHECK: "-target-cpu" "pitcairn"
// VERDE-CHECK: "-target-cpu" "verde"
// OLAND-CHECK: "-target-cpu" "oland"
+// HAINAN-CHECK: "-target-cpu" "hainan"
+// GFX700-CHECK: "-target-cpu" "gfx700"
// BONAIRE-CHECK: "-target-cpu" "bonaire"
-// KABINI-CHECK: "-target-cpu" "kabini"
// KAVERI-CHECK: "-target-cpu" "kaveri"
+// GFX701-CHECK: "-target-cpu" "gfx701"
// HAWAII-CHECK: "-target-cpu" "hawaii"
+// GFX702-CHECK: "-target-cpu" "gfx702"
+// GFX703-CHECK: "-target-cpu" "gfx703"
+// KABINI-CHECK: "-target-cpu" "kabini"
// MULLINS-CHECK: "-target-cpu" "mullins"
-// TONGA-CHECK: "-target-cpu" "tonga"
+// GFX800-CHECK: "-target-cpu" "gfx800"
// ICELAND-CHECK: "-target-cpu" "iceland"
+// GFX801-CHECK: "-target-cpu" "gfx801"
// CARRIZO-CHECK: "-target-cpu" "carrizo"
+// GFX802-CHECK: "-target-cpu" "gfx802"
+// TONGA-CHECK: "-target-cpu" "tonga"
+// GFX803-CHECK: "-target-cpu" "gfx803"
// FIJI-CHECK: "-target-cpu" "fiji"
+// POLARIS10-CHECK: "-target-cpu" "polaris10"
+// POLARIS11-CHECK: "-target-cpu" "polaris11"
+// GFX804-CHECK: "-target-cpu" "gfx804"
+// GFX810-CHECK: "-target-cpu" "gfx810"
// STONEY-CHECK: "-target-cpu" "stoney"
// GFX900-CHECK: "-target-cpu" "gfx900"
// GFX901-CHECK: "-target-cpu" "gfx901"
+// GFX902-CHECK: "-target-cpu" "gfx902"
+// GFX903-CHECK: "-target-cpu" "gfx903"
diff --git a/test/Driver/amdgpu-toolchain-opencl.cl b/test/Driver/amdgpu-toolchain-opencl.cl
new file mode 100644
index 000000000000..3994387f3ead
--- /dev/null
+++ b/test/Driver/amdgpu-toolchain-opencl.cl
@@ -0,0 +1,19 @@
+// RUN: %clang -### -target amdgcn-amd-amdhsa-opencl -x cl -c -emit-llvm -mcpu=fiji -O0 %s 2>&1 | FileCheck -check-prefix=CHECK_O0 %s
+// RUN: %clang -### -target amdgcn-amd-amdhsa-opencl -x cl -c -emit-llvm -mcpu=fiji -O1 %s 2>&1 | FileCheck -check-prefix=CHECK_O1 %s
+// RUN: %clang -### -target amdgcn-amd-amdhsa-opencl -x cl -c -emit-llvm -mcpu=fiji -O2 %s 2>&1 | FileCheck -check-prefix=CHECK_O2 %s
+// RUN: %clang -### -target amdgcn-amd-amdhsa-opencl -x cl -c -emit-llvm -mcpu=fiji -O3 %s 2>&1 | FileCheck -check-prefix=CHECK_O3 %s
+// RUN: %clang -### -target amdgcn-amd-amdhsa-opencl -x cl -c -emit-llvm -mcpu=fiji -O4 %s 2>&1 | FileCheck -check-prefix=CHECK_O4 %s
+// RUN: %clang -### -target amdgcn-amd-amdhsa-opencl -x cl -c -emit-llvm -mcpu=fiji -O5 %s 2>&1 | FileCheck -check-prefix=CHECK_O5 %s
+// RUN: %clang -### -target amdgcn-amd-amdhsa-opencl -x cl -c -emit-llvm -mcpu=fiji -Og %s 2>&1 | FileCheck -check-prefix=CHECK_Og %s
+// RUN: %clang -### -target amdgcn-amd-amdhsa-opencl -x cl -c -emit-llvm -mcpu=fiji -Ofast %s 2>&1 | FileCheck -check-prefix=CHECK_Ofast %s
+// RUN: %clang -### -target amdgcn-amd-amdhsa-opencl -x cl -c -emit-llvm -mcpu=fiji %s 2>&1 | FileCheck -check-prefix=CHECK_O_DEFAULT %s
+// CHECK_O0: clang{{.*}} "-O0"
+// CHECK_O1: clang{{.*}} "-O1"
+// CHECK_O2: clang{{.*}} "-O2"
+// CHECK_O3: clang{{.*}} "-O3"
+// CHECK_O4: clang{{.*}} "-O3"
+// CHECK_O5: clang{{.*}} "-O5"
+// CHECK_Og: clang{{.*}} "-Og"
+// CHECK_Ofast: {{.*}}clang{{.*}} "-Ofast"
+// CHECK_O_DEFAULT: clang{{.*}} "-O3"
+
diff --git a/test/Driver/android-pie.c b/test/Driver/android-pie.c
new file mode 100644
index 000000000000..2569c55d5888
--- /dev/null
+++ b/test/Driver/android-pie.c
@@ -0,0 +1,66 @@
+// NO-PIE-NOT: "-pie"
+// PIE: "-pie"
+
+// RUN: %clang %s -### -o %t.o 2>&1 --target=arm-linux-androideabi \
+// RUN: | FileCheck --check-prefix=NO-PIE %s
+// RUN: %clang %s -### -o %t.o 2>&1 --target=arm-linux-android \
+// RUN: | FileCheck --check-prefix=NO-PIE %s
+// RUN: %clang %s -### -o %t.o 2>&1 --target=arm-linux-android14 \
+// RUN: | FileCheck --check-prefix=NO-PIE %s
+// RUN: %clang %s -### -o %t.o 2>&1 --target=arm-linux-android16 \
+// RUN: | FileCheck --check-prefix=PIE %s
+// RUN: %clang %s -### -o %t.o 2>&1 --target=arm-linux-android24 \
+// RUN: | FileCheck --check-prefix=PIE %s
+
+// RUN: %clang %s -### -o %t.o 2>&1 --target=mipsel-linux-android \
+// RUN: | FileCheck --check-prefix=NO-PIE %s
+// RUN: %clang %s -### -o %t.o 2>&1 --target=mipsel-linux-android14 \
+// RUN: | FileCheck --check-prefix=NO-PIE %s
+// RUN: %clang %s -### -o %t.o 2>&1 --target=mipsel-linux-android16 \
+// RUN: | FileCheck --check-prefix=PIE %s
+// RUN: %clang %s -### -o %t.o 2>&1 --target=mipsel-linux-android24 \
+// RUN: | FileCheck --check-prefix=PIE %s
+
+// RUN: %clang %s -### -o %t.o 2>&1 --target=i686-linux-android \
+// RUN: | FileCheck --check-prefix=NO-PIE %s
+// RUN: %clang %s -### -o %t.o 2>&1 --target=i686-linux-android14 \
+// RUN: | FileCheck --check-prefix=NO-PIE %s
+// RUN: %clang %s -### -o %t.o 2>&1 --target=i686-linux-android16 \
+// RUN: | FileCheck --check-prefix=PIE %s
+// RUN: %clang %s -### -o %t.o 2>&1 --target=i686-linux-android24 \
+// RUN: | FileCheck --check-prefix=PIE %s
+
+// RUN: %clang %s -### -o %t.o 2>&1 --target=aarch64-linux-android \
+// RUN: | FileCheck --check-prefix=PIE %s
+// RUN: %clang %s -### -o %t.o 2>&1 --target=aarch64-linux-android24 \
+// RUN: | FileCheck --check-prefix=PIE %s
+
+// RUN: %clang %s -### -o %t.o 2>&1 --target=arm64-linux-android \
+// RUN: | FileCheck --check-prefix=PIE %s
+// RUN: %clang %s -### -o %t.o 2>&1 --target=arm64-linux-android24 \
+// RUN: | FileCheck --check-prefix=PIE %s
+
+// RUN: %clang %s -### -o %t.o 2>&1 --target=mips64el-linux-android \
+// RUN: | FileCheck --check-prefix=PIE %s
+// RUN: %clang %s -### -o %t.o 2>&1 --target=mips64el-linux-android24 \
+// RUN: | FileCheck --check-prefix=PIE %s
+
+// RUN: %clang %s -### -o %t.o 2>&1 --target=x86_64-linux-android \
+// RUN: | FileCheck --check-prefix=PIE %s
+// RUN: %clang %s -### -o %t.o 2>&1 --target=x86_64-linux-android24 \
+// RUN: | FileCheck --check-prefix=PIE %s
+
+// Override toolchain default setting.
+// RUN: %clang %s -### -o %t.o 2>&1 -pie --target=arm-linux-androideabi \
+// RUN: | FileCheck --check-prefix=PIE %s
+// RUN: %clang %s -### -o %t.o 2>&1 -pie --target=arm-linux-androideabi14 \
+// RUN: | FileCheck --check-prefix=PIE %s
+// RUN: %clang %s -### -o %t.o 2>&1 -no-pie -pie --target=arm-linux-androideabi24 \
+// RUN: | FileCheck --check-prefix=PIE %s
+
+// RUN: %clang %s -### -o %t.o 2>&1 -no-pie --target=arm-linux-androideabi24 \
+// RUN: | FileCheck --check-prefix=NO-PIE %s
+// RUN: %clang %s -### -o %t.o 2>&1 -nopie --target=arm-linux-androideabi24 \
+// RUN: | FileCheck --check-prefix=NO-PIE %s
+// RUN: %clang %s -### -o %t.o 2>&1 -pie -no-pie --target=arm-linux-androideabi24 \
+// RUN: | FileCheck --check-prefix=NO-PIE %s
diff --git a/test/Driver/arm-cortex-cpus.c b/test/Driver/arm-cortex-cpus.c
index 80912678e029..8f8178226d55 100644
--- a/test/Driver/arm-cortex-cpus.c
+++ b/test/Driver/arm-cortex-cpus.c
@@ -507,6 +507,12 @@
// RUN: %clang -target arm -mcpu=exynos-m3 -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV8A %s
// CHECK-CPUV8A: "-cc1"{{.*}} "-triple" "armv8-{{.*}}
+// RUN: %clang -target arm -mcpu=cortex-a55 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV82A %s
+// RUN: %clang -target arm -mcpu=cortex-a75 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV82A %s
+// RUN: %clang -target arm -mcpu=cortex-a55 -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV82A %s
+// RUN: %clang -target arm -mcpu=cortex-a75 -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV82A %s
+// CHECK-CPUV82A: "-cc1"{{.*}} "-triple" "armv8.2a-{{.*}}
+
// RUN: %clang -target armeb -mcpu=cortex-a32 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV8A %s
// RUN: %clang -target armeb -mcpu=cortex-a35 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV8A %s
// RUN: %clang -target armeb -mcpu=cortex-a53 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV8A %s
@@ -527,6 +533,12 @@
// RUN: %clang -target arm -mcpu=exynos-m3 -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV8A %s
// CHECK-BE-CPUV8A: "-cc1"{{.*}} "-triple" "armebv8-{{.*}}
+// RUN: %clang -target armeb -mcpu=cortex-a55 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV82A %s
+// RUN: %clang -target armeb -mcpu=cortex-a75 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV82A %s
+// RUN: %clang -target arm -mcpu=cortex-a55 -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV82A %s
+// RUN: %clang -target arm -mcpu=cortex-a75 -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV82A %s
+// CHECK-BE-CPUV82A: "-cc1"{{.*}} "-triple" "armebv8.2a-{{.*}}
+
// RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-r52 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV8R %s
// CHECK-CPUV8R: "-cc1"{{.*}} "-triple" "armv8r-{{.*}}
@@ -550,6 +562,12 @@
// RUN: %clang -target arm -mcpu=exynos-m3 -mlittle-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV8A-THUMB %s
// CHECK-CPUV8A-THUMB: "-cc1"{{.*}} "-triple" "thumbv8-{{.*}}
+// RUN: %clang -target arm -mcpu=cortex-a55 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECKCPUV82A-THUMB %s
+// RUN: %clang -target arm -mcpu=cortex-a75 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECKCPUV82A-THUMB %s
+// RUN: %clang -target arm -mcpu=cortex-a55 -mlittle-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECKCPUV82A-THUMB %s
+// RUN: %clang -target arm -mcpu=cortex-a75 -mlittle-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECKCPUV82A-THUMB %s
+// CHECKCPUV82A-THUMB: "-cc1"{{.*}} "-triple" "thumbv8.2a-{{.*}}
+
// RUN: %clang -target armeb -mcpu=cortex-a32 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV8A-THUMB %s
// RUN: %clang -target armeb -mcpu=cortex-a35 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV8A-THUMB %s
// RUN: %clang -target armeb -mcpu=cortex-a53 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV8A-THUMB %s
@@ -570,6 +588,12 @@
// RUN: %clang -target arm -mcpu=exynos-m3 -mbig-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV8A-THUMB %s
// CHECK-BE-CPUV8A-THUMB: "-cc1"{{.*}} "-triple" "thumbebv8-{{.*}}
+// RUN: %clang -target armeb -mcpu=cortex-a55 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV82A-THUMB %s
+// RUN: %clang -target armeb -mcpu=cortex-a75 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV82A-THUMB %s
+// RUN: %clang -target arm -mcpu=cortex-a55 -mbig-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV82A-THUMB %s
+// RUN: %clang -target arm -mcpu=cortex-a75 -mbig-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV82A-THUMB %s
+// CHECK-BE-CPUV82A-THUMB: "-cc1"{{.*}} "-triple" "thumbebv8.2a-{{.*}}
+
// RUN: %clang -target armv8a-arm-none-eabi -mcpu=cortex-a73 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CORTEX-A73 %s
// RUN: %clang -target armv8a-arm-none-eabi -mcpu=cortex-a73 -mfpu=crypto-neon-fp-armv8 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CORTEX-A73-MFPU %s
// RUN: %clang -target armv8a-arm-none-eabi -mcpu=cortex-a73 -mfloat-abi=soft -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CORTEX-A73-SOFT %s
@@ -579,6 +603,15 @@
// CHECK-CORTEX-A73-SOFT: "-target-feature" "+soft-float"
// CHECK-CORTEX-A73-SOFT: "-target-feature" "+soft-float-abi"
+// RUN: %clang -target armv8a-arm-none-eabi -mcpu=cortex-a75 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CORTEX-A75 %s
+// RUN: %clang -target armv8a-arm-none-eabi -mcpu=cortex-a75 -mfpu=crypto-neon-fp-armv8 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CORTEX-A75-MFPU %s
+// RUN: %clang -target armv8a-arm-none-eabi -mcpu=cortex-a75 -mfloat-abi=soft -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CORTEX-A75-SOFT %s
+// CHECK-CORTEX-A75: "-cc1"{{.*}} "-triple" "armv8.2a-{{.*}} "-target-cpu" "cortex-a75"
+// CHECK-CORTEX-A75-MFPU: "-cc1"{{.*}} "-target-feature" "+fp-armv8"
+// CHECK-CORTEX-A75-MFPU: "-target-feature" "+crypto"
+// CHECK-CORTEX-A75-SOFT: "-target-feature" "+soft-float"
+// CHECK-CORTEX-A75-SOFT: "-target-feature" "+soft-float-abi"
+
// RUN: %clang -target arm -mcpu=cortex-m23 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV8MBASE %s
// CHECK-CPUV8MBASE: "-cc1"{{.*}} "-triple" "thumbv8m.base-
diff --git a/test/Driver/arm-dotprod.c b/test/Driver/arm-dotprod.c
new file mode 100644
index 000000000000..a895d30deefc
--- /dev/null
+++ b/test/Driver/arm-dotprod.c
@@ -0,0 +1,11 @@
+// RUN: %clang -### -target arm %s 2>&1 | FileCheck %s --check-prefix=CHECK-NONE
+// RUN: %clang -### -target arm -march=armv8.1a %s 2>&1 | FileCheck %s --check-prefix=CHECK-NONE
+// RUN: %clang -### -target arm -march=armv8.2a %s 2>&1 | FileCheck %s --check-prefix=CHECK-NONE
+// RUN: %clang -### -target arm -march=armv8.3a %s 2>&1 | FileCheck %s --check-prefix=CHECK-NONE
+// CHECK-NONE-NOT: "-target-feature" "+dotprod"
+
+// RUN: %clang -### -target arm -march=armv8.2a+dotprod %s 2>&1 | FileCheck %s
+// RUN: %clang -### -target arm -march=armv8.3a+dotprod %s 2>&1 | FileCheck %s
+// RUN: %clang -### -target arm -mcpu=cortex-a75 %s 2>&1 | FileCheck %s
+// RUN: %clang -### -target arm -mcpu=cortex-a55 %s 2>&1 | FileCheck %s
+// CHECK: "+dotprod"
diff --git a/test/Driver/arm-ras.c b/test/Driver/arm-ras.c
index 6d2168c160bf..076bb4b5e08f 100644
--- a/test/Driver/arm-ras.c
+++ b/test/Driver/arm-ras.c
@@ -1,5 +1,7 @@
// RUN: %clang -target arm-none-none-eabi -march=armv8a+ras -### -c %s 2>&1 | FileCheck --check-prefix=CHECK-RAS %s
// RUN: %clang -target arm-none-none-eabi -mcpu=generic+ras -### -c %s 2>&1 | FileCheck --check-prefix=CHECK-RAS %s
+// RUN: %clang -target arm-none-none-eabi -mcpu=cortex-a75 -### -c %s 2>&1 | FileCheck --check-prefix=CHECK-RAS %s
+// RUN: %clang -target arm-none-none-eabi -mcpu=cortex-a55 -### -c %s 2>&1 | FileCheck --check-prefix=CHECK-RAS %s
// CHECK-RAS: "-target-feature" "+ras"
// RUN: %clang -target arm-none-none-eabi -march=armv8a+noras -### -c %s 2>&1 | FileCheck --check-prefix=CHECK-NORAS %s
diff --git a/test/Driver/arm-target-as-mthumb.s b/test/Driver/arm-target-as-mthumb.s
new file mode 100644
index 000000000000..c2c0fd0a653c
--- /dev/null
+++ b/test/Driver/arm-target-as-mthumb.s
@@ -0,0 +1,17 @@
+// Make sure -mthumb does not affect assembler triple, but -Wa,-mthumb or
+// -Xassembler -mthumb does. Also check that -Wa,-mthumb or -Xassembler -mthumb
+// does not affect non assembler files.
+
+// RUN: %clang -target armv7a-linux-gnueabi -### -c -mthumb %s 2>&1 | \
+// RUN: FileCheck -check-prefix=TRIPLE-ARM %s
+// RUN: %clang -target armv7a-linux-gnueabi -### -c -Wa,-mthumb \
+// RUN: %S/Inputs/wildcard1.c 2>&1 | FileCheck -check-prefix=TRIPLE-ARM %s
+
+// TRIPLE-ARM: "-triple" "armv7--linux-gnueabi"
+
+// RUN: %clang -target armv7a-linux-gnueabi -### -c -Wa,-mthumb %s 2>&1 | \
+// RUN: FileCheck -check-prefix=TRIPLE-THUMB %s
+// RUN: %clang -target armv7a-linux-gnueabi -### -c -Xassembler -mthumb %s \
+// RUN: 2>&1 | FileCheck -check-prefix=TRIPLE-THUMB %s
+
+// TRIPLE-THUMB: "-triple" "thumbv7--linux-gnueabi"
diff --git a/test/Driver/arm-thumb-only-cores.c b/test/Driver/arm-thumb-only-cores.c
new file mode 100644
index 000000000000..cf40bf0ffa4a
--- /dev/null
+++ b/test/Driver/arm-thumb-only-cores.c
@@ -0,0 +1,12 @@
+// RUN: not %clang -target arm-unknown-linux -marm -mcpu=cortex-m0 %s -o /dev/null 2>&1 \
+// RUN: | FileCheck --check-prefix M0 %s
+// M0: error: CPU 'cortex-m0' does not support 'ARM' execution mode
+
+// RUN: not %clang -target arm-unknown-linux -marm -march=armv7m %s -o /dev/null 2>&1 \
+// RUN: | FileCheck --check-prefix ARMV7M %s
+// RUN: not %clang -target armv7m-unknown-linux -mno-thumb %s -o /dev/null 2>&1 \
+// RUN: | FileCheck --check-prefix ARMV7M %s
+// ARMV7M: error: Architecture 'armv7m' does not support 'ARM' execution mode
+//
+// RUN: %clang -S -emit-llvm -target arm-unknown-linux -mcpu=cortex-m0 %s -o /dev/null 2>&1
+// M-Profile CPUs default to Thumb mode even if arm triples are provided.
diff --git a/test/Driver/arm-wchar_t-defaults.c b/test/Driver/arm-wchar_t-defaults.c
new file mode 100644
index 000000000000..8b2ae29d0019
--- /dev/null
+++ b/test/Driver/arm-wchar_t-defaults.c
@@ -0,0 +1,53 @@
+// RUN: %clang -### -target armv7-unknown-none-eabi -c %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-SHORT %s
+// RUN: %clang -### -target armv7-unknown-none-eabi -fno-short-wchar -c %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-LONG-UNSIGNED %s
+// RUN: %clang -### -target armv7-unknown-none-eabi -mthumb -c %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-SHORT %s
+// RUN: %clang -### -target armv7-unknown-none-eabi -mthumb -fno-short-wchar -c %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-LONG-UNSIGNED %s
+// RUN: %clang -### -target armv7eb-unknown-none-eabi -c %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-SHORT %s
+// RUN: %clang -### -target armv7eb-unknown-none-eabi -fno-short-wchar -c %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-LONG-UNSIGNED %s
+// RUN: %clang -### -target armv7eb-unknown-none-eabi -mthumb -c %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-SHORT %s
+// RUN: %clang -### -target armv7eb-unknown-none-eabi -mthumb -fno-short-wchar -c %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-LONG-UNSIGNED %s
+// RUN: %clang -### -target aarch64-unknown-none-eabi -c %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-SHORT %s
+// RUN: %clang -### -target aarch64-unknown-none-eabi -fno-short-wchar -c %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-LONG-UNSIGNED %s
+// RUN: %clang -### -target aarch64_be-unknown-none-eabi -c %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-SHORT %s
+// RUN: %clang -### -target aarch64_be-unknown-none-eabi -fno-short-wchar -c %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-LONG-UNSIGNED %s
+
+// RUN: %clang -### -target armv7-unknown-netbsd -c %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-SHORT %s
+// RUN: %clang -### -target armv7-unknown-netbsd -fno-short-wchar -c %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-LONG-SIGNED %s
+// RUN: %clang -### -target armv7-unknown-netbsd -mthumb -c %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-SHORT %s
+// RUN: %clang -### -target armv7-unknown-netbsd -mthumb -fno-short-wchar -c %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-LONG-SIGNED %s
+// RUN: %clang -### -target armv7eb-unknown-netbsd -c %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-SHORT %s
+// RUN: %clang -### -target armv7eb-unknown-netbsd -fno-short-wchar -c %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-LONG-SIGNED %s
+// RUN: %clang -### -target armv7eb-unknown-netbsd -mthumb -c %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-SHORT %s
+// RUN: %clang -### -target armv7eb-unknown-netbsd -mthumb -fno-short-wchar -c %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-LONG-SIGNED %s
+// RUN: %clang -### -target aarch64-unknown-netbsd -c %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-SHORT %s
+// RUN: %clang -### -target aarch64-unknown-netbsd -fno-short-wchar -c %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-LONG-SIGNED %s
+// RUN: %clang -### -target aarch64_be-unknown-netbsd -c %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-SHORT %s
+// RUN: %clang -### -target aarch64_be-unknown-netbsd -fno-short-wchar -c %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-LONG-SIGNED %s
+
+// RUN: %clang -### -target armv7-unknown-openbsd -c %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-SHORT %s
+// RUN: %clang -### -target armv7-unknown-openbsd -fno-short-wchar -c %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-LONG-SIGNED %s
+// RUN: %clang -### -target armv7-unknown-openbsd -mthumb -c %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-SHORT %s
+// RUN: %clang -### -target armv7-unknown-openbsd -mthumb -fno-short-wchar -c %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-LONG-SIGNED %s
+// RUN: %clang -### -target armv7eb-unknown-openbsd -c %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-SHORT %s
+// RUN: %clang -### -target armv7eb-unknown-openbsd -fno-short-wchar -c %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-LONG-SIGNED %s
+// RUN: %clang -### -target armv7eb-unknown-openbsd -mthumb -c %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-SHORT %s
+// RUN: %clang -### -target armv7eb-unknown-openbsd -mthumb -fno-short-wchar -c %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-LONG-SIGNED %s
+// RUN: %clang -### -target aarch64-unknown-openbsd -c %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-SHORT %s
+// RUN: %clang -### -target aarch64-unknown-openbsd -fno-short-wchar -c %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-LONG-SIGNED %s
+// RUN: %clang -### -target aarch64_be-unknown-openbsd -c %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-SHORT %s
+// RUN: %clang -### -target aarch64_be-unknown-openbsd -fno-short-wchar -c %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-LONG-SIGNED %s
+
+// RUN: %clang -### -target armv7-unknown-windows-msvc -c %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-SHORT %s
+// RUN: %clang -### -target armv7-unknown-windows-msvc -fno-short-wchar -c %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-LONG-SIGNED %s
+// RUN: %clang -### -target aarch64-unknown-windows-msvc -c %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-SHORT %s
+// RUN: %clang -### -target aarch64-unknown-windows-msvc -fno-short-wchar -c %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-LONG-SIGNED %s
+
+// CHECK-SHORT-NOT: "-fwchar-type=int"
+// CHECK-SHORT-NOT: "-fno-signed-wchar"
+
+// CHECK-LONG-UNSIGNED: "-fwchar-type=int"
+// CHECK-LONG-UNSIGNED: "-fno-signed-wchar"
+
+// CHECK-LONG-SIGNED: "-fwchar-type=int"
+// CHECK-LONG-SIGNED: "-fsigned-wchar"
+
diff --git a/test/Driver/as-mcpu.c b/test/Driver/as-mcpu.c
new file mode 100644
index 000000000000..23528b1a64c8
--- /dev/null
+++ b/test/Driver/as-mcpu.c
@@ -0,0 +1,11 @@
+// ================== Check that krait is substituted by cortex-a15 when invoking
+// the assembler
+// RUN: %clang -target arm-linux -mcpu=krait -### -c %s -v -fno-integrated-as 2>&1 | FileCheck -check-prefix=CHECK-CORTEX-A15 %s
+// CHECK-CORTEX-A15: as{{(.exe)?}}" "{{.*}}-mcpu=cortex-a15
+
+// ================== Check that kryo is substituted by cortex-a57 when invoking
+// the assembler
+// RUN: %clang -target arm-linux -mcpu=kryo -### -c %s -v -fno-integrated-as 2>&1 | FileCheck -check-prefix=CHECK-CORTEX-A57 %s
+// RUN: %clang -target aarch64-linux -mcpu=kryo -### -c %s -v -fno-integrated-as 2>&1 | FileCheck -check-prefix=CHECK-CORTEX-A57 %s
+
+// CHECK-CORTEX-A57: as{{(.exe)?}}" "{{.*}}-mcpu=cortex-a57
diff --git a/test/Driver/asan.c b/test/Driver/asan.c
index 4db103d26462..288666d1ca7b 100644
--- a/test/Driver/asan.c
+++ b/test/Driver/asan.c
@@ -6,8 +6,13 @@
// RUN: %clang -O1 -target i386-unknown-linux -fsanitize=kernel-address %s -S -emit-llvm -o - | FileCheck %s --check-prefix=CHECK-KASAN
// RUN: %clang -O2 -target i386-unknown-linux -fsanitize=kernel-address %s -S -emit-llvm -o - | FileCheck %s --check-prefix=CHECK-KASAN
// RUN: %clang -O3 -target i386-unknown-linux -fsanitize=kernel-address %s -S -emit-llvm -o - | FileCheck %s --check-prefix=CHECK-KASAN
+// RUN: %clang -target aarch64-unknown-linux -fsanitize=hwaddress %s -S -emit-llvm -o - | FileCheck %s --check-prefix=CHECK-HWASAN
+// RUN: %clang -O1 -target aarch64-unknown-linux -fsanitize=hwaddress %s -S -emit-llvm -o - | FileCheck %s --check-prefix=CHECK-HWASAN
+// RUN: %clang -O2 -target aarch64-unknown-linux -fsanitize=hwaddress %s -S -emit-llvm -o - | FileCheck %s --check-prefix=CHECK-HWASAN
+// RUN: %clang -O3 -target aarch64-unknown-linux -fsanitize=hwaddress %s -S -emit-llvm -o - | FileCheck %s --check-prefix=CHECK-HWASAN
// Verify that -fsanitize={address,kernel-address} invoke ASan and KASan instrumentation.
int foo(int *a) { return *a; }
// CHECK-ASAN: __asan_init
// CHECK-KASAN: __asan_load4_noabort
+// CHECK-HWASAN: __hwasan_init
diff --git a/test/Driver/autocomplete.c b/test/Driver/autocomplete.c
index c4d80f29f7bc..8b6d6cfc89c2 100644
--- a/test/Driver/autocomplete.c
+++ b/test/Driver/autocomplete.c
@@ -1,3 +1,20 @@
+// Test for the --autocompletion flag, which is an API used for shell
+// autocompletion. You may have to update tests in this file when you
+// add/modify flags, change HelpTexts or the values of some flags.
+
+// Some corner cases.
+// RUN: %clang --autocomplete= | FileCheck %s -check-prefix=ALL_FLAGS
+// RUN: %clang --autocomplete=# | FileCheck %s -check-prefix=ALL_FLAGS
+// Let's pick some example flags that are hopefully unlikely to change.
+// ALL_FLAGS: -fast
+// ALL_FLAGS: -fastcp
+// ALL_FLAGS: -fastf
+// Just test that this doesn't crash:
+// RUN: %clang --autocomplete=,
+// RUN: %clang --autocomplete==
+// RUN: %clang --autocomplete=,,
+// RUN: %clang --autocomplete=-
+
// RUN: %clang --autocomplete=-fsyn | FileCheck %s -check-prefix=FSYN
// FSYN: -fsyntax-only
// RUN: %clang --autocomplete=-std= | FileCheck %s -check-prefix=STD
@@ -89,3 +106,7 @@
// WARNING-NEXT: -Wmax-unsigned-zero
// RUN: %clang --autocomplete=-Wno-invalid-pp- | FileCheck %s -check-prefix=NOWARNING
// NOWARNING: -Wno-invalid-pp-token
+// RUN: %clang --autocomplete=-analyzer-checker, | FileCheck %s -check-prefix=ANALYZER
+// ANALYZER: unix.Malloc
+// RUN: %clang --autocomplete=-std=, | FileCheck %s -check-prefix=STDVAL
+// STDVAL: c99
diff --git a/test/Driver/baremetal.cpp b/test/Driver/baremetal.cpp
index 58fa9914d62c..a433e2df07cb 100644
--- a/test/Driver/baremetal.cpp
+++ b/test/Driver/baremetal.cpp
@@ -10,7 +10,7 @@
// CHECK-V6M-C-SAME: "-internal-isystem" "[[SYSROOT]]{{[/\\]+}}include{{[/\\]+}}c++{{[/\\]+}}v1"
// CHECk-V6M-C-SAME: "-internal-isystem" "[[SYSROOT]]{{[/\\]+}}include"
// CHECK-V6M-C-SAME: "-x" "c++" "{{.*}}baremetal.cpp"
-// CHECK-V6M-C-NEXT: "{{[^"]*}}ld.lld" "{{.*}}.o" "-Bstatic"
+// CHECK-V6M-C-NEXT: "{{[^"]*}}ld.lld{{(\.exe)?}}" "{{.*}}.o" "-Bstatic"
// CHECK-V6M-C-SAME: "-L[[RESOURCE_DIR:[^"]+]]{{[/\\]+}}lib{{[/\\]+}}baremetal"
// CHECK-V6M-C-SAME: "-T" "semihosted.lds" "-Lsome{{[/\\]+}}directory{{[/\\]+}}user{{[/\\]+}}asked{{[/\\]+}}for"
// CHECK-V6M-C-SAME: "-lc" "-lm" "-lclang_rt.builtins-armv6m.a"
@@ -32,7 +32,7 @@
// RUN: -target armv6m-none-eabi \
// RUN: --sysroot=%S/Inputs/baremetal_arm \
// RUN: | FileCheck --check-prefix=CHECK-V6M-DEFAULTCXX %s
-// CHECK-V6M-DEFAULTCXX: "{{[^"]*}}ld.lld" "{{.*}}.o" "-Bstatic"
+// CHECK-V6M-DEFAULTCXX: "{{[^"]*}}ld.lld{{(\.exe)?}}" "{{.*}}.o" "-Bstatic"
// CHECK-V6M-DEFAULTCXX-SAME: "-L{{[^"]*}}{{[/\\]+}}lib{{(64)?}}{{[/\\]+}}clang{{[/\\]+}}{{.*}}{{[/\\]+}}lib{{[/\\]+}}baremetal"
// CHECK-V6M-DEFAULTCXX-SAME: "-lc++" "-lc++abi" "-lunwind"
// CHECK-V6M-DEFAULTCXX-SAME: "-lc" "-lm" "-lclang_rt.builtins-armv6m.a"
@@ -45,7 +45,7 @@
// RUN: | FileCheck --check-prefix=CHECK-V6M-LIBCXX %s
// CHECK-V6M-LIBCXX-NOT: "-internal-isystem" "{{[^"]+}}{{[/\\]+}}include{{[/\\]+}}c++{{[/\\]+}}{{[^v].*}}"
// CHECK-V6M-LIBCXX: "-internal-isystem" "{{[^"]+}}{{[/\\]+}}include{{[/\\]+}}c++{{[/\\]+}}v1"
-// CHECK-V6M-LIBCXX: "{{[^"]*}}ld.lld" "{{.*}}.o" "-Bstatic"
+// CHECK-V6M-LIBCXX: "{{[^"]*}}ld.lld{{(\.exe)?}}" "{{.*}}.o" "-Bstatic"
// CHECK-V6M-LIBCXX-SAME: "-L{{[^"]*}}{{[/\\]+}}lib{{(64)?}}{{[/\\]+}}clang{{[/\\]+}}{{.*}}{{[/\\]+}}lib{{[/\\]+}}baremetal"
// CHECK-V6M-LIBCXX-SAME: "-lc++" "-lc++abi" "-lunwind"
// CHECK-V6M-LIBCXX-SAME: "-lc" "-lm" "-lclang_rt.builtins-armv6m.a"
@@ -58,7 +58,7 @@
// RUN: | FileCheck --check-prefix=CHECK-V6M-LIBSTDCXX %s
// CHECK-V6M-LIBSTDCXX-NOT: "-internal-isystem" "{{[^"]+}}{{[/\\]+}}include{{[/\\]+}}c++{{[/\\]+}}v1"
// CHECK-V6M-LIBSTDCXX: "-internal-isystem" "{{[^"]+}}{{[/\\]+}}include{{[/\\]+}}c++{{[/\\]+}}6.0.0"
-// CHECK-V6M-LIBSTDCXX: "{{[^"]*}}ld.lld" "{{.*}}.o" "-Bstatic"
+// CHECK-V6M-LIBSTDCXX: "{{[^"]*}}ld.lld{{(\.exe)?}}" "{{.*}}.o" "-Bstatic"
// CHECK-V6M-LIBSTDCXX-SAME: "-L{{[^"]*}}{{[/\\]+}}lib{{(64)?}}{{[/\\]+}}clang{{[/\\]+}}{{.*}}{{[/\\]+}}lib{{[/\\]+}}baremetal"
// CHECK-V6M-LIBSTDCXX-SAME: "-lstdc++" "-lsupc++" "-lunwind"
// CHECK-V6M-LIBSTDCXX-SAME: "-lc" "-lm" "-lclang_rt.builtins-armv6m.a"
@@ -69,7 +69,7 @@
// RUN: --sysroot=%S/Inputs/baremetal_arm \
// RUN: -nodefaultlibs \
// RUN: | FileCheck --check-prefix=CHECK-V6M-NDL %s
-// CHECK-V6M-NDL: "{{[^"]*}}ld.lld" "{{.*}}.o" "-Bstatic"
+// CHECK-V6M-NDL: "{{[^"]*}}ld.lld{{(\.exe)?}}" "{{.*}}.o" "-Bstatic"
// CHECK-V6M-NDL-SAME: "-L{{[^"]*}}{{[/\\]+}}lib{{(64)?}}{{[/\\]+}}clang{{[/\\]+}}{{.*}}{{[/\\]+}}lib{{[/\\]+}}baremetal" "-o" "{{.*}}.o"
// RUN: %clangxx -target arm-none-eabi -v 2>&1 \
diff --git a/test/Driver/bitrig.c b/test/Driver/bitrig.c
deleted file mode 100644
index a20a95aecdcc..000000000000
--- a/test/Driver/bitrig.c
+++ /dev/null
@@ -1,29 +0,0 @@
-// RUN: %clang -no-canonical-prefixes -target amd64-pc-bitrig %s -### 2>&1 \
-// RUN: | FileCheck --check-prefix=CHECK-LD-C %s
-// CHECK-LD-C: clang{{.*}}" "-cc1" "-triple" "amd64-pc-bitrig"
-// CHECK-LD-C: ld{{.*}}" {{.*}} "-lc" "-lclang_rt.amd64"
-
-// RUN: %clangxx -stdlib=platform -no-canonical-prefixes -target amd64-pc-bitrig %s -### 2>&1 \
-// RUN: | FileCheck --check-prefix=CHECK-LD-CXX-STDLIB %s
-// CHECK-LD-CXX-STDLIB: clang{{.*}}" "-cc1" "-triple" "amd64-pc-bitrig"
-// CHECK-LD-CXX-STDLIB: ld{{.*}}" {{.*}} "-lc++" "-lc++abi" "-lpthread" "-lm" "-lc" "-lclang_rt.amd64"
-
-// RUN: %clangxx -stdlib=libstdc++ -no-canonical-prefixes -target amd64-pc-bitrig %s -### 2>&1 \
-// RUN: | FileCheck --check-prefix=CHECK-LD-CXX %s
-// CHECK-LD-CXX: clang{{.*}}" "-cc1" "-triple" "amd64-pc-bitrig"
-// CHECK-LD-CXX: ld{{.*}}" {{.*}} "-lstdc++" "-lm" "-lc" "-lclang_rt.amd64"
-
-// RUN: %clang -no-canonical-prefixes -target amd64-pc-bitrig -pthread %s -### 2>&1 \
-// RUN: | FileCheck --check-prefix=CHECK-PTHREAD %s
-// CHECK-PTHREAD: clang{{.*}}" "-cc1" "-triple" "amd64-pc-bitrig"
-// CHECK-PTHREAD: ld{{.*}}" {{.*}} "{{.*}}crtbegin.o" {{.*}}.o" "-lpthread" "-lc" "-lclang_rt.amd64" "{{.*}}crtend.o"
-
-// RUN: %clang -no-canonical-prefixes -target amd64-pc-bitrig -pg -pthread %s -### 2>&1 \
-// RUN: | FileCheck --check-prefix=CHECK-PG-PTHREAD %s
-// CHECK-PG-PTHREAD: clang{{.*}}" "-cc1" "-triple" "amd64-pc-bitrig"
-// CHECK-PG-PTHREAD: ld{{.*}}" {{.*}} "{{.*}}crtbegin.o" {{.*}}.o" "-lpthread_p" "-lc_p" "-lclang_rt.amd64" "{{.*}}crtend.o"
-
-// RUN: %clang -no-canonical-prefixes -target amd64-pc-bitrig -shared -pg -pthread %s -### 2>&1 \
-// RUN: | FileCheck --check-prefix=CHECK-PG-PTHREAD-SHARED %s
-// CHECK-PG-PTHREAD-SHARED: clang{{.*}}" "-cc1" "-triple" "amd64-pc-bitrig"
-// CHECK-PG-PTHREAD-SHARED: ld{{.*}}" {{.*}} "{{.*}}crtbeginS.o" {{.*}}.o" "-lpthread" "-lclang_rt.amd64" "{{.*}}crtendS.o"
diff --git a/test/Driver/cl-cc-flags.c b/test/Driver/cl-cc-flags.c
index 76f116e199e2..d74062a65624 100644
--- a/test/Driver/cl-cc-flags.c
+++ b/test/Driver/cl-cc-flags.c
@@ -13,6 +13,9 @@
// RUN: %clang_cl --target=i686-windows-msvc /Gv -### -- %s 2>&1 | FileCheck --check-prefix=VECTORCALL %s
// VECTORCALL: -fdefault-calling-conv=vectorcall
+// RUN: %clang_cl --target=i686-windows-msvc /Gregcall -### -- %s 2>&1 | FileCheck --check-prefix=REGCALL %s
+// REGCALL: -fdefault-calling-conv=regcall
+
// Last one should win:
// RUN: %clang_cl --target=i686-windows-msvc /Gd /Gv -### -- %s 2>&1 | FileCheck --check-prefix=LASTWINS_VECTOR %s
diff --git a/test/Driver/cl-options.c b/test/Driver/cl-options.c
index 870378a8299d..b8a0166e7ad3 100644
--- a/test/Driver/cl-options.c
+++ b/test/Driver/cl-options.c
@@ -178,6 +178,9 @@
// Oy_2: -momit-leaf-frame-pointer
// Oy_2: -O2
+// RUN: %clang_cl --target=i686-pc-win32 -Werror /O2 /O2 -### -- %s 2>&1 | FileCheck -check-prefix=O2O2 %s
+// O2O2: "-O2"
+
// RUN: %clang_cl /Zs -Werror /Oy -- %s 2>&1
// RUN: %clang_cl --target=i686-pc-win32 -Werror /Oy- -### -- %s 2>&1 | FileCheck -check-prefix=Oy_ %s
@@ -194,8 +197,12 @@
// RUN: %clang_cl /E /showIncludes -### -- %s 2>&1 | FileCheck -check-prefix=showIncludes_E %s
// RUN: %clang_cl /EP /showIncludes -### -- %s 2>&1 | FileCheck -check-prefix=showIncludes_E %s
+// RUN: %clang_cl /E /EP /showIncludes -### -- %s 2>&1 | FileCheck -check-prefix=showIncludes_E %s
// showIncludes_E: warning: argument unused during compilation: '--show-includes'
+// RUN: %clang_cl /EP /P /showIncludes -### -- %s 2>&1 | FileCheck -check-prefix=showIncludes_E_And_P %s
+// showIncludes_E_And_P-NOT: warning: argument unused during compilation: '--show-includes'
+
// /source-charset: should warn on everything except UTF-8.
// RUN: %clang_cl /source-charset:utf-16 -### -- %s 2>&1 | FileCheck -check-prefix=source-charset-utf-16 %s
// source-charset-utf-16: invalid value 'utf-16'
@@ -248,9 +255,10 @@
// RUN: %clang_cl /W2 -### -- %s 2>&1 | FileCheck -check-prefix=W1 %s
// RUN: %clang_cl /W3 -### -- %s 2>&1 | FileCheck -check-prefix=W1 %s
// RUN: %clang_cl /W4 -### -- %s 2>&1 | FileCheck -check-prefix=W4 %s
-// RUN: %clang_cl /Wall -### -- %s 2>&1 | FileCheck -check-prefix=W4 %s
+// RUN: %clang_cl /Wall -### -- %s 2>&1 | FileCheck -check-prefix=Weverything %s
// W1: -Wall
// W4: -WCL4
+// Weverything: -Weverything
// RUN: %clang_cl /WX -### -- %s 2>&1 | FileCheck -check-prefix=WX %s
// WX: -Werror
@@ -517,8 +525,11 @@
// RUN: %clang_cl -fmsc-version=1900 -TP -std:c++14 -### -- %s 2>&1 | FileCheck -check-prefix=STDCXX14 %s
// STDCXX14: -std=c++14
+// RUN: %clang_cl -fmsc-version=1900 -TP -std:c++17 -### -- %s 2>&1 | FileCheck -check-prefix=STDCXX17 %s
+// STDCXX17: -std=c++17
+
// RUN: %clang_cl -fmsc-version=1900 -TP -std:c++latest -### -- %s 2>&1 | FileCheck -check-prefix=STDCXXLATEST %s
-// STDCXXLATEST: -std=c++1z
+// STDCXXLATEST: -std=c++2a
// RUN: env CL="/Gy" %clang_cl -### -- %s 2>&1 | FileCheck -check-prefix=ENV-CL %s
// ENV-CL: "-ffunction-sections"
@@ -564,6 +575,7 @@
// RUN: -fstandalone-debug \
// RUN: -flimit-debug-info \
// RUN: -flto \
+// RUN: --version \
// RUN: -Werror /Zs -- %s 2>&1
diff --git a/test/Driver/clang-translation.c b/test/Driver/clang-translation.c
index 3b30f7af76dc..a09a60c9f33e 100644
--- a/test/Driver/clang-translation.c
+++ b/test/Driver/clang-translation.c
@@ -73,6 +73,22 @@
// RUN: FileCheck -check-prefix=ARM64-APPLE %s
// ARM64-APPLE: -munwind-table
+// RUN: %clang -target arm64-apple-ios10 -### -ffreestanding -S %s -arch arm64 2>&1 | \
+// RUN: FileCheck -check-prefix=ARM64-FREESTANDING-APPLE %s
+//
+// RUN: %clang -target arm64-apple-ios10 -### -fno-unwind-tables -ffreestanding -S %s -arch arm64 2>&1 | \
+// RUN: FileCheck -check-prefix=ARM64-FREESTANDING-APPLE %s
+//
+// ARM64-FREESTANDING-APPLE-NOT: -munwind-table
+
+// RUN: %clang -target arm64-apple-ios10 -### -funwind-tables -S %s -arch arm64 2>&1 | \
+// RUN: FileCheck -check-prefix=ARM64-EXPLICIT-UWTABLE-APPLE %s
+//
+// RUN: %clang -target arm64-apple-ios10 -### -ffreestanding -funwind-tables -S %s -arch arm64 2>&1 | \
+// RUN: FileCheck -check-prefix=ARM64-EXPLICIT-UWTABLE-APPLE %s
+//
+// ARM64-EXPLICIT-UWTABLE-APPLE: -munwind-table
+
// RUN: %clang -target arm64-apple-ios10 -fno-exceptions -### -S %s -arch arm64 2>&1 | \
// RUN: FileCheck -check-prefix=ARM64-APPLE-EXCEP %s
// ARM64-APPLE-EXCEP-NOT: -munwind-table
@@ -87,6 +103,18 @@
// ARMV5E: "-cc1"
// ARMV5E: "-target-cpu" "arm1022e"
+// RUN: %clang -target arm-linux -mtp=cp15 -### -S %s -arch armv7 2>&1 | \
+// RUN: FileCheck -check-prefix=ARMv7_THREAD_POINTER-HARD %s
+// ARMv7_THREAD_POINTER-HARD: "-target-feature" "+read-tp-hard"
+
+// RUN: %clang -target arm-linux -mtp=soft -### -S %s -arch armv7 2>&1 | \
+// RUN: FileCheck -check-prefix=ARMv7_THREAD_POINTER_SOFT %s
+// ARMv7_THREAD_POINTER_SOFT-NOT: "-target-feature" "+read-tp-hard"
+
+// RUN: %clang -target arm-linux -### -S %s -arch armv7 2>&1 | \
+// RUN: FileCheck -check-prefix=ARMv7_THREAD_POINTER_NON %s
+// ARMv7_THREAD_POINTER_NON-NOT: "-target-feature" "+read-tp-hard"
+
// RUN: %clang -target powerpc64-unknown-linux-gnu \
// RUN: -### -S %s -mcpu=G5 2>&1 | FileCheck -check-prefix=PPCG5 %s
// PPCG5: clang
diff --git a/test/Driver/clang_f_opts.c b/test/Driver/clang_f_opts.c
index c17cec6eba9b..b22f74fb5557 100644
--- a/test/Driver/clang_f_opts.c
+++ b/test/Driver/clang_f_opts.c
@@ -1,7 +1,7 @@
// REQUIRES: clang-driver
// RUN: %clang -### -S -fasm -fblocks -fbuiltin -fno-math-errno -fcommon -fpascal-strings -fno-blocks -fno-builtin -fmath-errno -fno-common -fno-pascal-strings -fblocks -fbuiltin -fmath-errno -fcommon -fpascal-strings -fsplit-stack %s 2>&1 | FileCheck -check-prefix=CHECK-OPTIONS1 %s
-// RUN: %clang -### -S -fasm -fblocks -fbuiltin -fno-math-errno -fcommon -fpascal-strings -fno-asm -fno-blocks -fno-builtin -fmath-errno -fno-common -fno-pascal-strings -fno-show-source-location -fshort-enums -fshort-wchar %s 2>&1 | FileCheck -check-prefix=CHECK-OPTIONS2 %s
+// RUN: %clang -### -S -fasm -fblocks -fbuiltin -fno-math-errno -fcommon -fpascal-strings -fno-asm -fno-blocks -fno-builtin -fmath-errno -fno-common -fno-pascal-strings -fno-show-source-location -fshort-enums %s 2>&1 | FileCheck -check-prefix=CHECK-OPTIONS2 %s
// CHECK-OPTIONS1: -split-stacks
// CHECK-OPTIONS1: -fgnu-keywords
@@ -12,7 +12,6 @@
// CHECK-OPTIONS2: -fno-gnu-keywords
// CHECK-OPTIONS2: -fno-builtin
// CHECK-OPTIONS2: -fshort-enums
-// CHECK-OPTIONS2: -fshort-wchar
// CHECK-OPTIONS2: -fno-common
// CHECK-OPTIONS2: -fno-show-source-location
@@ -53,6 +52,9 @@
// CHECK-REROLL-LOOPS: "-freroll-loops"
// CHECK-NO-REROLL-LOOPS-NOT: "-freroll-loops"
+// RUN: %clang -### -S -fprofile-sample-accurate %s 2>&1 | FileCheck -check-prefix=CHECK-PROFILE-SAMPLE-ACCURATE %s
+// CHECK-PROFILE-SAMPLE-ACCURATE: "-fprofile-sample-accurate"
+
// RUN: %clang -### -S -fprofile-sample-use=%S/Inputs/file.prof %s 2>&1 | FileCheck -check-prefix=CHECK-SAMPLE-PROFILE %s
// CHECK-SAMPLE-PROFILE: "-fprofile-sample-use={{.*}}/file.prof"
@@ -463,15 +465,15 @@
// RUN: %clang -### -S -fno-unsigned-char %s 2>&1 | FileCheck -check-prefix=CHAR-SIGN4 %s
// CHAR-SIGN4-NOT: -fno-signed-char
-// RUN: %clang -### -fshort-wchar -fno-short-wchar %s 2>&1 | FileCheck -check-prefix=CHECK-WCHAR1 -check-prefix=DELIMITERS %s
-// RUN: %clang -### -fno-short-wchar -fshort-wchar %s 2>&1 | FileCheck -check-prefix=CHECK-WCHAR2 -check-prefix=DELIMITERS %s
+// RUN: %clang -target x86_64-unknown-none-none -### -fshort-wchar -fno-short-wchar %s 2>&1 | FileCheck -check-prefix=CHECK-WCHAR1 -check-prefix=DELIMITERS %s
+// RUN: %clang -target x86_64-unknown-none-none -### -fno-short-wchar -fshort-wchar %s 2>&1 | FileCheck -check-prefix=CHECK-WCHAR2 -check-prefix=DELIMITERS %s
// Make sure we don't match the -NOT lines with the linker invocation.
// Delimiters match the start of the cc1 and the start of the linker lines
// DELIMITERS: {{^ *"}}
-// CHECK-WCHAR1: -fno-short-wchar
-// CHECK-WCHAR1-NOT: -fshort-wchar
-// CHECK-WCHAR2: -fshort-wchar
-// CHECK-WCHAR2-NOT: -fno-short-wchar
+// CHECK-WCHAR1: -fwchar-type=int
+// CHECK-WCHAR1-NOT: -fwchar-type=short
+// CHECK-WCHAR2: -fwchar-type=short
+// CHECK-WCHAR2-NOT: -fwchar-type=int
// DELIMITERS: {{^ *"}}
// RUN: %clang -### -fno-experimental-new-pass-manager -fexperimental-new-pass-manager %s 2>&1 | FileCheck --check-prefix=CHECK-PM --check-prefix=CHECK-NEW-PM %s
@@ -496,3 +498,8 @@
// RUN: %clang -### -S -fno-allow-editor-placeholders %s 2>&1 | FileCheck -check-prefix=CHECK-NO-ALLOW-PLACEHOLDERS %s
// CHECK-ALLOW-PLACEHOLDERS: -fallow-editor-placeholders
// CHECK-NO-ALLOW-PLACEHOLDERS-NOT: -fallow-editor-placeholders
+
+// RUN: %clang -### -target x86_64-unknown-windows-msvc -fno-short-wchar %s 2>&1 | FileCheck -check-prefix CHECK-WINDOWS-ISO10646 %s
+// CHECK-WINDOWS-ISO10646: "-fwchar-type=int"
+// CHECK-WINDOWS-ISO10646: "-fsigned-wchar"
+
diff --git a/test/Driver/compilation_database.c b/test/Driver/compilation_database.c
index d5bafd41a647..017178d60cde 100644
--- a/test/Driver/compilation_database.c
+++ b/test/Driver/compilation_database.c
@@ -1,4 +1,4 @@
-// RUN: cd "%T"
+// RUN: mkdir -p %t && cd %t
// RUN: %clang -MD -MP --sysroot=somewhere -c -x c %s -xc++ %s -Wall -MJ - -no-canonical-prefixes 2>&1 | FileCheck %s
// RUN: not %clang -c -x c %s -MJ %s/non-existant -no-canonical-prefixes 2>&1 | FileCheck --check-prefix=ERROR %s
diff --git a/test/Driver/constructors.c b/test/Driver/constructors.c
index 39a199a3c6ae..884fbe8466cb 100644
--- a/test/Driver/constructors.c
+++ b/test/Driver/constructors.c
@@ -6,6 +6,12 @@
//
// RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \
// RUN: -target i386-unknown-linux \
+// RUN: --sysroot=%S/Inputs/resource_dir \
+// RUN: --gcc-toolchain="" \
+// RUN: | FileCheck --check-prefix=CHECK-INIT-ARRAY %s
+//
+// RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \
+// RUN: -target i386-unknown-linux \
// RUN: --sysroot=%S/Inputs/fake_install_tree \
// RUN: --gcc-toolchain="" \
// RUN: | FileCheck --check-prefix=CHECK-INIT-ARRAY %s
diff --git a/test/Driver/coverage.c b/test/Driver/coverage.c
new file mode 100644
index 000000000000..f6bfbfb5f63b
--- /dev/null
+++ b/test/Driver/coverage.c
@@ -0,0 +1,8 @@
+// Test coverage flag.
+// REQUIRES: system-windows
+//
+// RUN: %clang_cl -Wno-msvc-not-found -### -coverage %s -o foo/bar.o 2>&1 | FileCheck -check-prefix=CLANG-CL-COVERAGE %s
+// CLANG-CL-COVERAGE-NOT: error:
+// CLANG-CL-COVERAGE-NOT: warning:
+// CLANG-CL-COVERAGE-NOT: argument unused
+// CLANG-CL-COVERAGE-NOT: unknown argument
diff --git a/test/Driver/cpath.c b/test/Driver/cpath.c
index ea6ba49d6d51..7d63913810c1 100644
--- a/test/Driver/cpath.c
+++ b/test/Driver/cpath.c
@@ -1,20 +1,20 @@
-// RUN: mkdir -p %T/test1 %T/test2 %T/test3
+// RUN: mkdir -p %t/test1 %t/test2 %t/test3
-// RUN: env "CPATH=%T/test1%{pathsep}%T/test2" %clang -x c -E -v %s 2>&1 | FileCheck %s -check-prefix=CPATH
+// RUN: env "CPATH=%t/test1%{pathsep}%t/test2" %clang -x c -E -v %s 2>&1 | FileCheck %s -check-prefix=CPATH
// CPATH: -I{{.*}}/test1
// CPATH: -I{{.*}}/test2
// CPATH: search starts here
// CPATH: test1
// CPATH: test2
-// RUN: env "OBJC_INCLUDE_PATH=%T/test1%{pathsep}%T/test2" OBJCPLUS_INCLUDE_PATH=%T/test1 "CPLUS_INCLUDE_PATH=%T/test1%{pathsep}%t/test2" C_INCLUDE_PATH=%T/test3 %clang -x c -E -v %s 2>&1 | FileCheck %s -check-prefix=C_INCLUDE_PATH
+// RUN: env "OBJC_INCLUDE_PATH=%t/test1%{pathsep}%t/test2" OBJCPLUS_INCLUDE_PATH=%t/test1 "CPLUS_INCLUDE_PATH=%t/test1%{pathsep}%t/test2" C_INCLUDE_PATH=%t/test3 %clang -x c -E -v %s 2>&1 | FileCheck %s -check-prefix=C_INCLUDE_PATH
// C_INCLUDE_PATH: -c-isystem {{"?.*}}/test3{{"?}} -cxx-isystem {{"?.*}}/test1{{"?}} -cxx-isystem {{"?.*}}/test2{{"?}} -objc-isystem {{"?.*}}/test1{{"?}} -objc-isystem {{"?.*}}/test2{{"?}} -objcxx-isystem {{"?.*}}/test1{{"?}}
// C_INCLUDE_PATH: search starts here
// C_INCLUDE_PATH-NOT: test1
// C_INCLUDE_PATH: test3
// C_INCLUDE_PATH-NOT: test1
-// RUN: env OBJC_INCLUDE_PATH=%T/test1 OBJCPLUS_INCLUDE_PATH=%T/test3 CPLUS_INCLUDE_PATH=%T/test3 C_INCLUDE_PATH=%T/test1 %clang -x objective-c++ -E -v %s 2>&1 | FileCheck %s -check-prefix=OBJCPLUS_INCLUDE_PATH
+// RUN: env OBJC_INCLUDE_PATH=%t/test1 OBJCPLUS_INCLUDE_PATH=%t/test3 CPLUS_INCLUDE_PATH=%t/test3 C_INCLUDE_PATH=%t/test1 %clang -x objective-c++ -E -v %s 2>&1 | FileCheck %s -check-prefix=OBJCPLUS_INCLUDE_PATH
// OBJCPLUS_INCLUDE_PATH: -c-isystem {{"?.*}}/test1{{"?}} -cxx-isystem {{"?.*}}/test3{{"?}} -objc-isystem {{"?.*}}/test1{{"?}} -objcxx-isystem {{"?.*}}/test3{{"?}}
// OBJCPLUS_INCLUDE_PATH: search starts here
// OBJCPLUS_INCLUDE_PATH-NOT: test1
diff --git a/test/Driver/cuda-arch-translation.cu b/test/Driver/cuda-arch-translation.cu
index 64ddb3178cd2..a26d3740ff16 100644
--- a/test/Driver/cuda-arch-translation.cu
+++ b/test/Driver/cuda-arch-translation.cu
@@ -5,26 +5,36 @@
// REQUIRES: x86-registered-target
// REQUIRES: nvptx-registered-target
-// CHECK:fatbinary
-
// RUN: %clang -### -target x86_64-linux-gnu -c --cuda-gpu-arch=sm_20 %s 2>&1 \
-// RUN: | FileCheck -check-prefix ARCH64 -check-prefix SM20 %s
+// RUN: | FileCheck -check-prefixes=COMMON,SM20 %s
// RUN: %clang -### -target x86_64-linux-gnu -c --cuda-gpu-arch=sm_21 %s 2>&1 \
-// RUN: | FileCheck -check-prefix ARCH64 -check-prefix SM21 %s
+// RUN: | FileCheck -check-prefixes=COMMON,SM21 %s
// RUN: %clang -### -target x86_64-linux-gnu -c --cuda-gpu-arch=sm_30 %s 2>&1 \
-// RUN: | FileCheck -check-prefix ARCH64 -check-prefix SM30 %s
+// RUN: | FileCheck -check-prefixes=COMMON,SM30 %s
// RUN: %clang -### -target x86_64-linux-gnu -c --cuda-gpu-arch=sm_32 %s 2>&1 \
-// RUN: | FileCheck -check-prefix ARCH64 -check-prefix SM32 %s
+// RUN: | FileCheck -check-prefixes=COMMON,SM32 %s
// RUN: %clang -### -target x86_64-linux-gnu -c --cuda-gpu-arch=sm_35 %s 2>&1 \
-// RUN: | FileCheck -check-prefix ARCH64 -check-prefix SM35 %s
+// RUN: | FileCheck -check-prefixes=COMMON,SM35 %s
// RUN: %clang -### -target x86_64-linux-gnu -c --cuda-gpu-arch=sm_37 %s 2>&1 \
-// RUN: | FileCheck -check-prefix ARCH64 -check-prefix SM37 %s
+// RUN: | FileCheck -check-prefixes=COMMON,SM37 %s
// RUN: %clang -### -target x86_64-linux-gnu -c --cuda-gpu-arch=sm_50 %s 2>&1 \
-// RUN: | FileCheck -check-prefix ARCH64 -check-prefix SM50 %s
+// RUN: | FileCheck -check-prefixes=COMMON,SM50 %s
// RUN: %clang -### -target x86_64-linux-gnu -c --cuda-gpu-arch=sm_52 %s 2>&1 \
-// RUN: | FileCheck -check-prefix ARCH64 -check-prefix SM52 %s
+// RUN: | FileCheck -check-prefixes=COMMON,SM52 %s
// RUN: %clang -### -target x86_64-linux-gnu -c --cuda-gpu-arch=sm_53 %s 2>&1 \
-// RUN: | FileCheck -check-prefix ARCH64 -check-prefix SM53 %s
+// RUN: | FileCheck -check-prefixes=COMMON,SM53 %s
+// RUN: %clang -### -target x86_64-linux-gnu -c --cuda-gpu-arch=sm_60 %s 2>&1 \
+// RUN: | FileCheck -check-prefixes=COMMON,SM60 %s
+// RUN: %clang -### -target x86_64-linux-gnu -c --cuda-gpu-arch=sm_61 %s 2>&1 \
+// RUN: | FileCheck -check-prefixes=COMMON,SM61 %s
+// RUN: %clang -### -target x86_64-linux-gnu -c --cuda-gpu-arch=sm_62 %s 2>&1 \
+// RUN: | FileCheck -check-prefixes=COMMON,SM62 %s
+// RUN: %clang -### -target x86_64-linux-gnu -c --cuda-gpu-arch=sm_70 %s 2>&1 \
+// RUN: | FileCheck -check-prefixes=COMMON,SM70 %s
+
+// COMMON: ptxas
+// COMMON-SAME: -m64
+// COMMON: fatbinary
// SM20:--image=profile=sm_20{{.*}}--image=profile=compute_20
// SM21:--image=profile=sm_21{{.*}}--image=profile=compute_20
@@ -35,3 +45,7 @@
// SM50:--image=profile=sm_50{{.*}}--image=profile=compute_50
// SM52:--image=profile=sm_52{{.*}}--image=profile=compute_52
// SM53:--image=profile=sm_53{{.*}}--image=profile=compute_53
+// SM60:--image=profile=sm_60{{.*}}--image=profile=compute_60
+// SM61:--image=profile=sm_61{{.*}}--image=profile=compute_61
+// SM62:--image=profile=sm_62{{.*}}--image=profile=compute_62
+// SM70:--image=profile=sm_70{{.*}}--image=profile=compute_70
diff --git a/test/Driver/cuda-bad-arch.cu b/test/Driver/cuda-bad-arch.cu
index cbc2d11f90e6..a6559b0c7810 100644
--- a/test/Driver/cuda-bad-arch.cu
+++ b/test/Driver/cuda-bad-arch.cu
@@ -12,6 +12,12 @@
// BAD: error: Unsupported CUDA gpu architecture
+// RUN: %clang -### -v --target=x86_64-linux-gnu --cuda-gpu-arch=sm_21 \
+// RUN: --cuda-path=%S/Inputs/CUDA_90/usr/local/cuda %s 2>&1 \
+// RUN: | FileCheck -check-prefix BAD_CUDA9 %s
+
+// BAD_CUDA9: GPU arch sm_21 is supported by CUDA versions between 7.0 and 8.0
+
// RUN: %clang -### -target x86_64-linux-gnu --cuda-gpu-arch=sm_20 -c %s 2>&1 \
// RUN: | FileCheck -check-prefix OK %s
// RUN: %clang -### -target x86_64-linux-gnu --cuda-gpu-arch=sm_52 -c %s 2>&1 \
diff --git a/test/Driver/cuda-bail-out.cu b/test/Driver/cuda-bail-out.cu
new file mode 100644
index 000000000000..aaf771474315
--- /dev/null
+++ b/test/Driver/cuda-bail-out.cu
@@ -0,0 +1,54 @@
+// Test clang driver bails out after one error during CUDA compilation.
+
+// REQUIRES: clang-driver
+// REQUIRES: powerpc-registered-target
+// REQUIRES: nvptx-registered-target
+
+#ifdef FORCE_ERROR
+#error compilation failed
+#endif
+
+// RUN: not %clang -target powerpc64le-ibm-linux-gnu -fsyntax-only -nocudalib \
+// RUN: -nocudainc -DFORCE_ERROR %s 2>&1 | FileCheck %s
+// RUN: not %clang -target powerpc64le-ibm-linux-gnu -fsyntax-only -nocudalib \
+// RUN: -nocudainc -DFORCE_ERROR --cuda-gpu-arch=sm_35 --cuda-gpu-arch=sm_60 \
+// RUN: %s 2>&1 | FileCheck %s
+// RUN: not %clang -target powerpc64le-ibm-linux-gnu -fsyntax-only -nocudalib \
+// RUN: -nocudainc -DFORCE_ERROR --cuda-gpu-arch=sm_35 --cuda-gpu-arch=sm_60 \
+// RUN: --cuda-device-only %s 2>&1 | FileCheck %s
+
+#if defined(ERROR_HOST) && !defined(__CUDA_ARCH__)
+#error compilation failed
+#endif
+
+#if defined(ERROR_SM35) && (__CUDA_ARCH__ == 350)
+#error compilation failed
+#endif
+
+#if defined(ERROR_SM60) && (__CUDA_ARCH__ == 600)
+#error compilation failed
+#endif
+
+// RUN: not %clang -target powerpc64le-ibm-linux-gnu -fsyntax-only -nocudalib \
+// RUN: -nocudainc -DERROR_HOST --cuda-gpu-arch=sm_35 --cuda-gpu-arch=sm_60 \
+// RUN: %s 2>&1 | FileCheck %s
+// RUN: not %clang -target powerpc64le-ibm-linux-gnu -fsyntax-only -nocudalib \
+// RUN: -nocudainc -DERROR_SM35 --cuda-gpu-arch=sm_35 --cuda-gpu-arch=sm_60 \
+// RUN: --cuda-device-only %s 2>&1 | FileCheck %s
+// RUN: not %clang -target powerpc64le-ibm-linux-gnu -fsyntax-only -nocudalib \
+// RUN: -nocudainc -DERROR_SM60 --cuda-gpu-arch=sm_35 --cuda-gpu-arch=sm_60 \
+// RUN: --cuda-device-only %s 2>&1 | FileCheck %s
+
+// RUN: not %clang -target powerpc64le-ibm-linux-gnu -fsyntax-only -nocudalib \
+// RUN: -nocudainc -DERROR_HOST -DERROR_SM35 --cuda-gpu-arch=sm_35 \
+// RUN: --cuda-gpu-arch=sm_60 %s 2>&1 | FileCheck %s
+// RUN: not %clang -target powerpc64le-ibm-linux-gnu -fsyntax-only -nocudalib \
+// RUN: -nocudainc -DERROR_HOST -DERROR_SM60 --cuda-gpu-arch=sm_35 \
+// RUN: --cuda-gpu-arch=sm_60 %s 2>&1 | FileCheck %s
+// RUN: not %clang -target powerpc64le-ibm-linux-gnu -fsyntax-only -nocudalib \
+// RUN: -nocudainc -DERROR_SM35 -DERROR_SM60 --cuda-gpu-arch=sm_35 \
+// RUN: --cuda-gpu-arch=sm_60 %s 2>&1 | FileCheck %s
+
+
+// CHECK: error: compilation failed
+// CHECK-NOT: error: compilation failed
diff --git a/test/Driver/cuda-detect.cu b/test/Driver/cuda-detect.cu
index aaef89ac453d..1db0cfbfa3ce 100644
--- a/test/Driver/cuda-detect.cu
+++ b/test/Driver/cuda-detect.cu
@@ -2,7 +2,7 @@
// REQUIRES: x86-registered-target
// REQUIRES: nvptx-registered-target
//
-// # Check that we properly detect CUDA installation.
+// Check that we properly detect CUDA installation.
// RUN: %clang -v --target=i386-unknown-linux \
// RUN: --sysroot=%S/no-cuda-there 2>&1 | FileCheck %s -check-prefix NOCUDA
// RUN: %clang -v --target=i386-apple-macosx \
@@ -18,6 +18,19 @@
// RUN: %clang -v --target=i386-apple-macosx \
// RUN: --cuda-path=%S/Inputs/CUDA/usr/local/cuda 2>&1 | FileCheck %s
+// Check that we don't find a CUDA installation without libdevice ...
+// RUN: %clang -v --target=i386-unknown-linux \
+// RUN: --sysroot=%S/Inputs/CUDA-nolibdevice 2>&1 | FileCheck %s -check-prefix NOCUDA
+// RUN: %clang -v --target=i386-apple-macosx \
+// RUN: --sysroot=%S/Inputs/CUDA-nolibdevice 2>&1 | FileCheck %s -check-prefix NOCUDA
+
+// ... unless the user doesn't need libdevice
+// RUN: %clang -v --target=i386-unknown-linux -nocudalib \
+// RUN: --sysroot=%S/Inputs/CUDA-nolibdevice 2>&1 | FileCheck %s -check-prefix NO-LIBDEVICE
+// RUN: %clang -v --target=i386-apple-macosx -nocudalib \
+// RUN: --sysroot=%S/Inputs/CUDA-nolibdevice 2>&1 | FileCheck %s -check-prefix NO-LIBDEVICE
+
+
// Make sure we map libdevice bitcode files to proper GPUs. These
// tests use Inputs/CUDA_80 which has full set of libdevice files.
// However, libdevice mapping only matches CUDA-7.x at the moment.
@@ -112,6 +125,7 @@
// RUN: | FileCheck %s --check-prefix CHECK-CXXINCLUDE
// CHECK: Found CUDA installation: {{.*}}/Inputs/CUDA/usr/local/cuda
+// NO-LIBDEVICE: Found CUDA installation: {{.*}}/Inputs/CUDA-nolibdevice/usr/local/cuda
// NOCUDA-NOT: Found CUDA installation:
// MISSINGLIBDEVICE: error: cannot find libdevice for sm_20.
diff --git a/test/Driver/cuda-external-tools.cu b/test/Driver/cuda-external-tools.cu
index 809b8507683b..63b74fc06b9b 100644
--- a/test/Driver/cuda-external-tools.cu
+++ b/test/Driver/cuda-external-tools.cu
@@ -65,6 +65,10 @@
// RUN: %clang -### -target x86_32-apple-macosx -c %s 2>&1 \
// RUN: | FileCheck -check-prefix ARCH32 -check-prefix SM20 %s
+// Check that CLANG forwards the -v flag to PTXAS.
+// RUN: %clang -### -save-temps -no-canonical-prefixes -v %s 2>&1 \
+// RUN: | FileCheck -check-prefix=CHK-PTXAS-VERBOSE %s
+
// Match clang job that produces PTX assembly.
// CHECK: "-cc1" "-triple" "nvptx64-nvidia-cuda"
// SM20: "-target-cpu" "sm_20"
@@ -110,3 +114,5 @@
// Match the clang job for host compilation.
// CHECK: "-cc1" "-triple" "x86_64--linux-gnu"
// CHECK-SAME: "-fcuda-include-gpubinary" "[[FATBINARY]]"
+
+// CHK-PTXAS-VERBOSE: ptxas{{.*}}" "-v" \ No newline at end of file
diff --git a/test/Driver/cxa-atexit.cpp b/test/Driver/cxa-atexit.cpp
new file mode 100644
index 000000000000..01d4e20e7716
--- /dev/null
+++ b/test/Driver/cxa-atexit.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang -### -target armv7-unknown-windows-msvc -c %s -o /dev/null 2>&1 | FileCheck %s -check-prefix CHECK-WINDOWS
+// RUN: %clang -### -target armv7-unknown-windows-itanium -c %s -o /dev/null 2>&1 | FileCheck %s -check-prefix CHECK-WINDOWS
+// RUN: %clang -### -target armv7-unknown-windows-gnu -c %s -o /dev/null 2>&1 | FileCheck %s -check-prefix CHECK-WINDOWS
+// RUN: %clang -### -target armv7-unknown-windows-cygnus -c %s -o /dev/null 2>&1 | FileCheck %s -check-prefix CHECK-WINDOWS
+// RUN: %clang -### -target i686-unknown-windows-msvc -c %s -o /dev/null 2>&1 | FileCheck %s -check-prefix CHECK-WINDOWS
+// RUN: %clang -### -target i686-unknown-windows-itanium -c %s -o /dev/null 2>&1 | FileCheck %s -check-prefix CHECK-WINDOWS
+// RUN: %clang -### -target i686-unknown-windows-gnu -c %s -o /dev/null 2>&1 | FileCheck %s -check-prefix CHECK-WINDOWS
+// RUN: %clang -### -target i686-unknown-windows-cygnus -c %s -o /dev/null 2>&1 | FileCheck %s -check-prefix CHECK-WINDOWS
+// RUN: %clang -### -target x86_64-unknown-windows-msvc -c %s -o /dev/null 2>&1 | FileCheck %s -check-prefix CHECK-WINDOWS
+// RUN: %clang -### -target x86_64-unknown-windows-itanium -c %s -o /dev/null 2>&1 | FileCheck %s -check-prefix CHECK-WINDOWS
+// RUN: %clang -### -target x86_64-unknown-windows-gnu -c %s -o /dev/null 2>&1 | FileCheck %s -check-prefix CHECK-WINDOWS
+// RUN: %clang -### -target x86_64-unknown-windows-cygnus -c %s -o /dev/null 2>&1 | FileCheck %s -check-prefix CHECK-WINDOWS
+// RUN: %clang -### -target hexagon-unknown-none -c %s -o /dev/null 2>&1 | FileCheck %s -check-prefix CHECK-HEXAGON
+// RUN: %clang -### -target xcore-unknown-none -c %s -o /dev/null 2>&1 | FileCheck %s -check-prefix CHECK-XCORE
+// RUN: %clang -### -target armv7-mti-none -c %s -o /dev/null 2>&1 | FileCheck %s -check-prefix CHECK-MTI
+// RUN: %clang -### -target mips-unknown-none -c %s -o /dev/null 2>&1 | FileCheck %s -check-prefix CHECK-MIPS
+// RUN: %clang -### -target mips-unknown-none-gnu -c %s -o /dev/null 2>&1 | FileCheck %s -check-prefix CHECK-MIPS
+// RUN: %clang -### -target mips-mti-none-gnu -c %s -o /dev/null 2>&1 | FileCheck %s -check-prefix CHECK-MIPS
+// RUN: %clang -### -target sparc-sun-solaris -c %s -o /dev/null 2>&1 | FileCheck %s -check-prefix CHECK-SOLARIS
+
+// CHECK-WINDOWS: "-fno-use-cxa-atexit"
+// CHECK-SOLARIS: "-fno-use-cxa-atexit"
+// CHECK-HEXAGON: "-fno-use-cxa-atexit"
+// CHECK-XCORE: "-fno-use-cxa-atexit"
+// CHECK-MTI: "-fno-use-cxa-atexit"
+// CHECK-MIPS-NOT: "-fno-use-cxa-atexit"
+
diff --git a/test/Driver/darwin-ld-lto.c b/test/Driver/darwin-ld-lto.c
index 21c2214b771f..2725df4f5f5b 100644
--- a/test/Driver/darwin-ld-lto.c
+++ b/test/Driver/darwin-ld-lto.c
@@ -2,11 +2,11 @@
// Check that ld gets "-lto_library".
-// RUN: mkdir -p %T/bin
-// RUN: mkdir -p %T/lib
-// RUN: touch %T/lib/libLTO.dylib
+// RUN: mkdir -p %t/bin
+// RUN: mkdir -p %t/lib
+// RUN: touch %t/lib/libLTO.dylib
// RUN: %clang -target x86_64-apple-darwin10 -### %s \
-// RUN: -ccc-install-dir %T/bin -mlinker-version=133 2> %t.log
+// RUN: -ccc-install-dir %t/bin -mlinker-version=133 2> %t.log
// RUN: FileCheck -check-prefix=LINK_LTOLIB_PATH %s -input-file %t.log
//
// LINK_LTOLIB_PATH: {{ld(.exe)?"}}
diff --git a/test/Driver/darwin-ld.c b/test/Driver/darwin-ld.c
index 36e7ee53551e..3ddba02a43e8 100644
--- a/test/Driver/darwin-ld.c
+++ b/test/Driver/darwin-ld.c
@@ -341,3 +341,27 @@
// RUN: %clang -target x86_64-apple-darwin12 %t.o -fsave-optimization-record -fprofile-instr-use=blah -### -o foo/bar.out 2> %t.log
// RUN: FileCheck -check-prefix=PASS_REMARKS_WITH_HOTNESS %s < %t.log
// PASS_REMARKS_WITH_HOTNESS: "-mllvm" "-lto-pass-remarks-output" "-mllvm" "foo/bar.out.opt.yaml" "-mllvm" "-lto-pass-remarks-with-hotness"
+
+// RUN: %clang -target x86_64-apple-ios6.0 -miphoneos-version-min=6.0 -fprofile-instr-generate -### %t.o 2> %t.log
+// RUN: FileCheck -check-prefix=LINK_PROFILE_FIRST %s < %t.log
+// RUN: %clang -target x86_64-apple-darwin12 -fprofile-instr-generate -### %t.o 2> %t.log
+// RUN: FileCheck -check-prefix=LINK_PROFILE_FIRST %s < %t.log
+// RUN: %clang -target i386-apple-darwin9 -fprofile-instr-generate -### %t.o 2> %t.log
+// RUN: FileCheck -check-prefix=LINK_PROFILE_FIRST %s < %t.log
+// RUN: %clang -target arm64-apple-ios5.0 -miphoneos-version-min=5.0 -fprofile-instr-generate -### %t.o 2> %t.log
+// RUN: FileCheck -check-prefix=LINK_PROFILE_FIRST %s < %t.log
+// LINK_PROFILE_FIRST: {{ld(.exe)?"}} "{{[^"]+}}libclang_rt.profile_{{[a-z]+}}.a"
+
+// RUN: %clang -target x86_64-apple-darwin12 -fprofile-instr-generate -Wl,-exported_symbols_list,/dev/null -### %t.o 2> %t.log
+// RUN: FileCheck -check-prefix=PROFILE_EXPORT %s < %t.log
+// RUN: %clang -target x86_64-apple-darwin12 -fprofile-instr-generate -Wl,-exported_symbol,foo -### %t.o 2> %t.log
+// RUN: FileCheck -check-prefix=PROFILE_EXPORT %s < %t.log
+// RUN: %clang -target x86_64-apple-darwin12 -fprofile-instr-generate -Xlinker -exported_symbol -Xlinker foo -### %t.o 2> %t.log
+// RUN: FileCheck -check-prefix=PROFILE_EXPORT %s < %t.log
+// RUN: %clang -target x86_64-apple-darwin12 -fprofile-instr-generate -Xlinker -exported_symbols_list -Xlinker /dev/null -### %t.o 2> %t.log
+// RUN: FileCheck -check-prefix=PROFILE_EXPORT %s < %t.log
+// PROFILE_EXPORT: "-exported_symbol" "_VPMergeHook" "-exported_symbol" "___llvm_profile_filename" "-exported_symbol" "___llvm_profile_raw_version" "-exported_symbol" "_lprofCurFilename"
+//
+// RUN: %clang -target x86_64-apple-darwin12 -fprofile-instr-generate -### %t.o 2> %t.log
+// RUN: FileCheck -check-prefix=NO_PROFILE_EXPORT %s < %t.log
+// NO_PROFILE_EXPORT-NOT: "-exported_symbol"
diff --git a/test/Driver/darwin-sdkroot.c b/test/Driver/darwin-sdkroot.c
index 4f1fca2785b0..8b3782ea22a7 100644
--- a/test/Driver/darwin-sdkroot.c
+++ b/test/Driver/darwin-sdkroot.c
@@ -60,7 +60,7 @@
//
// CHECK-SIMULATOR: clang
// CHECK-SIMULATOR: "-cc1"
-// CHECK-SIMULATOR: "-triple" "x86_64-apple-ios8.0.0"
+// CHECK-SIMULATOR: "-triple" "x86_64-apple-ios8.0.0-simulator"
// CHECK-SIMULATOR: ld
// CHECK-SIMULATOR: "-ios_simulator_version_min" "8.0.0"
//
diff --git a/test/Driver/darwin-simulator-macro.c b/test/Driver/darwin-simulator-macro.c
index 6971e9303a6d..cf172997d67f 100644
--- a/test/Driver/darwin-simulator-macro.c
+++ b/test/Driver/darwin-simulator-macro.c
@@ -4,9 +4,8 @@
// RUN: %clang -target x86_64-apple-darwin10 -arch x86_64 -mappletvsimulator-version-min=6.0.0 -E -dM %s | FileCheck -check-prefix=SIM %s
// RUN: %clang -target x86_64-apple-darwin10 -arch x86_64 -mwatchos-simulator-version-min=6.0.0 -E -dM %s | FileCheck -check-prefix=SIM %s
// RUN: %clang -target x86_64-apple-darwin10 -arch x86_64 -mwatchsimulator-version-min=6.0.0 -E -dM %s | FileCheck -check-prefix=SIM %s
-// RUN: %clang -target x86_64-apple-darwin10 -arch x86_64 -mios-version-min=6.0.0 -E -dM %s | FileCheck -check-prefix=DEV %s
-// RUN: %clang -target x86_64-apple-darwin10 -arch x86_64 -mtvos-version-min=6.0.0 -E -dM %s | FileCheck -check-prefix=DEV %s
-// RUN: %clang -target x86_64-apple-darwin10 -arch x86_64 -mwatchos-version-min=6.0.0 -E -dM %s | FileCheck -check-prefix=DEV %s
+// RUN: %clang -target x86_64-apple-darwin10 -arch x86_64 -mios-version-min=6.0.0 -E -dM %s | FileCheck -check-prefix=SIM %s
+// RUN: %clang -target x86_64-apple-darwin10 -arch x86_64 -mtvos-version-min=6.0.0 -E -dM %s | FileCheck -check-prefix=SIM %s
+// RUN: %clang -target x86_64-apple-darwin10 -arch x86_64 -mwatchos-version-min=6.0.0 -E -dM %s | FileCheck -check-prefix=SIM %s
// SIM: #define __APPLE_EMBEDDED_SIMULATOR__ 1
-// DEV-NOT: __APPLE_EMBEDDED_SIMULATOR__
diff --git a/test/Driver/darwin-version.c b/test/Driver/darwin-version.c
index 3ff49aca6c02..9fddb1abcfa6 100644
--- a/test/Driver/darwin-version.c
+++ b/test/Driver/darwin-version.c
@@ -41,7 +41,7 @@
// RUN: %clang -target x86_64-apple-darwin -mios-simulator-version-min=11.0 -c -### %s 2>&1 | \
// RUN: FileCheck --check-prefix=CHECK-VERSION-IOS10 %s
-// CHECK-VERSION-IOS10: x86_64-apple-ios11.0.0
+// CHECK-VERSION-IOS10: x86_64-apple-ios11.0.0-simulator
// RUN: %clang -target arm64-apple-ios11.1 -c -### %s 2>&1 | \
// RUN: FileCheck --check-prefix=CHECK-VERSION-IOS11 %s
@@ -85,13 +85,13 @@
// CHECK-VERSION-TVOS83: "thumbv7-apple-tvos8.3.0"
// RUN: %clang -target i386-apple-darwin -mtvos-simulator-version-min=8.3 -c %s -### 2>&1 | \
// RUN: FileCheck --check-prefix=CHECK-VERSION-TVSIM83 %s
-// CHECK-VERSION-TVSIM83: "i386-apple-tvos8.3.0"
+// CHECK-VERSION-TVSIM83: "i386-apple-tvos8.3.0-simulator"
// RUN: %clang -target armv7k-apple-darwin -mwatchos-version-min=2.0 -c %s -### 2>&1 | \
// RUN: FileCheck --check-prefix=CHECK-VERSION-WATCHOS20 %s
// CHECK-VERSION-WATCHOS20: "thumbv7k-apple-watchos2.0.0"
// RUN: %clang -target i386-apple-darwin -mwatchos-simulator-version-min=2.0 -c %s -### 2>&1 | \
// RUN: FileCheck --check-prefix=CHECK-VERSION-WATCHSIM20 %s
-// CHECK-VERSION-WATCHSIM20: "i386-apple-watchos2.0.0"
+// CHECK-VERSION-WATCHSIM20: "i386-apple-watchos2.0.0-simulator"
// Check environment variable gets interpreted correctly
// RUN: env MACOSX_DEPLOYMENT_TARGET=10.5 IPHONEOS_DEPLOYMENT_TARGET=2.0 \
@@ -117,7 +117,7 @@
// RUN: env TVOS_DEPLOYMENT_TARGET=8.3.1 \
// RUN: %clang -target i386-apple-darwin9 -c %s -### 2>&1 | \
// RUN: FileCheck --check-prefix=CHECK-VERSION-TVOSSIM %s
-// CHECK-VERSION-TVOSSIM: "i386-apple-tvos8.3.1"
+// CHECK-VERSION-TVOSSIM: "i386-apple-tvos8.3.1-simulator"
// RUN: env MACOSX_DEPLOYMENT_TARGET=10.5 WATCHOS_DEPLOYMENT_TARGET=2.0 \
// RUN: %clang -target armv7-apple-darwin9 -c %s -### 2>&1 | \
@@ -126,16 +126,21 @@
// RUN: env WATCHOS_DEPLOYMENT_TARGET=2.0 \
// RUN: %clang -target i386-apple-darwin9 -c %s -### 2>&1 | \
// RUN: FileCheck --check-prefix=CHECK-VERSION-WATCHOSSIM %s
-// CHECK-VERSION-WATCHOSSIM: "i386-apple-watchos2.0.0"
+// CHECK-VERSION-WATCHOSSIM: "i386-apple-watchos2.0.0-simulator"
// RUN: %clang -target x86_64-apple-ios11.0.0 -c %s -### 2>&1 | \
// RUN: FileCheck --check-prefix=CHECK-VERSION-IOS-TARGET %s
-// CHECK-VERSION-IOS-TARGET: "x86_64-apple-ios11.0.0"
+// CHECK-VERSION-IOS-TARGET: "x86_64-apple-ios11.0.0-simulator"
// RUN: %clang -target x86_64-apple-tvos11.0 -c %s -### 2>&1 | \
// RUN: FileCheck --check-prefix=CHECK-VERSION-TVOS-TARGET %s
-// CHECK-VERSION-TVOS-TARGET: "x86_64-apple-tvos11.0.0"
+// CHECK-VERSION-TVOS-TARGET: "x86_64-apple-tvos11.0.0-simulator"
// RUN: %clang -target x86_64-apple-watchos4.0 -c %s -### 2>&1 | \
// RUN: FileCheck --check-prefix=CHECK-VERSION-WATCHOS-TARGET %s
-// CHECK-VERSION-WATCHOS-TARGET: "x86_64-apple-watchos4.0.0"
+// CHECK-VERSION-WATCHOS-TARGET: "x86_64-apple-watchos4.0.0-simulator"
+
+// RUN: env MACOSX_DEPLOYMENT_TARGET=1000.1000 \
+// RUN: %clang -target x86_64-apple-darwin -c %s -### 2>&1 | \
+// RUN: FileCheck --check-prefix=CHECK-VERSION-INVALID-ENV %s
+// CHECK-VERSION-INVALID-ENV: invalid version number in 'MACOSX_DEPLOYMENT_TARGET=1000.1000'
diff --git a/test/Driver/debug-options.c b/test/Driver/debug-options.c
index b4a2e909b3a3..3bec1e141d10 100644
--- a/test/Driver/debug-options.c
+++ b/test/Driver/debug-options.c
@@ -76,6 +76,8 @@
// RUN: | FileCheck -check-prefix=NOCI %s
// RUN: %clang -### -c %s -g -gcolumn-info -target x86_64-scei-ps4 2>&1 \
// RUN: | FileCheck -check-prefix=CI %s
+// RUN: %clang -### -c %s -gsce -target x86_64-unknown-linux 2>&1 \
+// RUN: | FileCheck -check-prefix=NOCI %s
// RUN: %clang -### -c -gdwarf-2 %s 2>&1 \
// RUN: | FileCheck -check-prefix=G_ONLY_DWARF2 %s
@@ -219,7 +221,7 @@
//
// GIGNORE-NOT: "argument unused during compilation"
//
-// GOPT: -generate-gnu-dwarf-pub-sections
+// GOPT: -ggnu-pubnames
//
// GARANGE: -generate-arange-section
//
diff --git a/test/Driver/fast-math.c b/test/Driver/fast-math.c
index 97fda009b9cf..7bb057fcf7d6 100644
--- a/test/Driver/fast-math.c
+++ b/test/Driver/fast-math.c
@@ -93,6 +93,8 @@
// RUN: | FileCheck --check-prefix=CHECK-NO-MATH-ERRNO %s
// RUN: %clang -### -target x86_64-unknown-dragonfly -c %s 2>&1 \
// RUN: | FileCheck --check-prefix=CHECK-NO-MATH-ERRNO %s
+// RUN: %clang -### -target x86_64-fuchsia -c %s 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-NO-MATH-ERRNO %s
//
// Check that -ffast-math disables -fmath-errno, and -fno-fast-math merely
// preserves the target default. Also check various flag set operations between
@@ -119,18 +121,23 @@
// RUN: | FileCheck --check-prefix=CHECK-UNSAFE-MATH %s
// CHECK-UNSAFE-MATH: "-cc1"
// CHECK-UNSAFE-MATH: "-menable-unsafe-fp-math"
+// CHECK-UNSAFE-MATH: "-mreassociate"
//
// RUN: %clang -### -fno-fast-math -fno-math-errno -fassociative-math -freciprocal-math \
// RUN: -fno-signed-zeros -fno-trapping-math -c %s 2>&1 \
// RUN: | FileCheck --check-prefix=CHECK-NO-FAST-MATH-UNSAFE-MATH %s
// CHECK-NO-FAST-MATH-UNSAFE-MATH: "-cc1"
// CHECK-NO-FAST-MATH-UNSAFE-MATH: "-menable-unsafe-fp-math"
-//
+// CHECK-NO-FAST-MATH-UNSAFE-MATH: "-mreassociate"
+
+// The 2nd -fno-fast-math overrides -fassociative-math.
+
// RUN: %clang -### -fno-fast-math -fno-math-errno -fassociative-math -freciprocal-math \
// RUN: -fno-fast-math -fno-signed-zeros -fno-trapping-math -c %s 2>&1 \
// RUN: | FileCheck --check-prefix=CHECK-UNSAFE-MATH-NO-FAST-MATH %s
// CHECK-UNSAFE-MATH-NO-FAST-MATH: "-cc1"
// CHECK-UNSAFE-MATH-NO-FAST-MATH-NOT: "-menable-unsafe-fp-math"
+// CHECK-UNSAFE-MATH-NO-FAST-MATH-NOT: "-mreassociate"
//
// Check that various umbrella flags also enable these frontend options.
// RUN: %clang -### -ffast-math -c %s 2>&1 \
@@ -149,7 +156,7 @@
// One umbrella flag is *really* weird and also changes the semantics of the
// program by adding a special preprocessor macro. Check that the frontend flag
// modeling this semantic change is provided. Also check that the flag is not
-// present if any of the optimization is disabled.
+// present if any of the optimizations are disabled.
// RUN: %clang -### -ffast-math -c %s 2>&1 \
// RUN: | FileCheck --check-prefix=CHECK-FAST-MATH %s
// RUN: %clang -### -fno-fast-math -ffast-math -c %s 2>&1 \
@@ -173,8 +180,11 @@
// RUN: | FileCheck --check-prefix=CHECK-NO-FAST-MATH %s
// RUN: %clang -### -ffast-math -fmath-errno -c %s 2>&1 \
// RUN: | FileCheck --check-prefix=CHECK-NO-FAST-MATH %s
+// RUN: %clang -### -ffast-math -fno-associative-math -c %s 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-NO-FAST-MATH --check-prefix=CHECK-ASSOC-MATH %s
// CHECK-NO-FAST-MATH: "-cc1"
// CHECK-NO-FAST-MATH-NOT: "-ffast-math"
+// CHECK-ASSOC-MATH-NOT: "-mreassociate"
//
// Check various means of disabling these flags, including disabling them after
// they've been enabled via an umbrella flag.
@@ -207,21 +217,16 @@
// CHECK-NO-NO-NANS-NOT: "-menable-no-nans"
// CHECK-NO-NO-NANS-NOT: "-ffinite-math-only"
// CHECK-NO-NO-NANS: "-o"
-//
+
+// A later inverted option overrides an earlier option.
+
// RUN: %clang -### -fassociative-math -freciprocal-math -fno-signed-zeros \
// RUN: -fno-trapping-math -fno-associative-math -c %s 2>&1 \
// RUN: | FileCheck --check-prefix=CHECK-NO-UNSAFE-MATH %s
-// RUN: %clang -### -fassociative-math -freciprocal-math -fno-signed-zeros \
-// RUN: -fno-trapping-math -fno-reciprocal-math -c %s 2>&1 \
-// RUN: | FileCheck --check-prefix=CHECK-NO-UNSAFE-MATH %s
-// RUN: %clang -### -fassociative-math -freciprocal-math -fno-signed-zeros \
-// RUN: -fno-trapping-math -fsigned-zeros -c %s 2>&1 \
-// RUN: | FileCheck --check-prefix=CHECK-NO-UNSAFE-MATH %s
-// RUN: %clang -### -fassociative-math -freciprocal-math -fno-signed-zeros \
-// RUN: -fno-trapping-math -ftrapping-math -c %s 2>&1 \
-// RUN: | FileCheck --check-prefix=CHECK-NO-UNSAFE-MATH %s
+
// RUN: %clang -### -funsafe-math-optimizations -fno-associative-math -c %s \
// RUN: 2>&1 | FileCheck --check-prefix=CHECK-NO-UNSAFE-MATH %s
+
// RUN: %clang -### -funsafe-math-optimizations -fno-reciprocal-math -c %s \
// RUN: 2>&1 | FileCheck --check-prefix=CHECK-NO-UNSAFE-MATH %s
// RUN: %clang -### -funsafe-math-optimizations -fsigned-zeros -c %s 2>&1 \
@@ -233,6 +238,7 @@
// RUN: | FileCheck --check-prefix=CHECK-NO-UNSAFE-MATH %s
// RUN: %clang -### -ffast-math -fno-associative-math -c %s 2>&1 \
// RUN: | FileCheck --check-prefix=CHECK-NO-UNSAFE-MATH %s
+
// RUN: %clang -### -ffast-math -fno-reciprocal-math -c %s 2>&1 \
// RUN: | FileCheck --check-prefix=CHECK-NO-UNSAFE-MATH %s
// RUN: %clang -### -ffast-math -fsigned-zeros -c %s 2>&1 \
@@ -241,10 +247,43 @@
// RUN: | FileCheck --check-prefix=CHECK-NO-UNSAFE-MATH %s
// RUN: %clang -### -ffast-math -fno-unsafe-math-optimizations -c %s 2>&1 \
// RUN: | FileCheck --check-prefix=CHECK-NO-UNSAFE-MATH %s
+
// CHECK-NO-UNSAFE-MATH: "-cc1"
// CHECK-NO-UNSAFE-MATH-NOT: "-menable-unsafe-fp-math"
+// CHECK-NO_UNSAFE-MATH-NOT: "-mreassociate"
// CHECK-NO-UNSAFE-MATH: "-o"
-//
+
+
+// Reassociate is allowed because it does not require reciprocal-math.
+
+// RUN: %clang -### -fassociative-math -freciprocal-math -fno-signed-zeros \
+// RUN: -fno-trapping-math -fno-reciprocal-math -c %s 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-REASSOC-NO-UNSAFE-MATH %s
+
+// CHECK-REASSOC-NO-UNSAFE-MATH: "-cc1"
+// CHECK-REASSOC-NO-UNSAFE-MATH-NOT: "-menable-unsafe-fp-math"
+// CHECK-REASSOC-NO_UNSAFE-MATH: "-mreassociate"
+// CHECK-REASSOC-NO-UNSAFE-MATH-NOT: "-menable-unsafe-fp-math"
+// CHECK-REASSOC-NO-UNSAFE-MATH: "-o"
+
+
+// In these runs, reassociate is not allowed because both no-signed-zeros and no-trapping-math are required.
+
+// RUN: %clang -### -fassociative-math -freciprocal-math -fno-signed-zeros \
+// RUN: -fno-trapping-math -fsigned-zeros -c %s 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-NO-REASSOC-NO-UNSAFE-MATH %s
+
+// RUN: %clang -### -fassociative-math -freciprocal-math -fno-signed-zeros \
+// RUN: -fno-trapping-math -ftrapping-math -c %s 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-NO-REASSOC-NO-UNSAFE-MATH %s
+
+// CHECK-NO-REASSOC-NO-UNSAFE-MATH: "-cc1"
+// CHECK-NO-REASSOC-NO-UNSAFE-MATH-NOT: "-menable-unsafe-fp-math"
+// CHECK-NO-REASSOC-NO_UNSAFE-MATH-NOT: "-mreassociate"
+// CHECK-NO-REASSOC-NO-UNSAFE-MATH-NOT: "-menable-unsafe-fp-math"
+// CHECK-NO-REASSOC-NO-UNSAFE-MATH: "-o"
+
+
// RUN: %clang -### -ftrapping-math -fno-trapping-math -c %s 2>&1 \
// RUN: | FileCheck --check-prefix=CHECK-NO-TRAPPING-MATH %s
// CHECK-NO-TRAPPING-MATH: "-fno-trapping-math"
diff --git a/test/Driver/freebsd.c b/test/Driver/freebsd.c
index f008b76b93ae..0f89d25ac4fa 100644
--- a/test/Driver/freebsd.c
+++ b/test/Driver/freebsd.c
@@ -127,7 +127,7 @@
// RUN: %clang -target x86_64-pc-freebsd8 %s -### -flto 2>&1 \
// RUN: | FileCheck --check-prefix=CHECK-LTO %s
-// CHECK-LTO: ld{{.*}}" "-plugin{{.*}}LLVMgold.so
+// CHECK-LTO: ld{{.*}}" "-plugin{{.*}}{{[/\\]}}LLVMgold.{{dll|dylib|so}}
// RUN: %clang -target sparc-unknown-freebsd8 %s -### -fpic -no-integrated-as 2>&1 \
// RUN: | FileCheck --check-prefix=CHECK-SPARC-PIE %s
diff --git a/test/Driver/fsanitize-blacklist.c b/test/Driver/fsanitize-blacklist.c
index adf776fcae73..0a063753dae2 100644
--- a/test/Driver/fsanitize-blacklist.c
+++ b/test/Driver/fsanitize-blacklist.c
@@ -13,6 +13,7 @@
// RUN: echo "badline" > %t.bad
// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fsanitize-blacklist=%t.good -fsanitize-blacklist=%t.second %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-BLACKLIST
+// RUN: %clang -target aarch64-linux-gnu -fsanitize=hwaddress -fsanitize-blacklist=%t.good -fsanitize-blacklist=%t.second %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-BLACKLIST
// CHECK-BLACKLIST: -fsanitize-blacklist={{.*}}.good" "-fsanitize-blacklist={{.*}}.second
// Now, check for -fdepfile-entry flags.
@@ -20,8 +21,16 @@
// CHECK-BLACKLIST2: -fdepfile-entry={{.*}}.good" "-fdepfile-entry={{.*}}.second
// Check that the default blacklist is not added as an extra dependency.
-// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -resource-dir=%S/Inputs/resource_dir %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-DEFAULT-BLACKLIST --implicit-check-not=fdepfile-entry
-// CHECK-DEFAULT-BLACKLIST: -fsanitize-blacklist={{.*}}asan_blacklist.txt
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -resource-dir=%S/Inputs/resource_dir %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-DEFAULT-BLACKLIST-ASAN --implicit-check-not=fdepfile-entry
+// CHECK-DEFAULT-BLACKLIST-ASAN: -fsanitize-blacklist={{.*[^w]}}asan_blacklist.txt
+// RUN: %clang -target aarch64-linux-gnu -fsanitize=hwaddress -resource-dir=%S/Inputs/resource_dir %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-DEFAULT-BLACKLIST-HWASAN --implicit-check-not=fdepfile-entry
+// CHECK-DEFAULT-BLACKLIST-HWASAN: -fsanitize-blacklist={{.*}}hwasan_blacklist.txt
+
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=integer -resource-dir=%S/Inputs/resource_dir %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-DEFAULT-UBSAN-BLACKLIST --implicit-check-not=fdepfile-entry
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=nullability -resource-dir=%S/Inputs/resource_dir %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-DEFAULT-UBSAN-BLACKLIST --implicit-check-not=fdepfile-entry
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=undefined -resource-dir=%S/Inputs/resource_dir %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-DEFAULT-UBSAN-BLACKLIST --implicit-check-not=fdepfile-entry
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=alignment -resource-dir=%S/Inputs/resource_dir %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-DEFAULT-UBSAN-BLACKLIST --implicit-check-not=fdepfile-entry
+// CHECK-DEFAULT-UBSAN-BLACKLIST: -fsanitize-blacklist={{.*}}ubsan_blacklist.txt
// Ignore -fsanitize-blacklist flag if there is no -fsanitize flag.
// RUN: %clang -target x86_64-linux-gnu -fsanitize-blacklist=%t.good %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-SANITIZE --check-prefix=DELIMITERS
diff --git a/test/Driver/fsanitize-coverage.c b/test/Driver/fsanitize-coverage.c
index b8a9fa60aa88..4073ea4864cd 100644
--- a/test/Driver/fsanitize-coverage.c
+++ b/test/Driver/fsanitize-coverage.c
@@ -6,6 +6,7 @@
// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fsanitize-coverage=func,trace-pc %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANITIZE-COVERAGE-FUNC
// RUN: %clang -target x86_64-linux-gnu -fsanitize=kernel-address -fsanitize-coverage=func,trace-pc %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANITIZE-COVERAGE-FUNC
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=hwaddress -fsanitize-coverage=func,trace-pc %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANITIZE-COVERAGE-FUNC
// RUN: %clang -target x86_64-linux-gnu -fsanitize=memory -fsanitize-coverage=func,trace-pc %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANITIZE-COVERAGE-FUNC
// RUN: %clang -target x86_64-linux-gnu -fsanitize=leak -fsanitize-coverage=func,trace-pc %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANITIZE-COVERAGE-FUNC
// RUN: %clang -target x86_64-linux-gnu -fsanitize=undefined -fsanitize-coverage=func,trace-pc %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANITIZE-COVERAGE-FUNC
@@ -72,6 +73,17 @@
// CHECK-TRACE_PC_GUARD_FUNC: -fsanitize-coverage-type=1
// CHECK-TRACE_PC_GUARD_FUNC: -fsanitize-coverage-trace-pc-guard
+// RUN: %clang -target x86_64-linux-gnu -fsanitize-coverage=stack-depth %s \
+// RUN: -### 2>&1 | FileCheck %s --check-prefix=CHECK-STACK-DEPTH
+// RUN: %clang -target x86_64-linux-gnu \
+// RUN: -fsanitize-coverage=trace-pc-guard,stack-depth %s -### 2>&1 | \
+// RUN: FileCheck %s --check-prefix=CHECK-STACK-DEPTH-PC-GUARD
+// CHECK-STACK-DEPTH: -fsanitize-coverage-type=1
+// CHECK-STACK-DEPTH: -fsanitize-coverage-stack-depth
+// CHECK-STACK-DEPTH-PC-GUARD: -fsanitize-coverage-type=3
+// CHECK-STACK-DEPTH-PC-GUARD: -fsanitize-coverage-trace-pc-guard
+// CHECK-STACK-DEPTH-PC-GUARD: -fsanitize-coverage-stack-depth
+
// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fsanitize-coverage=trace-cmp,indirect-calls %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-TYPE-NECESSARY
// CHECK-NO-TYPE-NECESSARY-NOT: error:
// CHECK-NO-TYPE-NECESSARY: -fsanitize-coverage-indirect-calls
@@ -86,8 +98,14 @@
// CHECK_NOPRUNE: -fsanitize-coverage-no-prune
// RUN: %clang -target x86_64-linux-gnu -fsanitize-coverage=inline-8bit-counters %s -### 2>&1 | FileCheck %s --check-prefix=CHECK_INLINE8BIT
+// RUN: %clang -target x86_64-linux-gnu -fsanitize-coverage=bb,inline-8bit-counters %s -### 2>&1 | FileCheck %s --check-prefix=CHECK_INLINE8BIT
+// CHECK_INLINE8BIT-NOT: warning
// CHECK_INLINE8BIT: -fsanitize-coverage-inline-8bit-counters
+// RUN: %clang -target x86_64-linux-gnu -fsanitize-coverage=inline-8bit-counters,pc-table %s -### 2>&1 | FileCheck %s --check-prefix=CHECK_PC_TABLE
+// RUN: %clang -target x86_64-linux-gnu -fsanitize-coverage=trace-pc-guard,pc-table %s -### 2>&1 | FileCheck %s --check-prefix=CHECK_PC_TABLE
+// CHECK_PC_TABLE: -fsanitize-coverage-pc-table
+
// RUN: %clang_cl --target=i386-pc-win32 -fsanitize=address -fsanitize-coverage=func,trace-pc-guard -c -### -- %s 2>&1 | FileCheck %s -check-prefix=CLANG-CL-COVERAGE
// CLANG-CL-COVERAGE-NOT: error:
// CLANG-CL-COVERAGE-NOT: warning:
@@ -95,3 +113,15 @@
// CLANG-CL-COVERAGE-NOT: unknown argument
// CLANG-CL-COVERAGE: -fsanitize-coverage-type=1
// CLANG-CL-COVERAGE: -fsanitize=address
+
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=safe-stack -fsanitize-coverage=trace-pc-guard %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-VS-SAFESTACK
+// CHECK-VS-SAFESTACK: -fsanitize=safe-stack
+// CHECK-VS-SAFESTACK-NOT: -fsanitize-coverage-trace-pc-guard
+
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=safe-stack -fsanitize-coverage=trace-pc-guard -fno-sanitize=safe-stack %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-SAFESTACK
+// CHECK-NO-SAFESTACK-NOT: error:
+// CHECK-NO-SAFESTACK-NOT: warning:
+// CHECK-NO-SAFESTACK-NOT: argument unused
+// CHECK-NO-SAFESTACK-NOT: unknown argument
+// CHECK-NO-SAFESTACK-NOT: -fsanitize=safe-stack
+// CHECK-NO-SAFESTACK: -fsanitize-coverage-trace-pc-guard
diff --git a/test/Driver/fsanitize.c b/test/Driver/fsanitize.c
index 0752ef6df090..eb8eab574cb1 100644
--- a/test/Driver/fsanitize.c
+++ b/test/Driver/fsanitize.c
@@ -3,18 +3,18 @@
// RUN: %clang -target x86_64-linux-gnu -fsanitize=undefined -fsanitize-undefined-trap-on-error %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-TRAP
// RUN: %clang -target x86_64-linux-gnu -fsanitize=undefined-trap -fsanitize-undefined-trap-on-error %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-TRAP
// RUN: %clang -target x86_64-linux-gnu -fsanitize-undefined-trap-on-error -fsanitize=undefined-trap %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-TRAP
-// CHECK-UNDEFINED-TRAP: "-fsanitize={{((signed-integer-overflow|integer-divide-by-zero|float-divide-by-zero|shift-base|shift-exponent|unreachable|return|vla-bound|alignment|null|pointer-overflow|float-cast-overflow|array-bounds|enum|bool|returns-nonnull-attribute|nonnull-attribute|function),?){18}"}}
-// CHECK-UNDEFINED-TRAP: "-fsanitize-trap=alignment,array-bounds,bool,enum,float-cast-overflow,float-divide-by-zero,function,integer-divide-by-zero,nonnull-attribute,null,pointer-overflow,return,returns-nonnull-attribute,shift-base,shift-exponent,signed-integer-overflow,unreachable,vla-bound"
-// CHECK-UNDEFINED-TRAP2: "-fsanitize-trap=alignment,array-bounds,bool,enum,float-cast-overflow,float-divide-by-zero,function,integer-divide-by-zero,nonnull-attribute,null,pointer-overflow,return,returns-nonnull-attribute,shift-base,shift-exponent,unreachable,vla-bound"
+// CHECK-UNDEFINED-TRAP: "-fsanitize={{((signed-integer-overflow|integer-divide-by-zero|float-divide-by-zero|shift-base|shift-exponent|unreachable|return|vla-bound|alignment|null|pointer-overflow|float-cast-overflow|array-bounds|enum|bool|builtin|returns-nonnull-attribute|nonnull-attribute|function),?){19}"}}
+// CHECK-UNDEFINED-TRAP: "-fsanitize-trap=alignment,array-bounds,bool,builtin,enum,float-cast-overflow,float-divide-by-zero,function,integer-divide-by-zero,nonnull-attribute,null,pointer-overflow,return,returns-nonnull-attribute,shift-base,shift-exponent,signed-integer-overflow,unreachable,vla-bound"
+// CHECK-UNDEFINED-TRAP2: "-fsanitize-trap=alignment,array-bounds,bool,builtin,enum,float-cast-overflow,float-divide-by-zero,function,integer-divide-by-zero,nonnull-attribute,null,pointer-overflow,return,returns-nonnull-attribute,shift-base,shift-exponent,unreachable,vla-bound"
// RUN: %clang -target x86_64-linux-gnu -fsanitize=undefined %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED
-// CHECK-UNDEFINED: "-fsanitize={{((signed-integer-overflow|integer-divide-by-zero|float-divide-by-zero|function|shift-base|shift-exponent|unreachable|return|vla-bound|alignment|null|vptr|pointer-overflow|float-cast-overflow|array-bounds|enum|bool|returns-nonnull-attribute|nonnull-attribute),?){19}"}}
+// CHECK-UNDEFINED: "-fsanitize={{((signed-integer-overflow|integer-divide-by-zero|float-divide-by-zero|function|shift-base|shift-exponent|unreachable|return|vla-bound|alignment|null|vptr|pointer-overflow|float-cast-overflow|array-bounds|enum|bool|builtin|returns-nonnull-attribute|nonnull-attribute),?){20}"}}
// RUN: %clang -target x86_64-apple-darwin10 -fsanitize=undefined %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-DARWIN
-// CHECK-UNDEFINED-DARWIN: "-fsanitize={{((signed-integer-overflow|integer-divide-by-zero|float-divide-by-zero|shift-base|shift-exponent|unreachable|return|vla-bound|alignment|null|pointer-overflow|float-cast-overflow|array-bounds|enum|bool|returns-nonnull-attribute|nonnull-attribute),?){17}"}}
+// CHECK-UNDEFINED-DARWIN: "-fsanitize={{((signed-integer-overflow|integer-divide-by-zero|float-divide-by-zero|function|shift-base|shift-exponent|unreachable|return|vla-bound|alignment|null|pointer-overflow|float-cast-overflow|array-bounds|enum|bool|builtin|returns-nonnull-attribute|nonnull-attribute),?){19}"}}
// RUN: %clang -target i386-unknown-openbsd -fsanitize=undefined %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-OPENBSD
-// CHECK-UNDEFINED-OPENBSD: "-fsanitize={{((signed-integer-overflow|integer-divide-by-zero|float-divide-by-zero|shift-base|shift-exponent|unreachable|return|vla-bound|alignment|null|pointer-overflow|float-cast-overflow|array-bounds|enum|bool|returns-nonnull-attribute|nonnull-attribute),?){17}"}}
+// CHECK-UNDEFINED-OPENBSD: "-fsanitize={{((signed-integer-overflow|integer-divide-by-zero|float-divide-by-zero|shift-base|shift-exponent|unreachable|return|vla-bound|alignment|null|pointer-overflow|float-cast-overflow|array-bounds|enum|bool|builtin|returns-nonnull-attribute|nonnull-attribute),?){18}"}}
// RUN: %clang -target i386-pc-win32 -fsanitize=undefined %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-WIN --check-prefix=CHECK-UNDEFINED-WIN32
// RUN: %clang -target i386-pc-win32 -fsanitize=undefined -x c++ %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-WIN --check-prefix=CHECK-UNDEFINED-WIN32 --check-prefix=CHECK-UNDEFINED-WIN-CXX
@@ -23,7 +23,7 @@
// CHECK-UNDEFINED-WIN32: "--dependent-lib={{[^"]*}}ubsan_standalone-i386.lib"
// CHECK-UNDEFINED-WIN64: "--dependent-lib={{[^"]*}}ubsan_standalone-x86_64.lib"
// CHECK-UNDEFINED-WIN-CXX: "--dependent-lib={{[^"]*}}ubsan_standalone_cxx{{[^"]*}}.lib"
-// CHECK-UNDEFINED-WIN-SAME: "-fsanitize={{((signed-integer-overflow|integer-divide-by-zero|float-divide-by-zero|shift-base|shift-exponent|unreachable|return|vla-bound|alignment|null|pointer-overflow|float-cast-overflow|array-bounds|enum|bool|returns-nonnull-attribute|nonnull-attribute),?){17}"}}
+// CHECK-UNDEFINED-WIN-SAME: "-fsanitize={{((signed-integer-overflow|integer-divide-by-zero|float-divide-by-zero|shift-base|shift-exponent|unreachable|return|vla-bound|alignment|null|pointer-overflow|float-cast-overflow|array-bounds|enum|bool|builtin|returns-nonnull-attribute|nonnull-attribute),?){18}"}}
// RUN: %clang -target i386-pc-win32 -fsanitize-coverage=bb %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-COVERAGE-WIN32
// CHECK-COVERAGE-WIN32: "--dependent-lib={{[^"]*}}ubsan_standalone-i386.lib"
@@ -42,7 +42,7 @@
// RUN: %clang -target x86_64-linux-gnu -fsanitize=address,undefined -fno-sanitize=all -fsanitize=thread %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-FNO-SANITIZE-ALL
// CHECK-FNO-SANITIZE-ALL: "-fsanitize=thread"
-// RUN: %clang -target x86_64-linux-gnu -fsanitize=thread,undefined -fno-sanitize=thread -fno-sanitize=float-cast-overflow,vptr,bool,enum %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-PARTIAL-UNDEFINED
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=thread,undefined -fno-sanitize=thread -fno-sanitize=float-cast-overflow,vptr,bool,builtin,enum %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-PARTIAL-UNDEFINED
// CHECK-PARTIAL-UNDEFINED: "-fsanitize={{((signed-integer-overflow|integer-divide-by-zero|float-divide-by-zero|function|shift-base|shift-exponent|unreachable|return|vla-bound|alignment|null|pointer-overflow|array-bounds|returns-nonnull-attribute|nonnull-attribute),?){15}"}}
// RUN: %clang -target x86_64-linux-gnu -fsanitize=shift -fno-sanitize=shift-base %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-FSANITIZE-SHIFT-PARTIAL
@@ -85,6 +85,15 @@
// RUN: %clang -target x86_64-linux-gnu -fsanitize=kernel-address,address -fno-rtti %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANKA-SANA
// CHECK-SANKA-SANA: '-fsanitize=kernel-address' not allowed with '-fsanitize=address'
+// RUN: %clang -target aarch64-linux-gnu -fsanitize=hwaddress,thread -fno-rtti %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANHA-SANT
+// CHECK-SANHA-SANT: '-fsanitize=hwaddress' not allowed with '-fsanitize=thread'
+
+// RUN: %clang -target aarch64-linux-gnu -fsanitize=hwaddress,memory -pie -fno-rtti %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANHA-SANM
+// CHECK-SANHA-SANM: '-fsanitize=hwaddress' not allowed with '-fsanitize=memory'
+
+// RUN: %clang -target aarch64-linux-gnu -fsanitize=hwaddress,address -fno-rtti %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANHA-SANA
+// CHECK-SANHA-SANA: '-fsanitize=hwaddress' not allowed with '-fsanitize=address'
+
// RUN: %clang -target x86_64-linux-gnu -fsanitize=kernel-address,leak -pie -fno-rtti %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANKA-SANL
// CHECK-SANKA-SANL: '-fsanitize=kernel-address' not allowed with '-fsanitize=leak'
@@ -172,8 +181,14 @@
// RUN: %clang -target x86_64-linux-gnu -fsanitize=memory -fsanitize-memory-track-origins=3 -pie %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TRACK-ORIGINS-3
// CHECK-TRACK-ORIGINS-3: error: invalid value '3' in '-fsanitize-memory-track-origins=3'
-// RUN: %clang -target x86_64-linux-gnu -fsanitize=memory -fsanitize-memory-use-after-dtor -pie %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-MSAN-USE-AFTER-DTOR
-// CHECK-MSAN-USE-AFTER-DTOR: -cc1{{.*}}-fsanitize-memory-use-after-dtor
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=memory -fsanitize-memory-use-after-dtor %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-USE-AFTER-DTOR
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=memory -fno-sanitize-memory-use-after-dtor -fsanitize-memory-use-after-dtor %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-USE-AFTER-DTOR
+// CHECK-USE-AFTER-DTOR: -cc1{{.*}}-fsanitize-memory-use-after-dtor
+
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=memory -fno-sanitize-memory-use-after-dtor %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-USE-AFTER-DTOR-OFF
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=memory -fsanitize-memory-use-after-dtor -fno-sanitize-memory-use-after-dtor %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-USE-AFTER-DTOR-OFF
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=memory %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-USE-AFTER-DTOR-OFF
+// CHECK-USE-AFTER-DTOR-OFF-NOT: -cc1{{.*}}memory-use-after-dtor
// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fsanitize-address-field-padding=0 %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-FIELD-PADDING-0
// CHECK-ASAN-FIELD-PADDING-0-NOT: -fsanitize-address-field-padding
@@ -196,7 +211,9 @@
// RUN: %clang -target x86_64-linux-gnu -fsanitize=memory %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-PIE
// RUN: %clang -target x86_64-unknown-freebsd -fsanitize=memory %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-PIE
// RUN: %clang -target aarch64-linux-gnu -fsanitize=memory %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-PIE
-// RUN: %clang -target arm-linux-androideabi -fsanitize=address %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-PIE
+// RUN: %clang -target arm-linux-androideabi -fsanitize=address %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-PIC-NO-PIE
+// RUN: %clang -target arm-linux-androideabi24 -fsanitize=address %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-PIE
+// RUN: %clang -target aarch64-linux-android -fsanitize=address %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-PIE
// RUN: %clang -target x86_64-linux-gnu -fsanitize=address %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-PIE
// RUN: %clang -target i386-linux-gnu -fsanitize=address %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-PIE
@@ -204,6 +221,10 @@
// CHECK-NO-PIE: "-mrelocation-model" "static"
// CHECK-NO-PIE-NOT: "-pie"
+// CHECK-PIC-NO-PIE-NOT: "-pie"
+// CHECK-PIC-NO-PIE: "-mrelocation-model" "pic"
+// CHECK-PIC-NO-PIE-NOT: "-pie"
+
// CHECK-PIE: "-mrelocation-model" "pic" "-pic-level" "2" "-pic-is-pie"
// CHECK-PIE: "-pie"
@@ -217,7 +238,7 @@
// RUN: %clang -target x86_64-linux-gnu %s -fsanitize=undefined -fno-sanitize-recover=undefined -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-RECOVER-UBSAN
// RUN: %clang -target x86_64-linux-gnu %s -fsanitize=undefined -fno-sanitize-recover=all -fsanitize-recover=thread -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-RECOVER-UBSAN
// RUN: %clang -target x86_64-linux-gnu %s -fsanitize=undefined -fsanitize-recover=all -fno-sanitize-recover=undefined -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-RECOVER-UBSAN
-// CHECK-RECOVER-UBSAN: "-fsanitize-recover={{((signed-integer-overflow|integer-divide-by-zero|float-divide-by-zero|function|shift-base|shift-exponent|vla-bound|alignment|null|vptr|pointer-overflow|float-cast-overflow|array-bounds|enum|bool|returns-nonnull-attribute|nonnull-attribute),?){17}"}}
+// CHECK-RECOVER-UBSAN: "-fsanitize-recover={{((signed-integer-overflow|integer-divide-by-zero|float-divide-by-zero|function|shift-base|shift-exponent|vla-bound|alignment|null|vptr|pointer-overflow|float-cast-overflow|array-bounds|enum|bool|builtin|returns-nonnull-attribute|nonnull-attribute),?){18}"}}
// CHECK-NO-RECOVER-UBSAN-NOT: sanitize-recover
// RUN: %clang -target x86_64-linux-gnu %s -fsanitize=undefined -fno-sanitize-recover=all -fsanitize-recover=object-size,shift-base -### 2>&1 | FileCheck %s --check-prefix=CHECK-PARTIAL-RECOVER
@@ -274,6 +295,9 @@
// RUN: %clang -target mips-unknown-linux -fsanitize=leak %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANL-MIPS
// CHECK-SANL-MIPS: unsupported option '-fsanitize=leak' for target 'mips-unknown-linux'
+// RUN: %clang -target powerpc64-unknown-linux -fsanitize=leak %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANL-PPC64
+// RUN: %clang -target powerpc64le-unknown-linux -fsanitize=leak %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANL-PPC64
+// CHECK-SANL-PPC64: "-fsanitize=leak"
// RUN: %clang -target powerpc-unknown-linux -fsanitize=leak %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANL-PPC
// CHECK-SANL-PPC: unsupported option '-fsanitize=leak' for target 'powerpc-unknown-linux'
@@ -319,10 +343,10 @@
// CHECK-TSAN-ARM-IOS: unsupported option '-fsanitize=thread' for target 'arm-apple-ios'
// RUN: %clang -target i386-apple-iossimulator -fsanitize=thread %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TSAN-I386-IOSSIMULATOR
-// CHECK-TSAN-I386-IOSSIMULATOR: unsupported option '-fsanitize=thread' for target 'i386-apple-iossimulator'
+// CHECK-TSAN-I386-IOSSIMULATOR: unsupported option '-fsanitize=thread' for target 'i386-apple-iossimulator-simulator'
// RUN: %clang -target i386-apple-tvossimulator -fsanitize=thread %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TSAN-I386-TVOSSIMULATOR
-// CHECK-TSAN-I386-TVOSSIMULATOR: unsupported option '-fsanitize=thread' for target 'i386-apple-tvossimulator'
+// CHECK-TSAN-I386-TVOSSIMULATOR: unsupported option '-fsanitize=thread' for target 'i386-apple-tvossimulator-simulator'
// RUN: %clang -target x86_64-linux-gnu -fsanitize=thread -fsanitize-thread-memory-access %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TSAN-MEMORY-ACCESS
// CHECK-TSAN-MEMORY-ACCESS-NOT: -cc1{{.*}}tsan-instrument-memory-accesses=0
@@ -354,10 +378,8 @@
// CHECK-TSAN-ATOMICS-BOTH-OFF: -cc1{{.*}}tsan-instrument-atomics=0
// RUN: %clang -target x86_64-apple-darwin10 -fsanitize=function %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-FSAN-DARWIN
-// CHECK-FSAN-DARWIN: unsupported option '-fsanitize=function' for target 'x86_64-apple-darwin10'
-
-// RUN: %clang -target x86_64-apple-darwin10 -fsanitize=function -fsanitize=undefined %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-FSAN-UBSAN-DARWIN
-// CHECK-FSAN-UBSAN-DARWIN: unsupported option '-fsanitize=function' for target 'x86_64-apple-darwin10'
+// RUN: %clang -target i386-apple-darwin10 -fsanitize=function %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-FSAN-DARWIN
+// CHECK-FSAN-DARWIN: -cc1{{.*}}"-fsanitize=function" "-fsanitize-recover=function"
// RUN: %clang -target x86_64-apple-darwin10 -mmacosx-version-min=10.8 -fsanitize=vptr %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-VPTR-DARWIN-OLD
// CHECK-VPTR-DARWIN-OLD: unsupported option '-fsanitize=vptr' for target 'x86_64-apple-darwin10'
@@ -410,11 +432,11 @@
// RUN: %clang -target i386-apple-iossimulator -fsanitize=efficiency-cache-frag %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ESAN-I386-IOSSIMULATOR
// RUN: %clang -target i386-apple-iossimulator -fsanitize=efficiency-working-set %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ESAN-I386-IOSSIMULATOR
-// CHECK-ESAN-I386-IOSSIMULATOR: unsupported option '-fsanitize=efficiency-{{.*}}' for target 'i386-apple-iossimulator'
+// CHECK-ESAN-I386-IOSSIMULATOR: unsupported option '-fsanitize=efficiency-{{.*}}' for target 'i386-apple-iossimulator-simulator'
// RUN: %clang -target i386-apple-tvossimulator -fsanitize=efficiency-cache-frag %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ESAN-I386-TVOSSIMULATOR
// RUN: %clang -target i386-apple-tvossimulator -fsanitize=efficiency-working-set %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ESAN-I386-TVOSSIMULATOR
-// CHECK-ESAN-I386-TVOSSIMULATOR: unsupported option '-fsanitize=efficiency-{{.*}}' for target 'i386-apple-tvossimulator'
+// CHECK-ESAN-I386-TVOSSIMULATOR: unsupported option '-fsanitize=efficiency-{{.*}}' for target 'i386-apple-tvossimulator-simulator'
@@ -451,6 +473,9 @@
// RUN: %clang -target x86_64-linux-gnu -fsanitize-trap=address -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-TRAP
// CHECK-ASAN-TRAP: error: unsupported argument 'address' to option '-fsanitize-trap'
+// RUN: %clang -target aarch64-linux-gnu -fsanitize-trap=hwaddress -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-HWASAN-TRAP
+// CHECK-HWASAN-TRAP: error: unsupported argument 'hwaddress' to option '-fsanitize-trap'
+
// RUN: %clang -target x86_64-apple-darwin10 -mmacosx-version-min=10.7 -flto -fsanitize=cfi-vcall -fno-sanitize-trap=cfi -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CFI-NOTRAP-OLD-MACOS
// CHECK-CFI-NOTRAP-OLD-MACOS: error: unsupported option '-fno-sanitize-trap=cfi-vcall' for target 'x86_64-apple-darwin10'
@@ -467,6 +492,14 @@
// CHECK-CFI-NO-CROSS-DSO: -emit-llvm-bc
// CHECK-CFI-NO-CROSS-DSO-NOT: -fsanitize-cfi-cross-dso
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=cfi-icall -fsanitize-cfi-icall-generalize-pointers -fvisibility=hidden -flto -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CFI-GENERALIZE-POINTERS
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=cfi-icall -fvisibility=hidden -flto -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-CFI-GENERALIZE-POINTERS
+// CHECK-CFI-GENERALIZE-POINTERS: -fsanitize-cfi-icall-generalize-pointers
+// CHECK-NO-CFI-GENERALIZE-POINTERS-NOT: -fsanitize-cfi-icall-generalize-pointers
+
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=cfi-icall -fsanitize-cfi-icall-generalize-pointers -fsanitize-cfi-cross-dso -fvisibility=hidden -flto -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CFI-GENERALIZE-AND-CROSS-DSO
+// CHECK-CFI-GENERALIZE-AND-CROSS-DSO: error: invalid argument '-fsanitize-cfi-cross-dso' not allowed with '-fsanitize-cfi-icall-generalize-pointers'
+
// RUN: %clang -target x86_64-linux-gnu -fsanitize=cfi -fsanitize-stats -flto -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CFI-STATS
// CHECK-CFI-STATS: -fsanitize-stats
@@ -516,6 +549,29 @@
// RUN: %clang -target x86_64-unknown-cloudabi -fsanitize=safe-stack %s -### 2>&1 | FileCheck %s -check-prefix=SAFESTACK-CLOUDABI
// SAFESTACK-CLOUDABI: "-fsanitize=safe-stack"
+// RUN: %clang -target i386--netbsd -fsanitize=address %s -### 2>&1 | FileCheck %s -check-prefix=ADDRESS-NETBSD
+// RUN: %clang -target x86_64--netbsd -fsanitize=address %s -### 2>&1 | FileCheck %s -check-prefix=ADDRESS-NETBSD
+// ADDRESS-NETBSD: "-fsanitize=address"
+
+// RUN: %clang -target i386--netbsd -fsanitize=vptr %s -### 2>&1 | FileCheck %s -check-prefix=VPTR-NETBSD
+// RUN: %clang -target x86_64--netbsd -fsanitize=vptr %s -### 2>&1 | FileCheck %s -check-prefix=VPTR-NETBSD
+// VPTR-NETBSD: "-fsanitize=vptr"
+
+// RUN: %clang -target i386--netbsd -fsanitize=safe-stack %s -### 2>&1 | FileCheck %s -check-prefix=SAFESTACK-NETBSD
+// RUN: %clang -target x86_64--netbsd -fsanitize=safe-stack %s -### 2>&1 | FileCheck %s -check-prefix=SAFESTACK-NETBSD
+// SAFESTACK-NETBSD: "-fsanitize=safe-stack"
+
+// RUN: %clang -target i386--netbsd -fsanitize=function %s -### 2>&1 | FileCheck %s -check-prefix=FUNCTION-NETBSD
+// RUN: %clang -target x86_64--netbsd -fsanitize=function %s -### 2>&1 | FileCheck %s -check-prefix=FUNCTION-NETBSD
+// FUNCTION-NETBSD: "-fsanitize=function"
+
+// RUN: %clang -target i386--netbsd -fsanitize=leak %s -### 2>&1 | FileCheck %s -check-prefix=LEAK-NETBSD
+// RUN: %clang -target x86_64--netbsd -fsanitize=leak %s -### 2>&1 | FileCheck %s -check-prefix=LEAK-NETBSD
+// LEAK-NETBSD: "-fsanitize=leak"
+
+// RUN: %clang -target x86_64--netbsd -fsanitize=thread %s -### 2>&1 | FileCheck %s -check-prefix=THREAD-NETBSD
+// THREAD-NETBSD: "-fsanitize=thread"
+
// RUN: %clang -target x86_64-scei-ps4 -fsanitize=function -fsanitize=undefined %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-FSAN-UBSAN-PS4
// CHECK-FSAN-UBSAN-PS4: unsupported option '-fsanitize=function' for target 'x86_64-scei-ps4'
// RUN: %clang -target x86_64-scei-ps4 -fsanitize=function %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-FSAN-PS4
@@ -535,3 +591,65 @@
// Make sure there are no *.{o,bc} or -l passed before the ASan library.
// CHECK-ASAN-PS4-NOT: {{(\.(o|bc)"? |-l).*-lSceDbgAddressSanitizer_stub_weak}}
// CHECK-ASAN-PS4: -lSceDbgAddressSanitizer_stub_weak
+
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fsanitize-minimal-runtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-MINIMAL
+// CHECK-ASAN-MINIMAL: error: invalid argument '-fsanitize-minimal-runtime' not allowed with '-fsanitize=address'
+
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=thread -fsanitize-minimal-runtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TSAN-MINIMAL
+// CHECK-TSAN-MINIMAL: error: invalid argument '-fsanitize-minimal-runtime' not allowed with '-fsanitize=thread'
+
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=undefined -fsanitize-minimal-runtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UBSAN-MINIMAL
+// CHECK-UBSAN-MINIMAL: "-fsanitize={{((signed-integer-overflow|integer-divide-by-zero|float-divide-by-zero|shift-base|shift-exponent|unreachable|return|vla-bound|alignment|null|pointer-overflow|float-cast-overflow|array-bounds|enum|bool|builtin|returns-nonnull-attribute|nonnull-attribute|function),?){19}"}}
+// CHECK-UBSAN-MINIMAL: "-fsanitize-minimal-runtime"
+
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=undefined -fsanitize=vptr -fsanitize-minimal-runtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UBSAN-VPTR-MINIMAL
+// CHECK-UBSAN-VPTR-MINIMAL: error: invalid argument '-fsanitize=vptr' not allowed with '-fsanitize-minimal-runtime'
+
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fsanitize-minimal-runtime -fsanitize=undefined %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-UBSAN-MINIMAL
+// CHECK-ASAN-UBSAN-MINIMAL: error: invalid argument '-fsanitize-minimal-runtime' not allowed with '-fsanitize=address'
+// RUN: %clang -target aarch64-linux-gnu -fsanitize=hwaddress -fsanitize-minimal-runtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-HWASAN-MINIMAL
+// CHECK-HWASAN-MINIMAL: error: invalid argument '-fsanitize-minimal-runtime' not allowed with '-fsanitize=hwaddress'
+
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=cfi -flto -fvisibility=hidden -fsanitize-minimal-runtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CFI-MINIMAL
+// CHECK-CFI-MINIMAL: "-fsanitize=cfi-derived-cast,cfi-icall,cfi-unrelated-cast,cfi-nvcall,cfi-vcall"
+// CHECK-CFI-MINIMAL: "-fsanitize-trap=cfi-derived-cast,cfi-icall,cfi-unrelated-cast,cfi-nvcall,cfi-vcall"
+// CHECK-CFI-MINIMAL: "-fsanitize-minimal-runtime"
+
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=cfi -fno-sanitize-trap=cfi-icall -flto -fvisibility=hidden -fsanitize-minimal-runtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CFI-NOTRAP-MINIMAL
+// CHECK-CFI-NOTRAP-MINIMAL: error: invalid argument 'fsanitize-minimal-runtime' only allowed with 'fsanitize-trap=cfi'
+
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=cfi -fno-sanitize-trap=cfi-icall -fno-sanitize=cfi-icall -flto -fvisibility=hidden -fsanitize-minimal-runtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CFI-NOICALL-MINIMAL
+// CHECK-CFI-NOICALL-MINIMAL: "-fsanitize=cfi-derived-cast,cfi-unrelated-cast,cfi-nvcall,cfi-vcall"
+// CHECK-CFI-NOICALL-MINIMAL: "-fsanitize-trap=cfi-derived-cast,cfi-unrelated-cast,cfi-nvcall,cfi-vcall"
+// CHECK-CFI-NOICALL-MINIMAL: "-fsanitize-minimal-runtime"
+
+// RUN: %clang -target aarch64-linux-gnu -fsanitize=scudo %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SCUDO
+// RUN: %clang -target arm-linux-androideabi -fsanitize=scudo %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SCUDO
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=scudo %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SCUDO
+// RUN: %clang -target i386-linux-gnu -fsanitize=scudo %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SCUDO
+// CHECK-SCUDO: "-fsanitize=scudo"
+
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=scudo %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SCUDO-PIE
+// RUN: %clang -target arm-linux-androideabi -fsanitize=scudo %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SCUDO-PIE
+// CHECK-SCUDO-PIE: "-mrelocation-model" "pic" "-pic-level" "2" "-pic-is-pie"
+// CHECK-SCUDO-PIE: "-pie"
+
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=scudo,undefined %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SCUDO-UBSAN
+// CHECK-SCUDO-UBSAN: "-fsanitize={{.*}}scudo"
+
+// RUN: %clang -target powerpc-unknown-linux -fsanitize=scudo %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-SCUDO
+// CHECK-NO-SCUDO: unsupported option
+
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=scudo,address %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SCUDO-ASAN
+// CHECK-SCUDO-ASAN: error: invalid argument '-fsanitize=scudo' not allowed with '-fsanitize=address'
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=scudo,leak %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SCUDO-LSAN
+// CHECK-SCUDO-LSAN: error: invalid argument '-fsanitize=scudo' not allowed with '-fsanitize=leak'
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=scudo,memory %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SCUDO-MSAN
+// CHECK-SCUDO-MSAN: error: invalid argument '-fsanitize=scudo' not allowed with '-fsanitize=memory'
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=scudo,thread %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SCUDO-TSAN
+// CHECK-SCUDO-TSAN: error: invalid argument '-fsanitize=scudo' not allowed with '-fsanitize=thread'
+// RUN: %clang -target aarch64-linux-gnu -fsanitize=scudo,hwaddress %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SCUDO-HWASAN
+// CHECK-SCUDO-HWASAN: error: invalid argument '-fsanitize=scudo' not allowed with '-fsanitize=hwaddress'
+
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=hwaddress %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANHA-X86_64
+// CHECK-SANHA-X86_64: unsupported option '-fsanitize=hwaddress' for target
diff --git a/test/Driver/fuchsia.c b/test/Driver/fuchsia.c
index 405086f3f07e..eb413b7509be 100644
--- a/test/Driver/fuchsia.c
+++ b/test/Driver/fuchsia.c
@@ -1,20 +1,27 @@
// RUN: %clang %s -### -no-canonical-prefixes --target=x86_64-unknown-fuchsia \
-// RUN: --sysroot=%S/platform -fuse-ld=ld 2>&1 | FileCheck %s
+// RUN: --sysroot=%S/platform 2>&1 \
+// RUN: | FileCheck -check-prefixes=CHECK,CHECK-X86_64 %s
+// RUN: %clang %s -### -no-canonical-prefixes --target=aarch64-unknown-fuchsia \
+// RUN: --sysroot=%S/platform 2>&1 \
+// RUN: | FileCheck -check-prefixes=CHECK,CHECK-AARCH64 %s
// CHECK: {{.*}}clang{{.*}}" "-cc1"
+// CHECK: "--mrelax-relocations"
+// CHECK: "-munwind-tables"
// CHECK: "-fuse-init-array"
// CHECK: "-isysroot" "[[SYSROOT:[^"]+]]"
// CHECK: "-internal-externc-isystem" "[[SYSROOT]]{{/|\\\\}}include"
-// CHECK: {{.*}}lld{{.*}}" "-flavor" "gnu"
-// CHECK: "-z" "rodynamic"
+// CHECK: {{.*}}ld.lld{{.*}}" "-z" "rodynamic"
// CHECK: "--sysroot=[[SYSROOT]]"
// CHECK: "-pie"
// CHECK: "--build-id"
+// CHECK: "--hash-style=gnu"
// CHECK: "-dynamic-linker" "ld.so.1"
// CHECK: Scrt1.o
// CHECK-NOT: crti.o
// CHECK-NOT: crtbegin.o
// CHECK: "-L[[SYSROOT]]{{/|\\\\}}lib"
-// CHECK: "{{.*[/\\]}}libclang_rt.builtins-x86_64.a"
+// CHECK-X86_64: "{{.*[/\\]}}libclang_rt.builtins-x86_64.a"
+// CHECK-AARCH64: "{{.*[/\\]}}libclang_rt.builtins-aarch64.a"
// CHECK: "-lc"
// CHECK-NOT: crtend.o
// CHECK-NOT: crtn.o
@@ -44,3 +51,31 @@
// RUN: -fsanitize=safe-stack 2>&1 \
// RUN: | FileCheck %s -check-prefix=CHECK-SAFESTACK
// CHECK-SAFESTACK: "-fsanitize=safe-stack"
+// CHECK-SAFESTACK-NOT: "{{.*[/\\]}}libclang_rt.safestack-x86_64.a"
+// CHECK-SAFESTACK-NOT: "__safestack_init"
+
+// RUN: %clang %s -### --target=x86_64-unknown-fuchsia \
+// RUN: -fsanitize=address 2>&1 \
+// RUN: | FileCheck %s -check-prefix=CHECK-ASAN-X86
+// CHECK-ASAN-X86: "-fsanitize=address"
+// CHECK-ASAN-X86: "-fsanitize-address-globals-dead-stripping"
+// CHECK-ASAN-X86: "-dynamic-linker" "asan/ld.so.1"
+// CHECK-ASAN-X86: "{{.*[/\\]}}libclang_rt.asan-x86_64.so"
+// CHECK-ASAN-X86: "{{.*[/\\]}}libclang_rt.asan-preinit-x86_64.a"
+
+// RUN: %clang %s -### --target=aarch64-fuchsia \
+// RUN: -fsanitize=address 2>&1 \
+// RUN: | FileCheck %s -check-prefix=CHECK-ASAN-AARCH64
+// CHECK-ASAN-AARCH64: "-fsanitize=address"
+// CHECK-ASAN-AARCH64: "-fsanitize-address-globals-dead-stripping"
+// CHECK-ASAN-AARCH64: "-dynamic-linker" "asan/ld.so.1"
+// CHECK-ASAN-AARCH64: "{{.*[/\\]}}libclang_rt.asan-aarch64.so"
+// CHECK-ASAN-AARCH64: "{{.*[/\\]}}libclang_rt.asan-preinit-aarch64.a"
+
+// RUN: %clang %s -### --target=x86_64-unknown-fuchsia \
+// RUN: -fsanitize=address -fPIC -shared 2>&1 \
+// RUN: | FileCheck %s -check-prefix=CHECK-ASAN-SHARED
+// CHECK-ASAN-SHARED: "-fsanitize=address"
+// CHECK-ASAN-SHARED: "-fsanitize-address-globals-dead-stripping"
+// CHECK-ASAN-SHARED: "{{.*[/\\]}}libclang_rt.asan-x86_64.so"
+// CHECK-ASAN-SHARED-NOT: "{{.*[/\\]}}libclang_rt.asan-preinit-x86_64.a"
diff --git a/test/Driver/fuchsia.cpp b/test/Driver/fuchsia.cpp
index 20299c342688..cbd08adb4490 100644
--- a/test/Driver/fuchsia.cpp
+++ b/test/Driver/fuchsia.cpp
@@ -1,13 +1,12 @@
// RUN: %clangxx %s -### -no-canonical-prefixes --target=x86_64-unknown-fuchsia \
-// RUN: --sysroot=%S/platform 2>&1 -fuse-ld=ld | FileCheck %s
+// RUN: --sysroot=%S/platform 2>&1 | FileCheck %s
// CHECK: {{.*}}clang{{.*}}" "-cc1"
// CHECK: "-triple" "x86_64-fuchsia"
// CHECK: "-fuse-init-array"
// CHECK: "-isysroot" "[[SYSROOT:[^"]+]]"
// CHECK: "-internal-isystem" "{{.*[/\\]}}x86_64-fuchsia{{/|\\\\}}include{{/|\\\\}}c++{{/|\\\\}}v1"
// CHECK: "-internal-externc-isystem" "[[SYSROOT]]{{/|\\\\}}include"
-// CHECK: {{.*}}lld{{.*}}" "-flavor" "gnu"
-// CHECK: "-z" "rodynamic"
+// CHECK: {{.*}}ld.lld{{.*}}" "-z" "rodynamic"
// CHECK: "--sysroot=[[SYSROOT]]"
// CHECK: "-pie"
// CHECK: "--build-id"
@@ -28,8 +27,8 @@
// RUN: %clangxx %s -### --target=x86_64-unknown-fuchsia -static-libstdc++ 2>&1 \
// RUN: | FileCheck %s -check-prefix=CHECK-STATIC
-// CHECK-STATIC: "-Bstatic"
+// CHECK-STATIC-NOT: "-Bstatic"
// CHECK-STATIC: "-lc++" "-lc++abi" "-lunwind"
-// CHECK-STATIC: "-Bdynamic"
+// CHECK-STATIC-NOT: "-Bdynamic"
// CHECK-STATIC: "-lm"
// CHECK-STATIC: "-lc"
diff --git a/test/Driver/fuse-ld.c b/test/Driver/fuse-ld.c
index bd8c9a538624..b043ce624ed8 100644
--- a/test/Driver/fuse-ld.c
+++ b/test/Driver/fuse-ld.c
@@ -67,3 +67,29 @@
// RUN: -gcc-toolchain %S/Inputs/basic_android_tree 2>&1 \
// RUN: | FileCheck %s -check-prefix=CHECK-ANDROID-ARM-GOLD-TC
// CHECK-ANDROID-ARM-GOLD-TC: Inputs/basic_android_tree/lib/gcc/arm-linux-androideabi/4.4.3/../../../../arm-linux-androideabi/bin{{/|\\+}}ld.gold
+
+
+// RUN: %clang %s -### -fuse-ld=link \
+// RUN: -target i686-unknown-windows-msvc 2>&1 \
+// RUN: | FileCheck %s --check-prefix CHECK-WINDOWS-MSVC-LINK
+// CHECK-WINDOWS-MSVC-LINK: "{{.*}}link.exe"
+// CHECK-WINDOWS-MSVC-LINK-SAME: "-out:{{.*}}"
+
+// RUN: %clang %s -### -fuse-ld=lld \
+// RUN: -target i686-unknown-windows-msvc 2>&1 \
+// RUN: | FileCheck %s --check-prefix CHECK-WINDOWS-MSVC-LLD
+// CHECK-WINDOWS-MSVC-LLD: "{{.*}}lld-link"
+// CHECK-WINDOWS-MSVC-LLD-SAME: "-out:{{.*}}"
+
+// RUN: %clang %s -### -fuse-ld=lld-link \
+// RUN: -target i686-unknown-windows-msvc 2>&1 \
+// RUN: | FileCheck %s --check-prefix CHECK-WINDOWS-MSVC-LLD-LINK
+// CHECK-WINDOWS-MSVC-LLD-LINK: "{{.*}}lld-link"
+// CHECK-WINDOWS-MSVC-LLD-LINK-SAME: "-out:{{.*}}"
+
+// RUN: %clang %s -### -fuse-ld=bfd \
+// RUN: -target i686-unknown-windows-msvc \
+// RUN: -B %S/Inputs/Windows/usr/bin 2>&1 \
+// RUN: | FileCheck %s --check-prefix CHECK-WINDOWS-MSVC-BFD
+// CHECK-WINDOWS-MSVC-BFD: "{{.*}}ld.bfd"
+// CHECK-WINDOWS-MSVC-BFD-SAME: "-o"
diff --git a/test/Driver/fuzzer.c b/test/Driver/fuzzer.c
index 989b3b9f6348..3fdf5ab9c9b9 100644
--- a/test/Driver/fuzzer.c
+++ b/test/Driver/fuzzer.c
@@ -2,10 +2,11 @@
// RUN: %clang -fsanitize=fuzzer %s -target x86_64-apple-darwin14 -### 2>&1 | FileCheck --check-prefixes=CHECK-FUZZER-LIB,CHECK-COVERAGE-FLAGS %s
//
-// CHECK-FUZZER-LIB: libLLVMFuzzer.a
-// CHECK-COVERAGE: -fsanitize-coverage-trace-pc-guard
+// CHECK-FUZZER-LIB: libclang_rt.fuzzer
+// CHECK-COVERAGE: -fsanitize-coverage-inline-8bit-counters
// CHECK-COVERAGE-SAME: -fsanitize-coverage-indirect-calls
// CHECK-COVERAGE-SAME: -fsanitize-coverage-trace-cmp
+// CHECK-COVERAGE-SAME: -fsanitize-coverage-pc-table
// RUN: %clang -fsanitize=fuzzer -target i386-unknown-linux -stdlib=platform %s -### 2>&1 | FileCheck --check-prefixes=CHECK-LIBCXX-LINUX %s
//
@@ -18,7 +19,12 @@
// Check that we don't link in libFuzzer.a when producing a shared object.
// RUN: %clang -fsanitize=fuzzer %s -shared -o %t.so -### 2>&1 | FileCheck --check-prefixes=CHECK-NOLIB-SO %s
-// CHECK-NOLIB-SO-NOT: libLLVMFuzzer.a
+// CHECK-NOLIB-SO-NOT: libclang_rt.libfuzzer
+
+// Check that we don't link in libFuzzer when compiling with -fsanitize=fuzzer-no-link.
+// RUN: %clang -fsanitize=fuzzer-no-link %s -target x86_64-apple-darwin14 -### 2>&1 | FileCheck --check-prefixes=CHECK-NOLIB,CHECK-COV %s
+// CHECK-NOLIB-NOT: libclang_rt.libfuzzer
+// CHECK-COV: -fsanitize-coverage-inline-8bit-counters
// RUN: %clang -fsanitize=fuzzer -fsanitize-coverage=trace-pc %s -### 2>&1 | FileCheck --check-prefixes=CHECK-MSG %s
// CHECK-MSG-NOT: argument unused during compilation
diff --git a/test/Driver/gold-lto-new-pass-man.c b/test/Driver/gold-lto-new-pass-man.c
new file mode 100644
index 000000000000..c2add0c73a12
--- /dev/null
+++ b/test/Driver/gold-lto-new-pass-man.c
@@ -0,0 +1,7 @@
+// RUN: touch %t.o
+//
+// RUN: %clang -target ppc64le-unknown-linux -### %t.o -flto 2>&1 \
+// RUN: -Wl,-plugin-opt=foo -O3 \
+// RUN: -fexperimental-new-pass-manager \
+// RUN: | FileCheck %s
+// CHECK: "-plugin-opt=new-pass-manager"
diff --git a/test/Driver/gold-lto.c b/test/Driver/gold-lto.c
index b8eca5112b5a..d16961eeda45 100644
--- a/test/Driver/gold-lto.c
+++ b/test/Driver/gold-lto.c
@@ -3,14 +3,14 @@
// RUN: %clang -target x86_64-unknown-linux -### %t.o -flto 2>&1 \
// RUN: -Wl,-plugin-opt=foo -O3 \
// RUN: | FileCheck %s --check-prefix=CHECK-X86-64-BASIC
-// CHECK-X86-64-BASIC: "-plugin" "{{.*}}/LLVMgold.so"
+// CHECK-X86-64-BASIC: "-plugin" "{{.*}}{{[/\\]}}LLVMgold.{{dll|dylib|so}}"
// CHECK-X86-64-BASIC: "-plugin-opt=O3"
// CHECK-X86-64-BASIC: "-plugin-opt=foo"
//
// RUN: %clang -target x86_64-unknown-linux -### %t.o -flto 2>&1 \
// RUN: -march=corei7 -Wl,-plugin-opt=foo -Ofast \
// RUN: | FileCheck %s --check-prefix=CHECK-X86-64-COREI7
-// CHECK-X86-64-COREI7: "-plugin" "{{.*}}/LLVMgold.so"
+// CHECK-X86-64-COREI7: "-plugin" "{{.*}}{{[/\\]}}LLVMgold.{{dll|dylib|so}}"
// CHECK-X86-64-COREI7: "-plugin-opt=mcpu=corei7"
// CHECK-X86-64-COREI7: "-plugin-opt=O3"
// CHECK-X86-64-COREI7: "-plugin-opt=foo"
@@ -18,11 +18,11 @@
// RUN: %clang -target arm-unknown-linux -### %t.o -flto 2>&1 \
// RUN: -march=armv7a -Wl,-plugin-opt=foo -O0 \
// RUN: | FileCheck %s --check-prefix=CHECK-ARM-V7A
-// CHECK-ARM-V7A: "-plugin" "{{.*}}/LLVMgold.so"
+// CHECK-ARM-V7A: "-plugin" "{{.*}}{{[/\\]}}LLVMgold.{{dll|dylib|so}}"
// CHECK-ARM-V7A: "-plugin-opt=mcpu=generic"
// CHECK-ARM-V7A: "-plugin-opt=O0"
// CHECK-ARM-V7A: "-plugin-opt=foo"
//
// RUN: %clang -target i686-linux-android -### %t.o -flto 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK-X86-ANDROID
-// CHECK-X86-ANDROID: "-plugin" "{{.*}}/LLVMgold.so"
+// CHECK-X86-ANDROID: "-plugin" "{{.*}}{{[/\\]}}LLVMgold.{{dll|dylib|so}}"
diff --git a/test/Driver/hexagon-hvx.c b/test/Driver/hexagon-hvx.c
new file mode 100644
index 000000000000..171d586760ed
--- /dev/null
+++ b/test/Driver/hexagon-hvx.c
@@ -0,0 +1,103 @@
+// -----------------------------------------------------------------------------
+// Tests for the hvx features and warnings.
+// -----------------------------------------------------------------------------
+
+// RUN: %clang -c %s -### -target hexagon-unknown-elf -mv65 -mhvx \
+// RUN: 2>&1 | FileCheck -check-prefix=CHECKHVX165 %s
+// CHECKHVX165: "-target-feature" "+hvxv65"
+
+// RUN: %clang -c %s -### -target hexagon-unknown-elf -mv62 -mhvx \
+// RUN: 2>&1 | FileCheck -check-prefix=CHECKHVX162 %s
+// CHECKHVX162: "-target-feature" "+hvxv62"
+
+// RUN: %clang -c %s -### -target hexagon-unknown-elf -mv65 -mhvx \
+// RUN: -mhvx-double 2>&1 | FileCheck -check-prefix=CHECKHVX2 %s
+
+// RUN: %clang -c %s -### -target hexagon-unknown-elf -mv62 -mhvx \
+// RUN: -mhvx-double 2>&1 | FileCheck -check-prefix=CHECKHVX2 %s
+
+// RUN: %clang -c %s -### -target hexagon-unknown-elf -mv65 -mhvx \
+// RUN: -mhvx-length=128B 2>&1 | FileCheck -check-prefix=CHECKHVX2 %s
+
+// RUN: %clang -c %s -### -target hexagon-unknown-elf -mv62 -mhvx \
+// RUN: -mhvx-length=128B 2>&1 | FileCheck -check-prefix=CHECKHVX2 %s
+// CHECKHVX2-NOT: "-target-feature" "+hvx-length64b"
+// CHECKHVX2: "-target-feature" "+hvx-length128b"
+
+// RUN: %clang -c %s -### -target hexagon-unknown-elf -mv65 2>&1 \
+// RUN: | FileCheck -check-prefix=CHECKHVX3 %s
+
+// RUN: %clang -c %s -### -target hexagon-unknown-elf -mv62 2>&1 \
+// RUN: | FileCheck -check-prefix=CHECKHVX3 %s
+// CHECKHVX3-NOT: "-target-feature" "+hvx
+
+// -mhvx-double is deprecated.
+// RUN: %clang -c %s -### -target hexagon-unknown-elf -mv62 -mhvx-double \
+// RUN: 2>&1 | FileCheck -check-prefix=CHECK-DEPRECATED %s
+// CHECK-DEPRECATED: warning: argument '-mhvx-double' is deprecated, use '-mhvx-length=128B' instead [-Wdeprecated]
+
+// -mno-hvx-double is deprecated.
+// RUN: %clang -c %s -### -target hexagon-unknown-elf -mv62 -mno-hvx-double \
+// RUN: 2>&1 | FileCheck -check-prefix=CHECK-NODEPRECATED %s
+// CHECK-NODEPRECATED: warning: argument '-mno-hvx-double' is deprecated, use '-mno-hvx' instead [-Wdeprecated]
+
+// No hvx target feature must be added if -mno-hvx/-mno-hvx-double occurs last
+// RUN: %clang -c %s -### -target hexagon-unknown-elf -mv62 -mno-hvx \
+// RUN: 2>&1 | FileCheck -check-prefix=CHECK-NOHVX %s
+// RUN: %clang -c %s -### -target hexagon-unknown-elf -mv62 -mhvx -mno-hvx \
+// RUN: 2>&1 | FileCheck -check-prefix=CHECK-NOHVX %s
+// RUN: %clang -c %s -### -target hexagon-unknown-elf -mv62 -mhvx -mno-hvx-double \
+// RUN: 2>&1 | FileCheck -check-prefix=CHECK-NOHVX %s
+// CHECK-NOHVX-NOT: "-target-feature" "+hvx
+
+// Hvx target feature should be added if -mno-hvx doesnot occur last
+// RUN: %clang -c %s -### -target hexagon-unknown-elf -mv62 -mno-hvx -mhvx\
+// RUN: 2>&1 | FileCheck -check-prefix=CHECK-HVXFEAT %s
+// CHECK-HVXFEAT: "-target-feature" "+hvxv62"
+
+// With -mhvx, the version of hvx defaults to Cpu
+// RUN: %clang -c %s -### -target hexagon-unknown-elf -mv60 -mhvx \
+// RUN: 2>&1 | FileCheck -check-prefix=CHECK-HVX-DEFAULT %s
+// CHECK-HVX-DEFAULT: "-target-feature" "+hvxv60"
+
+// Test -mhvx= flag
+// RUN: %clang -c %s -### -target hexagon-unknown-elf -mv60 -mhvx=v62 \
+// RUN: 2>&1 | FileCheck -check-prefix=CHECK-HVXEQ %s
+// CHECK-HVXEQ: "-target-feature" "+hvxv62"
+
+// Honor the last occured -mhvx=, -mhvx flag.
+// RUN: %clang -c %s -### -target hexagon-unknown-elf -mv60 -mhvx=v62 -mhvx\
+// RUN: 2>&1 | FileCheck -check-prefix=CHECK-HVXEQ-PRE %s
+// CHECK-HVXEQ-PRE-NOT: "-target-feature" "+hvxv62"
+// CHECK-HVXEQ-PRE: "-target-feature" "+hvxv60"
+// RUN: %clang -c %s -### -target hexagon-unknown-elf -mv60 -mhvx -mhvx=v62\
+// RUN: 2>&1 | FileCheck -check-prefix=CHECK-HVXEQ-PRE2 %s
+// CHECK-HVXEQ-PRE2-NOT: "-target-feature" "+hvxv60"
+// CHECK-HVXEQ-PRE2: "-target-feature" "+hvxv62"
+
+// Test -mhvx-length flag
+// The default mode on v60,v62 is 64B.
+// RUN: %clang -c %s -### -target hexagon-unknown-elf -mv60 -mhvx \
+// RUN: 2>&1 | FileCheck -check-prefix=CHECK-HVXLENGTH-64B %s
+// RUN: %clang -c %s -### -target hexagon-unknown-elf -mv60 -mhvx -mhvx-length=64B\
+// RUN: 2>&1 | FileCheck -check-prefix=CHECK-HVXLENGTH-64B %s
+// CHECK-HVXLENGTH-64B: "-target-feature" "+hvx{{.*}}" "-target-feature" "+hvx-length64b"
+// RUN: %clang -c %s -### -target hexagon-unknown-elf -mv62 -mhvx -mhvx-length=128B\
+// RUN: 2>&1 | FileCheck -check-prefix=CHECK-HVXLENGTH-128B %s
+// CHECK-HVXLENGTH-128B: "-target-feature" "+hvx{{.*}}" "-target-feature" "+hvx-length128b"
+
+// Bail out if -mhvx-length is specified without HVX enabled
+// RUN: %clang -c %s -### -target hexagon-unknown-elf -mhvx-length=64B \
+// RUN: 2>&1 | FileCheck -check-prefix=CHECK-HVXLENGTH-ERROR %s
+// RUN: %clang -c %s -### -target hexagon-unknown-elf -mhvx-length=128B \
+// RUN: 2>&1 | FileCheck -check-prefix=CHECK-HVXLENGTH-ERROR %s
+// RUN: %clang -c %s -### -target hexagon-unknown-elf -mhvx-double \
+// RUN: 2>&1 | FileCheck -check-prefix=CHECK-HVXLENGTH-ERROR %s
+// CHECK-HVXLENGTH-ERROR: error: -mhvx-length is not supported without a -mhvx/-mhvx= flag
+
+// Error out if an unsupported value is passed to -mhvx-length.
+// RUN: %clang -c %s -### -target hexagon-unknown-elf -mhvx -mhvx-length=B \
+// RUN: 2>&1 | FileCheck -check-prefix=CHECK-HVXLENGTH-VALUE-ERROR %s
+// RUN: %clang -c %s -### -target hexagon-unknown-elf -mhvx -mhvx-length=128 \
+// RUN: 2>&1 | FileCheck -check-prefix=CHECK-HVXLENGTH-VALUE-ERROR %s
+// CHECK-HVXLENGTH-VALUE-ERROR: error: unsupported argument '{{.*}}' to option 'mhvx-length='
diff --git a/test/Driver/hexagon-toolchain-elf.c b/test/Driver/hexagon-toolchain-elf.c
index 98582450e3fd..7dc82f351998 100644
--- a/test/Driver/hexagon-toolchain-elf.c
+++ b/test/Driver/hexagon-toolchain-elf.c
@@ -99,20 +99,28 @@
// RUN: %clang -### -target hexagon-unknown-elf \
// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/Tools/bin \
-// RUN: -O3 \
+// RUN: -mcpu=hexagonv65 \
// RUN: %s 2>&1 \
// RUN: | FileCheck -check-prefix=CHECK025 %s
-// CHECK025: "-ffp-contract=fast"
-// CHECK025: hexagon-link
+// CHECK025: "-cc1" {{.*}} "-target-cpu" "hexagonv65"
+// CHECK025: hexagon-link{{.*}}/Inputs/hexagon_tree/Tools/bin/../target/hexagon/lib/v65/crt0
// RUN: %clang -### -target hexagon-unknown-elf \
// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/Tools/bin \
-// RUN: -O3 -ffp-contract=off \
+// RUN: -O3 \
// RUN: %s 2>&1 \
// RUN: | FileCheck -check-prefix=CHECK026 %s
-// CHECK026-NOT: "-ffp-contract=fast"
+// CHECK026: "-ffp-contract=fast"
// CHECK026: hexagon-link
+// RUN: %clang -### -target hexagon-unknown-elf \
+// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/Tools/bin \
+// RUN: -O3 -ffp-contract=off \
+// RUN: %s 2>&1 \
+// RUN: | FileCheck -check-prefix=CHECK027 %s
+// CHECK027-NOT: "-ffp-contract=fast"
+// CHECK027: hexagon-link
+
// -----------------------------------------------------------------------------
// Test Linker related args
// -----------------------------------------------------------------------------
diff --git a/test/Driver/linker-opts.c b/test/Driver/linker-opts.c
index 29ef136c8b71..5fe29d7a13a6 100644
--- a/test/Driver/linker-opts.c
+++ b/test/Driver/linker-opts.c
@@ -1,7 +1,7 @@
// RUN: rm -rf %t
// RUN: mkdir %t
//
-// RUN: env LIBRARY_PATH=%T/test1 %clang -x c %s -### 2>&1 | FileCheck %s
+// RUN: env LIBRARY_PATH=%t/test1 %clang -x c %s -### 2>&1 | FileCheck %s
// CHECK: "-L{{.*}}/test1"
// GCC driver is used as linker on cygming. It should be aware of LIBRARY_PATH.
@@ -10,8 +10,8 @@
// REQUIRES: native
// Make sure that LIBRARY_PATH works for both i386 and x86_64 on Darwin.
-// RUN: env LIBRARY_PATH=%T/test1 %clang -target x86_64-apple-darwin %s -### 2>&1 | FileCheck %s
-// RUN: env LIBRARY_PATH=%T/test1 %clang -target i386-apple-darwin %s -### 2>&1 | FileCheck %s
+// RUN: env LIBRARY_PATH=%t/test1 %clang -target x86_64-apple-darwin %s -### 2>&1 | FileCheck %s
+// RUN: env LIBRARY_PATH=%t/test1 %clang -target i386-apple-darwin %s -### 2>&1 | FileCheck %s
//
// Make sure that we don't warn on unused compiler arguments.
// RUN: %clang -Xclang -I. -x c %s -c -o %t/tmp.o
diff --git a/test/Driver/linux-as.c b/test/Driver/linux-as.c
index c5cb1cd600b0..68cf403d9789 100644
--- a/test/Driver/linux-as.c
+++ b/test/Driver/linux-as.c
@@ -174,3 +174,18 @@
// RUN: -no-integrated-as -c %s 2>&1 \
// RUN: | FileCheck -check-prefix=CHECK-Z-ARCH-Z196 %s
// CHECK-Z-ARCH-Z196: as{{.*}} "-march=z196"
+//
+// RUN: %clang -target powerpc64le-linux -### \
+// RUN: -no-integrated-as -c %s 2>&1 \
+// RUN: | FileCheck -check-prefix=CHECK-PPC64LE %s
+// CHECK-PPC64LE: as{{.*}} "-mpower8"
+//
+// RUN: %clang -target powerpc64-linux -mcpu=pwr7 -### \
+// RUN: -no-integrated-as -c %s 2>&1 \
+// RUN: | FileCheck -check-prefix=CHECK-PPC64 %s
+// CHECK-PPC64: as{{.*}} "-mpower7"
+//
+// RUN: %clang -target powerpc-linux -mcpu=pwr9 -### \
+// RUN: -no-integrated-as -c %s 2>&1 \
+// RUN: | FileCheck -check-prefix=CHECK-PPC32 %s
+// CHECK-PPC32: as{{.*}} "-mpower9"
diff --git a/test/Driver/linux-ld.c b/test/Driver/linux-ld.c
index 1c5f1a4556b1..662aabb8671e 100644
--- a/test/Driver/linux-ld.c
+++ b/test/Driver/linux-ld.c
@@ -71,6 +71,27 @@
// CHECK-LD-RT: libclang_rt.builtins-x86_64.a"
//
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN: --target=i686-unknown-linux \
+// RUN: --gcc-toolchain="" \
+// RUN: --sysroot=%S/Inputs/basic_linux_tree \
+// RUN: --rtlib=compiler-rt \
+// RUN: | FileCheck --check-prefix=CHECK-LD-RT-I686 %s
+// CHECK-LD-RT-I686-NOT: warning:
+// CHECK-LD-RT-I686: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
+// CHECK-LD-RT-I686: "--eh-frame-hdr"
+// CHECK-LD-RT-I686: "-m" "elf_i386"
+// CHECK-LD-RT-I686: "-dynamic-linker"
+// CHECK-LD-RT-I686: "{{.*}}/usr/lib/gcc/i686-unknown-linux/4.6.0{{/|\\\\}}crtbegin.o"
+// CHECK-LD-RT-I686: "-L[[SYSROOT]]/usr/lib/gcc/i686-unknown-linux/4.6.0"
+// CHECK-LD-RT-I686: "-L[[SYSROOT]]/usr/lib/gcc/i686-unknown-linux/4.6.0/../../../../i686-unknown-linux/lib"
+// CHECK-LD-RT-I686: "-L[[SYSROOT]]/usr/lib/gcc/i686-unknown-linux/4.6.0/../../.."
+// CHECK-LD-RT-I686: "-L[[SYSROOT]]/lib"
+// CHECK-LD-RT-I686: "-L[[SYSROOT]]/usr/lib"
+// CHECK-LD-RT-I686: libclang_rt.builtins-i386.a"
+// CHECK-LD-RT-I686: "-lc"
+// CHECK-LD-RT-I686: libclang_rt.builtins-i386.a"
+//
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
// RUN: --target=arm-linux-androideabi \
// RUN: --gcc-toolchain="" \
// RUN: --sysroot=%S/Inputs/basic_android_tree/sysroot \
@@ -1112,6 +1133,7 @@
// RUN: --sysroot=%S/Inputs/basic_android_tree/sysroot \
// RUN: | FileCheck --check-prefix=CHECK-ANDROID %s
// CHECK-ANDROID: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
+// CHECK-ANDROID: "--enable-new-dtags"
// CHECK-ANDROID: "{{.*}}{{/|\\\\}}crtbegin_dynamic.o"
// CHECK-ANDROID: "-L[[SYSROOT]]/usr/lib"
// CHECK-ANDROID-NOT: "gcc_s"
@@ -1286,31 +1308,6 @@
// CHECK-ANDROID-PIE: "{{.*}}{{/|\\\\}}crtend_android.o"
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
// RUN: --target=arm-linux-androideabi \
-// RUN: | FileCheck --check-prefix=CHECK-ANDROID-NO-DEFAULT-PIE %s
-// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN: --target=arm-linux-android \
-// RUN: | FileCheck --check-prefix=CHECK-ANDROID-NO-DEFAULT-PIE %s
-// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN: --target=aarch64-linux-android \
-// RUN: | FileCheck --check-prefix=CHECK-ANDROID-NO-DEFAULT-PIE %s
-// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN: --target=arm64-linux-android \
-// RUN: | FileCheck --check-prefix=CHECK-ANDROID-NO-DEFAULT-PIE %s
-// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN: --target=mipsel-linux-android \
-// RUN: | FileCheck --check-prefix=CHECK-ANDROID-NO-DEFAULT-PIE %s
-// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN: --target=mips64el-linux-android \
-// RUN: | FileCheck --check-prefix=CHECK-ANDROID-NO-DEFAULT-PIE %s
-// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN: --target=i686-linux-android \
-// RUN: | FileCheck --check-prefix=CHECK-ANDROID-NO-DEFAULT-PIE %s
-// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN: --target=x86_64-linux-android \
-// RUN: | FileCheck --check-prefix=CHECK-ANDROID-NO-DEFAULT-PIE %s
-// CHECK-ANDROID-NO-DEFAULT-PIE-NOT: -pie
-// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN: --target=arm-linux-androideabi \
// RUN: --gcc-toolchain="" \
// RUN: --sysroot=%S/Inputs/basic_android_tree/sysroot \
// RUN: | FileCheck --check-prefix=CHECK-ANDROID-32 %s
diff --git a/test/Driver/lto-plugin-darwin.c b/test/Driver/lto-plugin-darwin.c
new file mode 100644
index 000000000000..2e9e6ba5b425
--- /dev/null
+++ b/test/Driver/lto-plugin-darwin.c
@@ -0,0 +1,6 @@
+// Check that Darwin uses LLVMgold.dylib.
+// REQUIRES: system-darwin
+// RUN: %clang -### %s -target x86_64-unknown-linux -flto 2>&1 \
+// RUN: | FileCheck -check-prefix=CHECK-LTO-PLUGIN %s
+//
+// CHECK-LTO-PLUGIN: "-plugin" "{{.*}}/LLVMgold.dylib"
diff --git a/test/Driver/lto-plugin-linux.c b/test/Driver/lto-plugin-linux.c
new file mode 100644
index 000000000000..ac1eb14e2e9f
--- /dev/null
+++ b/test/Driver/lto-plugin-linux.c
@@ -0,0 +1,6 @@
+// Check that non-Windows, non-Darwin OSs use LLVMgold.so.
+// REQUIRES: !system-darwin && !system-windows
+// RUN: %clang -### %s -target x86_64-unknown-linux -flto 2>&1 \
+// RUN: | FileCheck -check-prefix=CHECK-LTO-PLUGIN %s
+//
+// CHECK-LTO-PLUGIN: "-plugin" "{{.*}}/LLVMgold.so"
diff --git a/test/Driver/lto-plugin-windows.c b/test/Driver/lto-plugin-windows.c
new file mode 100644
index 000000000000..1b12702a98a7
--- /dev/null
+++ b/test/Driver/lto-plugin-windows.c
@@ -0,0 +1,6 @@
+// Check that Windows uses LLVMgold.dll.
+// REQUIRES: system-windows
+// RUN: %clang -### %s -target x86_64-unknown-linux -flto 2>&1 \
+// RUN: | FileCheck -check-prefix=CHECK-LTO-PLUGIN %s
+//
+// CHECK-LTO-PLUGIN: "-plugin" "{{.*}}\\LLVMgold.dll"
diff --git a/test/Driver/lto.c b/test/Driver/lto.c
index d2f68f571afd..570c80b94188 100644
--- a/test/Driver/lto.c
+++ b/test/Driver/lto.c
@@ -36,19 +36,19 @@
// RUN: %clang -target x86_64-unknown-linux -### %s -flto 2> %t
// RUN: FileCheck -check-prefix=CHECK-LINK-LTO-ACTION < %t %s
//
-// CHECK-LINK-LTO-ACTION: "-plugin" "{{.*}}/LLVMgold.so"
+// CHECK-LINK-LTO-ACTION: "-plugin" "{{.*}}{{[/\\]}}LLVMgold.{{dll|dylib|so}}"
// -flto=full should cause link using gold plugin
// RUN: %clang -target x86_64-unknown-linux -### %s -flto=full 2> %t
// RUN: FileCheck -check-prefix=CHECK-LINK-FULL-ACTION < %t %s
//
-// CHECK-LINK-FULL-ACTION: "-plugin" "{{.*}}/LLVMgold.so"
+// CHECK-LINK-FULL-ACTION: "-plugin" "{{.*}}{{[/\\]}}LLVMgold.{{dll|dylib|so}}"
// Check that subsequent -fno-lto takes precedence
// RUN: %clang -target x86_64-unknown-linux -### %s -flto=full -fno-lto 2> %t
// RUN: FileCheck -check-prefix=CHECK-LINK-NOLTO-ACTION < %t %s
//
-// CHECK-LINK-NOLTO-ACTION-NOT: "-plugin" "{{.*}}/LLVMgold.so"
+// CHECK-LINK-NOLTO-ACTION-NOT: "-plugin" "{{.*}}{{[/\\]}}LLVMgold.{{dll|dylib|so}}"
// -flto passes along an explicit debugger tuning argument.
// RUN: %clang -target x86_64-unknown-linux -### %s -flto -glldb 2> %t
diff --git a/test/Driver/mingw-msvcrt.c b/test/Driver/mingw-msvcrt.c
new file mode 100644
index 000000000000..b7c6584f95fe
--- /dev/null
+++ b/test/Driver/mingw-msvcrt.c
@@ -0,0 +1,5 @@
+// RUN: %clang -v -target i686-pc-windows-gnu -### %s 2>&1 | FileCheck -check-prefix=CHECK_DEFAULT %s
+// RUN: %clang -v -target i686-pc-windows-gnu -lmsvcr120 -### %s 2>&1 | FileCheck -check-prefix=CHECK_MSVCR120 %s
+
+// CHECK_DEFAULT: "-lmingwex" "-lmsvcrt" "-ladvapi32"
+// CHECK_MSVCR120: "-lmingwex" "-ladvapi32"
diff --git a/test/Driver/mingw-useld.c b/test/Driver/mingw-useld.c
deleted file mode 100644
index a0ab5a933864..000000000000
--- a/test/Driver/mingw-useld.c
+++ /dev/null
@@ -1,19 +0,0 @@
-// RUN: %clang -### -target i686-pc-windows-gnu --sysroot=%S/Inputs/mingw_clang_tree/mingw32 %s 2>&1 | FileCheck -check-prefix=CHECK_LD_32 %s
-// CHECK_LD_32: ld{{(.exe)?}}"
-// CHECK_LD_32: "i386pe"
-// CHECK_LD_32-NOT: "-flavor" "gnu"
-
-// RUN: %clang -### -target i686-pc-windows-gnu --sysroot=%S/Inputs/mingw_clang_tree/mingw32 %s -fuse-ld=lld 2>&1 | FileCheck -check-prefix=CHECK_LLD_32 %s
-// CHECK_LLD_32-NOT: invalid linker name in argument
-// CHECK_LLD_32: lld{{(.exe)?}}" "-flavor" "gnu"
-// CHECK_LLD_32: "i386pe"
-
-// RUN: %clang -### -target x86_64-pc-windows-gnu --sysroot=%S/Inputs/mingw_clang_tree/mingw32 %s -fuse-ld=lld 2>&1 | FileCheck -check-prefix=CHECK_LLD_64 %s
-// CHECK_LLD_64-NOT: invalid linker name in argument
-// CHECK_LLD_64: lld{{(.exe)?}}" "-flavor" "gnu"
-// CHECK_LLD_64: "i386pep"
-
-// RUN: %clang -### -target arm-pc-windows-gnu --sysroot=%S/Inputs/mingw_clang_tree/mingw32 %s -fuse-ld=lld 2>&1 | FileCheck -check-prefix=CHECK_LLD_ARM %s
-// CHECK_LLD_ARM-NOT: invalid linker name in argument
-// CHECK_LLD_ARM: lld{{(.exe)?}}" "-flavor" "gnu"
-// CHECK_LLD_ARM: "thumb2pe"
diff --git a/test/Driver/mips-abi.c b/test/Driver/mips-abi.c
index 8e3f7c0cd12c..8591a45d3eed 100644
--- a/test/Driver/mips-abi.c
+++ b/test/Driver/mips-abi.c
@@ -1,5 +1,7 @@
// Check passing Mips ABI options to the backend.
//
+// REQUIRES: mips-registered-target
+//
// RUN: %clang -target mips-linux-gnu -### -c %s 2>&1 \
// RUN: | FileCheck -check-prefix=MIPS32R2-O32 %s
// RUN: %clang -target mips64-linux-gnu -mips32r2 -mabi=32 -### -c %s 2>&1 \
diff --git a/test/Driver/mips-abicalls-warning.c b/test/Driver/mips-abicalls-warning.c
new file mode 100644
index 000000000000..848a5bfce520
--- /dev/null
+++ b/test/Driver/mips-abicalls-warning.c
@@ -0,0 +1,9 @@
+// REQUIRES: mips-registered-target
+// RUN: %clang -### -c -target mips64-mti-elf -fno-PIC -mabicalls %s 2>&1 | FileCheck %s
+// CHECK: warning: ignoring '-mabicalls' option as it cannot be used with non position-independent code and the N64 ABI
+
+// RUN: %clang -### -c -target mips-mti-elf -mlong-calls %s 2>&1 | FileCheck -check-prefix=LONGCALL-IMP %s
+// LONGCALL-IMP: warning: ignoring '-mlong-calls' option as it is not currently supported with the implicit usage of -mabicalls
+
+// RUN: %clang -### -c -target mips-mti-elf -mlong-calls -mabicalls %s 2>&1 | FileCheck -check-prefix=LONGCALL-EXP %s
+// LONGCALL-EXP: warning: ignoring '-mlong-calls' option as it is not currently supported with -mabicalls
diff --git a/test/Driver/mips-features.c b/test/Driver/mips-features.c
index b228a2d5781d..a9db0f101700 100644
--- a/test/Driver/mips-features.c
+++ b/test/Driver/mips-features.c
@@ -10,6 +10,99 @@
// RUN: | FileCheck --check-prefix=CHECK-MNOABICALLS %s
// CHECK-MNOABICALLS: "-target-feature" "+noabicalls"
//
+// -mno-abicalls non-PIC N64
+// RUN: %clang -target mips64-linux-gnu -### -c -fno-PIC %s 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-MNOABICALLS-N64NPIC %s
+// CHECK-MNOABICALLS-N64NPIC: "-target-feature" "+noabicalls"
+//
+// -mgpopt
+// RUN: %clang -target mips-linux-gnu -### -c %s -mno-gpopt -mgpopt -Wno-unsupported-gpopt 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-MGPOPT-DEF-ABICALLS %s
+// CHECK-MGPOPT-DEF-ABICALLS-NOT: "-mllvm" "-mgpopt"
+//
+// -mabicalls -mgpopt
+// RUN: %clang -target mips-linux-gnu -### -c %s -mabicalls -mno-gpopt -mgpopt -Wno-unsupported-gpopt 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-MGPOPT-EXPLICIT-ABICALLS %s
+// CHECK-MGPOPT-EXPLICIT-ABICALLS-NOT: "-mllvm" "-mgpopt"
+//
+// -mno-abicalls -mgpopt
+// RUN: %clang -target mips-linux-gnu -### -c %s -mno-abicalls -mno-gpopt -mgpopt 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-MGPOPT %s
+// CHECK-MGPOPT: "-mllvm" "-mgpopt"
+//
+// -mno-abicalls -mno-gpopt
+// RUN: %clang -target mips-linux-gnu -### -c %s -mno-abicalls -mgpopt -mno-gpopt 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-MNOGPOPT %s
+// CHECK-MNOGPOPT-NOT: "-mllvm" "-mgpopt"
+//
+// -mno-abicalls
+// RUN: %clang -target mips-linux-gnu -### -c %s -mno-abicalls 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-MGPOPTDEF %s
+// CHECK-MGPOPTDEF: "-mllvm" "-mgpopt"
+//
+// -mgpopt -mno-abicalls -mlocal-sdata
+// RUN: %clang -target mips-linux-gnu -### -c %s -mno-abicalls -mno-gpopt -mgpopt -mno-local-sdata -mlocal-sdata 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-MLOCALSDATA %s
+// CHECK-MLOCALSDATA: "-mllvm" "-mlocal-sdata=1"
+//
+// -mgpopt -mno-abicalls -mno-local-sdata
+// RUN: %clang -target mips-linux-gnu -### -c %s -mno-abicalls -mno-gpopt -mgpopt -mlocal-sdata -mno-local-sdata 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-MNOLOCALSDATA %s
+// CHECK-MNOLOCALSDATA: "-mllvm" "-mlocal-sdata=0"
+//
+// -mgpopt -mno-abicalls
+// RUN: %clang -target mips-linux-gnu -### -c %s -mno-abicalls -mgpopt 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-MLOCALSDATADEF %s
+// CHECK-MLOCALSDATADEF-NOT: "-mllvm" "-mlocal-sdata"
+//
+// -mno-abicalls -mgpopt -mextern-sdata
+// RUN: %clang -target mips-linux-gnu -### -c %s -mno-abicalls -mgpopt -mno-extern-sdata -mextern-sdata 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-MEXTERNSDATA %s
+// CHECK-MEXTERNSDATA: "-mllvm" "-mextern-sdata=1"
+//
+// -mno-abicalls -mgpopt -mno-extern-sdata
+// RUN: %clang -target mips-linux-gnu -### -c %s -mno-abicalls -mgpopt -mextern-sdata -mno-extern-sdata 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-MNOEXTERNSDATA %s
+// CHECK-MNOEXTERNSDATA: "-mllvm" "-mextern-sdata=0"
+//
+// -mno-abicalls -mgpopt
+// RUN: %clang -target mips-linux-gnu -### -c %s -mno-abicalls -mgpopt 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-MEXTERNSDATADEF %s
+// CHECK-MEXTERNSDATADEF-NOT: "-mllvm" "-mextern-sdata"
+//
+// -mno-abicalls -mgpopt -membedded-data
+// RUN: %clang -target mips-linux-gnu -### -c %s -mno-abicalls -mgpopt -mno-embedded-data -membedded-data 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-MEMBEDDEDDATA %s
+// CHECK-MEMBEDDEDDATA: "-mllvm" "-membedded-data=1"
+//
+// -mno-abicalls -mgpopt -mno-embedded-data
+// RUN: %clang -target mips-linux-gnu -### -c %s -mno-abicalls -mgpopt -membedded-data -mno-embedded-data 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-MNOEMBEDDEDDATA %s
+// CHECK-MNOEMBEDDEDDATA: "-mllvm" "-membedded-data=0"
+//
+// -mno-abicalls -mgpopt
+// RUN: %clang -target mips-linux-gnu -### -c %s -mno-abicalls -mgpopt 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-MEMBEDDEDDATADEF %s
+// CHECK-MEMBEDDEDDATADEF-NOT: "-mllvm" "-membedded-data"
+//
+// MIPS64 + N64: -fno-pic -> -mno-abicalls -mgpopt
+// RUN: %clang -target mips64-mti-elf -mabi=64 -### -c %s -fno-pic 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-N64-GPOPT %s
+// CHECK-N64-GPOPT: "-target-feature" "+noabicalls"
+// CHECK-N64-GPOPT: "-mllvm" "-mgpopt"
+//
+// MIPS64 + N64: -fno-pic -mno-gpopt
+// RUN: %clang -target mips64-mti-elf -mabi=64 -### -c %s -fno-pic -mno-gpopt 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-N64-MNO-GPOPT %s
+// CHECK-N64-MNO-GPOPT: "-target-feature" "+noabicalls"
+// CHECK-N64-MNO-GPOPT-NOT: "-mllvm" "-mgpopt"
+//
+// MIPS64 + N64: -mgpopt (-fpic is implicit)
+// RUN: %clang -target mips64-mti-linux-gnu -mabi=64 -### -c %s -mgpopt 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-N64-PIC-GPOPT %s
+// CHECK-N64-PIC-GPOPT-NOT: "-mllvm" "-mgpopt"
+// CHECK-N64-PIC-GPOPT: ignoring '-mgpopt' option as it cannot be used with the implicit usage of -mabicalls
+//
// -mips16
// RUN: %clang -target mips-linux-gnu -### -c %s \
// RUN: -mno-mips16 -mips16 2>&1 \
@@ -128,6 +221,31 @@
// RUN: | FileCheck --check-prefix=CHECK-NANLEGACY %s
// CHECK-NANLEGACY: "-target-feature" "-nan2008"
//
+// -mabs=2008 on pre R2
+// RUN: %clang -target mips-linux-gnu -march=mips32 -### -c %s \
+// RUN: -mabs=2008 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-ABSLEGACY %s
+//
+// -mabs=2008
+// RUN: %clang -target mips-linux-gnu -march=mips32r3 -### -c %s \
+// RUN: -mabs=2008 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-ABS2008 %s
+//
+// -mabs=legacy
+// RUN: %clang -target mips-linux-gnu -march=mips32r3 -### -c %s \
+// RUN: -mabs=legacy 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-ABSLEGACY %s
+//
+// -mabs=legacy on R6
+// RUN: %clang -target mips-linux-gnu -march=mips32r6 -### -c %s \
+// RUN: -mabs=legacy 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-ABS2008 %s
+//
+// CHECK-ABSLEGACY: "-target-feature" "-abs2008"
+// CHECK-ABSLEGACY-NOT: "-target-feature" "+abs2008"
+// CHECK-ABS2008: "-target-feature" "+abs2008"
+// CHECK-ABS2008-NOT: "-target-feature" "-abs2008"
+//
// -mcompact-branches=never
// RUN: %clang -target mips-linux-gnu -march=mips32r6 -### -c %s \
// RUN: -mcompact-branches=never 2>&1 \
@@ -261,12 +379,26 @@
// CHECK-IMG-SINGLEFLOAT-FPXX: "-target-feature" "+fpxx"
// -mlong-call
-// RUN: %clang -target mips-img-linux-gnu -### -c %s -mlong-calls 2>&1 \
+// RUN: %clang -target mips-img-linux-gnu -### -c %s \
+// RUN: -mno-abicalls -mlong-calls 2>&1 \
// RUN: | FileCheck --check-prefix=LONG-CALLS-ON %s
-// RUN: %clang -target mips-img-linux-gnu -### -c %s -mno-long-calls 2>&1 \
+// RUN: %clang -target mips-img-linux-gnu -### -c %s \
+// RUN: -mno-abicalls -mno-long-calls 2>&1 \
// RUN: | FileCheck --check-prefix=LONG-CALLS-OFF %s
// RUN: %clang -target mips-img-linux-gnu -### -c %s 2>&1 \
// RUN: | FileCheck --check-prefix=LONG-CALLS-DEF %s
+// RUN: %clang -target mips-img-linux-gnu -### -c %s -mlong-calls 2>&1 \
+// RUN: | FileCheck --check-prefix=LONG-CALLS-DEF %s
// LONG-CALLS-ON: "-target-feature" "+long-calls"
// LONG-CALLS-OFF: "-target-feature" "-long-calls"
// LONG-CALLS-DEF-NOT: "long-calls"
+//
+// -mbranch-likely
+// RUN: %clang -target -mips-mti-linux-gnu -### -c %s -mbranch-likely 2>&1 \
+// RUN: | FileCheck --check-prefix=BRANCH-LIKELY %s
+// BRANCH-LIKELY: argument unused during compilation: '-mbranch-likely'
+//
+// -mno-branch-likely
+// RUN: %clang -target -mips-mti-linux-gnu -### -c %s -mno-branch-likely 2>&1 \
+// RUN: | FileCheck --check-prefix=NO-BRANCH-LIKELY %s
+// NO-BRANCH-LIKELY: argument unused during compilation: '-mno-branch-likely'
diff --git a/test/Driver/mips-gpopt-warning.c b/test/Driver/mips-gpopt-warning.c
new file mode 100644
index 000000000000..b6677413729f
--- /dev/null
+++ b/test/Driver/mips-gpopt-warning.c
@@ -0,0 +1,6 @@
+// REQUIRES: mips-registered-target
+// RUN: %clang -### -c -target mips-mti-elf %s -mgpopt 2>&1 | FileCheck -check-prefix=IMPLICIT %s
+// IMPLICIT: warning: ignoring '-mgpopt' option as it cannot be used with the implicit usage of -mabicalls
+
+// RUN: %clang -### -c -target mips-mti-elf %s -mgpopt -mabicalls 2>&1 | FileCheck -check-prefix=EXPLICIT %s
+// EXPLICIT: warning: ignoring '-mgpopt' option as it cannot be used with -mabicalls
diff --git a/test/Driver/mips-mabs-warning.c b/test/Driver/mips-mabs-warning.c
new file mode 100644
index 000000000000..93175be4ccb8
--- /dev/null
+++ b/test/Driver/mips-mabs-warning.c
@@ -0,0 +1,6 @@
+// REQUIRES: mips-registered-target
+// RUN: %clang -c -target mips-unknown-gnu -mcpu=mips32 -mabs=2008 %s 2>&1 | FileCheck -check-prefix=NO2008 %s
+// NO2008: warning: ignoring '-mabs=2008' option because the 'mips32' architecture does not support it [-Wunsupported-abs]
+
+// RUN: %clang -c -target mips-unknown-gnu -mcpu=mips32r6 -mabs=legacy %s 2>&1 | FileCheck -check-prefix=NOLEGACY %s
+// NOLEGACY: warning: ignoring '-mabs=legacy' option because the 'mips32r6' architecture does not support it [-Wunsupported-abs]
diff --git a/test/Driver/mprefer-vector-width.c b/test/Driver/mprefer-vector-width.c
new file mode 100644
index 000000000000..d927b35c0982
--- /dev/null
+++ b/test/Driver/mprefer-vector-width.c
@@ -0,0 +1,24 @@
+////
+//// Verify that valid options for the -mprefer-vector-width flag are passed through and invalid options cause an error.
+////
+
+//// If there are no options, convert to 'all'.
+
+// RUN: %clang -### -S %s -mprefer-vector-width=none 2>&1 | FileCheck --check-prefix=WIDTHNONE %s
+// WIDTHNONE: "-mprefer-vector-width=none"
+
+//// Check options that cover all types.
+
+// RUN: %clang -### -S %s -mprefer-vector-width=128 2>&1 | FileCheck --check-prefix=WIDTH128 %s
+// WIDTH128: "-mprefer-vector-width=128"
+
+//// Check invalid parameters.
+
+// RUN: %clang -### -S %s -mprefer-vector-width=one 2>&1 | FileCheck --check-prefix=WIDTHONE %s
+// WIDTHONE: invalid value 'one' in 'mprefer-vector-width='
+
+// RUN: %clang -### -S %s -mprefer-vector-width=128.5 2>&1 | FileCheck --check-prefix=WIDTH128p5 %s
+// WIDTH128p5: invalid value '128.5' in 'mprefer-vector-width='
+
+// RUN: %clang -### -S %s -mprefer-vector-width=-128 2>&1 | FileCheck --check-prefix=WIDTHNEG128 %s
+// WIDTHNEG128: invalid value '-128' in 'mprefer-vector-width='
diff --git a/test/Driver/nostdlib.c b/test/Driver/nostdlib.c
index a9ef665c5744..c9793d968c59 100644
--- a/test/Driver/nostdlib.c
+++ b/test/Driver/nostdlib.c
@@ -27,5 +27,5 @@
//
// CHECK-LINUX-NOSTDLIB: warning: argument unused during compilation: '--rtlib=compiler-rt'
// CHECK-LINUX-NOSTDLIB: "{{(.*[^.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
-// CHECK-LINUX-NOSTDLIB-NOT: "{{.*}}/Inputs/resource_dir{{/|\\\\}}lib{{/|\\\\}}linux{{/|\\\\}}libclang_rt.builtins-i686.a"
+// CHECK-LINUX-NOSTDLIB-NOT: "{{.*}}/Inputs/resource_dir{{/|\\\\}}lib{{/|\\\\}}linux{{/|\\\\}}libclang_rt.builtins-i386.a"
// CHECK-MSVC-NOSTDLIB: warning: argument unused during compilation: '--rtlib=compiler-rt'
diff --git a/test/Driver/nostdlibxx.cpp b/test/Driver/nostdlibxx.cpp
new file mode 100644
index 000000000000..02bd62d96af5
--- /dev/null
+++ b/test/Driver/nostdlibxx.cpp
@@ -0,0 +1,8 @@
+// RUN: %clangxx -target i686-pc-linux-gnu -### -nostdlib++ %s 2> %t
+// RUN: FileCheck < %t %s
+
+// We should still have -lm and the C standard libraries, but not -lstdc++.
+
+// CHECK-NOT: -lstdc++
+// CHECK-NOT: -lc++
+// CHECK: -lm
diff --git a/test/Driver/openmp-offload-gpu.c b/test/Driver/openmp-offload-gpu.c
new file mode 100644
index 000000000000..16c321b9f499
--- /dev/null
+++ b/test/Driver/openmp-offload-gpu.c
@@ -0,0 +1,144 @@
+///
+/// Perform several driver tests for OpenMP offloading
+///
+
+// REQUIRES: clang-driver
+// REQUIRES: x86-registered-target
+// REQUIRES: powerpc-registered-target
+// REQUIRES: nvptx-registered-target
+
+/// ###########################################################################
+
+/// Check -Xopenmp-target uses one of the archs provided when several archs are used.
+// RUN: %clang -### -no-canonical-prefixes -fopenmp=libomp -fopenmp-targets=nvptx64-nvidia-cuda \
+// RUN: -Xopenmp-target -march=sm_35 -Xopenmp-target -march=sm_60 %s 2>&1 \
+// RUN: | FileCheck -check-prefix=CHK-FOPENMP-TARGET-ARCHS %s
+
+// CHK-FOPENMP-TARGET-ARCHS: ptxas{{.*}}" "--gpu-name" "sm_60"
+// CHK-FOPENMP-TARGET-ARCHS: nvlink{{.*}}" "-arch" "sm_60"
+
+/// ###########################################################################
+
+/// Check -Xopenmp-target -march=sm_35 works as expected when two triples are present.
+// RUN: %clang -### -no-canonical-prefixes -fopenmp=libomp \
+// RUN: -fopenmp-targets=powerpc64le-ibm-linux-gnu,nvptx64-nvidia-cuda \
+// RUN: -Xopenmp-target=nvptx64-nvidia-cuda -march=sm_35 %s 2>&1 \
+// RUN: | FileCheck -check-prefix=CHK-FOPENMP-TARGET-COMPILATION %s
+
+// CHK-FOPENMP-TARGET-COMPILATION: ptxas{{.*}}" "--gpu-name" "sm_35"
+// CHK-FOPENMP-TARGET-COMPILATION: nvlink{{.*}}" "-arch" "sm_35"
+
+/// ###########################################################################
+
+/// Check cubin file generation and usage by nvlink
+// RUN: %clang -### -no-canonical-prefixes -target powerpc64le-unknown-linux-gnu -fopenmp=libomp \
+// RUN: -fopenmp-targets=nvptx64-nvidia-cuda -save-temps %s 2>&1 \
+// RUN: | FileCheck -check-prefix=CHK-CUBIN-NVLINK %s
+/// Check cubin file generation and usage by nvlink when toolchain has BindArchAction
+// RUN: %clang -### -no-canonical-prefixes -target x86_64-apple-darwin17.0.0 -fopenmp=libomp \
+// RUN: -fopenmp-targets=nvptx64-nvidia-cuda %s 2>&1 \
+// RUN: | FileCheck -check-prefix=CHK-CUBIN-NVLINK %s
+
+// CHK-CUBIN-NVLINK: clang{{.*}}" "-o" "[[PTX:.*\.s]]"
+// CHK-CUBIN-NVLINK-NEXT: ptxas{{.*}}" "--output-file" "[[CUBIN:.*\.cubin]]" {{.*}}"[[PTX]]"
+// CHK-CUBIN-NVLINK-NEXT: nvlink{{.*}}" {{.*}}"[[CUBIN]]"
+
+/// ###########################################################################
+
+/// Check unbundlink of assembly file, cubin file generation and usage by nvlink
+// RUN: touch %t.s
+// RUN: %clang -### -target powerpc64le-unknown-linux-gnu -fopenmp=libomp -fopenmp-targets=nvptx64-nvidia-cuda \
+// RUN: -no-canonical-prefixes -save-temps %t.s 2>&1 \
+// RUN: | FileCheck -check-prefix=CHK-UNBUNDLING-PTXAS-CUBIN-NVLINK %s
+
+/// Use DAG to ensure that assembly file has been unbundled.
+// CHK-UNBUNDLING-PTXAS-CUBIN-NVLINK-DAG: ptxas{{.*}}" "--output-file" "[[CUBIN:.*\.cubin]]" {{.*}}"[[PTX:.*\.s]]"
+// CHK-UNBUNDLING-PTXAS-CUBIN-NVLINK-DAG: clang-offload-bundler{{.*}}" "-type=s" {{.*}}"-outputs={{.*}}[[PTX]]
+// CHK-UNBUNDLING-PTXAS-CUBIN-NVLINK-DAG-SAME: "-unbundle"
+// CHK-UNBUNDLING-PTXAS-CUBIN-NVLINK: nvlink{{.*}}" {{.*}}"[[CUBIN]]"
+
+/// ###########################################################################
+
+/// Check cubin file generation and bundling
+// RUN: %clang -### -target powerpc64le-unknown-linux-gnu -fopenmp=libomp -fopenmp-targets=nvptx64-nvidia-cuda \
+// RUN: -no-canonical-prefixes -save-temps %s -c 2>&1 \
+// RUN: | FileCheck -check-prefix=CHK-PTXAS-CUBIN-BUNDLING %s
+
+// CHK-PTXAS-CUBIN-BUNDLING: clang{{.*}}" "-o" "[[PTX:.*\.s]]"
+// CHK-PTXAS-CUBIN-BUNDLING-NEXT: ptxas{{.*}}" "--output-file" "[[CUBIN:.*\.cubin]]" {{.*}}"[[PTX]]"
+// CHK-PTXAS-CUBIN-BUNDLING: clang-offload-bundler{{.*}}" "-type=o" {{.*}}"-inputs={{.*}}[[CUBIN]]
+
+/// ###########################################################################
+
+/// Check cubin file unbundling and usage by nvlink
+// RUN: touch %t.o
+// RUN: %clang -### -target powerpc64le-unknown-linux-gnu -fopenmp=libomp -fopenmp-targets=nvptx64-nvidia-cuda \
+// RUN: -no-canonical-prefixes -save-temps %t.o 2>&1 \
+// RUN: | FileCheck -check-prefix=CHK-CUBIN-UNBUNDLING-NVLINK %s
+
+/// Use DAG to ensure that cubin file has been unbundled.
+// CHK-CUBIN-UNBUNDLING-NVLINK-DAG: nvlink{{.*}}" {{.*}}"[[CUBIN:.*\.cubin]]"
+// CHK-CUBIN-UNBUNDLING-NVLINK-DAG: clang-offload-bundler{{.*}}" "-type=o" {{.*}}"-outputs={{.*}}[[CUBIN]]
+// CHK-CUBIN-UNBUNDLING-NVLINK-DAG-SAME: "-unbundle"
+
+/// ###########################################################################
+
+/// Check cubin file generation and usage by nvlink
+// RUN: touch %t1.o
+// RUN: touch %t2.o
+// RUN: %clang -### -no-canonical-prefixes -target powerpc64le-unknown-linux-gnu -fopenmp=libomp \
+// RUN: -fopenmp-targets=nvptx64-nvidia-cuda %t1.o %t2.o 2>&1 \
+// RUN: | FileCheck -check-prefix=CHK-TWOCUBIN %s
+/// Check cubin file generation and usage by nvlink when toolchain has BindArchAction
+// RUN: %clang -### -no-canonical-prefixes -target x86_64-apple-darwin17.0.0 -fopenmp=libomp \
+// RUN: -fopenmp-targets=nvptx64-nvidia-cuda %t1.o %t2.o 2>&1 \
+// RUN: | FileCheck -check-prefix=CHK-TWOCUBIN %s
+
+// CHK-TWOCUBIN: nvlink{{.*}}openmp-offload-{{.*}}.cubin" "{{.*}}openmp-offload-{{.*}}.cubin"
+
+/// ###########################################################################
+
+/// Check PTXAS is passed -c flag when offloading to an NVIDIA device using OpenMP.
+// RUN: %clang -### -fopenmp=libomp -fopenmp-targets=nvptx64-nvidia-cuda -no-canonical-prefixes %s 2>&1 \
+// RUN: | FileCheck -check-prefix=CHK-PTXAS-DEFAULT %s
+
+// CHK-PTXAS-DEFAULT: ptxas{{.*}}" "-c"
+
+/// ###########################################################################
+
+/// PTXAS is passed -c flag by default when offloading to an NVIDIA device using OpenMP - disable it.
+// RUN: %clang -### -fopenmp=libomp -fopenmp-targets=nvptx64-nvidia-cuda -fnoopenmp-relocatable-target \
+// RUN: -save-temps -no-canonical-prefixes %s 2>&1 \
+// RUN: | FileCheck -check-prefix=CHK-PTXAS-NORELO %s
+
+// CHK-PTXAS-NORELO-NOT: ptxas{{.*}}" "-c"
+
+/// ###########################################################################
+
+/// PTXAS is passed -c flag by default when offloading to an NVIDIA device using OpenMP
+/// Check that the flag is passed when -fopenmp-relocatable-target is used.
+// RUN: %clang -### -fopenmp=libomp -fopenmp-targets=nvptx64-nvidia-cuda -fopenmp-relocatable-target \
+// RUN: -save-temps -no-canonical-prefixes %s 2>&1 \
+// RUN: | FileCheck -check-prefix=CHK-PTXAS-RELO %s
+
+// CHK-PTXAS-RELO: ptxas{{.*}}" "-c"
+
+/// ###########################################################################
+
+/// Check that error is not thrown by toolchain when no cuda lib flag is used.
+/// Check that the flag is passed when -fopenmp-relocatable-target is used.
+// RUN: %clang -### -fopenmp=libomp -fopenmp-targets=nvptx64-nvidia-cuda -Xopenmp-target -march=sm_60 \
+// RUN: -nocudalib -fopenmp-relocatable-target -save-temps -no-canonical-prefixes %s 2>&1 \
+// RUN: | FileCheck -check-prefix=CHK-FLAG-NOLIBDEVICE %s
+
+// CHK-FLAG-NOLIBDEVICE-NOT: error:{{.*}}sm_60
+
+/// ###########################################################################
+
+/// Check that error is not thrown by toolchain when no cuda lib device is found when using -S.
+/// Check that the flag is passed when -fopenmp-relocatable-target is used.
+// RUN: %clang -### -S -fopenmp=libomp -fopenmp-targets=nvptx64-nvidia-cuda -Xopenmp-target -march=sm_60 \
+// RUN: -fopenmp-relocatable-target -save-temps -no-canonical-prefixes %s 2>&1 \
+// RUN: | FileCheck -check-prefix=CHK-NOLIBDEVICE %s
+
+// CHK-NOLIBDEVICE-NOT: error:{{.*}}sm_60
diff --git a/test/Driver/openmp-offload.c b/test/Driver/openmp-offload.c
index d43aa331c9dc..67098c902238 100644
--- a/test/Driver/openmp-offload.c
+++ b/test/Driver/openmp-offload.c
@@ -39,6 +39,62 @@
/// ###########################################################################
+/// Check -Xopenmp-target=powerpc64le-ibm-linux-gnu -mcpu=pwr7 is passed when compiling for the device.
+// RUN: %clang -### -no-canonical-prefixes -fopenmp=libomp -fopenmp-targets=powerpc64le-ibm-linux-gnu -Xopenmp-target=powerpc64le-ibm-linux-gnu -mcpu=pwr7 %s 2>&1 \
+// RUN: | FileCheck -check-prefix=CHK-FOPENMP-EQ-TARGET %s
+
+// CHK-FOPENMP-EQ-TARGET: clang{{.*}} "-target-cpu" "pwr7" {{.*}}"-fopenmp-is-device"
+
+/// ###########################################################################
+
+/// Check -Xopenmp-target -mcpu=pwr7 is passed when compiling for the device.
+// RUN: %clang -### -no-canonical-prefixes -fopenmp=libomp -fopenmp-targets=powerpc64le-ibm-linux-gnu -Xopenmp-target -mcpu=pwr7 %s 2>&1 \
+// RUN: | FileCheck -check-prefix=CHK-FOPENMP-TARGET %s
+
+// CHK-FOPENMP-TARGET: clang{{.*}} "-target-cpu" "pwr7" {{.*}}"-fopenmp-is-device"
+
+/// ##########################################################################
+
+/// Check -mcpu=pwr7 is passed to the same triple.
+// RUN: %clang -### -no-canonical-prefixes -fopenmp=libomp -fopenmp-targets=powerpc64le-ibm-linux-gnu -target powerpc64le-ibm-linux-gnu -mcpu=pwr7 %s 2>&1 \
+// RUN: | FileCheck -check-prefix=CHK-FOPENMP-MCPU-TO-SAME-TRIPLE %s
+
+// CHK-FOPENMP-MCPU-TO-SAME-TRIPLE: clang{{.*}} "-target-cpu" "pwr7" {{.*}}"-fopenmp-is-device"
+
+/// ##########################################################################
+
+/// Check -march=pwr7 is NOT passed to nvptx64-nvidia-cuda.
+// RUN: %clang -### -no-canonical-prefixes -fopenmp=libomp -fopenmp-targets=nvptx64-nvidia-cuda -target powerpc64le-ibm-linux-gnu -march=pwr7 %s 2>&1 \
+// RUN: | FileCheck -check-prefix=CHK-FOPENMP-MARCH-TO-GPU %s
+
+// CHK-FOPENMP-MARCH-TO-GPU-NOT: clang{{.*}} "-target-cpu" "pwr7" {{.*}}"-fopenmp-is-device"
+
+/// ###########################################################################
+
+/// Check -march=pwr7 is NOT passed to x86_64-unknown-linux-gnu.
+// RUN: %clang -### -no-canonical-prefixes -fopenmp=libomp -fopenmp-targets=x86_64-unknown-linux-gnu -target powerpc64le-ibm-linux-gnu -march=pwr7 %s 2>&1 \
+// RUN: | FileCheck -check-prefix=CHK-FOPENMP-MARCH-TO-X86 %s
+
+// CHK-FOPENMP-MARCH-TO-X86-NOT: clang{{.*}} "-target-cpu" "pwr7" {{.*}}"-fopenmp-is-device"
+
+/// ###########################################################################
+
+/// Check -Xopenmp-target triggers error when multiple triples are used.
+// RUN: %clang -### -no-canonical-prefixes -fopenmp=libomp -fopenmp-targets=powerpc64le-ibm-linux-gnu,powerpc64le-unknown-linux-gnu -Xopenmp-target -mcpu=pwr8 %s 2>&1 \
+// RUN: | FileCheck -check-prefix=CHK-FOPENMP-TARGET-AMBIGUOUS-ERROR %s
+
+// CHK-FOPENMP-TARGET-AMBIGUOUS-ERROR: clang{{.*}} error: cannot deduce implicit triple value for -Xopenmp-target, specify triple using -Xopenmp-target=<triple>
+
+/// ###########################################################################
+
+/// Check -Xopenmp-target triggers error when an option requiring arguments is passed to it.
+// RUN: %clang -### -no-canonical-prefixes -fopenmp=libomp -fopenmp-targets=powerpc64le-ibm-linux-gnu -Xopenmp-target -Xopenmp-target -mcpu=pwr8 %s 2>&1 \
+// RUN: | FileCheck -check-prefix=CHK-FOPENMP-TARGET-NESTED-ERROR %s
+
+// CHK-FOPENMP-TARGET-NESTED-ERROR: clang{{.*}} error: invalid -Xopenmp-target argument: '-Xopenmp-target -Xopenmp-target', options requiring arguments are unsupported
+
+/// ###########################################################################
+
/// Check the phases graph when using a single target, different from the host.
/// We should have an offload action joining the host compile and device
/// preprocessor and another one joining the device linking outputs to the host
diff --git a/test/Driver/opt-record.c b/test/Driver/opt-record.c
index 6e684878d448..5e8a28f5f8cc 100644
--- a/test/Driver/opt-record.c
+++ b/test/Driver/opt-record.c
@@ -1,6 +1,10 @@
// RUN: %clang -### -S -o FOO -fsave-optimization-record %s 2>&1 | FileCheck %s
// RUN: %clang -### -c -o FOO -fsave-optimization-record %s 2>&1 | FileCheck %s
+// RUN: %clang -### -c -o FOO.o -fsave-optimization-record %s 2>&1 | FileCheck %s
+// RUN: %clang -### -save-temps -S -o FOO -fsave-optimization-record %s 2>&1 | FileCheck %s
+// RUN: %clang -### -save-temps -c -o FOO.o -fsave-optimization-record %s 2>&1 | FileCheck %s
// RUN: %clang -### -c -fsave-optimization-record %s 2>&1 | FileCheck %s -check-prefix=CHECK-NO-O
+// RUN: %clang -### -save-temps -c -fsave-optimization-record %s 2>&1 | FileCheck %s -check-prefix=CHECK-NO-O
// RUN: %clang -### -fsave-optimization-record %s 2>&1 | FileCheck %s -check-prefix=CHECK-NO-O
// RUN: %clang -### -S -fsave-optimization-record -x cuda -nocudainc -nocudalib %s 2>&1 | FileCheck %s -check-prefix=CHECK-NO-O -check-prefix=CHECK-CUDA-DEV
// RUN: %clang -### -fsave-optimization-record -x cuda -nocudainc -nocudalib %s 2>&1 | FileCheck %s -check-prefix=CHECK-NO-O -check-prefix=CHECK-CUDA-DEV
diff --git a/test/Driver/output-file-cleanup.c b/test/Driver/output-file-cleanup.c
index 314af4d6d37e..e3f2bdbb2fb8 100644
--- a/test/Driver/output-file-cleanup.c
+++ b/test/Driver/output-file-cleanup.c
@@ -25,30 +25,19 @@
invalid C code
#endif
-// RUN: touch %t1.c
-// RUN: echo "invalid C code" > %t2.c
-// RUN: cd %T && not %clang -S %t1.c %t2.c
-// RUN: test -f %t1.s
-// RUN: test ! -f %t2.s
+// RUN: rm -rf %t-dir
+// RUN: mkdir -p %t-dir
+// RUN: cd %t-dir
-// RUN: touch %t1.c
-// RUN: touch %t2.c
-// RUN: chmod -r %t2.c
-// RUN: cd %T && not %clang -S %t1.c %t2.c
-// RUN: test -f %t1.s
-// RUN: test ! -f %t2.s
+// RUN: touch %t-dir/1.c
+// RUN: echo "invalid C code" > %t-dir/2.c
+// RUN: not %clang -S %t-dir/1.c %t-dir/2.c
+// RUN: test -f %t-dir/1.s
+// RUN: test ! -f %t-dir/2.s
-// When given multiple .c files to compile, clang compiles them in order until
-// it hits an error, at which point it stops.
-//
-// RUN: touch %t1.c
-// RUN: echo "invalid C code" > %t2.c
-// RUN: touch %t3.c
-// RUN: echo "invalid C code" > %t4.c
-// RUN: touch %t5.c
-// RUN: cd %T && not %clang -S %t1.c %t2.c %t3.c %t4.c %t5.c
-// RUN: test -f %t1.s
-// RUN: test ! -f %t2.s
-// RUN: test ! -f %t3.s
-// RUN: test ! -f %t4.s
-// RUN: test ! -f %t5.s
+// RUN: touch %t-dir/1.c
+// RUN: touch %t-dir/2.c
+// RUN: chmod -r %t-dir/2.c
+// RUN: not %clang -S %t-dir/1.c %t-dir/2.c
+// RUN: test -f %t-dir/1.s
+// RUN: test ! -f %t-dir/2.s
diff --git a/test/Driver/parse-progname.c b/test/Driver/parse-progname.c
index 33c637822348..c432b10e31b2 100644
--- a/test/Driver/parse-progname.c
+++ b/test/Driver/parse-progname.c
@@ -1,58 +1,58 @@
// REQUIRES: shell, arm-registered-target
-
-
-// RUN: ln -fs %clang %T/clang++
-// RUN: ln -fs %clang %T/clang++3.5.0
-// RUN: ln -fs %clang %T/clang++-3.5
-// RUN: ln -fs %clang %T/clang++-tot
-// RUN: ln -fs %clang %T/clang-c++
-// RUN: ln -fs %clang %T/clang-g++
-// RUN: ln -fs %clang %T/c++
-// RUN: ln -fs %clang %T/foo-clang++
-// RUN: ln -fs %clang %T/foo-clang++-3.5
-// RUN: ln -fs %clang %T/foo-clang++3.5
-// RUN: %T/clang++ -### %s 2>&1 | FileCheck -check-prefix=CXXMODE %s
-// RUN: %T/clang++3.5.0 -### %s 2>&1 | FileCheck -check-prefix=CXXMODE %s
-// RUN: %T/clang++-3.5 -### %s 2>&1 | FileCheck -check-prefix=CXXMODE %s
-// RUN: %T/clang++-tot -### %s 2>&1 | FileCheck -check-prefix=CXXMODE %s
-// RUN: %T/clang-c++ -### %s 2>&1 | FileCheck -check-prefix=CXXMODE %s
-// RUN: %T/clang-g++ -### %s 2>&1 | FileCheck -check-prefix=CXXMODE %s
-// RUN: %T/c++ -### %s 2>&1 | FileCheck -check-prefix=CXXMODE %s
-// RUN: %T/foo-clang++ -### %s 2>&1 | FileCheck -check-prefix=CXXMODE %s
-// RUN: %T/foo-clang++-3.5 -### %s 2>&1 | FileCheck -check-prefix=CXXMODE %s
-// RUN: %T/foo-clang++3.5 -### %s 2>&1 | FileCheck -check-prefix=CXXMODE %s
+// RUN: mkdir -p %t
+
+// RUN: ln -fs %clang %t/clang++
+// RUN: ln -fs %clang %t/clang++3.5.0
+// RUN: ln -fs %clang %t/clang++-3.5
+// RUN: ln -fs %clang %t/clang++-tot
+// RUN: ln -fs %clang %t/clang-c++
+// RUN: ln -fs %clang %t/clang-g++
+// RUN: ln -fs %clang %t/c++
+// RUN: ln -fs %clang %t/foo-clang++
+// RUN: ln -fs %clang %t/foo-clang++-3.5
+// RUN: ln -fs %clang %t/foo-clang++3.5
+// RUN: %t/clang++ -### %s 2>&1 | FileCheck -check-prefix=CXXMODE %s
+// RUN: %t/clang++3.5.0 -### %s 2>&1 | FileCheck -check-prefix=CXXMODE %s
+// RUN: %t/clang++-3.5 -### %s 2>&1 | FileCheck -check-prefix=CXXMODE %s
+// RUN: %t/clang++-tot -### %s 2>&1 | FileCheck -check-prefix=CXXMODE %s
+// RUN: %t/clang-c++ -### %s 2>&1 | FileCheck -check-prefix=CXXMODE %s
+// RUN: %t/clang-g++ -### %s 2>&1 | FileCheck -check-prefix=CXXMODE %s
+// RUN: %t/c++ -### %s 2>&1 | FileCheck -check-prefix=CXXMODE %s
+// RUN: %t/foo-clang++ -### %s 2>&1 | FileCheck -check-prefix=CXXMODE %s
+// RUN: %t/foo-clang++-3.5 -### %s 2>&1 | FileCheck -check-prefix=CXXMODE %s
+// RUN: %t/foo-clang++3.5 -### %s 2>&1 | FileCheck -check-prefix=CXXMODE %s
// CXXMODE: "-x" "c++"
-// RUN: ln -fs %clang %T/clang-cl
-// RUN: ln -fs %clang %T/cl
-// RUN: ln -fs %clang %T/cl.exe
-// RUN: ln -fs %clang %T/clang-cl3.5
-// RUN: ln -fs %clang %T/clang-cl-3.5
+// RUN: ln -fs %clang %t/clang-cl
+// RUN: ln -fs %clang %t/cl
+// RUN: ln -fs %clang %t/cl.exe
+// RUN: ln -fs %clang %t/clang-cl3.5
+// RUN: ln -fs %clang %t/clang-cl-3.5
// Note: use -- in front of the filename so it's not mistaken for an option on
// filesystems that use slashes for dir separators.
-// RUN: %T/clang-cl -### -- %s 2>&1 | FileCheck -check-prefix=CLMODE %s
-// RUN: %T/cl -### -- %s 2>&1 | FileCheck -check-prefix=CLMODE %s
-// RUN: %T/cl.exe -### -- %s 2>&1 | FileCheck -check-prefix=CLMODE %s
-// RUN: %T/clang-cl3.5 -### -- %s 2>&1 | FileCheck -check-prefix=CLMODE %s
-// RUN: %T/clang-cl-3.5 -### -- %s 2>&1 | FileCheck -check-prefix=CLMODE %s
+// RUN: %t/clang-cl -### -- %s 2>&1 | FileCheck -check-prefix=CLMODE %s
+// RUN: %t/cl -### -- %s 2>&1 | FileCheck -check-prefix=CLMODE %s
+// RUN: %t/cl.exe -### -- %s 2>&1 | FileCheck -check-prefix=CLMODE %s
+// RUN: %t/clang-cl3.5 -### -- %s 2>&1 | FileCheck -check-prefix=CLMODE %s
+// RUN: %t/clang-cl-3.5 -### -- %s 2>&1 | FileCheck -check-prefix=CLMODE %s
// CLMODE: "-fdiagnostics-format" "msvc"
-// RUN: ln -fs %clang %T/clang-cpp
-// RUN: ln -fs %clang %T/cpp
-// RUN: %T/clang-cpp -### %s 2>&1 | FileCheck -check-prefix=CPPMODE %s
-// RUN: %T/cpp -### %s 2>&1 | FileCheck -check-prefix=CPPMODE %s
+// RUN: ln -fs %clang %t/clang-cpp
+// RUN: ln -fs %clang %t/cpp
+// RUN: %t/clang-cpp -### %s 2>&1 | FileCheck -check-prefix=CPPMODE %s
+// RUN: %t/cpp -### %s 2>&1 | FileCheck -check-prefix=CPPMODE %s
// CPPMODE: "-E"
-// RUN: ln -fs %clang %T/cl-clang
-// RUN: %T/cl-clang -### %s 2>&1 | FileCheck -check-prefix=CMODE %s
+// RUN: ln -fs %clang %t/cl-clang
+// RUN: %t/cl-clang -### %s 2>&1 | FileCheck -check-prefix=CMODE %s
// CMODE: "-x" "c"
// CMODE-NOT: "-fdiagnostics-format" "msvc"
-// RUN: ln -fs %clang %T/arm-linux-gnueabi-clang
-// RUN: %T/arm-linux-gnueabi-clang -### %s 2>&1 | FileCheck -check-prefix=TARGET %s
+// RUN: ln -fs %clang %t/arm-linux-gnueabi-clang
+// RUN: %t/arm-linux-gnueabi-clang -### %s 2>&1 | FileCheck -check-prefix=TARGET %s
// TARGET: Target: arm--linux-gnueabi
diff --git a/test/Driver/pic.c b/test/Driver/pic.c
index 6b01c583b8b1..9b3aa0e77135 100644
--- a/test/Driver/pic.c
+++ b/test/Driver/pic.c
@@ -152,6 +152,22 @@
// RUN: %clang %s -target i386-unknown-linux -shared -pie -### 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK-NO-PIE
//
+// On Musl Linux, PIE is enabled by default, but can be disabled.
+// RUN: %clang -c %s -target x86_64-linux-musl -### 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CHECK-PIE2
+// RUN: %clang -c %s -target i686-linux-musl -### 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CHECK-PIE2
+// RUN: %clang -c %s -target armv6-linux-musleabihf -### 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CHECK-PIE2
+// RUN: %clang -c %s -target armv7-linux-musleabihf -### 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CHECK-PIE2
+// RUN: %clang %s -target x86_64-linux-musl -nopie -### 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CHECK-NO-PIE
+// RUN: %clang %s -target x86_64-linux-musl -pie -nopie -### 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CHECK-NO-PIE
+// RUN: %clang %s -target x86_64-linux-musl -nopie -pie -### 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CHECK-PIE2
+//
// Darwin is a beautiful and unique snowflake when it comes to these flags.
// When targeting a 32-bit darwin system, only level 2 is supported. On 64-bit
// targets, there is simply nothing you can do, there is no PIE, there is only
@@ -251,17 +267,54 @@
// RUN: %clang %s -target i386-pc-openbsd -no-pie -### 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK-NOPIE-LD
//
-// On Android PIC is enabled by default
+// On Android PIC is enabled by default, and PIE is enabled by default starting
+// with API16.
// RUN: %clang -c %s -target i686-linux-android -### 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK-PIC2
+// RUN: %clang -c %s -target i686-linux-android14 -### 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CHECK-PIC2
+// RUN: %clang -c %s -target i686-linux-android16 -### 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CHECK-PIE2
+// RUN: %clang -c %s -target i686-linux-android24 -### 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CHECK-PIE2
+//
// RUN: %clang -c %s -target arm-linux-androideabi -### 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK-PIC1
+// RUN: %clang -c %s -target arm-linux-androideabi14 -### 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CHECK-PIC1
+// RUN: %clang -c %s -target arm-linux-androideabi16 -### 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CHECK-PIE2
+// RUN: %clang -c %s -target arm-linux-androideabi24 -### 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CHECK-PIE2
+//
// RUN: %clang -c %s -target mipsel-linux-android -### 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK-PIC1
-// RUN: %clang -c %s -target aarch64-linux-android -### 2>&1 \
+// RUN: %clang -c %s -target mipsel-linux-android14 -### 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK-PIC1
+// RUN: %clang -c %s -target mipsel-linux-android16 -### 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CHECK-PIE2
+// RUN: %clang -c %s -target mipsel-linux-android24 -### 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CHECK-PIE2
+//
+// 64-bit Android targets are always PIE.
+// RUN: %clang -c %s -target aarch64-linux-android -### 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CHECK-PIE2
+// RUN: %clang -c %s -target aarch64-linux-android24 -### 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CHECK-PIE2
// RUN: %clang -c %s -target arm64-linux-android -### 2>&1 \
-// RUN: | FileCheck %s --check-prefix=CHECK-PIC1
+// RUN: | FileCheck %s --check-prefix=CHECK-PIE2
+//
+// Default value of PIE can be overwritten, even on 64-bit targets.
+// RUN: %clang -c %s -target arm-linux-androideabi -fPIE -### 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CHECK-PIE2
+// RUN: %clang -c %s -target i686-linux-android14 -fPIE -### 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CHECK-PIE2
+// RUN: %clang -c %s -target i686-linux-android16 -fno-PIE -### 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CHECK-NO-PIC
+// RUN: %clang -c %s -target aarch64-linux-android -fno-PIE -### 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CHECK-NO-PIC
+// RUN: %clang -c %s -target aarch64-linux-android24 -fno-PIE -### 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CHECK-NO-PIC
//
// On Windows-X64 PIC is enabled by default
// RUN: %clang -c %s -target x86_64-pc-windows-msvc18.0.0 -### 2>&1 \
diff --git a/test/Driver/ppc-features.cpp b/test/Driver/ppc-features.cpp
index f37af0918d9e..621c407d37ef 100644
--- a/test/Driver/ppc-features.cpp
+++ b/test/Driver/ppc-features.cpp
@@ -171,8 +171,8 @@
// RUN: %clang -target powerpc64le-unknown-linux-gnu %s -### -o %t.o -no-integrated-as 2>&1 | FileCheck -check-prefix=CHECK_LE_AS_ARGS %s
// CHECK_LE_AS_ARGS: "-mppc64"
-// CHECK_LE_AS_ARGS: "-many"
// CHECK_LE_AS_ARGS: "-mlittle-endian"
+// CHECK_LE_AS_ARGS: "-mpower8"
// linker features
// RUN: %clang -target powerpc64-unknown-linux-gnu %s -### -o %t.o 2>&1 | FileCheck -check-prefix=CHECK_BE_LD_ARGS %s
diff --git a/test/Driver/print-libgcc-file-name-clangrt.c b/test/Driver/print-libgcc-file-name-clangrt.c
index 9f8120c31d90..ce941dc4a128 100644
--- a/test/Driver/print-libgcc-file-name-clangrt.c
+++ b/test/Driver/print-libgcc-file-name-clangrt.c
@@ -6,6 +6,32 @@
// CHECK-CLANGRT-X8664: libclang_rt.builtins-x86_64.a
// RUN: %clang -rtlib=compiler-rt -print-libgcc-file-name 2>&1 \
+// RUN: --target=i386-pc-linux \
+// RUN: | FileCheck --check-prefix=CHECK-CLANGRT-I386 %s
+// CHECK-CLANGRT-I386: libclang_rt.builtins-i386.a
+
+// Check whether alternate arch values map to the correct library.
+//
+// RUN: %clang -rtlib=compiler-rt -print-libgcc-file-name 2>&1 \
// RUN: --target=i686-pc-linux \
-// RUN: | FileCheck --check-prefix=CHECK-CLANGRT-I686 %s
-// CHECK-CLANGRT-I686: libclang_rt.builtins-i686.a
+// RUN: | FileCheck --check-prefix=CHECK-CLANGRT-I386 %s
+
+// RUN: %clang -rtlib=compiler-rt -print-libgcc-file-name 2>&1 \
+// RUN: --target=arm-linux-gnueabi \
+// RUN: | FileCheck --check-prefix=CHECK-CLANGRT-ARM %s
+// CHECK-CLANGRT-ARM: libclang_rt.builtins-arm.a
+
+// RUN: %clang -rtlib=compiler-rt -print-libgcc-file-name 2>&1 \
+// RUN: --target=arm-linux-androideabi \
+// RUN: | FileCheck --check-prefix=CHECK-CLANGRT-ARM-ANDROID %s
+// CHECK-CLANGRT-ARM-ANDROID: libclang_rt.builtins-arm-android.a
+
+// RUN: %clang -rtlib=compiler-rt -print-libgcc-file-name 2>&1 \
+// RUN: --target=arm-linux-gnueabihf \
+// RUN: | FileCheck --check-prefix=CHECK-CLANGRT-ARMHF %s
+// CHECK-CLANGRT-ARMHF: libclang_rt.builtins-armhf.a
+
+// RUN: %clang -rtlib=compiler-rt -print-libgcc-file-name 2>&1 \
+// RUN: --target=arm-linux-gnueabi -mfloat-abi=hard \
+// RUN: | FileCheck --check-prefix=CHECK-CLANGRT-ARM-ABI %s
+// CHECK-CLANGRT-ARM-ABI: libclang_rt.builtins-armhf.a
diff --git a/test/Driver/ps4-linker-non-win.c b/test/Driver/ps4-linker-non-win.c
index e2f8386b2c78..3197292176c4 100644
--- a/test/Driver/ps4-linker-non-win.c
+++ b/test/Driver/ps4-linker-non-win.c
@@ -1,21 +1,21 @@
// UNSUPPORTED: system-windows
// REQUIRES: x86-registered-target
-// RUN: mkdir -p %T/Output
-// RUN: rm -f %T/Output/orbis-ld
-// RUN: touch %T/Output/orbis-ld
-// RUN: chmod +x %T/Output/orbis-ld
+// RUN: mkdir -p %t
+// RUN: rm -f %t/orbis-ld
+// RUN: touch %t/orbis-ld
+// RUN: chmod +x %t/orbis-ld
-// RUN: env "PATH=%T/Output:%PATH%" %clang -### -target x86_64-scei-ps4 %s -fuse-ld=gold 2>&1 \
+// RUN: env "PATH=%t:%PATH%" %clang -### -target x86_64-scei-ps4 %s -fuse-ld=gold 2>&1 \
// RUN: | FileCheck --check-prefix=CHECK-PS4-LINKER %s
-// RUN: env "PATH=%T/Output:%PATH%" %clang -### -target x86_64-scei-ps4 %s -shared 2>&1 \
+// RUN: env "PATH=%t:%PATH%" %clang -### -target x86_64-scei-ps4 %s -shared 2>&1 \
// RUN: | FileCheck --check-prefix=CHECK-PS4-LINKER %s
-// RUN: env "PATH=%T/Output:%PATH%" %clang -### -target x86_64-scei-ps4 %s 2>&1 \
+// RUN: env "PATH=%t:%PATH%" %clang -### -target x86_64-scei-ps4 %s 2>&1 \
// RUN: | FileCheck --check-prefix=CHECK-PS4-LINKER %s
-// RUN: env "PATH=%T/Output:%PATH%" %clang -### -target x86_64-scei-ps4 %s -fuse-ld=ps4 2>&1 \
+// RUN: env "PATH=%t:%PATH%" %clang -### -target x86_64-scei-ps4 %s -fuse-ld=ps4 2>&1 \
// RUN: | FileCheck --check-prefix=CHECK-PS4-LINKER %s
-// RUN: env "PATH=%T/Output:%PATH%" %clang -### -target x86_64-scei-ps4 %s -shared \
+// RUN: env "PATH=%t:%PATH%" %clang -### -target x86_64-scei-ps4 %s -shared \
// RUN: -fuse-ld=ps4 2>&1 | FileCheck --check-prefix=CHECK-PS4-LINKER %s
// CHECK-PS4-LINKER: /orbis-ld
diff --git a/test/Driver/ps4-linker-win.c b/test/Driver/ps4-linker-win.c
index 6fbd84bb6dee..fafa579a0743 100644
--- a/test/Driver/ps4-linker-win.c
+++ b/test/Driver/ps4-linker-win.c
@@ -7,19 +7,20 @@
// REQUIRES: system-windows, x86-registered-target
-// RUN: touch %T/orbis-ld.exe
-// RUN: touch %T/orbis-ld.gold.exe
+// RUN: mkdir -p %t
+// RUN: touch %t/orbis-ld.exe
+// RUN: touch %t/orbis-ld.gold.exe
-// RUN: env "PATH=%T;%PATH%;" %clang -target x86_64-scei-ps4 %s -fuse-ld=gold -### 2>&1 \
+// RUN: env "PATH=%t;%PATH%;" %clang -target x86_64-scei-ps4 %s -fuse-ld=gold -### 2>&1 \
// RUN: | FileCheck --check-prefix=CHECK-PS4-GOLD %s
-// RUN: env "PATH=%T;%PATH%;" %clang -target x86_64-scei-ps4 %s -shared -### 2>&1 \
+// RUN: env "PATH=%t;%PATH%;" %clang -target x86_64-scei-ps4 %s -shared -### 2>&1 \
// RUN: | FileCheck --check-prefix=CHECK-PS4-GOLD %s
-// RUN: env "PATH=%T;%PATH%;" %clang -target x86_64-scei-ps4 %s -### 2>&1 \
+// RUN: env "PATH=%t;%PATH%;" %clang -target x86_64-scei-ps4 %s -### 2>&1 \
// RUN: | FileCheck --check-prefix=CHECK-PS4-LINKER %s
-// RUN: env "PATH=%T;%PATH%;" %clang -target x86_64-scei-ps4 %s -fuse-ld=ps4 -### 2>&1 \
+// RUN: env "PATH=%t;%PATH%;" %clang -target x86_64-scei-ps4 %s -fuse-ld=ps4 -### 2>&1 \
// RUN: | FileCheck --check-prefix=CHECK-PS4-LINKER %s
-// RUN: env "PATH=%T;%PATH%;" %clang -target x86_64-scei-ps4 %s -shared \
+// RUN: env "PATH=%t;%PATH%;" %clang -target x86_64-scei-ps4 %s -shared \
// RUN: -fuse-ld=ps4 -### 2>&1 | FileCheck --check-prefix=CHECK-PS4-LINKER %s
// CHECK-PS4-GOLD: \\orbis-ld.gold
diff --git a/test/Driver/rewrite-legacy-objc.m b/test/Driver/rewrite-legacy-objc.m
index 6a2b44b8fb9b..8ac357c84472 100644
--- a/test/Driver/rewrite-legacy-objc.m
+++ b/test/Driver/rewrite-legacy-objc.m
@@ -3,11 +3,11 @@
// TEST0: clang{{.*}}" "-cc1"
// TEST0: "-rewrite-objc"
// FIXME: CHECK-NOT is broken somehow, it doesn't work here. Check adjacency instead.
-// TEST0: "-fmessage-length" "0" "-stack-protector" "1" "-fblocks" "-fobjc-runtime=macosx-fragile" "-fencode-extended-block-signature" "-fno-objc-infer-related-result-type" "-fobjc-exceptions" "-fexceptions" "-fmax-type-align=16" "-fdiagnostics-show-option"
+// TEST0: "-fmessage-length" "0" "-stack-protector" "1" "-fblocks" "-fencode-extended-block-signature" "-fobjc-runtime=macosx-fragile" "-fno-objc-infer-related-result-type" "-fobjc-exceptions" "-fexceptions" "-fmax-type-align=16" "-fdiagnostics-show-option"
// TEST0: rewrite-legacy-objc.m"
// RUN: %clang -no-canonical-prefixes -target i386-apple-macosx10.9.0 -rewrite-legacy-objc %s -o - -### 2>&1 | \
// RUN: FileCheck -check-prefix=TEST1 %s
// RUN: %clang -no-canonical-prefixes -target i386-apple-macosx10.6.0 -rewrite-legacy-objc %s -o - -### 2>&1 | \
// RUN: FileCheck -check-prefix=TEST2 %s
-// TEST1: "-fmessage-length" "0" "-stack-protector" "1" "-fblocks" "-fobjc-runtime=macosx-fragile" "-fobjc-subscripting-legacy-runtime" "-fencode-extended-block-signature" "-fno-objc-infer-related-result-type" "-fobjc-exceptions" "-fmax-type-align=16" "-fdiagnostics-show-option"
-// TEST2: "-fmessage-length" "0" "-stack-protector" "1" "-fblocks" "-fobjc-runtime=macosx-fragile" "-fencode-extended-block-signature" "-fno-objc-infer-related-result-type" "-fobjc-exceptions" "-fmax-type-align=16" "-fdiagnostics-show-option"
+// TEST1: "-fmessage-length" "0" "-stack-protector" "1" "-fblocks" "-fencode-extended-block-signature" "-fobjc-runtime=macosx-fragile" "-fobjc-subscripting-legacy-runtime" "-fno-objc-infer-related-result-type" "-fobjc-exceptions" "-fmax-type-align=16" "-fdiagnostics-show-option"
+// TEST2: "-fmessage-length" "0" "-stack-protector" "1" "-fblocks" "-fencode-extended-block-signature" "-fobjc-runtime=macosx-fragile" "-fno-objc-infer-related-result-type" "-fobjc-exceptions" "-fmax-type-align=16" "-fdiagnostics-show-option"
diff --git a/test/Driver/rewrite-objc.m b/test/Driver/rewrite-objc.m
index ca1e84042c55..b8a1ffe8b806 100644
--- a/test/Driver/rewrite-objc.m
+++ b/test/Driver/rewrite-objc.m
@@ -3,4 +3,4 @@
// TEST0: clang{{.*}}" "-cc1"
// TEST0: "-rewrite-objc"
// FIXME: CHECK-NOT is broken somehow, it doesn't work here. Check adjacency instead.
-// TEST0: "-fmessage-length" "0" "-stack-protector" "1" "-fblocks" "-fobjc-runtime=macosx" "-fencode-extended-block-signature" "-fno-objc-infer-related-result-type" "-fobjc-exceptions" "-fexceptions" "-fmax-type-align=16" "-fdiagnostics-show-option"
+// TEST0: "-fmessage-length" "0" "-stack-protector" "1" "-fblocks" "-fencode-extended-block-signature" "-fobjc-runtime=macosx" "-fno-objc-infer-related-result-type" "-fobjc-exceptions" "-fexceptions" "-fmax-type-align=16" "-fdiagnostics-show-option"
diff --git a/test/Driver/sanitize_unwind_tables.c b/test/Driver/sanitize_unwind_tables.c
index b78843ef8f2b..e74c15833f90 100644
--- a/test/Driver/sanitize_unwind_tables.c
+++ b/test/Driver/sanitize_unwind_tables.c
@@ -9,5 +9,7 @@
// RUN: %clang -target x86_64-linux-gnu -fsanitize=dataflow %s -### 2>&1 | FileCheck %s
// RUN: %clang -target x86_64-linux-gnu -fsanitize=efficiency-cache-frag %s -### 2>&1 | FileCheck %s
// RUN: %clang -target x86_64-linux-gnu -fsanitize=efficiency-working-set %s -### 2>&1 | FileCheck %s
+// RUN: %clang -target aarch64-linux-gnu -fsanitize=hwaddress %s -### 2>&1 | FileCheck %s
+// RUN: %clang -target aarch64-linux-android -fsanitize=hwaddress %s -### 2>&1 | FileCheck %s
// CHECK: -munwind-tables
diff --git a/test/Driver/sanitizer-ld.c b/test/Driver/sanitizer-ld.c
index efdd1245778d..0da4255f6995 100644
--- a/test/Driver/sanitizer-ld.c
+++ b/test/Driver/sanitizer-ld.c
@@ -17,10 +17,23 @@
// CHECK-ASAN-LINUX: "-ldl"
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN: -target i386-unknown-linux -fuse-ld=ld -fsanitize=address -shared-libsan \
+// RUN: -resource-dir=%S/Inputs/resource_dir \
+// RUN: --sysroot=%S/Inputs/basic_linux_tree \
+// RUN: | FileCheck --check-prefix=CHECK-SHARED-ASAN-LINUX %s
+
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
// RUN: -target i386-unknown-linux -fuse-ld=ld -fsanitize=address -shared-libasan \
// RUN: -resource-dir=%S/Inputs/resource_dir \
// RUN: --sysroot=%S/Inputs/basic_linux_tree \
// RUN: | FileCheck --check-prefix=CHECK-SHARED-ASAN-LINUX %s
+
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN: -target i386-unknown-linux -fuse-ld=ld -fsanitize=address \
+// RUN: -shared-libsan -static-libsan -shared-libasan \
+// RUN: -resource-dir=%S/Inputs/resource_dir \
+// RUN: --sysroot=%S/Inputs/basic_linux_tree \
+// RUN: | FileCheck --check-prefix=CHECK-SHARED-ASAN-LINUX %s
//
// CHECK-SHARED-ASAN-LINUX: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
// CHECK-SHARED-ASAN-LINUX-NOT: "-lc"
@@ -34,7 +47,7 @@
// CHECK-SHARED-ASAN-LINUX-NOT: "--dynamic-list"
// RUN: %clang -no-canonical-prefixes %s -### -o %t.so -shared 2>&1 \
-// RUN: -target i386-unknown-linux -fuse-ld=ld -fsanitize=address -shared-libasan \
+// RUN: -target i386-unknown-linux -fuse-ld=ld -fsanitize=address -shared-libsan \
// RUN: -resource-dir=%S/Inputs/resource_dir \
// RUN: --sysroot=%S/Inputs/basic_linux_tree \
// RUN: | FileCheck --check-prefix=CHECK-DSO-SHARED-ASAN-LINUX %s
@@ -127,18 +140,63 @@
//
// CHECK-ASAN-ANDROID: "{{(.*[^.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
// CHECK-ASAN-ANDROID-NOT: "-lc"
-// CHECK-ASAN-ANDROID: "-pie"
+// CHECK-ASAN-ANDROID-NOT: "-pie"
// CHECK-ASAN-ANDROID-NOT: "-lpthread"
// CHECK-ASAN-ANDROID: libclang_rt.asan-arm-android.so"
// CHECK-ASAN-ANDROID-NOT: "-lpthread"
+
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN: -target arm-linux-androideabi -fuse-ld=ld -fsanitize=address \
+// RUN: --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN: -static-libsan \
+// RUN: | FileCheck --check-prefix=CHECK-ASAN-ANDROID-STATICLIBASAN %s
+//
+// CHECK-ASAN-ANDROID-STATICLIBASAN: "{{(.*[^.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
+// CHECK-ASAN-ANDROID-STATICLIBASAN: libclang_rt.asan-arm-android.a"
+// CHECK-ASAN-ANDROID-STATICLIBASAN: "-lpthread"
+
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN: -target arm-linux-androideabi -fuse-ld=ld -fsanitize=undefined \
+// RUN: --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN: | FileCheck --check-prefix=CHECK-UBSAN-ANDROID %s
+//
+// CHECK-UBSAN-ANDROID: "{{(.*[^.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
+// CHECK-UBSAN-ANDROID-NOT: "-lc"
+// CHECK-UBSAN-ANDROID-NOT: "-pie"
+// CHECK-UBSAN-ANDROID-NOT: "-lpthread"
+// CHECK-UBSAN-ANDROID: libclang_rt.ubsan_standalone-arm-android.so"
+// CHECK-UBSAN-ANDROID-NOT: "-lpthread"
+
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN: -target arm-linux-androideabi -fuse-ld=ld -fsanitize=undefined \
+// RUN: --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN: -static-libsan \
+// RUN: | FileCheck --check-prefix=CHECK-UBSAN-ANDROID-STATICLIBASAN %s
+//
+// CHECK-UBSAN-ANDROID-STATICLIBASAN: "{{(.*[^.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
+// CHECK-UBSAN-ANDROID-STATICLIBASAN: libclang_rt.ubsan_standalone-arm-android.a"
+// CHECK-UBSAN-ANDROID-STATICLIBASAN: "-lpthread"
+
+//
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN: -target i686-linux-android -fuse-ld=ld -fsanitize=address \
+// RUN: --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN: | FileCheck --check-prefix=CHECK-ASAN-ANDROID-X86 %s
+//
+// CHECK-ASAN-ANDROID-X86: "{{(.*[^.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
+// CHECK-ASAN-ANDROID-X86-NOT: "-lc"
+// CHECK-ASAN-ANDROID-X86-NOT: "-pie"
+// CHECK-ASAN-ANDROID-X86-NOT: "-lpthread"
+// CHECK-ASAN-ANDROID-X86: libclang_rt.asan-i686-android.so"
+// CHECK-ASAN-ANDROID-X86-NOT: "-lpthread"
//
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
// RUN: -target arm-linux-androideabi -fsanitize=address \
// RUN: --sysroot=%S/Inputs/basic_android_tree/sysroot \
-// RUN: -shared-libasan \
+// RUN: -shared-libsan \
// RUN: | FileCheck --check-prefix=CHECK-ASAN-ANDROID-SHARED-LIBASAN %s
//
-// CHECK-ASAN-ANDROID-SHARED-LIBASAN-NOT: argument unused during compilation: '-shared-libasan'
+// CHECK-ASAN-ANDROID-SHARED-LIBASAN-NOT: argument unused during compilation: '-shared-libsan'
//
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
// RUN: -target arm-linux-androideabi -fuse-ld=ld -fsanitize=address \
@@ -202,6 +260,13 @@
// RUN: -target i386-unknown-linux -fuse-ld=ld \
// RUN: --sysroot=%S/Inputs/basic_linux_tree \
// RUN: | FileCheck --check-prefix=CHECK-UBSAN-LINUX %s
+
+// RUN: %clang -fsanitize=undefined %s -### -o %t.o 2>&1 \
+// RUN: -target i386-unknown-linux -fuse-ld=ld \
+// RUN: --sysroot=%S/Inputs/basic_linux_tree \
+// RUN: -static-libsan \
+// RUN: | FileCheck --check-prefix=CHECK-UBSAN-LINUX %s
+
// CHECK-UBSAN-LINUX: "{{.*}}ld{{(.exe)?}}"
// CHECK-UBSAN-LINUX-NOT: libclang_rt.asan
// CHECK-UBSAN-LINUX-NOT: libclang_rt.ubsan_standalone_cxx
@@ -211,6 +276,27 @@
// CHECK-UBSAN-LINUX-NOT: "-lstdc++"
// CHECK-UBSAN-LINUX: "-lpthread"
+// RUN: %clang -fsanitize=undefined %s -### -o %t.o 2>&1 \
+// RUN: -target i386-unknown-linux -fuse-ld=ld \
+// RUN: --sysroot=%S/Inputs/basic_linux_tree \
+// RUN: -shared-libsan \
+// RUN: | FileCheck --check-prefix=CHECK-UBSAN-LINUX-SHAREDLIBASAN %s
+
+// RUN: %clang -fsanitize=undefined %s -### -o %t.o 2>&1 \
+// RUN: -target i386-unknown-linux -fuse-ld=ld \
+// RUN: --sysroot=%S/Inputs/basic_linux_tree \
+// RUN: -static-libsan -shared-libsan \
+// RUN: | FileCheck --check-prefix=CHECK-UBSAN-LINUX-SHAREDLIBASAN %s
+
+// RUN: %clang -fsanitize=undefined %s -### -o %t.o 2>&1 \
+// RUN: -target i386-unknown-linux -fuse-ld=ld \
+// RUN: --sysroot=%S/Inputs/basic_linux_tree \
+// RUN: -shared -shared-libsan \
+// RUN: | FileCheck --check-prefix=CHECK-UBSAN-LINUX-SHAREDLIBASAN %s
+
+// CHECK-UBSAN-LINUX-SHAREDLIBASAN: "{{.*}}ld{{(.exe)?}}"
+// CHECK-UBSAN-LINUX-SHAREDLIBASAN: "{{.*}}libclang_rt.ubsan_standalone-i386.so{{.*}}"
+
// RUN: %clang -fsanitize=undefined -fsanitize-link-c++-runtime %s -### -o %t.o 2>&1 \
// RUN: -target i386-unknown-linux \
// RUN: --sysroot=%S/Inputs/basic_linux_tree \
@@ -234,6 +320,28 @@
// CHECK-UBSAN-LINUX-CXX-NOT: libclang_rt.asan
// CHECK-UBSAN-LINUX-CXX: "-lpthread"
+// RUN: %clang -fsanitize=undefined -fsanitize-minimal-runtime %s -### -o %t.o 2>&1 \
+// RUN: -target i386-unknown-linux -fuse-ld=ld \
+// RUN: --sysroot=%S/Inputs/basic_linux_tree \
+// RUN: | FileCheck --check-prefix=CHECK-UBSAN-MINIMAL-LINUX %s
+// CHECK-UBSAN-MINIMAL-LINUX: "{{.*}}ld{{(.exe)?}}"
+// CHECK-UBSAN-MINIMAL-LINUX: "-whole-archive" "{{.*}}libclang_rt.ubsan_minimal-i386.a" "-no-whole-archive"
+// CHECK-UBSAN-MINIMAL-LINUX: "-lpthread"
+
+// RUN: %clang -fsanitize=undefined -fsanitize-minimal-runtime %s -### -o %t.o 2>&1 \
+// RUN: -target x86_64-apple-darwin -fuse-ld=ld \
+// RUN: --sysroot=%S/Inputs/basic_linux_tree \
+// RUN: | FileCheck --check-prefix=CHECK-UBSAN-MINIMAL-DARWIN %s
+// CHECK-UBSAN-MINIMAL-DARWIN: "{{.*}}ld{{(.exe)?}}"
+// CHECK-UBSAN-MINIMAL-DARWIN: "{{.*}}libclang_rt.ubsan_minimal_osx_dynamic.dylib"
+
+// RUN: %clang -fsanitize=undefined %s -### -o %t.o 2>&1 \
+// RUN: -target x86_64-apple-darwin -fuse-ld=ld -static-libsan \
+// RUN: --sysroot=%S/Inputs/basic_linux_tree \
+// RUN: | FileCheck --check-prefix=CHECK-UBSAN-STATIC-DARWIN %s
+// CHECK-UBSAN-STATIC-DARWIN: "{{.*}}ld{{(.exe)?}}"
+// CHECK-UBSAN-STATIC-DARWIN: "{{.*}}libclang_rt.ubsan_osx.a"
+
// RUN: %clang -fsanitize=address,undefined %s -### -o %t.o 2>&1 \
// RUN: -target i386-unknown-linux -fuse-ld=ld \
// RUN: --sysroot=%S/Inputs/basic_linux_tree \
@@ -400,6 +508,24 @@
// CHECK-CFI-CROSS-DSO-DIAG-LINUX: "-whole-archive" "{{[^"]*}}libclang_rt.cfi_diag-x86_64.a" "-no-whole-archive"
// CHECK-CFI-CROSS-DSO-DIAG-LINUX: -export-dynamic
+// Cross-DSO CFI on Android does not link runtime libraries.
+// RUN: %clang -fsanitize=cfi -fsanitize-cfi-cross-dso %s -### -o %t.o 2>&1 \
+// RUN: -target aarch64-linux-android -fuse-ld=ld \
+// RUN: --sysroot=%S/Inputs/basic_android_tree \
+// RUN: | FileCheck --check-prefix=CHECK-CFI-CROSS-DSO-ANDROID %s
+// CHECK-CFI-CROSS-DSO-ANDROID: "{{.*}}ld{{(.exe)?}}"
+// CHECK-CFI-CROSS-DSO-ANDROID-NOT: libclang_rt.
+
+// Cross-DSO CFI with diagnostics on Android links just the UBSAN runtime.
+// RUN: %clang -fsanitize=cfi -fsanitize-cfi-cross-dso %s -### -o %t.o 2>&1 \
+// RUN: -fno-sanitize-trap=cfi -fsanitize-recover=cfi \
+// RUN: -target aarch64-linux-android -fuse-ld=ld \
+// RUN: --sysroot=%S/Inputs/basic_android_tree \
+// RUN: | FileCheck --check-prefix=CHECK-CFI-CROSS-DSO-DIAG-ANDROID %s
+// CHECK-CFI-CROSS-DSO-DIAG-ANDROID: "{{.*}}ld{{(.exe)?}}"
+// CHECK-CFI-CROSS-DSO-DIAG-ANDROID: "{{[^"]*}}libclang_rt.ubsan_standalone-aarch64-android.so"
+// CHECK-CFI-CROSS-DSO-DIAG-ANDROID: "-export-dynamic-symbol=__cfi_check"
+
// RUN: %clangxx -fsanitize=address %s -### -o %t.o 2>&1 \
// RUN: -mmacosx-version-min=10.6 \
// RUN: -target x86_64-apple-darwin13.4.0 -fuse-ld=ld -stdlib=platform \
@@ -488,26 +614,6 @@
// CHECK-SAFESTACK-ANDROID-AARCH64: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
// CHECK-SAFESTACK-ANDROID-AARCH64-NOT: libclang_rt.safestack
-// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN: -target arm-linux-androideabi -fuse-ld=ld -fsanitize=cfi \
-// RUN: --sysroot=%S/Inputs/basic_android_tree \
-// RUN: | FileCheck --check-prefix=CHECK-CFI-ANDROID %s
-//
-// CHECK-CFI-ANDROID: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
-// CHECK-CFI-ANDROID-NOT: libclang_rt.cfi
-// CHECK-CFI-ANDROID-NOT: __cfi_check
-
-// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN: -target arm-linux-androideabi -fuse-ld=ld -fsanitize=cfi \
-// RUN: -fsanitize-cfi-cross-dso \
-// RUN: --sysroot=%S/Inputs/basic_android_tree \
-// RUN: | FileCheck --check-prefix=CHECK-CROSSDSO-CFI-ANDROID %s
-//
-// CHECK-CROSSDSO-CFI-ANDROID: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
-// CHECK-CROSSDSO-CFI-ANDROID-NOT: libclang_rt.cfi
-// CHECK-CROSSDSO-CFI-ANDROID: -export-dynamic-symbol=__cfi_check
-// CHECK-CROSSDSO-CFI-ANDROID-NOT: libclang_rt.cfi
-
// RUN: %clang -fsanitize=undefined %s -### -o %t.o 2>&1 \
// RUN: -target x86_64-scei-ps4 -fuse-ld=ld \
// RUN: -shared \
@@ -538,3 +644,106 @@
//
// CHECK-ESAN-LINUX: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
// CHECK-ESAN-LINUX: libclang_rt.esan-x86_64.a
+
+// RUN: %clang -fsanitize=scudo %s -### -o %t.o 2>&1 \
+// RUN: -target i386-unknown-linux -fuse-ld=ld \
+// RUN: --sysroot=%S/Inputs/basic_linux_tree \
+// RUN: | FileCheck --check-prefix=CHECK-SCUDO-LINUX %s
+// CHECK-SCUDO-LINUX: "{{.*}}ld{{(.exe)?}}"
+// CHECK-SCUDO-LINUX: "-pie"
+// CHECK-SCUDO-LINUX: "-whole-archive" "{{.*}}libclang_rt.scudo-i386.a" "-no-whole-archive"
+// CHECK-SCUDO-LINUX-NOT: "-lstdc++"
+// CHECK-SCUDO-LINUX: "-lpthread"
+// CHECK-SCUDO-LINUX: "-ldl"
+
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.so -shared 2>&1 \
+// RUN: -target i386-unknown-linux -fuse-ld=ld -fsanitize=scudo -shared-libsan \
+// RUN: -resource-dir=%S/Inputs/resource_dir \
+// RUN: --sysroot=%S/Inputs/basic_linux_tree \
+// RUN: | FileCheck --check-prefix=CHECK-SCUDO-SHARED-LINUX %s
+//
+// CHECK-SCUDO-SHARED-LINUX: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
+// CHECK-SCUDO-SHARED-LINUX-NOT: "-lc"
+// CHECK-SCUDO-SHARED-LINUX-NOT: libclang_rt.scudo-i386.a"
+// CHECK-SCUDO-SHARED-LINUX: libclang_rt.scudo-i386.so"
+// CHECK-SCUDO-SHARED-LINUX-NOT: "-lpthread"
+// CHECK-SCUDO-SHARED-LINUX-NOT: "-lrt"
+// CHECK-SCUDO-SHARED-LINUX-NOT: "-ldl"
+// CHECK-SCUDO-SHARED-LINUX-NOT: "-export-dynamic"
+// CHECK-SCUDO-SHARED-LINUX-NOT: "--dynamic-list"
+
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN: -target arm-linux-androideabi -fuse-ld=ld -fsanitize=scudo \
+// RUN: --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN: | FileCheck --check-prefix=CHECK-SCUDO-ANDROID %s
+//
+// CHECK-SCUDO-ANDROID: "{{(.*[^.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
+// CHECK-SCUDO-ANDROID-NOT: "-lc"
+// CHECK-SCUDO-ANDROID: "-pie"
+// CHECK-SCUDO-ANDROID-NOT: "-lpthread"
+// CHECK-SCUDO-ANDROID: libclang_rt.scudo-arm-android.so"
+// CHECK-SCUDO-ANDROID-NOT: "-lpthread"
+
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN: -target arm-linux-androideabi -fuse-ld=ld -fsanitize=scudo \
+// RUN: --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN: -static-libsan \
+// RUN: | FileCheck --check-prefix=CHECK-SCUDO-ANDROID-STATIC %s
+// CHECK-SCUDO-ANDROID-STATIC: "{{(.*[^.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
+// CHECK-SCUDO-ANDROID-STATIC: "-pie"
+// CHECK-SCUDO-ANDROID-STATIC: "-whole-archive" "{{.*}}libclang_rt.scudo-arm-android.a" "-no-whole-archive"
+// CHECK-SCUDO-ANDROID-STATIC-NOT: "-lstdc++"
+// CHECK-SCUDO-ANDROID-STATIC: "-lpthread"
+
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN: -target aarch64-unknown-linux -fuse-ld=ld -fsanitize=hwaddress \
+// RUN: -resource-dir=%S/Inputs/resource_dir \
+// RUN: --sysroot=%S/Inputs/basic_linux_tree \
+// RUN: | FileCheck --check-prefix=CHECK-HWASAN-LINUX %s
+//
+// CHECK-HWASAN-LINUX: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
+// CHECK-HWASAN-LINUX-NOT: "-lc"
+// CHECK-HWASAN-LINUX: libclang_rt.hwasan-aarch64.a"
+// CHECK-HWASAN-LINUX-NOT: "-export-dynamic"
+// CHECK-HWASAN-LINUX: "--dynamic-list={{.*}}libclang_rt.hwasan-aarch64.a.syms"
+// CHECK-HWASAN-LINUX-NOT: "-export-dynamic"
+// CHECK-HWASAN-LINUX: "-lpthread"
+// CHECK-HWASAN-LINUX: "-lrt"
+// CHECK-HWASAN-LINUX: "-ldl"
+
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN: -target aarch64-unknown-linux -fuse-ld=ld -fsanitize=hwaddress -shared-libsan \
+// RUN: -resource-dir=%S/Inputs/resource_dir \
+// RUN: --sysroot=%S/Inputs/basic_linux_tree \
+// RUN: | FileCheck --check-prefix=CHECK-SHARED-HWASAN-LINUX %s
+
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN: -target aarch64-unknown-linux -fuse-ld=ld -fsanitize=hwaddress \
+// RUN: -shared-libsan \
+// RUN: -resource-dir=%S/Inputs/resource_dir \
+// RUN: --sysroot=%S/Inputs/basic_linux_tree \
+// RUN: | FileCheck --check-prefix=CHECK-SHARED-HWASAN-LINUX %s
+//
+// CHECK-SHARED-HWASAN-LINUX: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
+// CHECK-SHARED-HWASAN-LINUX-NOT: "-lc"
+// CHECK-SHARED-HWASAN-LINUX: libclang_rt.hwasan-aarch64.so"
+// CHECK-SHARED-HWASAN-LINUX-NOT: "-lpthread"
+// CHECK-SHARED-HWASAN-LINUX-NOT: "-lrt"
+// CHECK-SHARED-HWASAN-LINUX-NOT: "-ldl"
+// CHECK-SHARED-HWASAN-LINUX-NOT: "-export-dynamic"
+// CHECK-SHARED-HWASAN-LINUX-NOT: "--dynamic-list"
+
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.so -shared 2>&1 \
+// RUN: -target aarch64-unknown-linux -fuse-ld=ld -fsanitize=hwaddress -shared-libsan \
+// RUN: -resource-dir=%S/Inputs/resource_dir \
+// RUN: --sysroot=%S/Inputs/basic_linux_tree \
+// RUN: | FileCheck --check-prefix=CHECK-DSO-SHARED-HWASAN-LINUX %s
+//
+// CHECK-DSO-SHARED-HWASAN-LINUX: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
+// CHECK-DSO-SHARED-HWASAN-LINUX-NOT: "-lc"
+// CHECK-DSO-SHARED-HWASAN-LINUX: libclang_rt.hwasan-aarch64.so"
+// CHECK-DSO-SHARED-HWASAN-LINUX-NOT: "-lpthread"
+// CHECK-DSO-SHARED-HWASAN-LINUX-NOT: "-lrt"
+// CHECK-DSO-SHARED-HWASAN-LINUX-NOT: "-ldl"
+// CHECK-DSO-SHARED-HWASAN-LINUX-NOT: "-export-dynamic"
+// CHECK-DSO-SHARED-HWASAN-LINUX-NOT: "--dynamic-list"
diff --git a/test/Driver/stack-protector.c b/test/Driver/stack-protector.c
index 6769b65f6382..a3e40b50eed8 100644
--- a/test/Driver/stack-protector.c
+++ b/test/Driver/stack-protector.c
@@ -36,27 +36,20 @@
// Test default stack protector values for Darwin platforms
// RUN: %clang -target armv7k-apple-watchos2.0 -### %s 2>&1 | FileCheck %s -check-prefix=SSP_WATCHOS
+// RUN: %clang -ffreestanding -target armv7k-apple-watchos2.0 -### %s 2>&1 | FileCheck %s -check-prefix=SSP_WATCHOS
// SSP_WATCHOS: "-stack-protector" "1"
// RUN: %clang -target arm64-apple-ios8.0.0 -### %s 2>&1 | FileCheck %s -check-prefix=SSP_IOS
+// RUN: %clang -ffreestanding -target arm64-apple-ios8.0.0 -### %s 2>&1 | FileCheck %s -check-prefix=SSP_IOS
// SSP_IOS: "-stack-protector" "1"
// RUN: %clang -target x86_64-apple-darwin10 -mmacosx-version-min=10.6 -### %s 2>&1 | FileCheck %s -check-prefix=SSP_MACOSX
+// RUN: %clang -ffreestanding -target x86_64-apple-darwin10 -mmacosx-version-min=10.6 -### %s 2>&1 | FileCheck %s -check-prefix=SSP_MACOSX
// SSP_MACOSX: "-stack-protector" "1"
// RUN: %clang -target x86_64-apple-darwin10 -mmacosx-version-min=10.5 -### %s 2>&1 | FileCheck %s -check-prefix=SSP_MACOSX_10_5
+// RUN: %clang -ffreestanding -target x86_64-apple-darwin10 -mmacosx-version-min=10.5 -### %s 2>&1 | FileCheck %s -check-prefix=SSP_MACOSX_10_5
// SSP_MACOSX_10_5: "-stack-protector" "1"
// RUN: %clang -target x86_64-apple-darwin10 -mmacosx-version-min=10.5 -mkernel -### %s 2>&1 | FileCheck %s -check-prefix=SSP_MACOSX_KERNEL
// SSP_MACOSX_KERNEL-NOT: "-stack-protector"
// RUN: %clang -target x86_64-apple-darwin10 -mmacosx-version-min=10.6 -### %s 2>&1 | FileCheck %s -check-prefix=SSP_MACOSX_10_6_KERNEL
+// RUN: %clang -ffreestanding -target x86_64-apple-darwin10 -mmacosx-version-min=10.6 -### %s 2>&1 | FileCheck %s -check-prefix=SSP_MACOSX_10_6_KERNEL
// SSP_MACOSX_10_6_KERNEL: "-stack-protector" "1"
-// Test default stack protector values for Darwin platforms with -ffreestanding
-
-// RUN: %clang -ffreestanding -target armv7k-apple-watchos2.0 -### %s 2>&1 | FileCheck %s -check-prefix=SSP_FREE_WATCHOS
-// SSP_FREE_WATCHOS-NOT: "-stack-protector"
-// RUN: %clang -ffreestanding -target arm64-apple-ios8.0.0 -### %s 2>&1 | FileCheck %s -check-prefix=SSP_FREE_IOS
-// SSP_FREE_IOS-NOT: "-stack-protector"
-// RUN: %clang -ffreestanding -target x86_64-apple-darwin10 -mmacosx-version-min=10.6 -### %s 2>&1 | FileCheck %s -check-prefix=SSP_FREE_MACOSX
-// SSP_FREE_MACOSX-NOT: "-stack-protector"
-// RUN: %clang -ffreestanding -target x86_64-apple-darwin10 -mmacosx-version-min=10.5 -### %s 2>&1 | FileCheck %s -check-prefix=SSP_FREE_MACOSX_10_5
-// SSP_FREE_MACOSX_10_5-NOT: "-stack-protector"
-// RUN: %clang -ffreestanding -target x86_64-apple-darwin10 -mmacosx-version-min=10.6 -### %s 2>&1 | FileCheck %s -check-prefix=SSP_FREE_MACOSX_10_6_KERNEL
-// SSP_FREE_MACOSX_10_6_KERNEL-NOT: "-stack-protector"
diff --git a/test/Driver/target-override.c b/test/Driver/target-override.c
new file mode 100644
index 000000000000..49ca90fd6f47
--- /dev/null
+++ b/test/Driver/target-override.c
@@ -0,0 +1,16 @@
+// REQUIRES: shell
+// REQUIRES: x86-registered-target
+
+// RUN: mkdir -p %T/testbin
+// RUN: [ ! -s %T/testbin/i386-clang ] || rm %T/testbin/i386-clang
+// RUN: ln -s %clang %T/testbin/i386-clang
+
+// Check if invocation of "foo-clang" adds option "-target foo".
+//
+// RUN: %T/testbin/i386-clang -c -no-canonical-prefixes %s -### 2>&1 | FileCheck -check-prefix CHECK-TG1 %s
+// CHECK-TG1: Target: i386
+
+// Check if invocation of "foo-clang -target bar" overrides option "-target foo".
+//
+// RUN: %T/testbin/i386-clang -c -no-canonical-prefixes -target x86_64 %s -### 2>&1 | FileCheck -check-prefix CHECK-TG2 %s
+// CHECK-TG2: Target: x86_64
diff --git a/test/Driver/thinlto.c b/test/Driver/thinlto.c
index 0369b78be0f5..bef7b2b0a6f1 100644
--- a/test/Driver/thinlto.c
+++ b/test/Driver/thinlto.c
@@ -19,19 +19,19 @@
// RUN: %clang -target x86_64-unknown-linux -### %s -flto=full -fno-lto -flto=thin 2> %t
// RUN: FileCheck -check-prefix=CHECK-LINK-THIN-ACTION < %t %s
//
-// CHECK-LINK-THIN-ACTION: "-plugin" "{{.*}}/LLVMgold.so"
+// CHECK-LINK-THIN-ACTION: "-plugin" "{{.*}}{{[/\\]}}LLVMgold.{{dll|dylib|so}}"
// CHECK-LINK-THIN-ACTION: "-plugin-opt=thinlto"
// Check that subsequent -flto=full takes precedence
// RUN: %clang -target x86_64-unknown-linux -### %s -flto=thin -flto=full 2> %t
// RUN: FileCheck -check-prefix=CHECK-LINK-FULL-ACTION < %t %s
//
-// CHECK-LINK-FULL-ACTION: "-plugin" "{{.*}}/LLVMgold.so"
+// CHECK-LINK-FULL-ACTION: "-plugin" "{{.*}}{{[/\\]}}LLVMgold.{{dll|dylib|so}}"
// CHECK-LINK-FULL-ACTION-NOT: "-plugin-opt=thinlto"
// Check that subsequent -fno-lto takes precedence
// RUN: %clang -target x86_64-unknown-linux -### %s -flto=thin -fno-lto 2> %t
// RUN: FileCheck -check-prefix=CHECK-LINK-NOLTO-ACTION < %t %s
//
-// CHECK-LINK-NOLTO-ACTION-NOT: "-plugin" "{{.*}}/LLVMgold.so"
+// CHECK-LINK-NOLTO-ACTION-NOT: "-plugin" "{{.*}}{{[/\\]}}LLVMgold.{{dll|dylib|so}}"
// CHECK-LINK-NOLTO-ACTION-NOT: "-plugin-opt=thinlto"
diff --git a/test/Driver/unix-conformance.c b/test/Driver/unix-conformance.c
new file mode 100644
index 000000000000..ddf77c7a28e6
--- /dev/null
+++ b/test/Driver/unix-conformance.c
@@ -0,0 +1,24 @@
+// Check UNIX conformance for cc/c89/c99
+// When c99 encounters a compilation error that causes an object file not to be
+// created, it shall write a diagnostic to standard error and continue to
+// compile other source code operands, but it shall not perform the link phase
+// and it shall return a non-zero exit status.
+
+// When given multiple .c files to compile, clang compiles them in order until
+// it hits an error, at which point it stops.
+//
+// RUN: rm -rf %t-dir
+// RUN: mkdir -p %t-dir
+// RUN: cd %t-dir
+//
+// RUN: touch %t-dir/1.c
+// RUN: echo "invalid C code" > %t-dir/2.c
+// RUN: touch %t-dir/3.c
+// RUN: echo "invalid C code" > %t-dir/4.c
+// RUN: touch %t-dir/5.c
+// RUN: not %clang -S %t-dir/1.c %t-dir/2.c %t-dir/3.c %t-dir/4.c %t-dir/5.c
+// RUN: test -f %t-dir/1.s
+// RUN: test ! -f %t-dir/2.s
+// RUN: test -f %t-dir/3.s
+// RUN: test ! -f %t-dir/4.s
+// RUN: test -f %t-dir/5.s
diff --git a/test/Driver/unknown-std.c b/test/Driver/unknown-std.c
index 41736ec4887e..9ef70a4227a6 100644
--- a/test/Driver/unknown-std.c
+++ b/test/Driver/unknown-std.c
@@ -14,6 +14,8 @@
// CHECK-NEXT: note: use 'gnu99' for 'ISO C 1999 with GNU extensions' standard
// CHECK-NEXT: note: use 'c11' or 'iso9899:2011' for 'ISO C 2011' standard
// CHECK-NEXT: note: use 'gnu11' for 'ISO C 2011 with GNU extensions' standard
+// CHECK-NEXT: note: use 'c17' or 'iso9899:2017' for 'ISO C 2017' standard
+// CHECK-NEXT: note: use 'gnu17' for 'ISO C 2017 with GNU extensions' standard
// Make sure that no other output is present.
// CHECK-NOT: {{^.+$}}
diff --git a/test/Driver/unknown-std.cpp b/test/Driver/unknown-std.cpp
index a7aae5112221..2122a7468d03 100644
--- a/test/Driver/unknown-std.cpp
+++ b/test/Driver/unknown-std.cpp
@@ -4,7 +4,7 @@
// RUN: not %clang %s -std=foobar -c 2>&1 | FileCheck --match-full-lines %s
// RUN: not %clang -x objective-c++ %s -std=foobar -c 2>&1 | FileCheck --match-full-lines %s
-// RUN: not %clang -x cuda -nocudainc -nocudalib %s -std=foobar -c 2>&1 | FileCheck --match-full-lines --check-prefix=CHECK --check-prefix=CUDA %s
+// RUN: not %clang -x cuda -nocudainc -nocudalib --cuda-path=%S/Inputs/CUDA/usr/local/cuda %s -std=foobar -c 2>&1 | FileCheck --match-full-lines --check-prefix=CHECK --check-prefix=CUDA %s
// CHECK: error: invalid value 'foobar' in '-std=foobar'
// CHECK-NEXT: note: use 'c++98' or 'c++03' for 'ISO C++ 1998 with amendments' standard
diff --git a/test/Driver/warning-options.cpp b/test/Driver/warning-options.cpp
index 7b9d4ab53a32..d836ad143a1c 100644
--- a/test/Driver/warning-options.cpp
+++ b/test/Driver/warning-options.cpp
@@ -4,5 +4,5 @@
// LARGE_VALUE_COPY_JOINED: -Wlarge-by-value-copy=128
// Check that -isysroot warns on nonexistent paths.
-// RUN: %clang -### -c -target i386-apple-darwin10 -isysroot %T/warning-options %s 2>&1 | FileCheck --check-prefix=CHECK-ISYSROOT %s
+// RUN: %clang -### -c -target i386-apple-darwin10 -isysroot %t/warning-options %s 2>&1 | FileCheck --check-prefix=CHECK-ISYSROOT %s
// CHECK-ISYSROOT: warning: no such sysroot directory: '{{.*}}/warning-options'
diff --git a/test/Driver/wasm-toolchain.c b/test/Driver/wasm-toolchain.c
index 8debc0287007..e9862f0b7d8d 100644
--- a/test/Driver/wasm-toolchain.c
+++ b/test/Driver/wasm-toolchain.c
@@ -27,18 +27,10 @@
// RUN: %clang -### -no-canonical-prefixes -target wasm32-unknown-unknown --sysroot=/foo %s 2>&1 | FileCheck -check-prefix=LINK %s
// LINK: clang{{.*}}" "-cc1" {{.*}} "-o" "[[temp:[^"]*]]"
-// LINK: lld{{.*}}" "-flavor" "wasm" "-L/foo/lib" "crt1.o" "crti.o" "[[temp]]" "-allow-undefined-file" "wasm.syms" "-lc" "-lcompiler_rt" "crtn.o" "-o" "a.out"
+// LINK: lld{{.*}}" "-flavor" "wasm" "-L/foo/lib" "crt1.o" "[[temp]]" "-allow-undefined-file" "wasm.syms" "-lc" "{{.*[/\\]}}libclang_rt.builtins-wasm32.a" "-o" "a.out"
-// A basic C link command-line with optimization. WebAssembly is somewhat
-// special in enabling --gc-sections by default.
+// A basic C link command-line with optimization.
// RUN: %clang -### -O2 -no-canonical-prefixes -target wasm32-unknown-unknown --sysroot=/foo %s 2>&1 | FileCheck -check-prefix=LINK_OPT %s
// LINK_OPT: clang{{.*}}" "-cc1" {{.*}} "-o" "[[temp:[^"]*]]"
-// LINK_OPT: lld{{.*}}" "-flavor" "wasm" "--gc-sections" "-L/foo/lib" "crt1.o" "crti.o" "[[temp]]" "-allow-undefined-file" "wasm.syms" "-lc" "-lcompiler_rt" "crtn.o" "-o" "a.out"
-
-// Ditto, but ensure that a user --no-gc-sections comes after the
-// default --gc-sections.
-
-// RUN: %clang -### -O2 -no-canonical-prefixes -target wasm32-unknown-unknown --sysroot=/foo -Wl,--no-gc-sections %s 2>&1 | FileCheck -check-prefix=NO_GC_SECTIONS %s
-// NO_GC_SECTIONS: clang{{.*}}" "-cc1" {{.*}} "-o" "[[temp:[^"]*]]"
-// NO_GC_SECTIONS: lld{{.*}}" "-flavor" "wasm" "--gc-sections" "-L/foo/lib" "crt1.o" "crti.o" "--no-gc-sections" "[[temp]]" "-allow-undefined-file" "wasm.syms" "-lc" "-lcompiler_rt" "crtn.o" "-o" "a.out"
+// LINK_OPT: lld{{.*}}" "-flavor" "wasm" "-L/foo/lib" "crt1.o" "[[temp]]" "-allow-undefined-file" "wasm.syms" "-lc" "{{.*[/\\]}}libclang_rt.builtins-wasm32.a" "-o" "a.out"
diff --git a/test/Driver/whole-program-vtables.c b/test/Driver/whole-program-vtables.c
index 4ca985e6d71d..de0c606594c1 100644
--- a/test/Driver/whole-program-vtables.c
+++ b/test/Driver/whole-program-vtables.c
@@ -1,2 +1,11 @@
// RUN: %clang -target x86_64-unknown-linux -fwhole-program-vtables -### %s 2>&1 | FileCheck --check-prefix=NO-LTO %s
+// RUN: %clang_cl --target=x86_64-pc-win32 -fwhole-program-vtables -### -- %s 2>&1 | FileCheck --check-prefix=NO-LTO %s
// NO-LTO: invalid argument '-fwhole-program-vtables' only allowed with '-flto'
+
+// RUN: %clang -target x86_64-unknown-linux -fwhole-program-vtables -flto -### %s 2>&1 | FileCheck --check-prefix=LTO %s
+// RUN: %clang_cl --target=x86_64-pc-win32 -fwhole-program-vtables -flto -### -- %s 2>&1 | FileCheck --check-prefix=LTO %s
+// LTO: "-fwhole-program-vtables"
+
+// RUN: %clang -target x86_64-unknown-linux -fwhole-program-vtables -fno-whole-program-vtables -flto -### %s 2>&1 | FileCheck --check-prefix=LTO-DISABLE %s
+// RUN: %clang_cl --target=x86_64-pc-win32 -fwhole-program-vtables -fno-whole-program-vtables -flto -### -- %s 2>&1 | FileCheck --check-prefix=LTO-DISABLE %s
+// LTO-DISABLE-NOT: "-fwhole-program-vtables"
diff --git a/test/Driver/windows-cross.c b/test/Driver/windows-cross.c
index 0e688f0a26e7..4b52e99cee34 100644
--- a/test/Driver/windows-cross.c
+++ b/test/Driver/windows-cross.c
@@ -1,8 +1,3 @@
-// RUN: %clang -### --driver-mode=g++ -target armv7-windows-itanium --sysroot %S/Inputs/Windows/ARM/8.1 -B %S/Inputs/Windows/ARM/8.1/usr/bin -fuse-ld=ld -stdlib=libstdc++ -rtlib=platform -o /dev/null %s 2>&1 \
-// RUN: | FileCheck %s --check-prefix CHECK-BASIC-LIBSTDCXX
-
-// CHECK-BASIC-LIBSTDCXX: armv7-windows-itanium-ld" "--sysroot={{.*}}/Inputs/Windows/ARM/8.1" "-m" "thumb2pe" "-Bdynamic" "--entry" "mainCRTStartup" "--allow-multiple-definition" "-o" "{{[^"]*}}" "-L{{.*}}/Inputs/Windows/ARM/8.1/usr/lib" "-L{{.*}}/Inputs/Windows/ARM/8.1/usr/lib/gcc" "{{.*}}.o" "-lstdc++" "-lmingw32" "-lmingwex" "-lgcc" "-lmoldname" "-lmingw32" "-lmsvcrt" "-lgcc_s" "-lgcc"
-
// RUN: %clang -### -target armv7-windows-itanium --sysroot %S/Inputs/Windows/ARM/8.1 -B %S/Inputs/Windows/ARM/8.1/usr/bin -fuse-ld=ld -stdlib=libstdc++ -rtlib=compiler-rt -o /dev/null %s 2>&1 \
// RUN: | FileCheck %s --check-prefix CHECK-BASIC-LIBCXX
@@ -38,11 +33,6 @@
// CHECK-STANDALONE: armv7-windows-itanium-ld" "--sysroot={{.*}}/Inputs/Windows/ARM/8.1" "-m" "thumb2pe" "-shared" "-Bdynamic" "--enable-auto-image-base" "--entry" "_DllMainCRTStartup" "--allow-multiple-definition" "-o" "shared.dll" "--out-implib" "shared.lib" "{{.*}}.o"
-// RUN: %clang -### -target armv7-windows-itanium --sysroot %S/Inputs/Windows/ARM/8.1 -B %/Inputs/Windows/ARM/8.1/usr/bin -stdlib=libstdc++ -shared -o shared.dll -x c++ %s 2>&1 \
-// RUN: | FileCheck %s --check-prefix CHECK-LIBSTDCXX
-
-// CHECK-LIBSTDCXX: "-internal-isystem" "{{.*}}/usr/include/c++" "-internal-isystem" "{{.*}}/usr/include/c++/armv7--windows-itanium" "-internal-isystem" "{{.*}}/usr/include/c++/backwards"
-
// RUN: %clang -### -target armv7-windows-itanium --sysroot %S/Inputs/Windows/ARM/8.1 -B %S/Inputs/Windows/ARM/8.1/usr/bin -fuse-ld=lld-link2 -shared -o shared.dll -x c++ %s 2>&1 \
// RUN: | FileCheck %s --check-prefix CHECK-FUSE-LD
@@ -64,7 +54,7 @@
// RUN: | FileCheck %s --check-prefix CHECK-SANITIZE-ADDRESS-EXE-X86
// CHECK-SANITIZE-ADDRESS-EXE-X86: "-fsanitize=address"
-// CHECK-SANITIZE-ADDRESS-EXE-X86: "{{.*}}clang_rt.asan_dynamic-i686.lib" "{{.*}}clang_rt.asan_dynamic_runtime_thunk-i686.lib" "--undefined" "___asan_seh_interceptor"
+// CHECK-SANITIZE-ADDRESS-EXE-X86: "{{.*}}clang_rt.asan_dynamic-i386.lib" "{{.*}}clang_rt.asan_dynamic_runtime_thunk-i386.lib" "--undefined" "___asan_seh_interceptor"
// RUN: %clang -### -target armv7-windows-itanium --sysroot %S/Inputs/Windows/ARM/8.1 -B %S/Inputs/Windows/ARM/8.1/usr/bin -fuse-ld=lld-link2 -shared -o shared.dll -fsanitize=tsan -x c++ %s 2>&1 \
// RUN: | FileCheck %s --check-prefix CHECK-SANITIZE-TSAN
diff --git a/test/Driver/x86-march.c b/test/Driver/x86-march.c
index b12bf405b0b0..f08c9dfadc09 100644
--- a/test/Driver/x86-march.c
+++ b/test/Driver/x86-march.c
@@ -52,10 +52,18 @@
// RUN: | FileCheck %s -check-prefix=knl
// knl: "-target-cpu" "knl"
//
+// RUN: %clang -target x86_64-unknown-unknown -c -### %s -march=knm 2>&1 \
+// RUN: | FileCheck %s -check-prefix=knm
+// knm: "-target-cpu" "knm"
+//
// RUN: %clang -target x86_64-unknown-unknown -c -### %s -march=cannonlake 2>&1 \
// RUN: | FileCheck %s -check-prefix=cannonlake
// cannonlake: "-target-cpu" "cannonlake"
//
+// RUN: %clang -target x86_64-unknown-unknown -c -### %s -march=icelake 2>&1 \
+// RUN: | FileCheck %s -check-prefix=icelake
+// icelake: "-target-cpu" "icelake"
+//
// RUN: %clang -target x86_64-unknown-unknown -c -### %s -march=lakemont 2>&1 \
// RUN: | FileCheck %s -check-prefix=lakemont
// lakemont: "-target-cpu" "lakemont"
diff --git a/test/Driver/x86-target-features.c b/test/Driver/x86-target-features.c
index dc32f6c470b4..c552ef7bd275 100644
--- a/test/Driver/x86-target-features.c
+++ b/test/Driver/x86-target-features.c
@@ -70,6 +70,16 @@
// MPX: "-target-feature" "+mpx"
// NO-MPX: "-target-feature" "-mpx"
+// RUN: %clang -target i386-unknown-linux-gnu -march=i386 -mshstk %s -### -o %t.o 2>&1 | FileCheck -check-prefix=CETSS %s
+// RUN: %clang -target i386-unknown-linux-gnu -march=i386 -mno-shstk %s -### -o %t.o 2>&1 | FileCheck -check-prefix=NO-CETSS %s
+// CETSS: "-target-feature" "+shstk"
+// NO-CETSS: "-target-feature" "-shstk"
+
+// RUN: %clang -target i386-unknown-linux-gnu -march=i386 -mibt %s -### -o %t.o 2>&1 | FileCheck -check-prefix=CETIBT %s
+// RUN: %clang -target i386-unknown-linux-gnu -march=i386 -mno-ibt %s -### -o %t.o 2>&1 | FileCheck -check-prefix=NO-CETIBT %s
+// CETIBT: "-target-feature" "+ibt"
+// NO-CETIBT: "-target-feature" "-ibt"
+
// RUN: %clang -target i386-unknown-linux-gnu -march=i386 -msgx %s -### -o %t.o 2>&1 | FileCheck -check-prefix=SGX %s
// RUN: %clang -target i386-unknown-linux-gnu -march=i386 -mno-sgx %s -### -o %t.o 2>&1 | FileCheck -check-prefix=NO-SGX %s
// SGX: "-target-feature" "+sgx"
diff --git a/test/FixIt/Inputs/nullability-objc.h b/test/FixIt/Inputs/nullability-objc.h
new file mode 100644
index 000000000000..e3e6baafd66d
--- /dev/null
+++ b/test/FixIt/Inputs/nullability-objc.h
@@ -0,0 +1,48 @@
+@class Item;
+@class Container<ObjectType>;
+@protocol Protocol;
+
+// rdar://problem/34260995
+// The first pointer in the file is handled in a different way so need
+// a separate test for this case even if the parameter type is the same as in
+// objcIdParameterWithProtocol.
+void objcIdParameterWithProtocolFirstInFile(id<Protocol> i); // expected-warning {{pointer is missing a nullability type specifier}}
+// expected-note@-1 {{insert '_Nullable'}}
+// expected-note@-2 {{insert '_Nonnull'}}
+// CHECK: fix-it:"{{.*}}nullability-objc.h":{[[@LINE-3]]:57-[[@LINE-3]]:57}:" _Nullable"
+// CHECK: fix-it:"{{.*}}nullability-objc.h":{[[@LINE-4]]:57-[[@LINE-4]]:57}:" _Nonnull"
+
+int * _Nonnull forceNullabilityWarningsObjC(void);
+
+void objcClassParameter(Item *i); // expected-warning {{pointer is missing a nullability type specifier}}
+// expected-note@-1 {{insert '_Nullable'}}
+// expected-note@-2 {{insert '_Nonnull'}}
+// CHECK: fix-it:"{{.*}}nullability-objc.h":{[[@LINE-3]]:31-[[@LINE-3]]:31}:" _Nullable "
+// CHECK: fix-it:"{{.*}}nullability-objc.h":{[[@LINE-4]]:31-[[@LINE-4]]:31}:" _Nonnull "
+
+void objcClassParameterWithProtocol(Item<Protocol> *i); // expected-warning {{pointer is missing a nullability type specifier}}
+// expected-note@-1 {{insert '_Nullable'}}
+// expected-note@-2 {{insert '_Nonnull'}}
+// CHECK: fix-it:"{{.*}}nullability-objc.h":{[[@LINE-3]]:53-[[@LINE-3]]:53}:" _Nullable "
+// CHECK: fix-it:"{{.*}}nullability-objc.h":{[[@LINE-4]]:53-[[@LINE-4]]:53}:" _Nonnull "
+
+// rdar://problem/34260995
+void objcIdParameterWithProtocol(id<Protocol> i); // expected-warning {{pointer is missing a nullability type specifier}}
+// expected-note@-1 {{insert '_Nullable'}}
+// expected-note@-2 {{insert '_Nonnull'}}
+// CHECK: fix-it:"{{.*}}nullability-objc.h":{[[@LINE-3]]:46-[[@LINE-3]]:46}:" _Nullable"
+// CHECK: fix-it:"{{.*}}nullability-objc.h":{[[@LINE-4]]:46-[[@LINE-4]]:46}:" _Nonnull"
+
+// Class parameters don't have nullability type specifier.
+void objcParameterizedClassParameter(Container<Item *> *c); // expected-warning {{pointer is missing a nullability type specifier}}
+// expected-note@-1 {{insert '_Nullable'}}
+// expected-note@-2 {{insert '_Nonnull'}}
+// CHECK: fix-it:"{{.*}}nullability-objc.h":{[[@LINE-3]]:57-[[@LINE-3]]:57}:" _Nullable "
+// CHECK: fix-it:"{{.*}}nullability-objc.h":{[[@LINE-4]]:57-[[@LINE-4]]:57}:" _Nonnull "
+
+// Class parameters don't have nullability type specifier.
+void objcParameterizedClassParameterWithProtocol(Container<id<Protocol>> *c); // expected-warning {{pointer is missing a nullability type specifier}}
+// expected-note@-1 {{insert '_Nullable'}}
+// expected-note@-2 {{insert '_Nonnull'}}
+// CHECK: fix-it:"{{.*}}nullability-objc.h":{[[@LINE-3]]:75-[[@LINE-3]]:75}:" _Nullable "
+// CHECK: fix-it:"{{.*}}nullability-objc.h":{[[@LINE-4]]:75-[[@LINE-4]]:75}:" _Nonnull "
diff --git a/test/FixIt/fixit-availability.c b/test/FixIt/fixit-availability.c
index 038dee08b13c..4b3c8a43920d 100644
--- a/test/FixIt/fixit-availability.c
+++ b/test/FixIt/fixit-availability.c
@@ -8,3 +8,11 @@ void use() {
// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"if (__builtin_available(macOS 10.12, *)) {\n "
// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:14-[[@LINE-2]]:14}:"\n } else {\n // Fallback on earlier versions\n }"
}
+
+__attribute__((availability(macos, introduced=10.12)))
+struct New { };
+
+struct NoFixit {
+ struct New field;
+};
+// CHECK-NOT: API_AVAILABLE
diff --git a/test/FixIt/fixit-availability.mm b/test/FixIt/fixit-availability.mm
index d044a73efdb9..a5660825327f 100644
--- a/test/FixIt/fixit-availability.mm
+++ b/test/FixIt/fixit-availability.mm
@@ -108,4 +108,43 @@ void wrapDeclStmtUses() {
// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:24-[[@LINE-2]]:24}:"\n } else {\n // Fallback on earlier versions\n }"
anotherFunction(y);
anotherFunction(x);
+
+ if (@available(macOS 10.1, *)) {
+ int z = function();
+ (void)z;
+// CHECK: fix-it:{{.*}}:{[[@LINE-2]]:5-[[@LINE-2]]:5}:"if (@available(macOS 10.12, *)) {\n "
+// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:13-[[@LINE-2]]:13}:"\n } else {\n // Fallback on earlier versions\n }"
+ anotherFunction(x);
+ }
}
+
+#define API_AVAILABLE(X) __attribute__((availability(macos, introduced=10.12))) // dummy macro
+
+API_AVAILABLE(macos(10.12))
+@interface NewClass
+@end
+
+@interface OldButOfferFixit
+@property(copy) NewClass *prop;
+// CHECK: fix-it:{{.*}}:{[[@LINE-2]]:1-[[@LINE-2]]:1}:"API_AVAILABLE(macos(10.12))\n"
+
+- (NewClass *)fixitMe;
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:22-[[@LINE-1]]:22}:" API_AVAILABLE(macos(10.12))"
+@end
+
+void oldButOfferFixitFn(NewClass *) {
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:1-[[@LINE-1]]:1}:"API_AVAILABLE(macos(10.12))\n"
+}
+
+template<typename T>
+struct OldButOfferFixitTag {
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:7-[[@LINE-1]]:7}:" API_AVAILABLE(macos(10.12))"
+ NewClass *x;
+};
+
+// Avoid a fixit for declarations that already have an attribute:
+__attribute__((availability(macos, introduced=10.11)))
+@interface WithoutFixit
+@property(copy) NewClass *prop;
+// CHECK-NOT: API_AVAILABLE
+@end
diff --git a/test/FixIt/fixit-cxx0x.cpp b/test/FixIt/fixit-cxx0x.cpp
index 5aebcb3defaa..337b5d62bed7 100644
--- a/test/FixIt/fixit-cxx0x.cpp
+++ b/test/FixIt/fixit-cxx0x.cpp
@@ -54,7 +54,6 @@ struct S2 {
void S2::f(int i) {
(void)[&, &i, &i]{}; // expected-error 2{{'&' cannot precede a capture when the capture default is '&'}}
- (void)[=, this]{ this->g(5); }; // expected-error{{'this' cannot be explicitly captured}}
(void)[i, i]{ }; // expected-error{{'i' can appear only once in a capture list}}
(void)[&, i, i]{ }; // expected-error{{'i' can appear only once in a capture list}}
(void)[] mutable { }; // expected-error{{lambda requires '()' before 'mutable'}}
diff --git a/test/FixIt/fixit-format-ios.m b/test/FixIt/fixit-format-ios.m
new file mode 100644
index 000000000000..ef6643077869
--- /dev/null
+++ b/test/FixIt/fixit-format-ios.m
@@ -0,0 +1,26 @@
+// RUN: cp %s %t
+// RUN: %clang_cc1 -triple thumbv7-apple-ios8.0.0 -fsyntax-only -Wformat -fixit %t
+// RUN: grep -v CHECK %t | FileCheck %s
+
+int printf(const char * restrict, ...);
+typedef unsigned int NSUInteger;
+typedef int NSInteger;
+NSUInteger getNSUInteger();
+NSInteger getNSInteger();
+
+void test() {
+ // For thumbv7-apple-ios8.0.0 the underlying type of ssize_t is long
+ // and the underlying type of size_t is unsigned long.
+
+ printf("test 1: %zu", getNSUInteger());
+ // CHECK: printf("test 1: %lu", (unsigned long)getNSUInteger());
+
+ printf("test 2: %zu %zu", getNSUInteger(), getNSUInteger());
+ // CHECK: printf("test 2: %lu %lu", (unsigned long)getNSUInteger(), (unsigned long)getNSUInteger());
+
+ printf("test 3: %zd", getNSInteger());
+ // CHECK: printf("test 3: %ld", (long)getNSInteger());
+
+ printf("test 4: %zd %zd", getNSInteger(), getNSInteger());
+ // CHECK: printf("test 4: %ld %ld", (long)getNSInteger(), (long)getNSInteger());
+}
diff --git a/test/FixIt/fixit-include.c b/test/FixIt/fixit-include.c
index fd5d7a9ac142..455455687c0d 100644
--- a/test/FixIt/fixit-include.c
+++ b/test/FixIt/fixit-include.c
@@ -1,12 +1,13 @@
// RUN: %clang_cc1 -fsyntax-only -Wall -pedantic -verify %s
-// RUN: cp %s %t
-// RUN: cp %S/fixit-include.h %T
-// RUN: not %clang_cc1 -fsyntax-only -fixit %t
-// RUN: %clang_cc1 -Wall -pedantic %t
+// RUN: mkdir -p %t-dir
+// RUN: cp %s %t-dir/fixit-include.c
+// RUN: cp %S/fixit-include.h %t-dir/fixit-include.h
+// RUN: not %clang_cc1 -fsyntax-only -fixit %t-dir/fixit-include.c
+// RUN: %clang_cc1 -Wall -pedantic %t-dir/fixit-include.c
// RUN: not %clang_cc1 -fsyntax-only -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
#include <fixit-include.h> // expected-error {{'fixit-include.h' file not found with <angled> include; use "quotes" instead}}
-// CHECK: fix-it:{{.*}}:{8:10-8:27}
+// CHECK: fix-it:{{.*}}:{9:10-9:27}
#pragma does_not_exist // expected-warning {{unknown pragma ignored}}
diff --git a/test/FixIt/fixit-pragma-pack.c b/test/FixIt/fixit-pragma-pack.c
new file mode 100644
index 000000000000..acab4a8bb434
--- /dev/null
+++ b/test/FixIt/fixit-pragma-pack.c
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -fsyntax-only -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
+
+#pragma pack (push, 1)
+#pragma pack()
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:14-[[@LINE-1]]:14}:"pop"
diff --git a/test/FixIt/fixit-vexing-parse.cpp b/test/FixIt/fixit-vexing-parse.cpp
index 71d3eff5329a..973c6961a087 100644
--- a/test/FixIt/fixit-vexing-parse.cpp
+++ b/test/FixIt/fixit-vexing-parse.cpp
@@ -106,3 +106,24 @@ namespace N {
wchar_t wc(); // expected-warning {{function declaration}} expected-note {{replace parentheses with an initializer}}
}
}
+
+namespace RedundantParens {
+struct Y {
+ Y();
+ Y(int);
+ ~Y();
+};
+int n;
+
+void test() {
+ // CHECK: add a variable name
+ // CHECK: fix-it:"{{.*}}":{[[@LINE+7]]:4-[[@LINE+7]]:4}:" varname"
+ // CHECK: add enclosing parentheses
+ // CHECK: fix-it:"{{.*}}":{[[@LINE+5]]:3-[[@LINE+5]]:3}:"("
+ // CHECK: fix-it:"{{.*}}":{[[@LINE+4]]:7-[[@LINE+4]]:7}:")"
+ // CHECK: remove parentheses
+ // CHECK: fix-it:"{{.*}}":{[[@LINE+2]]:4-[[@LINE+2]]:5}:" "
+ // CHECK: fix-it:"{{.*}}":{[[@LINE+1]]:6-[[@LINE+1]]:7}:""
+ Y(n); // expected-warning {{declaration of variable named 'n'}} expected-note 3{{}}
+}
+}
diff --git a/test/FixIt/format.m b/test/FixIt/format.m
index c3cf2b1f3c56..40655a0e808e 100644
--- a/test/FixIt/format.m
+++ b/test/FixIt/format.m
@@ -242,6 +242,37 @@ void testSizeTypes() {
// see the comment in PrintfSpecifier::fixType in PrintfFormatString.cpp.
}
+typedef __PTRDIFF_TYPE__ ptrdiff_t;
+#define __UNSIGNED_PTRDIFF_TYPE__ \
+ __typeof__(_Generic((__PTRDIFF_TYPE__)0, \
+ long long int : (unsigned long long int)0, \
+ long int : (unsigned long int)0, \
+ int : (unsigned int)0, \
+ short : (unsigned short)0, \
+ signed char : (unsigned char)0))
+
+void testPtrDiffTypes() {
+ __UNSIGNED_PTRDIFF_TYPE__ p1 = 0;
+ printf("%tu", p1); // No warning.
+
+ printf("%tu", 0.f); // expected-warning-re{{format specifies type 'unsigned ptrdiff_t' (aka '{{.+}}') but the argument has type 'float'}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:14}:"%f"
+
+ ptrdiff_t p2 = 0;
+ printf("%td", p2); // No warning.
+
+ printf("%td", 0.f); // expected-warning-re{{format specifies type 'ptrdiff_t' (aka '{{.+}}') but the argument has type 'float'}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:14}:"%f"
+
+ ptrdiff_t p3 = 0;
+ printf("%tn", &p3); // No warning.
+
+ short x;
+ printf("%tn", &x); // expected-warning-re{{format specifies type 'ptrdiff_t *' (aka '{{.+}}') but the argument has type 'short *'}}
+ // PrintfSpecifier::fixType doesn't handle %n, so a fix-it is not emitted,
+ // see the comment in PrintfSpecifier::fixType in PrintfFormatString.cpp.
+}
+
void testEnum() {
typedef enum {
ImplicitA = 1,
diff --git a/test/FixIt/nullability.mm b/test/FixIt/nullability.mm
index 815c84419243..a91ccc0f5f64 100644
--- a/test/FixIt/nullability.mm
+++ b/test/FixIt/nullability.mm
@@ -2,8 +2,10 @@
// RUN: not %clang_cc1 -fdiagnostics-parseable-fixits -fblocks -std=gnu++11 -I %S/Inputs %s >%t.txt 2>&1
// RUN: FileCheck %s < %t.txt
// RUN: FileCheck %S/Inputs/nullability.h < %t.txt
+// RUN: FileCheck %S/Inputs/nullability-objc.h < %t.txt
#include "nullability.h"
+#include "nullability-objc.h"
#pragma clang assume_nonnull begin
diff --git a/test/Format/style-on-command-line.cpp b/test/Format/style-on-command-line.cpp
index b2724353da13..0e6078e2fd67 100644
--- a/test/Format/style-on-command-line.cpp
+++ b/test/Format/style-on-command-line.cpp
@@ -2,20 +2,21 @@
// RUN: clang-format -style="{BasedOnStyle: LLVM, IndentWidth: 7}" %s | FileCheck -strict-whitespace -check-prefix=CHECK2 %s
// RUN: not clang-format -style="{BasedOnStyle: invalid, IndentWidth: 7}" -fallback-style=LLVM %s 2>&1 | FileCheck -strict-whitespace -check-prefix=CHECK3 %s
// RUN: not clang-format -style="{lsjd}" %s -fallback-style=LLVM 2>&1 | FileCheck -strict-whitespace -check-prefix=CHECK4 %s
-// RUN: printf "BasedOnStyle: google\nIndentWidth: 5\n" > %T/.clang-format
-// RUN: clang-format -style=file -assume-filename=%T/foo.cpp < %s | FileCheck -strict-whitespace -check-prefix=CHECK5 %s
-// RUN: printf "\n" > %T/.clang-format
-// RUN: not clang-format -style=file -fallback-style=webkit -assume-filename=%T/foo.cpp < %s 2>&1 | FileCheck -strict-whitespace -check-prefix=CHECK6 %s
-// RUN: rm %T/.clang-format
-// RUN: printf "BasedOnStyle: google\nIndentWidth: 6\n" > %T/_clang-format
-// RUN: clang-format -style=file -assume-filename=%T/foo.cpp < %s | FileCheck -strict-whitespace -check-prefix=CHECK7 %s
+// RUN: mkdir -p %t
+// RUN: printf "BasedOnStyle: google\nIndentWidth: 5\n" > %t/.clang-format
+// RUN: clang-format -style=file -assume-filename=%t/foo.cpp < %s | FileCheck -strict-whitespace -check-prefix=CHECK5 %s
+// RUN: printf "\n" > %t/.clang-format
+// RUN: not clang-format -style=file -fallback-style=webkit -assume-filename=%t/foo.cpp < %s 2>&1 | FileCheck -strict-whitespace -check-prefix=CHECK6 %s
+// RUN: rm %t/.clang-format
+// RUN: printf "BasedOnStyle: google\nIndentWidth: 6\n" > %t/_clang-format
+// RUN: clang-format -style=file -assume-filename=%t/foo.cpp < %s | FileCheck -strict-whitespace -check-prefix=CHECK7 %s
// RUN: clang-format -style="{BasedOnStyle: LLVM, PointerBindsToType: true}" %s | FileCheck -strict-whitespace -check-prefix=CHECK8 %s
// RUN: clang-format -style="{BasedOnStyle: WebKit, PointerBindsToType: false}" %s | FileCheck -strict-whitespace -check-prefix=CHECK9 %s
// Fallback style tests
// Test config file with no based style, and fallback style "none", formatting is applied
-// RUN: printf "IndentWidth: 6\n" > %T/_clang-format
-// RUN: clang-format -style=file -fallback-style=none -assume-filename=%T/foo.cpp < %s 2>&1 | FileCheck -strict-whitespace -check-prefix=CHECK10 %s
+// RUN: printf "IndentWidth: 6\n" > %t/_clang-format
+// RUN: clang-format -style=file -fallback-style=none -assume-filename=%t/foo.cpp < %s 2>&1 | FileCheck -strict-whitespace -check-prefix=CHECK10 %s
// Test yaml with no based style, and fallback style "none", LLVM formatting applied
// RUN: clang-format -style="{IndentWidth: 7}" -fallback-style=none %s | FileCheck -strict-whitespace -check-prefix=CHECK11 %s
diff --git a/test/Format/verbose.cpp b/test/Format/verbose.cpp
new file mode 100644
index 000000000000..dd625e3f67e5
--- /dev/null
+++ b/test/Format/verbose.cpp
@@ -0,0 +1,16 @@
+// RUN: clang-format %s 2> %t.stderr
+// RUN: not grep "Formatting" %t.stderr
+// RUN: clang-format %s -verbose 2> %t.stderr
+// RUN: grep -E "Formatting (.*)verbose.cpp(.*)" %t.stderr
+// RUN: clang-format %s -verbose=false 2> %t.stderr
+// RUN: not grep "Formatting" %t.stderr
+
+int a;
+// RUN: clang-format %s 2> %t.stderr
+// RUN: not grep "Formatting" %t.stderr
+// RUN: clang-format %s -verbose 2> %t.stderr
+// RUN: grep -E "Formatting (.*)verbose.cpp(.*)" %t.stderr
+// RUN: clang-format %s -verbose=false 2> %t.stderr
+// RUN: not grep "Formatting" %t.stderr
+
+int a;
diff --git a/test/Frontend/Inputs/optimization-remark-with-hotness-sample.proftext b/test/Frontend/Inputs/optimization-remark-with-hotness-sample.proftext
index 730dc4a0d5b1..0eef9bdc012c 100644
--- a/test/Frontend/Inputs/optimization-remark-with-hotness-sample.proftext
+++ b/test/Frontend/Inputs/optimization-remark-with-hotness-sample.proftext
@@ -1,7 +1,7 @@
-foo:0:0
- 0: 0
+foo:29:29
+ 0: 29
bar:29:29
- 9: foo:0
-main:0:0
- 0: 0 bar:0
+ 8: 29 foo:29
+main:29:1
+ 3: 29 bar:29
diff --git a/test/Frontend/Inputs/optimization-remark-with-hotness.proftext b/test/Frontend/Inputs/optimization-remark-with-hotness.proftext
index af111d6d06bb..4ed20ab21a6f 100644
--- a/test/Frontend/Inputs/optimization-remark-with-hotness.proftext
+++ b/test/Frontend/Inputs/optimization-remark-with-hotness.proftext
@@ -1,6 +1,6 @@
foo
# Func Hash:
-0
+24
# Num Counters:
1
# Counter Values:
@@ -16,7 +16,7 @@ bar
main
# Func Hash:
-4
+1160280
# Num Counters:
2
# Counter Values:
diff --git a/test/Frontend/diagnostics-order.c b/test/Frontend/diagnostics-order.c
new file mode 100644
index 000000000000..37c0cd90d15c
--- /dev/null
+++ b/test/Frontend/diagnostics-order.c
@@ -0,0 +1,12 @@
+// Make sure a note stays with its associated command-line argument diagnostic.
+// Previously, these diagnostics were grouped by diagnostic level with all
+// notes last.
+//
+// RUN: not %clang_cc1 -O999 -std=bogus -verify=-foo %s 2> %t
+// RUN: FileCheck < %t %s
+//
+// CHECK: error: invalid value '-foo' in '-verify='
+// CHECK-NEXT: note: -verify prefixes must start with a letter and contain only alphanumeric characters, hyphens, and underscores
+// CHECK-NEXT: warning: optimization level '-O999' is not supported
+// CHECK-NEXT: error: invalid value 'bogus' in '-std=bogus'
+// CHECK-NEXT: note: use {{.*}} for {{.*}} standard
diff --git a/test/Frontend/float16.cpp b/test/Frontend/float16.cpp
new file mode 100644
index 000000000000..febd6b8e36a0
--- /dev/null
+++ b/test/Frontend/float16.cpp
@@ -0,0 +1,326 @@
+// RUN: %clang_cc1 -std=c++11 -ast-dump %s | FileCheck %s --strict-whitespace
+// RUN: %clang_cc1 -std=c++11 -ast-dump -fnative-half-type %s | FileCheck %s --check-prefix=CHECK-NATIVE --strict-whitespace
+
+/* Various contexts where type _Float16 can appear. */
+
+/* Namespace */
+namespace {
+ _Float16 f1n;
+ _Float16 f2n = 33.f16;
+ _Float16 arr1n[10];
+ _Float16 arr2n[] = { 1.2, 3.0, 3.e4 };
+ const volatile _Float16 func1n(const _Float16 &arg) {
+ return arg + f2n + arr1n[4] - arr2n[1];
+ }
+}
+
+//CHECK: |-NamespaceDecl
+//CHECK-NEXT: | |-VarDecl {{.*}} f1n '_Float16'
+//CHECK-NEXT: | |-VarDecl {{.*}} f2n '_Float16' cinit
+//CHECK-NEXT: | | `-FloatingLiteral {{.*}} '_Float16' 3.300000e+01
+//CHECK-NEXT: | |-VarDecl {{.*}} arr1n '_Float16 [10]'
+//CHECK-NEXT: | |-VarDecl {{.*}} arr2n '_Float16 [3]' cinit
+//CHECK-NEXT: | | `-InitListExpr {{.*}} '_Float16 [3]'
+//CHECK-NEXT: | | |-ImplicitCastExpr {{.*}} '_Float16' <FloatingCast>
+//CHECK-NEXT: | | | `-FloatingLiteral {{.*}} 'double' 1.200000e+00
+//CHECK-NEXT: | | |-ImplicitCastExpr {{.*}} '_Float16' <FloatingCast>
+//CHECK-NEXT: | | | `-FloatingLiteral {{.*}} 'double' 3.000000e+00
+//CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} '_Float16' <FloatingCast>
+//CHECK-NEXT: | | `-FloatingLiteral {{.*}} 'double' 3.000000e+04
+//CHECK-NEXT: | `-FunctionDecl {{.*}} func1n 'const volatile _Float16 (const _Float16 &)'
+
+/* File */
+_Float16 f1f;
+_Float16 f2f = 32.4;
+_Float16 arr1f[10];
+_Float16 arr2f[] = { -1.2, -3.0, -3.e4 };
+_Float16 func1f(_Float16 arg);
+
+//CHECK: |-VarDecl {{.*}} f1f '_Float16'
+//CHECK-NEXT: |-VarDecl {{.*}} f2f '_Float16' cinit
+//CHECK-NEXT: | `-ImplicitCastExpr {{.*}} '_Float16' <FloatingCast>
+//CHECK-NEXT: | `-FloatingLiteral {{.*}} 'double' 3.240000e+01
+//CHECK-NEXT: |-VarDecl {{.*}} arr1f '_Float16 [10]'
+//CHECK-NEXT: |-VarDecl {{.*}} arr2f '_Float16 [3]' cinit
+//CHECK-NEXT: | `-InitListExpr {{.*}} '_Float16 [3]'
+//CHECK-NEXT: | |-ImplicitCastExpr {{.*}} '_Float16' <FloatingCast>
+//CHECK-NEXT: | | `-UnaryOperator {{.*}} 'double' prefix '-'
+//CHECK-NEXT: | | `-FloatingLiteral {{.*}} 'double' 1.200000e+00
+//CHECK-NEXT: | |-ImplicitCastExpr {{.*}} '_Float16' <FloatingCast>
+//CHECK-NEXT: | | `-UnaryOperator {{.*}} 'double' prefix '-'
+//CHECK-NEXT: | | `-FloatingLiteral {{.*}} 'double' 3.000000e+00
+//CHECK-NEXT: | `-ImplicitCastExpr {{.*}} '_Float16' <FloatingCast>
+//CHECK-NEXT: | `-UnaryOperator {{.*}} 'double' prefix '-'
+//CHECK-NEXT: | `-FloatingLiteral {{.*}} 'double' 3.000000e+04
+//CHECK-NEXT: |-FunctionDecl {{.*}} func1f '_Float16 (_Float16)'
+//CHECK-NEXT: | `-ParmVarDecl {{.*}} arg '_Float16'
+
+
+// Mixing __fp16 and Float16 types:
+// The _Float16 type is first converted to __fp16 type and then the operation
+// is completed as if both operands were of __fp16 type.
+
+__fp16 B = -0.1;
+auto C = -1.0f16 + B;
+
+// When we do *not* have native half types, we expect __fp16 to be promoted to
+// float, and consequently also _Float16 promotions to float:
+
+//CHECK: -VarDecl {{.*}} used B '__fp16' cinit
+//CHECK-NEXT: | `-ImplicitCastExpr {{.*}} '__fp16' <FloatingCast>
+//CHECK-NEXT: | `-UnaryOperator {{.*}} 'double' prefix '-'
+//CHECK-NEXT: | `-FloatingLiteral {{.*}} 'double' 1.000000e-01
+//CHECK-NEXT: |-VarDecl {{.*}} C 'float':'float' cinit
+//CHECK-NEXT: | `-BinaryOperator {{.*}} 'float' '+'
+//CHECK-NEXT: | |-ImplicitCastExpr {{.*}} 'float' <FloatingCast>
+//CHECK-NEXT: | | `-UnaryOperator {{.*}} '_Float16' prefix '-'
+//CHECK-NEXT: | | `-FloatingLiteral {{.*}} '_Float16' 1.000000e+00
+//CHECK-NEXT: | `-ImplicitCastExpr {{.*}} 'float' <FloatingCast>
+//CHECK-NEXT: | `-ImplicitCastExpr {{.*}} '__fp16' <LValueToRValue>
+//CHECK-NEXT: | `-DeclRefExpr {{.*}} '__fp16' lvalue Var 0x{{.*}} 'B' '__fp16'
+
+// When do have native half types, we expect to see promotions to fp16:
+
+//CHECK-NATIVE: |-VarDecl {{.*}} used B '__fp16' cinit
+//CHECK-NATIVE: | `-ImplicitCastExpr {{.*}} '__fp16' <FloatingCast>
+//CHECK-NATIVE: | `-UnaryOperator {{.*}} 'double' prefix '-'
+//CHECK-NATIVE: | `-FloatingLiteral {{.*}} 'double' 1.000000e-01
+//CHECK-NATIVE: |-VarDecl {{.*}} C '__fp16':'__fp16' cinit
+//CHECK-NATIVE: | `-BinaryOperator {{.*}} '__fp16' '+'
+//CHECK-NATIVE: | |-ImplicitCastExpr {{.*}} '__fp16' <FloatingCast>
+//CHECK-NATIVE: | | `-UnaryOperator {{.*}} '_Float16' prefix '-'
+//CHECK-NATIVE: | | `-FloatingLiteral {{.*}} '_Float16' 1.000000e+00
+//CHECK-NATIVE: | `-ImplicitCastExpr {{.*}} '__fp16' <LValueToRValue>
+//CHECK-NATIVE: | `-DeclRefExpr {{.*}} '__fp16' lvalue Var 0x{{.*}} 'B' '__fp16'
+
+
+/* Class */
+
+class C1 {
+ _Float16 f1c;
+ static const _Float16 f2c;
+ volatile _Float16 f3c;
+public:
+ C1(_Float16 arg) : f1c(arg), f3c(arg) { }
+ _Float16 func1c(_Float16 arg ) {
+ return f1c + arg;
+ }
+ static _Float16 func2c(_Float16 arg) {
+ return arg * C1::f2c;
+ }
+};
+
+//CHECK: |-CXXRecordDecl {{.*}} referenced class C1 definition
+//CHECK: | |-CXXRecordDecl {{.*}} implicit referenced class C1
+//CHECK-NEXT: | |-FieldDecl {{.*}} referenced f1c '_Float16'
+//CHECK-NEXT: | |-VarDecl {{.*}} used f2c 'const _Float16' static
+//CHECK-NEXT: | |-FieldDecl {{.*}} f3c 'volatile _Float16'
+//CHECK-NEXT: | |-AccessSpecDecl
+//CHECK-NEXT: | |-CXXConstructorDecl {{.*}} used C1 'void (_Float16)
+//CHECK-NEXT: | | |-ParmVarDecl {{.*}} used arg '_Float16'
+//CHECK-NEXT: | | |-CXXCtorInitializer Field {{.*}} 'f1c' '_Float16'
+//CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
+//CHECK-NEXT: | | | `-DeclRefExpr {{.*}} '_Float16' lvalue ParmVar 0x{{.*}} 'arg' '_Float16'
+//CHECK-NEXT: | | |-CXXCtorInitializer Field {{.*}} 'f3c' 'volatile _Float16'
+//CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
+//CHECK-NEXT: | | | `-DeclRefExpr {{.*}} '_Float16' lvalue ParmVar 0x{{.*}} 'arg' '_Float16'
+//CHECK-NEXT: | | `-CompoundStmt
+//CHECK-NEXT: | |-CXXMethodDecl {{.*}} used func1c '_Float16 (_Float16)
+//CHECK-NEXT: | | |-ParmVarDecl {{.*}} used arg '_Float16'
+//CHECK-NEXT: | | `-CompoundStmt
+//CHECK-NEXT: | | `-ReturnStmt
+//CHECK-NEXT: | | `-BinaryOperator {{.*}} '_Float16' '+'
+//CHECK-NEXT: | | |-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
+//CHECK-NEXT: | | | `-MemberExpr {{.*}} '_Float16' lvalue ->f1c 0x{{.*}}
+//CHECK-NEXT: | | | `-CXXThisExpr {{.*}} 'class C1 *' this
+//CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
+//CHECK-NEXT: | | `-DeclRefExpr {{.*}} '_Float16' lvalue ParmVar 0x{{.*}} 'arg' '_Float16'
+//CHECK-NEXT: | |-CXXMethodDecl {{.*}} used func2c '_Float16 (_Float16)' static
+//CHECK-NEXT: | | |-ParmVarDecl {{.*}} used arg '_Float16'
+//CHECK-NEXT: | | `-CompoundStmt
+//CHECK-NEXT: | | `-ReturnStmt
+//CHECK-NEXT: | | `-BinaryOperator {{.*}} '_Float16' '*'
+//CHECK-NEXT: | | |-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
+//CHECK-NEXT: | | | `-DeclRefExpr {{.*}} '_Float16' lvalue ParmVar 0x{{.*}} 'arg' '_Float16'
+//CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
+//CHECK-NEXT: | | `-DeclRefExpr {{.*}} 'const _Float16' lvalue Var 0x{{.*}} 'f2c' 'const _Float16'
+
+
+/* Template */
+
+template <class C> C func1t(C arg) {
+ return arg * 2.f16;
+}
+
+//CHECK: |-FunctionTemplateDecl {{.*}} func1t
+//CHECK-NEXT: | |-TemplateTypeParmDecl {{.*}} C
+//CHECK-NEXT: | |-FunctionDecl {{.*}} func1t 'C (C)'
+//CHECK-NEXT: | | |-ParmVarDecl {{.*}} referenced arg 'C'
+//CHECK-NEXT: | | `-CompoundStmt
+//CHECK-NEXT: | | `-ReturnStmt
+//CHECK-NEXT: | | `-BinaryOperator {{.*}} '<dependent type>' '*'
+//CHECK-NEXT: | | |-DeclRefExpr {{.*}} 'C' lvalue ParmVar {{.*}} 'arg' 'C'
+//CHECK-NEXT: | | `-FloatingLiteral {{.*}} '_Float16' 2.000000e+00
+//CHECK-NEXT: | `-FunctionDecl {{.*}} used func1t '_Float16 (_Float16)'
+//CHECK-NEXT: | |-TemplateArgument type '_Float16'
+//CHECK-NEXT: | |-ParmVarDecl {{.*}} used arg '_Float16':'_Float16'
+//CHECK-NEXT: | `-CompoundStmt
+//CHECK-NEXT: | `-ReturnStmt
+//CHECK-NEXT: | `-BinaryOperator {{.*}} '_Float16' '*'
+//CHECK-NEXT: | |-ImplicitCastExpr {{.*}} '_Float16':'_Float16' <LValueToRValue>
+//CHECK-NEXT: | | `-DeclRefExpr {{.*}} '_Float16':'_Float16' lvalue ParmVar {{.*}} 'arg' '_Float16':'_Float16'
+//CHECK-NEXT: | `-FloatingLiteral {{.*}} '_Float16' 2.000000e+00
+
+
+template <class C> struct S1 {
+ C mem1;
+};
+
+//CHECK: |-ClassTemplateDecl {{.*}} S1
+//CHECK-NEXT: | |-TemplateTypeParmDecl {{.*}} referenced class depth 0 index 0 C
+//CHECK-NEXT: | |-CXXRecordDecl {{.*}} struct S1 definition
+//CHECK: | | |-CXXRecordDecl {{.*}} implicit struct S1
+//CHECK-NEXT: | | `-FieldDecl {{.*}} mem1 'C'
+//CHECK-NEXT: | `-ClassTemplateSpecialization {{.*}} 'S1'
+
+template <> struct S1<_Float16> {
+ _Float16 mem2;
+};
+
+
+/* Local */
+
+extern int printf (const char *__restrict __format, ...);
+
+int main(void) {
+ _Float16 f1l = 1e3f16;
+//CHECK: | `-VarDecl {{.*}} used f1l '_Float16' cinit
+//CHECK-NEXT: | `-FloatingLiteral {{.*}} '_Float16' 1.000000e+03
+
+ _Float16 f2l = -0.f16;
+//CHECK: | `-VarDecl {{.*}} used f2l '_Float16' cinit
+//CHECK-NEXT: | `-UnaryOperator {{.*}} '_Float16' prefix '-'
+//CHECK-NEXT: | `-FloatingLiteral {{.*}} '_Float16' 0.000000e+00
+
+ _Float16 f3l = 1.000976562;
+//CHECK: | `-VarDecl {{.*}} used f3l '_Float16' cinit
+//CHECK-NEXT: | `-ImplicitCastExpr {{.*}} '_Float16' <FloatingCast>
+//CHECK-NEXT: | `-FloatingLiteral {{.*}} 'double' 1.000977e+00
+
+ C1 c1(f1l);
+//CHECK: | `-VarDecl{{.*}} used c1 'class C1' callinit
+//CHECK-NEXT: | `-CXXConstructExpr {{.*}} 'class C1' 'void (_Float16)
+//CHECK-NEXT: | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
+//CHECK-NEXT: | `-DeclRefExpr {{.*}} '_Float16' lvalue Var 0x{{.*}} 'f1l' '_Float16'
+
+ S1<_Float16> s1 = { 132.f16 };
+//CHECK: | `-VarDecl {{.*}} used s1 'S1<_Float16>':'struct S1<_Float16>' cinit
+//CHECK-NEXT: | `-InitListExpr {{.*}} 'S1<_Float16>':'struct S1<_Float16>'
+//CHECK-NEXT: | `-FloatingLiteral {{.*}} '_Float16' 1.320000e+02
+
+ _Float16 f4l = func1n(f1l) + func1f(f2l) + c1.func1c(f3l) + c1.func2c(f1l) +
+ func1t(f1l) + s1.mem2 - f1n + f2n;
+//CHECK: | `-VarDecl {{.*}} used f4l '_Float16' cinit
+//CHECK-NEXT: | `-BinaryOperator {{.*}} '_Float16' '+'
+//CHECK-NEXT: | |-BinaryOperator {{.*}} '_Float16' '-'
+//CHECK-NEXT: | | |-BinaryOperator {{.*}} '_Float16' '+'
+//CHECK-NEXT: | | | |-BinaryOperator {{.*}} '_Float16' '+'
+//CHECK-NEXT: | | | | |-BinaryOperator {{.*}} '_Float16' '+'
+//CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} '_Float16' '+'
+//CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} '_Float16' '+'
+//CHECK-NEXT: | | | | | | | |-CallExpr {{.*}} '_Float16'
+//CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} 'const volatile _Float16 (*)(const _Float16 &)' <FunctionToPointerDecay>
+//CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} 'const volatile _Float16 (const _Float16 &)' lvalue Function {{.*}} 'func1n' 'const volatile _Float16 (const _Float16 &)'
+//CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} 'const _Float16' lvalue <NoOp>
+//CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f1l' '_Float16'
+//CHECK-NEXT: | | | | | | | `-CallExpr {{.*}} '_Float16'
+//CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} '_Float16 (*)(_Float16)' <FunctionToPointerDecay>
+//CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} '_Float16 (_Float16)' lvalue Function {{.*}} 'func1f' '_Float16 (_Float16)'
+//CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
+//CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f2l' '_Float16'
+//CHECK-NEXT: | | | | | | `-CXXMemberCallExpr {{.*}} '_Float16'
+//CHECK-NEXT: | | | | | | |-MemberExpr {{.*}} '<bound member function type>' .func1c {{.*}}
+//CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} 'class C1' lvalue Var {{.*}} 'c1' 'class C1'
+//CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
+//CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f3l' '_Float16'
+//CHECK-NEXT: | | | | | `-CallExpr {{.*}} '_Float16'
+//CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} '_Float16 (*)(_Float16)' <FunctionToPointerDecay>
+//CHECK-NEXT: | | | | | | `-MemberExpr {{.*}} '_Float16 (_Float16)' lvalue .func2c {{.*}}
+//CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} 'class C1' lvalue Var {{.*}} 'c1' 'class C1'
+//CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
+//CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f1l' '_Float16'
+//CHECK-NEXT: | | | | `-CallExpr {{.*}} '_Float16':'_Float16'
+//CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} '_Float16 (*)(_Float16)' <FunctionToPointerDecay>
+//CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} '_Float16 (_Float16)' lvalue Function {{.*}} 'func1t' '_Float16 (_Float16)' (FunctionTemplate {{.*}} 'func1t')
+//CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
+//CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f1l' '_Float16'
+//CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
+//CHECK-NEXT: | | | `-MemberExpr {{.*}} '_Float16' lvalue .mem2 {{.*}}
+//CHECK-NEXT: | | | `-DeclRefExpr {{.*}} 'S1<_Float16>':'struct S1<_Float16>' lvalue Var {{.*}} 's1' 'S1<_Float16>':'struct S1<_Float16>'
+//CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
+//CHECK-NEXT: | | `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f1n' '_Float16'
+//CHECK-NEXT: | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
+//CHECK-NEXT: | `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f2n' '_Float16'
+
+ auto f5l = -1.f16, *f6l = &f2l, f7l = func1t(f3l);
+//CHECK: | |-VarDecl {{.*}} f5l '_Float16':'_Float16' cinit
+//CHECK-NEXT: | | `-UnaryOperator {{.*}} '_Float16' prefix '-'
+//CHECK-NEXT: | | `-FloatingLiteral {{.*}} '_Float16' 1.000000e+00
+//CHECK-NEXT: | |-VarDecl {{.*}} f6l '_Float16 *' cinit
+//CHECK-NEXT: | | `-UnaryOperator {{.*}} '_Float16 *' prefix '&'
+//CHECK-NEXT: | | `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f2l' '_Float16'
+//CHECK-NEXT: | `-VarDecl {{.*}} f7l '_Float16':'_Float16' cinit
+//CHECK-NEXT: | `-CallExpr {{.*}} '_Float16':'_Float16'
+//CHECK-NEXT: | |-ImplicitCastExpr {{.*}} '_Float16 (*)(_Float16)' <FunctionToPointerDecay>
+//CHECK-NEXT: | | `-DeclRefExpr {{.*}} '_Float16 (_Float16)' lvalue Function {{.*}} 'func1t' '_Float16 (_Float16)' (FunctionTemplate {{.*}} 'func1t')
+//CHECK-NEXT: | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
+//CHECK-NEXT: | `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f3l' '_Float16'
+
+ _Float16 f8l = f4l++;
+//CHECK: | `-VarDecl {{.*}} f8l '_Float16' cinit
+//CHECK-NEXT: | `-UnaryOperator {{.*}} '_Float16' postfix '++'
+//CHECK-NEXT: | `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f4l' '_Float16'
+
+ _Float16 arr1l[] = { -1.f16, -0.f16, -11.f16 };
+//CHECK: `-VarDecl {{.*}} arr1l '_Float16 [3]' cinit
+//CHECK-NEXT: `-InitListExpr {{.*}} '_Float16 [3]'
+//CHECK-NEXT: |-UnaryOperator {{.*}} '_Float16' prefix '-'
+//CHECK-NEXT: | `-FloatingLiteral {{.*}} '_Float16' 1.000000e+00
+//CHECK-NEXT: |-UnaryOperator {{.*}} '_Float16' prefix '-'
+//CHECK-NEXT: | `-FloatingLiteral {{.*}} '_Float16' 0.000000e+00
+//CHECK-NEXT: `-UnaryOperator {{.*}} '_Float16' prefix '-'
+//CHECK-NEXT: `-FloatingLiteral {{.*}} '_Float16' 1.100000e+01
+
+ float cvtf = f2n;
+//CHECK: `-VarDecl {{.*}} cvtf 'float' cinit
+//CHECK-NEXT: `-ImplicitCastExpr {{.*}} 'float' <FloatingCast>
+//CHECK-NEXT: `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
+//CHECK-NEXT: `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f2n' '_Float16'
+
+ double cvtd = f2n;
+//CHECK: `-VarDecl {{.*}} cvtd 'double' cinit
+//CHECK-NEXT: `-ImplicitCastExpr {{.*}} 'double' <FloatingCast>
+//CHECK-NEXT: `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
+//CHECK-NEXT: `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f2n' '_Float16'
+
+ long double cvtld = f2n;
+//CHECK: `-VarDecl {{.*}} cvtld 'long double' cinit
+//CHECK-NEXT: `-ImplicitCastExpr {{.*}} 'long double' <FloatingCast>
+//CHECK-NEXT: `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
+//CHECK-NEXT: `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f2n' '_Float16'
+
+ _Float16 f2h = 42.0f;
+//CHECK: `-VarDecl {{.*}} f2h '_Float16' cinit
+//CHECK-NEXT: `-ImplicitCastExpr {{.*}} '_Float16' <FloatingCast>
+//CHECK-NEXT: `-FloatingLiteral {{.*}} 'float' 4.200000e+01
+
+ _Float16 d2h = 42.0;
+//CHECK: `-VarDecl {{.*}} d2h '_Float16' cinit
+//CHECK-NEXT: `-ImplicitCastExpr {{.*}} '_Float16' <FloatingCast>
+//CHECK-NEXT: `-FloatingLiteral {{.*}} 'double' 4.200000e+01
+
+ _Float16 ld2h = 42.0l;
+//CHECK: `-VarDecl {{.*}} ld2h '_Float16' cinit
+//CHECK-NEXT: `-ImplicitCastExpr {{.*}} '_Float16' <FloatingCast>
+//CHECK-NEXT: `-FloatingLiteral {{.*}} 'long double' 4.200000e+01
+}
diff --git a/test/Frontend/gnu-mcount.c b/test/Frontend/gnu-mcount.c
index 10baa8a88260..3953d2415382 100644
--- a/test/Frontend/gnu-mcount.c
+++ b/test/Frontend/gnu-mcount.c
@@ -28,10 +28,6 @@
// RUN: %clang -target armv7-apple-ios -pg -meabi gnu -S -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK -check-prefix CHECK-ARM-IOS
// RUN: %clang -target arm64-apple-ios -pg -S -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK -check-prefix CHECK-ARM-IOS
// RUN: %clang -target arm64-apple-ios -pg -meabi gnu -S -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK -check-prefix CHECK-ARM-IOS
-// RUN: %clang -target armv7-unknown-bitrig-gnueabihf -pg -S -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK -check-prefix CHECK-ARM-EABI-BIGRIG
-// RUN: %clang -target armv7-unknown-bitrig-gnueabihf -meabi gnu -pg -S -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK -check-prefix CHECK-ARM-EABI-BIGRIG
-// RUN: %clang -target aarch64-unknown-bitrig-gnueabihf -pg -S -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK -check-prefix CHECK-ARM64-EABI-BITRIG
-// RUN: %clang -target aarch64-unknown-bitrig-gnueabihf -meabi gnu -pg -S -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK -check-prefix CHECK-ARM64-EABI-BITRIG
// RUN: %clang -target armv7-unknown-rtems-gnueabihf -pg -S -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK -check-prefix CHECK-ARM-EABI-RTEMS
// RUN: %clang -target armv7-unknown-rtems-gnueabihf -meabi gnu -pg -S -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK -check-prefix CHECK-ARM-EABI-RTEMS
// RUN: %clang -target aarch64-unknown-rtems-gnueabihf -pg -S -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK -check-prefix CHECK-ARM64-EABI-RTEMS
@@ -47,40 +43,36 @@ int f() {
// CHECK-LABEL: f
// TODO: add profiling support for arm-baremetal
-// CHECK-ARM-BAREMETAL-EABI-NOT: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="\01mcount"{{.*}} }
-// CHECK-ARM-BAREMETAL-EABI-NOT: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="\01__gnu_mcount_nc"{{.*}} }
-// CHECK-ARM64-BAREMETAL-EABI: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="mcount"{{.*}} }
-// CHECK-ARM64-BAREMETAL-EABI-MEABI-GNU: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="\01_mcount"{{.*}} }
-// CHECK-ARM-IOS-NOT: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="_mcount"{{.*}} }
-// CHECK-ARM-IOS-NOT: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="\01__gnu_mcount_nc"{{.*}} }
-// CHECK-ARM-EABI: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="\01mcount"{{.*}} }
-// CHECK-ARM-EABI-NOT: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="\01__gnu_mcount_nc"{{.*}} }
-// CHECK-ARM64-EABI: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="mcount"{{.*}} }
-// CHECK-ARM64-EABI-MEABI-GNU: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="\01_mcount"{{.*}} }
-// CHECK-ARM64-EABI-NOT: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="\01__gnu_mcount_nc"{{.*}} }
-// CHECK-ARM64-EABI-LINUX: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="\01_mcount"{{.*}} }
-// CHECK-ARM-EABI-FREEBSD: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="__mcount"{{.*}} }
-// CHECK-ARM-EABI-FREEBSD-NOT: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="\01__gnu_mcount_nc"{{.*}} }
-// CHECK-ARM64-EABI-FREEBSD: attributes #{{[0-9]+}} = { {{.*}}"counting-function"=".mcount"{{.*}} }
-// CHECK-ARM64-EABI-FREEBSD-NOT: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="\01__gnu_mcount_nc"{{.*}} }
-// CHECK-ARM-EABI-NETBSD: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="_mcount"{{.*}} }
-// CHECK-ARM-EABI-NETBSD-NOT: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="\01__gnu_mcount_nc"{{.*}} }
-// CHECK-ARM-EABI-OPENBSD: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="__mcount"{{.*}} }
-// CHECK-ARM-EABI-OPENBSD-NOT: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="\01__gnu_mcount_nc"{{.*}} }
-// CHECK-ARM64-EABI-OPENBSD: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="__mcount"{{.*}} }
-// CHECK-ARM64-EABI-OPENBSD-NOT: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="\01__gnu_mcount_nc"{{.*}} }
-// CHECK-ARM-EABI-MEABI-GNU-NOT: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="mcount"{{.*}} }
-// CHECK-ARM-EABI-MEABI-GNU: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="\01__gnu_mcount_nc"{{.*}} }
-// CHECK-ARM-EABI-BITRIG: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="__mcount"{{.*}} }
-// CHECK-ARM-EABI-BITRIG-NOT: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="\01__gnu_mcount_nc"{{.*}} }
-// CHECK-ARM54-EABI-BITRIG: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="mcount"{{.*}} }
-// CHECK-ARM54-EABI-BITRIG-NOT: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="\01__gnu_mcount_nc"{{.*}} }
-// CHECK-ARM-EABI-RTEMS: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="mcount"{{.*}} }
-// CHECK-ARM-EABI-RTEMS-NOT: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="\01__gnu_mcount_nc"{{.*}} }
-// CHECK-ARM64-EABI-RTEMS: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="mcount"{{.*}} }
-// CHECK-ARM64-EABI-RTEMS-NOT: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="\01__gnu_mcount_nc"{{.*}} }
-// CHECK-ARM-EABI-CLOUDABI: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="mcount"{{.*}} }
-// CHECK-ARM-EABI-CLOUDABI-NOT: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="\01__gnu_mcount_nc"{{.*}} }
-// CHECK-ARM64-EABI-CLOUDABI: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="mcount"{{.*}} }
-// CHECK-ARM64-EABI-CLOUDABI-NOT: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="\01__gnu_mcount_nc"{{.*}} }
+// CHECK-ARM-BAREMETAL-EABI-NOT: attributes #{{[0-9]+}} = { {{.*}}"instrument-function-entry-inlined"="\01mcount"{{.*}} }
+// CHECK-ARM-BAREMETAL-EABI-NOT: attributes #{{[0-9]+}} = { {{.*}}"instrument-function-entry-inlined"="\01__gnu_mcount_nc"{{.*}} }
+// CHECK-ARM64-BAREMETAL-EABI: attributes #{{[0-9]+}} = { {{.*}}"instrument-function-entry-inlined"="mcount"{{.*}} }
+// CHECK-ARM64-BAREMETAL-EABI-MEABI-GNU: attributes #{{[0-9]+}} = { {{.*}}"instrument-function-entry-inlined"="\01_mcount"{{.*}} }
+// CHECK-ARM-IOS-NOT: attributes #{{[0-9]+}} = { {{.*}}"instrument-function-entry-inlined"="_mcount"{{.*}} }
+// CHECK-ARM-IOS-NOT: attributes #{{[0-9]+}} = { {{.*}}"instrument-function-entry-inlined"="\01__gnu_mcount_nc"{{.*}} }
+// CHECK-ARM-EABI: attributes #{{[0-9]+}} = { {{.*}}"instrument-function-entry-inlined"="\01mcount"{{.*}} }
+// CHECK-ARM-EABI-NOT: attributes #{{[0-9]+}} = { {{.*}}"instrument-function-entry-inlined"="\01__gnu_mcount_nc"{{.*}} }
+// CHECK-ARM64-EABI: attributes #{{[0-9]+}} = { {{.*}}"instrument-function-entry-inlined"="mcount"{{.*}} }
+// CHECK-ARM64-EABI-MEABI-GNU: attributes #{{[0-9]+}} = { {{.*}}"instrument-function-entry-inlined"="\01_mcount"{{.*}} }
+// CHECK-ARM64-EABI-NOT: attributes #{{[0-9]+}} = { {{.*}}"instrument-function-entry-inlined"="\01__gnu_mcount_nc"{{.*}} }
+// CHECK-ARM64-EABI-LINUX: attributes #{{[0-9]+}} = { {{.*}}"instrument-function-entry-inlined"="\01_mcount"{{.*}} }
+// CHECK-ARM-EABI-FREEBSD: attributes #{{[0-9]+}} = { {{.*}}"instrument-function-entry-inlined"="__mcount"{{.*}} }
+// CHECK-ARM-EABI-FREEBSD-NOT: attributes #{{[0-9]+}} = { {{.*}}"instrument-function-entry-inlined"="\01__gnu_mcount_nc"{{.*}} }
+// CHECK-ARM64-EABI-FREEBSD: attributes #{{[0-9]+}} = { {{.*}}"instrument-function-entry-inlined"=".mcount"{{.*}} }
+// CHECK-ARM64-EABI-FREEBSD-NOT: attributes #{{[0-9]+}} = { {{.*}}"instrument-function-entry-inlined"="\01__gnu_mcount_nc"{{.*}} }
+// CHECK-ARM-EABI-NETBSD: attributes #{{[0-9]+}} = { {{.*}}"instrument-function-entry-inlined"="_mcount"{{.*}} }
+// CHECK-ARM-EABI-NETBSD-NOT: attributes #{{[0-9]+}} = { {{.*}}"instrument-function-entry-inlined"="\01__gnu_mcount_nc"{{.*}} }
+// CHECK-ARM-EABI-OPENBSD: attributes #{{[0-9]+}} = { {{.*}}"instrument-function-entry-inlined"="__mcount"{{.*}} }
+// CHECK-ARM-EABI-OPENBSD-NOT: attributes #{{[0-9]+}} = { {{.*}}"instrument-function-entry-inlined"="\01__gnu_mcount_nc"{{.*}} }
+// CHECK-ARM64-EABI-OPENBSD: attributes #{{[0-9]+}} = { {{.*}}"instrument-function-entry-inlined"="__mcount"{{.*}} }
+// CHECK-ARM64-EABI-OPENBSD-NOT: attributes #{{[0-9]+}} = { {{.*}}"instrument-function-entry-inlined"="\01__gnu_mcount_nc"{{.*}} }
+// CHECK-ARM-EABI-MEABI-GNU-NOT: attributes #{{[0-9]+}} = { {{.*}}"instrument-function-entry-inlined"="mcount"{{.*}} }
+// CHECK-ARM-EABI-MEABI-GNU: attributes #{{[0-9]+}} = { {{.*}}"instrument-function-entry-inlined"="\01__gnu_mcount_nc"{{.*}} }
+// CHECK-ARM-EABI-RTEMS: attributes #{{[0-9]+}} = { {{.*}}"instrument-function-entry-inlined"="mcount"{{.*}} }
+// CHECK-ARM-EABI-RTEMS-NOT: attributes #{{[0-9]+}} = { {{.*}}"instrument-function-entry-inlined"="\01__gnu_mcount_nc"{{.*}} }
+// CHECK-ARM64-EABI-RTEMS: attributes #{{[0-9]+}} = { {{.*}}"instrument-function-entry-inlined"="mcount"{{.*}} }
+// CHECK-ARM64-EABI-RTEMS-NOT: attributes #{{[0-9]+}} = { {{.*}}"instrument-function-entry-inlined"="\01__gnu_mcount_nc"{{.*}} }
+// CHECK-ARM-EABI-CLOUDABI: attributes #{{[0-9]+}} = { {{.*}}"instrument-function-entry-inlined"="mcount"{{.*}} }
+// CHECK-ARM-EABI-CLOUDABI-NOT: attributes #{{[0-9]+}} = { {{.*}}"instrument-function-entry-inlined"="\01__gnu_mcount_nc"{{.*}} }
+// CHECK-ARM64-EABI-CLOUDABI: attributes #{{[0-9]+}} = { {{.*}}"instrument-function-entry-inlined"="mcount"{{.*}} }
+// CHECK-ARM64-EABI-CLOUDABI-NOT: attributes #{{[0-9]+}} = { {{.*}}"instrument-function-entry-inlined"="\01__gnu_mcount_nc"{{.*}} }
diff --git a/test/Frontend/optimization-remark-extra-analysis.c b/test/Frontend/optimization-remark-extra-analysis.c
new file mode 100644
index 000000000000..1a8415e69cff
--- /dev/null
+++ b/test/Frontend/optimization-remark-extra-analysis.c
@@ -0,0 +1,11 @@
+// Test that the is*RemarkEnabled overrides are working properly. This remark
+// requiring extra analysis is only conditionally enabled.
+
+// RUN: %clang_cc1 %s -Rpass-missed=gvn -O2 -emit-llvm-only -verify
+
+int foo(int *x, int *y) {
+ int a = *x;
+ *y = 2;
+ // expected-remark@+1 {{load of type i32 not eliminated}}
+ return a + *x;
+}
diff --git a/test/Frontend/optimization-remark-options.c b/test/Frontend/optimization-remark-options.c
index a2d717a2422d..38dbbfbaccec 100644
--- a/test/Frontend/optimization-remark-options.c
+++ b/test/Frontend/optimization-remark-options.c
@@ -14,7 +14,7 @@ double foo(int N) {
// CHECK: {{.*}}:17:3: remark: loop not vectorized: cannot prove it is safe to reorder memory operations; allow reordering by specifying '#pragma clang loop vectorize(enable)' before the loop. If the arrays will always be independent specify '#pragma clang loop vectorize(assume_safety)' before the loop or provide the '__restrict__' qualifier with the independent array arguments. Erroneous results will occur if these options are incorrectly applied!
void foo2(int *dw, int *uw, int *A, int *B, int *C, int *D, int N) {
- for (int i = 0; i < N; i++) {
+ for (long i = 0; i < N; i++) {
dw[i] = A[i] + B[i - 1] + C[i - 2] + D[i - 3];
uw[i] = A[i] + B[i + 1] + C[i + 2] + D[i + 3];
}
diff --git a/test/Frontend/optimization-remark-with-hotness.c b/test/Frontend/optimization-remark-with-hotness.c
index 875fc75ae159..6d3ab0697a21 100644
--- a/test/Frontend/optimization-remark-with-hotness.c
+++ b/test/Frontend/optimization-remark-with-hotness.c
@@ -11,18 +11,22 @@
// RUN: -fprofile-instrument-use-path=%t.profdata -Rpass=inline \
// RUN: -Rpass-analysis=inline -Rpass-missed=inline \
// RUN: -fdiagnostics-show-hotness -verify
+// The clang version of the previous test.
+// RUN: %clang -target x86_64-apple-macosx10.9 %s -c -emit-llvm -o /dev/null \
+// RUN: -fprofile-instr-use=%t.profdata -Rpass=inline \
+// RUN: -Rpass-analysis=inline -Rpass-missed=inline \
+// RUN: -fdiagnostics-show-hotness -Xclang -verify
// RUN: %clang_cc1 -triple x86_64-apple-macosx10.9 -main-file-name \
// RUN: optimization-remark-with-hotness.c %s -emit-llvm-only \
// RUN: -fprofile-sample-use=%t-sample.profdata -Rpass=inline \
// RUN: -Rpass-analysis=inline -Rpass-missed=inline \
// RUN: -fdiagnostics-show-hotness -fdiagnostics-hotness-threshold=10 \
// RUN: -verify
-// The clang version of the previous test.
-// RUN: %clang -target x86_64-apple-macosx10.9 %s -c -emit-llvm -o /dev/null \
-// RUN: -fprofile-instr-use=%t.profdata -Rpass=inline \
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.9 -main-file-name \
+// RUN: optimization-remark-with-hotness.c %s -emit-llvm-only \
+// RUN: -fprofile-instrument-use-path=%t.profdata -Rpass=inline \
// RUN: -Rpass-analysis=inline -Rpass-missed=inline \
-// RUN: -fdiagnostics-show-hotness -fdiagnostics-hotness-threshold=10 \
-// RUN: -Xclang -verify
+// RUN: -fdiagnostics-show-hotness -fdiagnostics-hotness-threshold=10 -verify
// RUN: %clang_cc1 -triple x86_64-apple-macosx10.9 -main-file-name \
// RUN: optimization-remark-with-hotness.c %s -emit-llvm-only \
// RUN: -fprofile-instrument-use-path=%t.profdata -Rpass=inline \
@@ -56,14 +60,13 @@ void bar(int x) {
// THRESHOLD-NOT: hotness
// NO_PGO: '-fdiagnostics-show-hotness' requires profile-guided optimization information
// NO_PGO: '-fdiagnostics-hotness-threshold=' requires profile-guided optimization information
- // expected-remark@+2 {{foo should always be inlined (cost=always) (hotness: 30)}}
- // expected-remark@+1 {{foo inlined into bar (hotness: 30)}}
+ // expected-remark@+1 {{foo inlined into bar with cost=always (hotness:}}
sum += foo(x, x - 2);
}
int main(int argc, const char *argv[]) {
for (int i = 0; i < 30; i++)
- // expected-remark@+1 {{bar not inlined into main because it should never be inlined}}
+ // expected-remark@+1 {{bar not inlined into main because it should never be inlined (cost=never) (hotness:}}
bar(argc);
return sum;
}
diff --git a/test/Frontend/optimization-remark.c b/test/Frontend/optimization-remark.c
index 7c02233d6835..29eaa03243e0 100644
--- a/test/Frontend/optimization-remark.c
+++ b/test/Frontend/optimization-remark.c
@@ -42,9 +42,8 @@ float foz(int x, int y) { return x * y; }
// twice.
//
int bar(int j) {
-// expected-remark@+4 {{foz not inlined into bar because it should never be inlined (cost=never)}}
// expected-remark@+3 {{foz not inlined into bar because it should never be inlined (cost=never)}}
-// expected-remark@+2 {{foo should always be inlined}}
+// expected-remark@+2 {{foz not inlined into bar because it should never be inlined (cost=never)}}
// expected-remark@+1 {{foo inlined into bar}}
return foo(j, j - 2) * foz(j - 2, j);
}
diff --git a/test/Frontend/remove-file-on-signal.c b/test/Frontend/remove-file-on-signal.c
new file mode 100644
index 000000000000..95d9b105f092
--- /dev/null
+++ b/test/Frontend/remove-file-on-signal.c
@@ -0,0 +1,7 @@
+// RUN: rm -rf %t && mkdir -p %t && cd %t
+// RUN: not --crash %clang_cc1 %s -emit-llvm -o foo.ll
+// RUN: ls . | FileCheck %s --allow-empty
+// CHECK-NOT: foo.ll
+
+#pragma clang __debug crash
+FOO
diff --git a/test/Frontend/system-header-line-directive-ms-lineendings.c b/test/Frontend/system-header-line-directive-ms-lineendings.c
new file mode 100644
index 000000000000..8ed1e5401047
--- /dev/null
+++ b/test/Frontend/system-header-line-directive-ms-lineendings.c
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 %s -E -o - -I %S/Inputs -isystem %S/Inputs/SystemHeaderPrefix | FileCheck %s
+#include <noline.h>
+#include <line-directive-in-system.h>
+
+#include "line-directive.h"
+
+// This tests that the line numbers for the current file are correctly outputted
+// for the include-file-completed test case. This file should be CRLF.
+
+// CHECK: # 1 "{{.*}}system-header-line-directive-ms-lineendings.c" 2
+// CHECK: # 1 "{{.*}}noline.h" 1 3
+// CHECK: foo();
+// CHECK: # 3 "{{.*}}system-header-line-directive-ms-lineendings.c" 2
+// CHECK: # 1 "{{.*}}line-directive-in-system.h" 1 3
+// The "3" below indicates that "foo.h" is considered a system header.
+// CHECK: # 1 "foo.h" 3
+// CHECK: foo();
+// CHECK: # 4 "{{.*}}system-header-line-directive-ms-lineendings.c" 2
+// CHECK: # 1 "{{.*}}line-directive.h" 1
+// CHECK: # 10 "foo.h"{{$}}
+// CHECK: # 6 "{{.*}}system-header-line-directive-ms-lineendings.c" 2
diff --git a/test/Frontend/verify-prefixes.c b/test/Frontend/verify-prefixes.c
new file mode 100644
index 000000000000..c5b545cf84c0
--- /dev/null
+++ b/test/Frontend/verify-prefixes.c
@@ -0,0 +1,118 @@
+#if GC
+# define GCONST const
+#else
+# define GCONST
+#endif
+
+// gconst-note@8 {{variable 'glb' declared const here}}
+GCONST int glb = 5;
+
+
+// Check various correct prefix spellings and combinations.
+//
+// RUN: %clang_cc1 -DGC -verify=gconst %s
+// RUN: %clang_cc1 -Wcast-qual -DLC -verify=lconst %s
+// RUN: %clang_cc1 -DSC -verify=expected %s
+// RUN: %clang_cc1 -DSC -verify %s
+// RUN: %clang_cc1 -DSC -verify -verify %s
+// RUN: %clang_cc1 -verify=nconst %s
+// RUN: %clang_cc1 -verify=n-const %s
+// RUN: %clang_cc1 -verify=n_const %s
+// RUN: %clang_cc1 -verify=NConst %s
+// RUN: %clang_cc1 -verify=NConst2 %s
+// RUN: %clang_cc1 -Wcast-qual -DGC -DLC -verify=gconst,lconst %s
+// RUN: %clang_cc1 -Wcast-qual -DGC -DLC -DSC -verify=gconst,lconst,expected %s
+// RUN: %clang_cc1 -Wcast-qual -DGC -DLC -verify=gconst -verify=lconst %s
+// RUN: %clang_cc1 -Wcast-qual -DGC -DLC -DSC -verify=gconst,lconst -verify %s
+// RUN: %clang_cc1 -DGC -DSC -verify -verify=gconst -verify %s
+//
+// Duplicate prefixes.
+// RUN: %clang_cc1 -Wcast-qual -DGC -DLC -verify=gconst,lconst,gconst %s
+// RUN: %clang_cc1 -DGC -verify=gconst -verify=gconst,gconst %s
+// RUN: %clang_cc1 -DSC -verify=expected -verify=expected %s
+// RUN: %clang_cc1 -DSC -verify -verify=expected %s
+//
+// Various tortured cases: multiple directives with different prefixes per
+// line, prefixes used as comments, prefixes prefixing prefixes, and prefixes
+// with special suffixes.
+// RUN: %clang_cc1 -Wcast-qual -DLC -verify=foo %s
+// RUN: %clang_cc1 -DSC -verify=bar %s
+// RUN: %clang_cc1 -Wcast-qual -DLC -DSC -verify=foo,bar %s
+// RUN: %clang_cc1 -Wcast-qual -DLC -DSC -verify=bar,foo %s
+// RUN: %clang_cc1 -DSC -verify=foo-bar %s
+// RUN: %clang_cc1 -Wcast-qual -DLC -verify=bar-foo %s
+// RUN: %clang_cc1 -Wcast-qual -DLC -DSC -verify=foo,foo-bar %s
+// RUN: %clang_cc1 -Wcast-qual -DLC -DSC -verify=foo-bar,foo %s
+// RUN: %clang_cc1 -Wcast-qual -DLC -DSC -verify=bar,bar-foo %s
+// RUN: %clang_cc1 -Wcast-qual -DLC -DSC -verify=bar-foo,bar %s
+// RUN: %clang_cc1 -Wcast-qual -DLC -DSC -verify=foo-bar,bar-foo %s
+// RUN: %clang_cc1 -DSC -verify=foo-warning %s
+// RUN: %clang_cc1 -Wcast-qual -DLC -verify=bar-warning-re %s
+// RUN: %clang_cc1 -Wcast-qual -DLC -DSC -verify=foo,foo-warning %s
+// RUN: %clang_cc1 -Wcast-qual -DLC -DSC -verify=foo-warning,foo %s
+// RUN: %clang_cc1 -Wcast-qual -DLC -DSC -verify=bar,bar-warning-re %s
+// RUN: %clang_cc1 -Wcast-qual -DLC -DSC -verify=bar-warning-re,bar %s
+
+
+// Check invalid prefixes. Check that there's no additional output, which
+// might indicate that diagnostic verification became enabled even though it
+// was requested incorrectly. Check that prefixes are reported in command-line
+// order.
+//
+// RUN: not %clang_cc1 -verify=5abc,-xy,foo,_k -verify='#a,b$' %s 2> %t
+// RUN: FileCheck --check-prefixes=ERR %s < %t
+//
+// ERR-NOT: {{.}}
+// ERR: error: invalid value '5abc' in '-verify='
+// ERR-NEXT: note: -verify prefixes must start with a letter and contain only alphanumeric characters, hyphens, and underscores
+// ERR-NEXT: error: invalid value '-xy' in '-verify='
+// ERR-NEXT: note: -verify prefixes must start with a letter and contain only alphanumeric characters, hyphens, and underscores
+// ERR-NEXT: error: invalid value '_k' in '-verify='
+// ERR-NEXT: note: -verify prefixes must start with a letter and contain only alphanumeric characters, hyphens, and underscores
+// ERR-NEXT: error: invalid value '#a' in '-verify='
+// ERR-NEXT: note: -verify prefixes must start with a letter and contain only alphanumeric characters, hyphens, and underscores
+// ERR-NEXT: error: invalid value 'b$' in '-verify='
+// ERR-NEXT: note: -verify prefixes must start with a letter and contain only alphanumeric characters, hyphens, and underscores
+// ERR-NOT: {{.}}
+
+
+// Check that our test code actually has expected diagnostics when there's no
+// -verify.
+//
+// RUN: not %clang_cc1 -Wcast-qual -DGC -DLC -DSC %s 2> %t
+// RUN: FileCheck --check-prefix=ALL %s < %t
+//
+// ALL: cannot assign to variable 'glb' with const-qualified type 'const int'
+// ALL: variable 'glb' declared const here
+// ALL: cast from 'const int *' to 'int *' drops const qualifier
+// ALL: initializing 'int *' with an expression of type 'const int *' discards qualifiers
+
+
+#if LC
+# define LCONST const
+#else
+# define LCONST
+#endif
+
+#if SC
+# define SCONST const
+#else
+# define SCONST
+#endif
+
+void foo() {
+ LCONST int loc = 5;
+ SCONST static int sta = 5;
+ // We don't actually expect 1-2 occurrences of this error. We're just
+ // checking the parsing.
+ glb = 6; // gconst-error1-2 {{cannot assign to variable 'glb' with const-qualified type 'const int'}}
+ *(int*)(&loc) = 6; // lconst-warning {{cast from 'const int *' to 'int *' drops const qualifier}}
+ ; // Code, comments, and many directives with different prefixes per line, including cases where some prefixes (foo and bar) prefix others (such as foo-bar and bar-foo), such that some prefixes appear as normal comments and some have special suffixes (-warning and -re): foo-warning@-1 {{cast from 'const int *' to 'int *' drops const qualifier}} foo-bar-warning@+1 {{initializing 'int *' with an expression of type 'const int *' discards qualifiers}} foo-warning-warning@+1 {{initializing 'int *' with an expression of type 'const int *' discards qualifiers}} bar-warning-re-warning@-1 {{cast from 'const int *' to 'int *' drops const qualifier}} bar-foo-warning@-1 {{cast from 'const int *' to 'int *' drops const qualifier}} bar-warning@+1 {{initializing 'int *' with an expression of type 'const int *' discards qualifiers}}
+ int *p = &sta; // expected-warning {{initializing 'int *' with an expression of type 'const int *' discards qualifiers}}
+}
+
+// nconst-no-diagnostics
+// n-const-no-diagnostics
+// n_const-no-diagnostics
+// NConst-no-diagnostics
+// NConst2-no-diagnostics
diff --git a/test/Frontend/x86-target-cpu.c b/test/Frontend/x86-target-cpu.c
index 4e0db5568a93..b5103d238c9d 100644
--- a/test/Frontend/x86-target-cpu.c
+++ b/test/Frontend/x86-target-cpu.c
@@ -13,7 +13,9 @@
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-cpu skylake-avx512 -verify %s
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-cpu skx -verify %s
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-cpu cannonlake -verify %s
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-cpu icelake -verify %s
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-cpu knl -verify %s
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-cpu knm -verify %s
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-cpu bonnell -verify %s
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-cpu silvermont -verify %s
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-cpu k8 -verify %s
diff --git a/test/Headers/float16.c b/test/Headers/float16.c
new file mode 100644
index 000000000000..3b905adb33e9
--- /dev/null
+++ b/test/Headers/float16.c
@@ -0,0 +1,65 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c89 -ffreestanding %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c99 -ffreestanding %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c11 -ffreestanding %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -x c++ -ffreestanding %s
+// expected-no-diagnostics
+
+#define __STDC_WANT_IEC_60559_TYPES_EXT__
+#include <float.h>
+
+#ifndef FLT16_MIN_10_EXP
+ #error "Macro FLT16_MIN_10_EXP is missing."
+#elif FLT16_MIN_10_EXP > -13
+ #error "Macro FLT16_MIN_10_EXP is invalid."
+#endif
+
+_Static_assert(FLT16_MIN_10_EXP == __FLT16_MIN_10_EXP__, "");
+
+#ifndef FLT16_MIN_EXP
+ #error "Macro FLT16_MIN_EXP is missing."
+#elif FLT16_MIN_EXP > -14
+ #error "Macro FLT16_MIN_EXP is invalid."
+#endif
+
+_Static_assert(FLT16_MIN_EXP == __FLT16_MIN_EXP__, "");
+
+#ifndef FLT16_MAX_10_EXP
+ #error "Macro FLT16_MAX_10_EXP is missing."
+#elif FLT16_MAX_10_EXP < 4
+ #error "Macro FLT16_MAX_10_EXP is invalid."
+#endif
+
+_Static_assert(FLT16_MAX_10_EXP == __FLT16_MAX_10_EXP__, "");
+
+#ifndef FLT16_MAX_EXP
+ #error "Macro FLT16_MAX_EXP is missing."
+#elif FLT16_MAX_EXP < 15
+ #error "Macro FLT16_MAX_EXP is invalid."
+#endif
+
+_Static_assert(FLT16_MAX_EXP == __FLT16_MAX_EXP__, "");
+
+#ifndef FLT16_DECIMAL_DIG
+ #error "Macro FLT16_DECIMAL_DIG is missing."
+#elif FLT16_DECIMAL_DIG < 5
+ #error "Macro FLT16_DECIMAL_DIG is invalid."
+#endif
+
+_Static_assert(FLT16_DECIMAL_DIG == __FLT16_DECIMAL_DIG__, "");
+
+#ifndef FLT16_DIG
+ #error "Macro FLT16_DIG is missing."
+#elif FLT16_DIG < 3
+ #error "Macro FLT16_DIG is invalid."
+#endif
+
+_Static_assert(FLT16_DIG == __FLT16_DIG__, "");
+
+#ifndef FLT16_MANT_DIG
+ #error "Macro FLT16_MANT_DIG is missing."
+#elif FLT16_MANT_DIG < 11
+ #error "Macro FLT16_MANT_DIG is invalid."
+#endif
+
+_Static_assert(FLT16_MANT_DIG == __FLT16_MANT_DIG__, "");
+
diff --git a/test/Headers/mm3dnow.c b/test/Headers/mm3dnow.c
new file mode 100644
index 000000000000..255483cb9b83
--- /dev/null
+++ b/test/Headers/mm3dnow.c
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -fsyntax-only -ffreestanding %s -verify
+// RUN: %clang_cc1 -fsyntax-only -ffreestanding -x c++ %s -verify
+// expected-no-diagnostics
+
+#if defined(i386) || defined(__x86_64__)
+#include <mm3dnow.h>
+
+int __attribute__((__target__(("3dnow")))) foo(int a) {
+ _m_femms();
+ return 4;
+}
+
+__m64 __attribute__((__target__(("3dnowa")))) bar(__m64 a) {
+ return _m_pf2iw(a);
+}
+#endif
diff --git a/test/Headers/ms-intrin.cpp b/test/Headers/ms-intrin.cpp
index d410b1d95f50..b0fef9cc06a7 100644
--- a/test/Headers/ms-intrin.cpp
+++ b/test/Headers/ms-intrin.cpp
@@ -64,4 +64,8 @@ void f() {
#ifdef _M_ARM
__dmb(_ARM_BARRIER_ISHST);
#endif
+
+#ifdef _M_ARM64
+ __dmb(_ARM64_BARRIER_SY);
+#endif
}
diff --git a/test/Headers/stdarg.cpp b/test/Headers/stdarg.cpp
new file mode 100644
index 000000000000..502a0ddcb545
--- /dev/null
+++ b/test/Headers/stdarg.cpp
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -emit-llvm -std=c99 -x c %s -triple aarch64-linux -o - | FileCheck %s --check-prefix=AARCH64-C
+// RUN: %clang_cc1 -emit-llvm -std=c++17 -x c++ %s -triple aarch64-linux -o - | FileCheck %s --check-prefix=AARCH64-CXX
+// RUN: %clang_cc1 -emit-llvm -std=c99 -x c %s -triple x86_64-linux -o - | FileCheck %s --check-prefix=X86_64-C
+// RUN: %clang_cc1 -emit-llvm -std=c++17 -x c++ %s -triple x86_64-linux -o - | FileCheck %s --check-prefix=X86_64-CXX
+// RUN: %clang_cc1 -emit-llvm -std=c99 -x c %s -triple ppc64-linux -o - | FileCheck %s --check-prefix=PPC64-C
+// RUN: %clang_cc1 -emit-llvm -std=c++17 -x c++ %s -triple ppc64-linux -o - | FileCheck %s --check-prefix=PPC64-CXX
+// RUN: %clang_cc1 -emit-llvm -std=c99 -x c %s -triple armv7-apple-darwin9 -target-abi aapcs -o - | FileCheck %s --check-prefix=AAPCS-C
+// RUN: %clang_cc1 -emit-llvm -std=c++17 -x c++ %s -triple armv7-apple-darwin9 -target-abi aapcs -o - | FileCheck %s --check-prefix=AAPCS-CXX
+// RUN: %clang_cc1 -emit-llvm -std=c99 -x c %s -triple s390x-linux -o - | FileCheck %s --check-prefix=SYSTEMZ-C
+// RUN: %clang_cc1 -emit-llvm -std=c++17 -x c++ %s -triple s390x-linux -o - | FileCheck %s --check-prefix=SYSTEMZ-CXX
+// RUN: %clang_cc1 -emit-llvm -std=c99 -x c %s -triple le32-nacl -o - | FileCheck %s --check-prefix=PNACL-C
+// RUN: %clang_cc1 -emit-llvm -std=c++17 -x c++ %s -triple le32-nacl -o - | FileCheck %s --check-prefix=PNACL-CXX
+// RUN: %clang_cc1 -emit-llvm -std=c99 -x c %s -triple i686-linux -o - | FileCheck %s --check-prefix=CHARPTR-C
+// RUN: %clang_cc1 -emit-llvm -std=c++17 -x c++ %s -triple i686-linux -o - | FileCheck %s --check-prefix=CHARPTR-CXX
+// RUN: %clang_cc1 -emit-llvm -std=c99 -x c %s -triple xcore -o - | FileCheck %s --check-prefix=VOIDPTR-C
+// RUN: %clang_cc1 -emit-llvm -std=c++17 -x c++ %s -triple xcore -o - | FileCheck %s --check-prefix=VOIDPTR-CXX
+
+#include <stdarg.h>
+
+// AARCH64-C: define {{.*}} @f(i32 %n, %struct.__va_list* %list)
+// AARCH64-CXX: define {{.*}} @_Z1fiSt9__va_list(i32 %n, %"struct.std::__va_list"* %list)
+// X86_64-C: define {{.*}} @f(i32 %n, %struct.__va_list_tag* %list)
+// X86_64-CXX: define {{.*}} @_Z1fiP13__va_list_tag(i32 %n, %struct.__va_list_tag* %list)
+// PPC64-C: define {{.*}} @f(i32 signext %n, i8* %list)
+// PPC64-CXX: define {{.*}} @_Z1fiPc(i32 signext %n, i8* %list)
+// AAPCS-C: define {{.*}} @f(i32 %n, [1 x i32] %list.coerce)
+// AAPCS-CXX: define {{.*}} @_Z1fiSt9__va_list(i32 %n, [1 x i32] %list.coerce)
+// SYSTEMZ-C: define {{.*}} @f(i32 signext %n, %struct.__va_list_tag* %list)
+// SYSTEMZ-CXX: define {{.*}} @_Z1fiP13__va_list_tag(i32 signext %n, %struct.__va_list_tag* %list)
+// PNACL-C: define {{.*}} @f(i32 %n, i32* %list)
+// PNACL-CXX: define {{.*}} @_Z1fiPi(i32 %n, i32* %list)
+// CHARPTR-C: define {{.*}} @f(i32 %n, i8* %list)
+// CHARPTR-CXX: define {{.*}} @_Z1fiPc(i32 %n, i8* %list)
+// VOIDPTR-C: define {{.*}} @f(i32 %n, i8* %list)
+// VOIDPTR-CXX: define {{.*}} @_Z1fiPv(i32 %n, i8* %list)
+void f(int n, va_list list) {}
diff --git a/test/Headers/stdbool.cpp b/test/Headers/stdbool.cpp
index 7c927db441b2..0110a45b2dc6 100644
--- a/test/Headers/stdbool.cpp
+++ b/test/Headers/stdbool.cpp
@@ -1,13 +1,19 @@
-// RUN: %clang_cc1 -E -dM %s | FileCheck --check-prefix=CHECK-GNU-COMPAT %s
+// RUN: %clang_cc1 -std=gnu++98 -E -dM %s | FileCheck --check-prefix=CHECK-GNU-COMPAT-98 %s
+// RUN: %clang_cc1 -std=gnu++11 -E -dM %s | FileCheck --check-prefix=CHECK-GNU-COMPAT-11 %s
// RUN: %clang_cc1 -std=c++98 -E -dM %s | FileCheck --check-prefix=CHECK-CONFORMING %s
// RUN: %clang_cc1 -fsyntax-only -std=gnu++98 -verify -Weverything %s
#include <stdbool.h>
#define zzz
-// CHECK-GNU-COMPAT: #define _Bool bool
-// CHECK-GNU-COMPAT: #define bool bool
-// CHECK-GNU-COMPAT: #define false false
-// CHECK-GNU-COMPAT: #define true true
+// CHECK-GNU-COMPAT-98: #define _Bool bool
+// CHECK-GNU-COMPAT-98: #define bool bool
+// CHECK-GNU-COMPAT-98: #define false false
+// CHECK-GNU-COMPAT-98: #define true true
+
+// CHECK-GNU-COMPAT-11: #define _Bool bool
+// CHECK-GNU-COMPAT-11-NOT: #define bool bool
+// CHECK-GNU-COMPAT-11-NOT: #define false false
+// CHECK-GNU-COMPAT-11-NOT: #define true true
// CHECK-CONFORMING-NOT: #define _Bool
// CHECK-CONFORMING: #define __CHAR_BIT__
diff --git a/test/Headers/wchar_limits.cpp b/test/Headers/wchar_limits.cpp
index 35ae7affb514..7393e32745ee 100644
--- a/test/Headers/wchar_limits.cpp
+++ b/test/Headers/wchar_limits.cpp
@@ -1,5 +1,5 @@
// RUN: %clang_cc1 -ffreestanding -fsyntax-only -verify %s
-// RUN: %clang_cc1 -ffreestanding -fsyntax-only -verify -fshort-wchar %s
+// RUN: %clang_cc1 -ffreestanding -fsyntax-only -verify -fwchar-type=short -fno-signed-wchar %s
// expected-no-diagnostics
#include <stdint.h>
diff --git a/test/Import/extern-c-function/Inputs/F.cpp b/test/Import/extern-c-function/Inputs/F.cpp
new file mode 100644
index 000000000000..c417d5630260
--- /dev/null
+++ b/test/Import/extern-c-function/Inputs/F.cpp
@@ -0,0 +1,3 @@
+extern "C" {
+ void f(int arg);
+}
diff --git a/test/Import/extern-c-function/test.cpp b/test/Import/extern-c-function/test.cpp
new file mode 100644
index 000000000000..50227cdf9c2b
--- /dev/null
+++ b/test/Import/extern-c-function/test.cpp
@@ -0,0 +1,4 @@
+// RUN: clang-import-test -import %S/Inputs/F.cpp -expression %s
+void expr() {
+ f(2);
+} \ No newline at end of file
diff --git a/test/Import/forward-declared-objc-class/Inputs/S1.m b/test/Import/forward-declared-objc-class/Inputs/S1.m
new file mode 100644
index 000000000000..b9305d7e89f1
--- /dev/null
+++ b/test/Import/forward-declared-objc-class/Inputs/S1.m
@@ -0,0 +1 @@
+@class MyClass; \ No newline at end of file
diff --git a/test/Import/forward-declared-objc-class/Inputs/S2.m b/test/Import/forward-declared-objc-class/Inputs/S2.m
new file mode 100644
index 000000000000..69d067a3bdbb
--- /dev/null
+++ b/test/Import/forward-declared-objc-class/Inputs/S2.m
@@ -0,0 +1,6 @@
+@interface MyClass {
+ int j;
+};
++(MyClass*)fromInteger:(int)_j;
+-(int)getInteger;
+@end \ No newline at end of file
diff --git a/test/Import/forward-declared-objc-class/Inputs/S3.m b/test/Import/forward-declared-objc-class/Inputs/S3.m
new file mode 100644
index 000000000000..b9305d7e89f1
--- /dev/null
+++ b/test/Import/forward-declared-objc-class/Inputs/S3.m
@@ -0,0 +1 @@
+@class MyClass; \ No newline at end of file
diff --git a/test/Import/forward-declared-objc-class/test.m b/test/Import/forward-declared-objc-class/test.m
new file mode 100644
index 000000000000..098818be3cb0
--- /dev/null
+++ b/test/Import/forward-declared-objc-class/test.m
@@ -0,0 +1,6 @@
+// RUN: clang-import-test -x objective-c++ -import %S/Inputs/S1.m --import %S/Inputs/S2.m --import %S/Inputs/S3.m -expression %s
+void expr() {
+ MyClass *c = [MyClass fromInteger:3];
+ const int i = [c getInteger];
+ const int j = c->j;
+}
diff --git a/test/Import/forward-declared-struct/Inputs/S3.c b/test/Import/forward-declared-struct/Inputs/S3.c
new file mode 100644
index 000000000000..28377c2760ba
--- /dev/null
+++ b/test/Import/forward-declared-struct/Inputs/S3.c
@@ -0,0 +1 @@
+struct S;
diff --git a/test/Import/forward-declared-struct/test.c b/test/Import/forward-declared-struct/test.c
index 7ccdcf9e97d0..8199aa267d54 100644
--- a/test/Import/forward-declared-struct/test.c
+++ b/test/Import/forward-declared-struct/test.c
@@ -1,4 +1,4 @@
-// RUN: clang-import-test -import %S/Inputs/S1.c --import %S/Inputs/S2.c -expression %s
+// RUN: clang-import-test -import %S/Inputs/S1.c --import %S/Inputs/S2.c --import %S/Inputs/S3.c -expression %s
void expr() {
struct S MyS;
MyS.a = 3;
diff --git a/test/Import/local-struct-use-origins/Inputs/Callee.cpp b/test/Import/local-struct-use-origins/Inputs/Callee.cpp
new file mode 100644
index 000000000000..96cd2f22e493
--- /dev/null
+++ b/test/Import/local-struct-use-origins/Inputs/Callee.cpp
@@ -0,0 +1,12 @@
+struct Bar {
+ void bar(int _a, bool _b) {
+ {
+ struct S { int a; };
+ S s = { _a };
+ }
+ {
+ struct S { bool b; };
+ S t = { _b };
+ }
+ };
+};
diff --git a/test/Import/local-struct-use-origins/test.cpp b/test/Import/local-struct-use-origins/test.cpp
new file mode 100644
index 000000000000..abbdbd16d022
--- /dev/null
+++ b/test/Import/local-struct-use-origins/test.cpp
@@ -0,0 +1,7 @@
+// RUN: clang-import-test -dump-ir -use-origins -import %S/Inputs/Callee.cpp -expression %s | FileCheck %s
+// CHECK: %struct.S = type { i
+// CHECK: %struct.S.0 = type { i
+
+void foo() {
+ return Bar().bar(3, true);
+}
diff --git a/test/Import/local-struct/Inputs/Callee.cpp b/test/Import/local-struct/Inputs/Callee.cpp
new file mode 100644
index 000000000000..96cd2f22e493
--- /dev/null
+++ b/test/Import/local-struct/Inputs/Callee.cpp
@@ -0,0 +1,12 @@
+struct Bar {
+ void bar(int _a, bool _b) {
+ {
+ struct S { int a; };
+ S s = { _a };
+ }
+ {
+ struct S { bool b; };
+ S t = { _b };
+ }
+ };
+};
diff --git a/test/Import/local-struct/test.cpp b/test/Import/local-struct/test.cpp
new file mode 100644
index 000000000000..1e838477a007
--- /dev/null
+++ b/test/Import/local-struct/test.cpp
@@ -0,0 +1,7 @@
+// RUN: clang-import-test -dump-ir -import %S/Inputs/Callee.cpp -expression %s | FileCheck %s
+// CHECK: %struct.S = type { i
+// CHECK: %struct.S.0 = type { i
+
+void foo() {
+ return Bar().bar(3, true);
+}
diff --git a/test/Import/objc-definitions-in-expression/Inputs/S.m b/test/Import/objc-definitions-in-expression/Inputs/S.m
new file mode 100644
index 000000000000..cf8ffaa602a8
--- /dev/null
+++ b/test/Import/objc-definitions-in-expression/Inputs/S.m
@@ -0,0 +1,4 @@
+@interface C {
+}
+-(int)m;
+@end
diff --git a/test/Import/objc-definitions-in-expression/test.m b/test/Import/objc-definitions-in-expression/test.m
new file mode 100644
index 000000000000..0c9984731d19
--- /dev/null
+++ b/test/Import/objc-definitions-in-expression/test.m
@@ -0,0 +1,21 @@
+// RUN: clang-import-test -x objective-c++ -import %S/Inputs/S.m -expression %s
+@class D;
+
+@interface B {
+ int x;
+ int y;
+}
+@end
+
+@interface D : B {
+ int z;
+}
+-(int)n;
+@end
+
+void expr() {
+ C *c;
+ int i = [c m];
+ D *d;
+ int j = [d n] + d->x;
+}
diff --git a/test/Import/objc-method/Inputs/S.m b/test/Import/objc-method/Inputs/S.m
new file mode 100644
index 000000000000..cf8ffaa602a8
--- /dev/null
+++ b/test/Import/objc-method/Inputs/S.m
@@ -0,0 +1,4 @@
+@interface C {
+}
+-(int)m;
+@end
diff --git a/test/Import/objc-method/test.m b/test/Import/objc-method/test.m
new file mode 100644
index 000000000000..7707110d8249
--- /dev/null
+++ b/test/Import/objc-method/test.m
@@ -0,0 +1,5 @@
+// RUN: clang-import-test -x objective-c++ -import %S/Inputs/S.m -expression %s
+void expr() {
+ C *c;
+ int i = [c m];
+}
diff --git a/test/Import/struct-and-var/Inputs/S1.cpp b/test/Import/struct-and-var/Inputs/S1.cpp
new file mode 100644
index 000000000000..9678b94102ee
--- /dev/null
+++ b/test/Import/struct-and-var/Inputs/S1.cpp
@@ -0,0 +1 @@
+int F;
diff --git a/test/Import/struct-and-var/Inputs/S2.cpp b/test/Import/struct-and-var/Inputs/S2.cpp
new file mode 100644
index 000000000000..3f0ad8e16024
--- /dev/null
+++ b/test/Import/struct-and-var/Inputs/S2.cpp
@@ -0,0 +1,3 @@
+struct F {
+ int a;
+};
diff --git a/test/Import/struct-and-var/test.cpp b/test/Import/struct-and-var/test.cpp
new file mode 100644
index 000000000000..76f539e41f9f
--- /dev/null
+++ b/test/Import/struct-and-var/test.cpp
@@ -0,0 +1,5 @@
+// RUN: clang-import-test --import %S/Inputs/S1.cpp --import %S/Inputs/S2.cpp -expression %s
+void expr() {
+ struct F f;
+ int x = f.a;
+}
diff --git a/test/Import/struct-layout/Inputs/Callee.cpp b/test/Import/struct-layout/Inputs/Callee.cpp
new file mode 100644
index 000000000000..62422af6c2de
--- /dev/null
+++ b/test/Import/struct-layout/Inputs/Callee.cpp
@@ -0,0 +1,9 @@
+struct S {
+ int a;
+};
+
+struct Bar {
+ void bar(int _a) {
+ S s = { _a };
+ };
+};
diff --git a/test/Import/struct-layout/test.cpp b/test/Import/struct-layout/test.cpp
new file mode 100644
index 000000000000..698d0609fa05
--- /dev/null
+++ b/test/Import/struct-layout/test.cpp
@@ -0,0 +1,6 @@
+// RUN: clang-import-test -dump-ir -import %S/Inputs/Callee.cpp -expression %s | FileCheck %s
+// CHECK: %struct.S = type { i
+
+void foo() {
+ return Bar().bar(3);
+}
diff --git a/test/Import/template/Inputs/T.cpp b/test/Import/template/Inputs/T.cpp
new file mode 100644
index 000000000000..2499936788a4
--- /dev/null
+++ b/test/Import/template/Inputs/T.cpp
@@ -0,0 +1,5 @@
+template <typename T> struct A {
+ struct B {
+ T f;
+ };
+};
diff --git a/test/Import/template/test.cpp b/test/Import/template/test.cpp
new file mode 100644
index 000000000000..89cbda8b92fb
--- /dev/null
+++ b/test/Import/template/test.cpp
@@ -0,0 +1,4 @@
+// RUN: clang-import-test -import %S/Inputs/T.cpp -expression %s
+void expr() {
+ A<int>::B b;
+}
diff --git a/test/Index/Core/index-dependent-source.cpp b/test/Index/Core/index-dependent-source.cpp
index 59c6286cd3dd..2e111339af61 100644
--- a/test/Index/Core/index-dependent-source.cpp
+++ b/test/Index/Core/index-dependent-source.cpp
@@ -158,3 +158,69 @@ void infiniteTraitRecursion(Trait<T> &t) {
// Shouldn't crash!
t.lookup;
}
+
+template <typename T>
+struct UsingA {
+// CHECK: [[@LINE+1]]:15 | type-alias/C | Type | c:index-dependent-source.cpp@ST>1#T@UsingA@T@Type | <no-cgname> | Def,RelChild | rel: 1
+ typedef int Type;
+// CHECK: [[@LINE+1]]:15 | static-method/C++ | func | c:@ST>1#T@UsingA@F@func#S | <no-cgname> | Decl,RelChild | rel: 1
+ static void func();
+// CHECK: [[@LINE+1]]:8 | instance-method/C++ | operator() | c:@ST>1#T@UsingA@F@operator()#I# | <no-cgname> | Decl,RelChild | rel: 1
+ void operator()(int);
+// CHECK: [[@LINE+1]]:8 | instance-method/C++ | operator+ | c:@ST>1#T@UsingA@F@operator+#&1>@ST>1#T@UsingA1t0.0# | <no-cgname> | Decl,RelChild | rel: 1
+ void operator+(const UsingA &);
+};
+
+template <typename T>
+struct OtherUsing {};
+
+template <typename T>
+struct UsingB : public UsingA<T> {
+// CHECK: [[@LINE+2]]:40 | type-alias/C | TypeB | c:index-dependent-source.cpp@ST>1#T@UsingB@T@TypeB | <no-cgname> | Def,RelChild | rel: 1
+// CHECK: [[@LINE+1]]:20 | struct(Gen)/C++ | OtherUsing | c:@ST>1#T@OtherUsing | <no-cgname> | Ref,RelCont | rel: 1
+ typedef typename OtherUsing<T>::Type TypeB;
+// CHECK: [[@LINE+2]]:29 | using/using-typename(Gen)/C++ | Type | c:index-dependent-source.cpp@ST>1#T@UsingB@UUT@UsingA<T>::Type | <no-cgname> | Decl,RelChild | rel: 1
+// CHECK: [[@LINE+1]]:18 | struct(Gen)/C++ | UsingA | c:@ST>1#T@UsingA | <no-cgname> | Ref,RelCont | rel: 1
+ using typename UsingA<T>::Type;
+// CHECK: [[@LINE+2]]:20 | using/using-value(Gen)/C++ | func | c:index-dependent-source.cpp@ST>1#T@UsingB@UUV@UsingA<T>::func | <no-cgname> | Decl,RelChild | rel: 1
+// CHECK: [[@LINE+1]]:9 | struct(Gen)/C++ | UsingA | c:@ST>1#T@UsingA | <no-cgname> | Ref,RelCont | rel: 1
+ using UsingA<T>::func;
+
+// CHECK: [[@LINE+2]]:20 | using/using-value(Gen)/C++ | operator() | c:index-dependent-source.cpp@ST>1#T@UsingB@UUV@UsingA<T>::operator() | <no-cgname> | Decl,RelChild | rel: 1
+// CHECK: [[@LINE+1]]:9 | struct(Gen)/C++ | UsingA | c:@ST>1#T@UsingA | <no-cgname> | Ref,RelCont | rel: 1
+ using UsingA<T>::operator();
+// CHECK: [[@LINE+2]]:20 | using/using-value(Gen)/C++ | operator+ | c:index-dependent-source.cpp@ST>1#T@UsingB@UUV@UsingA<T>::operator+ | <no-cgname> | Decl,RelChild | rel: 1
+// CHECK: [[@LINE+1]]:9 | struct(Gen)/C++ | UsingA | c:@ST>1#T@UsingA | <no-cgname> | Ref,RelCont | rel: 1
+ using UsingA<T>::operator+;
+};
+
+template <typename T>
+struct UsingC : public UsingB<T> {
+ static void test() {
+// CHECK: [[@LINE+2]]:25 | type-alias/C | TypeB | c:index-dependent-source.cpp@ST>1#T@UsingB@T@TypeB | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK: [[@LINE+1]]:14 | struct(Gen)/C++ | UsingB | c:@ST>1#T@UsingB | <no-cgname> | Ref,RelCont | rel: 1
+ typename UsingB<T>::TypeB value1;
+// CHECK: [[@LINE+2]]:25 | using/using-typename(Gen)/C++ | Type | c:index-dependent-source.cpp@ST>1#T@UsingB@UUT@UsingA<T>::Type | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK: [[@LINE+1]]:14 | struct(Gen)/C++ | UsingB | c:@ST>1#T@UsingB | <no-cgname> | Ref,RelCont | rel: 1
+ typename UsingB<T>::Type value2;
+// CHECK: [[@LINE+2]]:16 | using/using-value(Gen)/C++ | func | c:index-dependent-source.cpp@ST>1#T@UsingB@UUV@UsingA<T>::func | <no-cgname> | Ref,Call,RelCall,RelCont | rel: 1
+// CHECK: [[@LINE+1]]:5 | struct(Gen)/C++ | UsingB | c:@ST>1#T@UsingB | <no-cgname> | Ref,RelCont | rel: 1
+ UsingB<T>::func();
+ }
+};
+
+template <typename T>
+struct UsingD {
+// CHECK: [[@LINE+1]]:8 | instance-method/C++ | foo | c:@ST>1#T@UsingD@F@foo#t0.0# | <no-cgname> | Decl,RelChild | rel: 1
+ void foo(T);
+};
+
+template <typename T, typename U>
+struct UsingE : public UsingD<T>, public UsingD<U> {
+// CHECK: [[@LINE+2]]:20 | using/using-value(Gen)/C++ | foo | c:index-dependent-source.cpp@ST>2#T#T@UsingE@UUV@UsingD<T>::foo | <no-cgname> | Decl,RelChild | rel: 1
+// CHECK: [[@LINE+1]]:9 | struct(Gen)/C++ | UsingD | c:@ST>1#T@UsingD | <no-cgname> | Ref,RelCont | rel: 1
+ using UsingD<T>::foo;
+// CHECK: [[@LINE+2]]:20 | using/using-value(Gen)/C++ | foo | c:index-dependent-source.cpp@ST>2#T#T@UsingE@UUV@UsingD<U>::foo | <no-cgname> | Decl,RelChild | rel: 1
+// CHECK: [[@LINE+1]]:9 | struct(Gen)/C++ | UsingD | c:@ST>1#T@UsingD | <no-cgname> | Ref,RelCont | rel: 1
+ using UsingD<U>::foo;
+};
diff --git a/test/Index/Core/index-source.cpp b/test/Index/Core/index-source.cpp
index 4864d6cf0150..6f485feb47c5 100644
--- a/test/Index/Core/index-source.cpp
+++ b/test/Index/Core/index-source.cpp
@@ -201,8 +201,8 @@ class PseudoOverridesInSpecializations<double, int> {
template<typename U>
class InnerClass;
-// CHECK: [[@LINE-1]]:9 | class(Gen)/C++ | InnerClass | c:@S@PseudoOverridesInSpecializations>#d#I@ST>1#T@InnerClass | <no-cgname> | Ref,RelCont,RelSpecialization | rel: 2
-// CHECK-NEXT: RelCont
+// CHECK: [[@LINE-1]]:9 | class(Gen)/C++ | InnerClass | c:@S@PseudoOverridesInSpecializations>#d#I@ST>1#T@InnerClass | <no-cgname> | Decl,RelChild,RelSpecialization | rel: 2
+// CHECK-NEXT: RelChild
// CHECK-NEXT: RelSpecialization | InnerClass | c:@ST>2#T#T@PseudoOverridesInSpecializations@ST>1#T@InnerClass
};
@@ -274,7 +274,7 @@ void ContainsSpecializedMemberFunction::memberSpecialization<int>() {
template<typename T>
class SpecializationDecl;
-// CHECK: [[@LINE-1]]:7 | class(Gen)/C++ | SpecializationDecl | c:@ST>1#T@SpecializationDecl | <no-cgname> | Ref | rel: 0
+// CHECK: [[@LINE-1]]:7 | class(Gen)/C++ | SpecializationDecl | c:@ST>1#T@SpecializationDecl | <no-cgname> | Decl | rel: 0
template<typename T>
class SpecializationDecl { };
@@ -497,6 +497,19 @@ void localStructuredBindingAndRef() {
}
+template<typename T>
+struct Guided { T t; };
+// CHECK: [[@LINE-1]]:8 | struct(Gen)/C++ | Guided | c:@ST>1#T@Guided | <no-cgname> | Def | rel: 0
+// CHECK-NEXT: [[@LINE-2]]:19 | field/C++ | t | c:@ST>1#T@Guided@FI@t | <no-cgname> | Def,RelChild | rel: 1
+// CHECK-NEXT: RelChild | Guided | c:@ST>1#T@Guided
+Guided(double) -> Guided<float>;
+// CHECK: [[@LINE-1]]:19 | struct(Gen)/C++ | Guided | c:@ST>1#T@Guided | <no-cgname> | Ref | rel: 0
+// CHECK-NEXT: [[@LINE-2]]:1 | struct(Gen)/C++ | Guided | c:@ST>1#T@Guided | <no-cgname> | Ref | rel: 0
+auto guided = Guided{1.0};
+// CHECK: [[@LINE-1]]:6 | variable/C | guided | c:@guided | _guided | Def | rel: 0
+// CHECK-NEXT: [[@LINE-2]]:15 | struct(Gen)/C++ | Guided | c:@ST>1#T@Guided | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK-NEXT: RelCont | guided | c:@guided
+
namespace rd33122110 {
struct Outer {
@@ -512,3 +525,36 @@ struct rd33122110::Outer::Nested<int>;
// CHECK-NEXT: RelCont | Nested | c:@N@rd33122110@S@Outer@S@Nested>#I
// CHECK: [[@LINE-3]]:20 | struct/C++ | Outer | c:@N@rd33122110@S@Outer | <no-cgname> | Ref,RelCont | rel: 1
// CHECK-NEXT: RelCont | Nested | c:@N@rd33122110@S@Outer@S@Nested>#I
+
+namespace index_offsetof {
+
+struct Struct {
+ int field;
+};
+
+struct Struct2 {
+ Struct array[4][2];
+};
+
+void foo() {
+ __builtin_offsetof(Struct, field);
+// CHECK: [[@LINE-1]]:30 | field/C | field | c:@N@index_offsetof@S@Struct@FI@field | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK-NEXT: RelCont | foo | c:@N@index_offsetof@F@foo#
+ __builtin_offsetof(Struct2, array[1][0].field);
+// CHECK: [[@LINE-1]]:31 | field/C | array | c:@N@index_offsetof@S@Struct2@FI@array | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK-NEXT: RelCont | foo | c:@N@index_offsetof@F@foo#
+// CHECK: [[@LINE-3]]:43 | field/C | field | c:@N@index_offsetof@S@Struct@FI@field | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK-NEXT: RelCont | foo | c:@N@index_offsetof@F@foo#
+}
+
+#define OFFSET_OF_(X, Y) __builtin_offsetof(X, Y)
+
+class SubclassOffsetof : public Struct {
+ void foo() {
+ OFFSET_OF_(SubclassOffsetof, field);
+// CHECK: [[@LINE-1]]:34 | field/C | field | c:@N@index_offsetof@S@Struct@FI@field | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK-NEXT: RelCont | foo | c:@N@index_offsetof@S@SubclassOffsetof@F@foo#
+ }
+};
+
+}
diff --git a/test/Index/Core/index-source.m b/test/Index/Core/index-source.m
index 1333cafd7575..2931e664eac6 100644
--- a/test/Index/Core/index-source.m
+++ b/test/Index/Core/index-source.m
@@ -389,6 +389,15 @@ struct Separate separateE;
@interface ClassReceivers
@property(class) int p1;
+// CHECK: [[@LINE-1]]:22 | class-method/acc-get/ObjC | p1 | c:objc(cs)ClassReceivers(cm)p1 | +[ClassReceivers p1] | Decl,Dyn,Impl,RelChild,RelAcc | rel: 2
+// CHECK-NEXT: RelChild | ClassReceivers | c:objc(cs)ClassReceivers
+// CHECK-NEXT: RelAcc | p1 | c:objc(cs)ClassReceivers(cpy)p1
+// CHECK: [[@LINE-4]]:22 | class-method/acc-set/ObjC | setP1: | c:objc(cs)ClassReceivers(cm)setP1: | +[ClassReceivers setP1:] | Decl,Dyn,Impl,RelChild,RelAcc | rel: 2
+// CHECK-NEXT: RelChild | ClassReceivers | c:objc(cs)ClassReceivers
+// CHECK-NEXT: RelAcc | p1 | c:objc(cs)ClassReceivers(cpy)p1
+// CHECK: [[@LINE-7]]:22 | instance-property/ObjC | p1 | c:objc(cs)ClassReceivers(cpy)p1 | <no-cgname> | Decl,RelChild | rel: 1
+// CHECK-NEXT: RelChild | ClassReceivers | c:objc(cs)ClassReceivers
+
+ (int)implicit;
+ (void)setImplicit:(int)x;
@@ -399,13 +408,13 @@ void classReceivers() {
// CHECK: [[@LINE-1]]:3 | class/ObjC | ClassReceivers | c:objc(cs)ClassReceivers | _OBJC_CLASS_$_ClassReceivers | Ref,RelCont | rel: 1
// CHECK: [[@LINE-2]]:18 | instance-property/ObjC | p1 | c:objc(cs)ClassReceivers(cpy)p1 | <no-cgname> | Ref,Writ,RelCont | rel: 1
// CHECK-NEXT: RelCont | classReceivers | c:@F@classReceivers
-// CHECK: [[@LINE-4]]:18 | class-method/ObjC | setP1: | c:objc(cs)ClassReceivers(cm)setP1: | +[ClassReceivers setP1:] | Ref,Call,Impl,RelCall,RelCont | rel: 1
+// CHECK: [[@LINE-4]]:18 | class-method/acc-set/ObjC | setP1: | c:objc(cs)ClassReceivers(cm)setP1: | +[ClassReceivers setP1:] | Ref,Call,Impl,RelCall,RelCont | rel: 1
// CHECK-NEXT: RelCall,RelCont | classReceivers | c:@F@classReceivers
(void)ClassReceivers.p1;
// CHECK: [[@LINE-1]]:9 | class/ObjC | ClassReceivers | c:objc(cs)ClassReceivers | _OBJC_CLASS_$_ClassReceivers | Ref,RelCont | rel: 1
// CHECK: [[@LINE-2]]:24 | instance-property/ObjC | p1 | c:objc(cs)ClassReceivers(cpy)p1 | <no-cgname> | Ref,RelCont | rel: 1
// CHECK-NEXT: RelCont | classReceivers | c:@F@classReceivers
-// CHECK: [[@LINE-4]]:24 | class-method/ObjC | p1 | c:objc(cs)ClassReceivers(cm)p1 | +[ClassReceivers p1] | Ref,Call,Impl,RelCall,RelCont | rel: 1
+// CHECK: [[@LINE-4]]:24 | class-method/acc-get/ObjC | p1 | c:objc(cs)ClassReceivers(cm)p1 | +[ClassReceivers p1] | Ref,Call,Impl,RelCall,RelCont | rel: 1
// CHECK-NEXT: RelCall,RelCont | classReceivers | c:@F@classReceivers
ClassReceivers.implicit = 0;
diff --git a/test/Index/Inputs/record-parsing-invocation-remap.c b/test/Index/Inputs/record-parsing-invocation-remap.c
new file mode 100644
index 000000000000..4a32ca66ef08
--- /dev/null
+++ b/test/Index/Inputs/record-parsing-invocation-remap.c
@@ -0,0 +1,2 @@
+
+#pragma clang __debug parser_crash
diff --git a/test/Index/USR/array-type.cpp b/test/Index/USR/array-type.cpp
new file mode 100644
index 000000000000..40ff20d388a5
--- /dev/null
+++ b/test/Index/USR/array-type.cpp
@@ -0,0 +1,11 @@
+// RUN: c-index-test core -print-source-symbols -- %s | FileCheck %s
+
+// Function template specializations differing in array type parameter should have unique USRs.
+
+template<class buffer> void foo(buffer);
+// CHECK: {{[0-9]+}}:17 | function(Gen,TS)/C++ | foo | c:@F@foo<#{n16C>#*C#
+template<> void foo<char[16]>(char[16]);
+// CHECK: {{[0-9]+}}:17 | function(Gen,TS)/C++ | foo | c:@F@foo<#{n32C>#*C#
+template<> void foo<char[32]>(char[32]);
+// CHECK: {{[0-9]+}}:17 | function(Gen,TS)/C++ | foo | c:@F@foo<#{n64C>#*C#
+template<> void foo<char[64]>(char[64]);
diff --git a/test/Index/USR/func-type.cpp b/test/Index/USR/func-type.cpp
new file mode 100644
index 000000000000..ff1cd37a7fc4
--- /dev/null
+++ b/test/Index/USR/func-type.cpp
@@ -0,0 +1,18 @@
+// RUN: c-index-test core -print-source-symbols -- %s | FileCheck %s
+
+// Functions taking function pointer parameters with different signatures should result in unique USRs.
+
+typedef void (*_VoidToVoidPtr_)();
+typedef void (*_IntToVoidPtr_)( int );
+typedef _VoidToVoidPtr_ (*IntTo_VoidToVoidPtr_Ptr)( int );
+typedef _IntToVoidPtr_ (*VoidTo_IntToVoidPtr_Ptr)();
+
+void Func( IntTo_VoidToVoidPtr_Ptr );
+// CHECK: {{[0-9]+}}:6 | function/C | Func | c:@F@Func#*F*Fv()(#I)# |
+void Func( VoidTo_IntToVoidPtr_Ptr );
+// CHECK: {{[0-9]+}}:6 | function/C | Func | c:@F@Func#*F*Fv(#I)()# |
+
+void Func( void (* (*)(int, int))(int, int) );
+// CHECK: {{[0-9]+}}:6 | function/C | Func | c:@F@Func#*F*Fv(#I#I)(#I#I)# |
+void Func( void (* (*)(int, int, int))(int) );
+// CHECK: {{[0-9]+}}:6 | function/C | Func | c:@F@Func#*F*Fv(#I)(#I#I#I)# |
diff --git a/test/Index/annotate-attribute.cpp b/test/Index/annotate-attribute.cpp
index d822210e493e..bf415fc8fe64 100644
--- a/test/Index/annotate-attribute.cpp
+++ b/test/Index/annotate-attribute.cpp
@@ -16,6 +16,12 @@ protected:
void methodWithoutAttribute();
};
+template <typename T>
+class __attribute__((annotate("works"))) TemplateTest {};
+
+template <typename T>
+int templateFunction(T value) __attribute__((annotate("works")));
+
// CHECK: ClassDecl=Test:3:7 (Definition) Extent=[3:1 - 17:2]
// CHECK-NEXT: CXXAccessSpecifier=:4:1 (Definition) Extent=[4:1 - 4:8]
// CHECK-NEXT: CXXMethod=aMethod:5:51 Extent=[5:3 - 5:60]
@@ -31,3 +37,9 @@ protected:
// CHECK-NEXT: CompoundStmt= Extent=[12:23 - 12:25]
// CHECK-NEXT: CXXAccessSpecifier=:14:1 (Definition) Extent=[14:1 - 14:11]
// CHECK-NEXT: CXXMethod=methodWithoutAttribute:16:8 Extent=[16:3 - 16:32]
+// CHECK: ClassTemplate=TemplateTest:20:42 (Definition) Extent=[19:1 - 20:57]
+// CHECK-NEXT: TemplateTypeParameter=T:19:20 (Definition) Extent=[19:11 - 19:21] [access=public]
+// CHECK-NEXT: attribute(annotate)=works Extent=[20:22 - 20:39]
+// CHECK: FunctionTemplate=templateFunction:23:5 Extent=[22:1 - 23:65]
+// CHECK-NEXT: TemplateTypeParameter=T:22:20 (Definition) Extent=[22:11 - 22:21] [access=public]
+// CHECK-NEXT: attribute(annotate)=works Extent=[23:46 - 23:63]
diff --git a/test/Index/code-completion.cpp b/test/Index/code-completion.cpp
index f52bb10a35b0..00f158f3d09d 100644
--- a/test/Index/code-completion.cpp
+++ b/test/Index/code-completion.cpp
@@ -37,6 +37,16 @@ Z::operator int() const {
return 0;
}
+template <typename T>
+struct Foo { T member; };
+
+template<typename T> using Bar = Foo<T>;
+
+void test_template_alias() {
+ // RUN: env CINDEXTEST_COMPLETION_CACHING=1 c-index-test -code-completion-at=%s:47:1 %s | FileCheck -check-prefix=CHECK-TEMPLATE-ALIAS %s
+
+}
+
// CHECK-MEMBER: FieldDecl:{ResultType double}{TypedText member}
// CHECK-MEMBER: FieldDecl:{ResultType int}{Text X::}{TypedText member}
// CHECK-MEMBER: FieldDecl:{ResultType float}{Text Y::}{TypedText member}
@@ -88,3 +98,5 @@ Z::operator int() const {
// CHECK-EXPR-NEXT: Class name
// CHECK-EXPR-NEXT: Nested name specifier
// CHECK-EXPR-NEXT: Objective-C interface
+
+// CHECK-TEMPLATE-ALIAS: AliasTemplateDecl:{TypedText Bar}{LeftAngle <}{Placeholder typename T}{RightAngle >} (50)
diff --git a/test/Index/comment-cplus-decls.cpp b/test/Index/comment-cplus-decls.cpp
index 6e32c60a2228..c4b08eb779a1 100644
--- a/test/Index/comment-cplus-decls.cpp
+++ b/test/Index/comment-cplus-decls.cpp
@@ -46,7 +46,7 @@ protected:
data* reserved;
};
// CHECK: <Declaration>class Test {}</Declaration>
-// CHECK: <Declaration>Test() : reserved(new Test::data()) {}</Declaration>
+// CHECK: <Declaration>Test()</Declaration>
// CHECK: <Declaration>unsigned int getID() const</Declaration>
// CHECK: <Declaration>~Test(){{( noexcept)?}}</Declaration>
// CHECK: <Declaration>Test::data *reserved</Declaration>
diff --git a/test/Index/comment-to-html-xml-conversion-with-original-literals.cpp b/test/Index/comment-to-html-xml-conversion-with-original-literals.cpp
new file mode 100644
index 000000000000..26ca2238834e
--- /dev/null
+++ b/test/Index/comment-to-html-xml-conversion-with-original-literals.cpp
@@ -0,0 +1,26 @@
+// RUN: c-index-test -test-load-source all -comments-xml-schema=%S/../../bindings/xml/comment-xml-schema.rng %s -std=c++11 | FileCheck %s
+
+constexpr int value(float f) { return int(f); }
+
+enum MyEnum {
+hexadecimal = 0x10 //!< a
+// CHECK: <Declaration>hexadecimal = 0x10</Declaration>
+
+, withSuffix = 1u + 010 //!< b
+// CHECK: <Declaration>withSuffix = 1u + 010</Declaration>
+
+#define ARG(x) x
+, macroArg = ARG(0x1) //!< c
+// CHECK: <Declaration>macroArg = ARG(0x1)</Declaration>
+
+#define MACROCONCAT(x, y) 22##x##y
+, macroConcat = MACROCONCAT(3, 2) //!< d
+// CHECK: <Declaration>macroConcat = MACROCONCAT(3, 2)</Declaration>
+
+#define MACRO(a,n) = 0x##a##n
+, weirdMacros MACRO(2,1) //!< e
+// CHECK: <Declaration>weirdMacros = 33</Declaration>
+
+, floatLiteral = value(0.25e3) //!< f
+// CHECK: <Declaration>floatLiteral = value(0.25e3)</Declaration>
+};
diff --git a/test/Index/complete-access-checks.cpp b/test/Index/complete-access-checks.cpp
index c77a5d656a97..7eec41ec5610 100644
--- a/test/Index/complete-access-checks.cpp
+++ b/test/Index/complete-access-checks.cpp
@@ -41,12 +41,12 @@ void Y::doSomething() {
// CHECK-SUPER-ACCESS: FieldDecl:{ResultType int}{Informative X::}{TypedText member1} (37)
// CHECK-SUPER-ACCESS: FieldDecl:{ResultType int}{Informative X::}{TypedText member2} (37) (inaccessible)
// CHECK-SUPER-ACCESS: FieldDecl:{ResultType int}{Informative X::}{TypedText member3} (37) (inaccessible)
-// CHECK-SUPER-ACCESS: CXXMethod:{ResultType Y &}{TypedText operator=}{LeftParen (}{Placeholder const Y &}{RightParen )} (34)
-// CHECK-SUPER-ACCESS: CXXMethod:{ResultType X &}{Text X::}{TypedText operator=}{LeftParen (}{Placeholder const X &}{RightParen )} (36)
+// CHECK-SUPER-ACCESS: CXXMethod:{ResultType Y &}{TypedText operator=}{LeftParen (}{Placeholder const Y &}{RightParen )} (79)
+// CHECK-SUPER-ACCESS: CXXMethod:{ResultType X &}{Text X::}{TypedText operator=}{LeftParen (}{Placeholder const X &}{RightParen )} (81)
// CHECK-SUPER-ACCESS: StructDecl:{TypedText X}{Text ::} (77)
// CHECK-SUPER-ACCESS: StructDecl:{TypedText Y}{Text ::} (75)
-// CHECK-SUPER-ACCESS: CXXDestructor:{ResultType void}{Informative X::}{TypedText ~X}{LeftParen (}{RightParen )} (36)
-// CHECK-SUPER-ACCESS: CXXDestructor:{ResultType void}{TypedText ~Y}{LeftParen (}{RightParen )} (34)
+// CHECK-SUPER-ACCESS: CXXDestructor:{ResultType void}{Informative X::}{TypedText ~X}{LeftParen (}{RightParen )} (81)
+// CHECK-SUPER-ACCESS: CXXDestructor:{ResultType void}{TypedText ~Y}{LeftParen (}{RightParen )} (79)
// CHECK-ACCESS: CXXMethod:{ResultType void}{TypedText func1}{LeftParen (}{RightParen )} (34)
// CHECK-ACCESS: CXXMethod:{ResultType void}{TypedText func2}{LeftParen (}{RightParen )} (34) (inaccessible)
@@ -54,9 +54,9 @@ void Y::doSomething() {
// CHECK-ACCESS: FieldDecl:{ResultType int}{TypedText member1} (35)
// CHECK-ACCESS: FieldDecl:{ResultType int}{TypedText member2} (35) (inaccessible)
// CHECK-ACCESS: FieldDecl:{ResultType int}{TypedText member3} (35) (inaccessible)
-// CHECK-ACCESS: CXXMethod:{ResultType Z &}{TypedText operator=}{LeftParen (}{Placeholder const Z &}{RightParen )} (34)
+// CHECK-ACCESS: CXXMethod:{ResultType Z &}{TypedText operator=}{LeftParen (}{Placeholder const Z &}{RightParen )} (79)
// CHECK-ACCESS: ClassDecl:{TypedText Z}{Text ::} (75)
-// CHECK-ACCESS: CXXDestructor:{ResultType void}{TypedText ~Z}{LeftParen (}{RightParen )} (34)
+// CHECK-ACCESS: CXXDestructor:{ResultType void}{TypedText ~Z}{LeftParen (}{RightParen )} (79)
class P {
protected:
@@ -76,14 +76,14 @@ void f(P x, Q y) {
}
// CHECK-USING-INACCESSIBLE: FieldDecl:{ResultType int}{TypedText member} (35) (inaccessible)
-// CHECK-USING-INACCESSIBLE: CXXMethod:{ResultType P &}{TypedText operator=}{LeftParen (}{Placeholder const P &}{RightParen )} (34)
+// CHECK-USING-INACCESSIBLE: CXXMethod:{ResultType P &}{TypedText operator=}{LeftParen (}{Placeholder const P &}{RightParen )} (79)
// CHECK-USING-INACCESSIBLE: ClassDecl:{TypedText P}{Text ::} (75)
-// CHECK-USING-INACCESSIBLE: CXXDestructor:{ResultType void}{TypedText ~P}{LeftParen (}{RightParen )} (34)
+// CHECK-USING-INACCESSIBLE: CXXDestructor:{ResultType void}{TypedText ~P}{LeftParen (}{RightParen )} (79)
// CHECK-USING-ACCESSIBLE: FieldDecl:{ResultType int}{TypedText member} (35)
-// CHECK-USING-ACCESSIBLE: CXXMethod:{ResultType Q &}{TypedText operator=}{LeftParen (}{Placeholder const Q &}{RightParen )} (34)
-// CHECK-USING-ACCESSIBLE: CXXMethod:{ResultType P &}{Text P::}{TypedText operator=}{LeftParen (}{Placeholder const P &}{RightParen )} (36)
+// CHECK-USING-ACCESSIBLE: CXXMethod:{ResultType Q &}{TypedText operator=}{LeftParen (}{Placeholder const Q &}{RightParen )} (79)
+// CHECK-USING-ACCESSIBLE: CXXMethod:{ResultType P &}{Text P::}{TypedText operator=}{LeftParen (}{Placeholder const P &}{RightParen )} (81)
// CHECK-USING-ACCESSIBLE: ClassDecl:{TypedText P}{Text ::} (77)
// CHECK-USING-ACCESSIBLE: ClassDecl:{TypedText Q}{Text ::} (75)
-// CHECK-USING-ACCESSIBLE: CXXDestructor:{ResultType void}{Informative P::}{TypedText ~P}{LeftParen (}{RightParen )} (36)
-// CHECK-USING-ACCESSIBLE: CXXDestructor:{ResultType void}{TypedText ~Q}{LeftParen (}{RightParen )} (34)
+// CHECK-USING-ACCESSIBLE: CXXDestructor:{ResultType void}{Informative P::}{TypedText ~P}{LeftParen (}{RightParen )} (81)
+// CHECK-USING-ACCESSIBLE: CXXDestructor:{ResultType void}{TypedText ~Q}{LeftParen (}{RightParen )} (79)
diff --git a/test/Index/complete-call.cpp b/test/Index/complete-call.cpp
index 9750bd6f7100..ca116485ac95 100644
--- a/test/Index/complete-call.cpp
+++ b/test/Index/complete-call.cpp
@@ -94,6 +94,24 @@ int main() {
s.foo_7(42,);
}
+struct Bar {
+ static void foo_1();
+ void foo_1(float);
+ static void foo_1(int);
+};
+
+void test() {
+ Bar::foo_1();
+ Bar b;
+ b.foo_1();
+}
+
+struct Bar2 : public Bar {
+ Bar2() {
+ Bar::foo_1();
+ }
+};
+
// RUN: c-index-test -code-completion-at=%s:47:9 %s | FileCheck -check-prefix=CHECK-CC1 %s
// CHECK-CC1: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{RightParen )} (1)
// CHECK-CC1: Completion contexts:
@@ -803,3 +821,46 @@ int main() {
// CHECK-CC59-NEXT: Class name
// CHECK-CC59-NEXT: Nested name specifier
// CHECK-CC59-NEXT: Objective-C interface
+
+// RUN: c-index-test -code-completion-at=%s:104:14 %s | FileCheck -check-prefix=CHECK-CC60 %s
+// CHECK-CC60: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{RightParen )} (1)
+// CHECK-CC60: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter float}{RightParen )} (1)
+// CHECK-CC60: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter int}{RightParen )} (1)
+// CHECK-CC60: Completion contexts:
+// CHECK-CC60-NEXT: Any type
+// CHECK-CC60-NEXT: Any value
+// CHECK-CC60-NEXT: Enum tag
+// CHECK-CC60-NEXT: Union tag
+// CHECK-CC60-NEXT: Struct tag
+// CHECK-CC60-NEXT: Class name
+// CHECK-CC60-NEXT: Nested name specifier
+// CHECK-CC60-NEXT: Objective-C interface
+
+// RUN: c-index-test -code-completion-at=%s:106:11 %s | FileCheck -check-prefix=CHECK-CC61 %s
+// CHECK-CC61: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{RightParen )} (1)
+// CHECK-CC61: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter float}{RightParen )} (1)
+// CHECK-CC61: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter int}{RightParen )} (1)
+// CHECK-CC61: Completion contexts:
+// CHECK-CC61-NEXT: Any type
+// CHECK-CC61-NEXT: Any value
+// CHECK-CC61-NEXT: Enum tag
+// CHECK-CC61-NEXT: Union tag
+// CHECK-CC61-NEXT: Struct tag
+// CHECK-CC61-NEXT: Class name
+// CHECK-CC61-NEXT: Nested name specifier
+// CHECK-CC61-NEXT: Objective-C interface
+
+// RUN: c-index-test -code-completion-at=%s:111:16 %s | FileCheck -check-prefix=CHECK-CC62 %s
+// CHECK-CC62: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{RightParen )} (1)
+// CHECK-CC62: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter float}{RightParen )} (1)
+// CHECK-CC62: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter int}{RightParen )} (1)
+// CHECK-CC62: Completion contexts:
+// CHECK-CC62-NEXT: Any type
+// CHECK-CC62-NEXT: Any value
+// CHECK-CC62-NEXT: Enum tag
+// CHECK-CC62-NEXT: Union tag
+// CHECK-CC62-NEXT: Struct tag
+// CHECK-CC62-NEXT: Class name
+// CHECK-CC62-NEXT: Nested name specifier
+// CHECK-CC62-NEXT: Objective-C interface
+
diff --git a/test/Index/complete-constructor-params.cpp b/test/Index/complete-constructor-params.cpp
index 6685626a5875..949077a2143a 100644
--- a/test/Index/complete-constructor-params.cpp
+++ b/test/Index/complete-constructor-params.cpp
@@ -18,6 +18,20 @@ int main() {
int(42);
}
+struct Foo {
+ Foo() = default;
+ Foo(const Foo&) = delete;
+};
+
+struct Bar {
+ Foo f;
+};
+
+void function() {
+ Bar b1;
+ Bar b2(b1);
+}
+
// RUN: c-index-test -code-completion-at=%s:11:10 %s | FileCheck -check-prefix=CHECK-CC1 %s
// CHECK-CC1: OverloadCandidate:{Text S}{LeftParen (}{CurrentParameter const S<int> &}{RightParen )} (1)
// CHECK-CC1: OverloadCandidate:{Text S}{LeftParen (}{CurrentParameter int}{Comma , }{Placeholder U}{Comma , }{Placeholder U}{RightParen )} (1)
@@ -138,3 +152,6 @@ int main() {
// CHECK-CC10-NEXT: Class name
// CHECK-CC10-NEXT: Nested name specifier
// CHECK-CC10-NEXT: Objective-C interface
+
+// RUN: c-index-test -code-completion-at=%s:32:12 -std=c++11 %s | FileCheck -check-prefix=CHECK-CC11 %s
+// CHECK-CC11-NOT: OverloadCandidate:{Text Bar}{LeftParen (}{CurrentParameter const Bar &}{RightParen )} (1)
diff --git a/test/Index/complete-cxx-inline-methods.cpp b/test/Index/complete-cxx-inline-methods.cpp
index ee359f75e445..0f78e8caa748 100644
--- a/test/Index/complete-cxx-inline-methods.cpp
+++ b/test/Index/complete-cxx-inline-methods.cpp
@@ -25,11 +25,11 @@ private:
// RUN: c-index-test -code-completion-at=%s:4:9 -std=c++98 %s | FileCheck %s
// RUN: c-index-test -code-completion-at=%s:13:7 -std=c++98 %s | FileCheck %s
-// CHECK: CXXMethod:{ResultType MyCls::Vec &}{TypedText operator=}{LeftParen (}{Placeholder const MyCls::Vec &}{RightParen )} (34)
+// CHECK: CXXMethod:{ResultType Vec &}{TypedText operator=}{LeftParen (}{Placeholder const Vec &}{RightParen )} (79)
// CHECK-NEXT: StructDecl:{TypedText Vec}{Text ::} (75)
// CHECK-NEXT: FieldDecl:{ResultType int}{TypedText x} (35)
// CHECK-NEXT: FieldDecl:{ResultType int}{TypedText y} (35)
-// CHECK-NEXT: CXXDestructor:{ResultType void}{TypedText ~Vec}{LeftParen (}{RightParen )} (34)
+// CHECK-NEXT: CXXDestructor:{ResultType void}{TypedText ~Vec}{LeftParen (}{RightParen )} (79)
// CHECK-NEXT: Completion contexts:
// CHECK-NEXT: Dot member access
// CHECK-NEXT: Container Kind: StructDecl
diff --git a/test/Index/complete-interfaces.m b/test/Index/complete-interfaces.m
index 2f86c3d8f43c..3e90407c78d7 100644
--- a/test/Index/complete-interfaces.m
+++ b/test/Index/complete-interfaces.m
@@ -45,3 +45,19 @@
// RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_COMPLETION_CACHING=1 c-index-test -code-completion-at=%s:11:12 %s | FileCheck -check-prefix=CHECK-CC2 %s
+
+
+void useClasses() {
+ int i = 0;
+ [Int3 message:1];
+}
+
+// RUN: c-index-test -code-completion-at=%s:51:11 %s | FileCheck -check-prefix=CHECK-USE %s
+// RUN: c-index-test -code-completion-at=%s:52:17 %s | FileCheck -check-prefix=CHECK-USE %s
+// CHECK-USE: ObjCInterfaceDecl:{TypedText Int2} (50)
+// CHECK-USE: ObjCInterfaceDecl:{TypedText Int3} (50)
+// CHECK-USE-NOT: Int1
+// CHECK-USE-NOT: Int4
+
+// Caching should work too:
+// RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_COMPLETION_CACHING=1 c-index-test -code-completion-at=%s:51:11 %s | FileCheck -check-prefix=CHECK-USE %s
diff --git a/test/Index/complete-method-decls.m b/test/Index/complete-method-decls.m
index 8a1714226664..f561f81496a9 100644
--- a/test/Index/complete-method-decls.m
+++ b/test/Index/complete-method-decls.m
@@ -236,3 +236,25 @@ typedef A *MyObjectRef;
// RUN: c-index-test -code-completion-at=%s:107:2 %s -target x86_64-apple-macosx10.7 | FileCheck -check-prefix=CHECK-NULLABILITY2 %s
// CHECK-NULLABILITY2: ObjCInstanceMethodDecl:{LeftParen (}{Text instancetype}{RightParen )}{TypedText getI3} (40)
// CHECK-NULLABILITY2: ObjCInstanceMethodDecl:{LeftParen (}{Text I3 *}{RightParen )}{TypedText produceI3}{TypedText :}{LeftParen (}{Text I3 *}{RightParen )}{Text i3} (40)
+
+@interface CompleteWithoutLeadingPrefix
+
+- (void)aMethod;
++ (int)aClassMethod:(int)x;
+@property int p;
+
+@end
+
+@implementation CompleteWithoutLeadingPrefix
+
+
+
+@end
+
+// RUN: c-index-test -code-completion-at=%s:250:1 %s | FileCheck -check-prefix=CHECK-COMP-NO-PREFIX %s
+// CHECK-COMP-NO-PREFIX: NotImplemented:{TypedText @end} (40)
+// CHECK-COMP-NO-PREFIX: ObjCClassMethodDecl:{Text +}{HorizontalSpace }{LeftParen (}{Text int}{RightParen )}{TypedText aClassMethod}{TypedText :}{LeftParen (}{Text int}{RightParen )}{Text x} (40)
+// CHECK-COMP-NO-PREFIX: ObjCInstanceMethodDecl:{Text -}{HorizontalSpace }{LeftParen (}{Text void}{RightParen )}{TypedText aMethod} (40)
+// CHECK-COMP-NO-PREFIX: ObjCInterfaceDecl:{TypedText I1}
+// CHECK-COMP-NO-PREFIX: ObjCInstanceMethodDecl:{Text -}{HorizontalSpace }{LeftParen (}{Text int}{RightParen )}{TypedText p} (40)
+// CHECK-COMP-NO-PREFIX: ObjCInstanceMethodDecl:{Text -}{HorizontalSpace }{LeftParen (}{Text void}{RightParen )}{TypedText setP}{TypedText :}{LeftParen (}{Text int}{RightParen )}{Text p} (40)
diff --git a/test/Index/complete-qualified.cpp b/test/Index/complete-qualified.cpp
index a17ea25370c7..11abd53b86c2 100644
--- a/test/Index/complete-qualified.cpp
+++ b/test/Index/complete-qualified.cpp
@@ -17,4 +17,4 @@ void foo()
// CHECK-CC1: FieldDecl:{ResultType C<Foo, class Bar>}{TypedText c} (35)
// CHECK-CC1: ClassDecl:{TypedText Foo} (35)
// CHECK-CC1: CXXMethod:{ResultType Foo &}{TypedText operator=}{LeftParen (}{Placeholder const Foo &}{RightParen )}
-// CHECK-CC1: CXXDestructor:{ResultType void}{TypedText ~Foo}{LeftParen (}{RightParen )} (35)
+// CHECK-CC1: CXXDestructor:{ResultType void}{TypedText ~Foo}{LeftParen (}{RightParen )} (80)
diff --git a/test/Index/complete-super.cpp b/test/Index/complete-super.cpp
index 9ffa7c8a4056..92d3f7f585f3 100644
--- a/test/Index/complete-super.cpp
+++ b/test/Index/complete-super.cpp
@@ -40,3 +40,8 @@ void B::bar(float real) {
// CHECK-ACCESS-PATTERN: NotImplemented:{TypedText private}{Colon :} (40)
// CHECK-ACCESS-PATTERN: NotImplemented:{TypedText protected}{Colon :} (40)
// CHECK-ACCESS-PATTERN: NotImplemented:{TypedText public}{Colon :} (40)
+
+// RUN: env CINDEXTEST_CODE_COMPLETE_PATTERNS=1 c-index-test -code-completion-at=%s:10:12 %s | FileCheck -check-prefix=CHECK-INHERITANCE-PATTERN %s
+// CHECK-INHERITANCE-PATTERN: NotImplemented:{TypedText private} (40)
+// CHECK-INHERITANCE-PATTERN: NotImplemented:{TypedText protected} (40)
+// CHECK-INHERITANCE-PATTERN: NotImplemented:{TypedText public} (40)
diff --git a/test/Index/complete-with-annotations.cpp b/test/Index/complete-with-annotations.cpp
index afa8d9ed6607..7bad8f1b7cbe 100644
--- a/test/Index/complete-with-annotations.cpp
+++ b/test/Index/complete-with-annotations.cpp
@@ -17,7 +17,7 @@ void X::doSomething() {
// CHECK: FieldDecl:{ResultType int}{TypedText field} (35) ("three", "two", "one")
// CHECK: CXXMethod:{ResultType void}{TypedText func2}{LeftParen (}{RightParen )} (34) ("some annotation")
// CHECK: FieldDecl:{ResultType int}{TypedText member2} (35) ("another annotation", "some annotation")
-// CHECK: CXXMethod:{ResultType X &}{TypedText operator=}{LeftParen (}{Placeholder const X &}{RightParen )} (34)
+// CHECK: CXXMethod:{ResultType X &}{TypedText operator=}{LeftParen (}{Placeholder const X &}{RightParen )} (79)
// CHECK: ClassDecl:{TypedText X}{Text ::} (75)
-// CHECK: CXXDestructor:{ResultType void}{TypedText ~X}{LeftParen (}{RightParen )} (34)
+// CHECK: CXXDestructor:{ResultType void}{TypedText ~X}{LeftParen (}{RightParen )} (79)
diff --git a/test/Index/get-cursor.cpp b/test/Index/get-cursor.cpp
index 8aa12d5bc310..e997fc493d8c 100644
--- a/test/Index/get-cursor.cpp
+++ b/test/Index/get-cursor.cpp
@@ -152,6 +152,11 @@ void f_dynamic_noexcept_none() throw();
void f_dynamic_noexcept() throw(int);
void f_dynamic_noexcept_any() throw(...);
+enum EnumType { Enumerator };
+struct Z {
+ EnumType e = Enumerator;
+};
+
// RUN: c-index-test -cursor-at=%s:6:4 %s | FileCheck -check-prefix=CHECK-COMPLETION-1 %s
// CHECK-COMPLETION-1: CXXConstructor=X:6:3
// CHECK-COMPLETION-1-NEXT: Completion string: {TypedText X}{LeftParen (}{Placeholder int}{Comma , }{Placeholder int}{RightParen )}
@@ -275,3 +280,6 @@ void f_dynamic_noexcept_any() throw(...);
// CHECK-FORRANGE: 141:18 DeclRefExpr=coll:140:20 Extent=[141:18 - 141:22] Spelling=coll ([141:18 - 141:22])
// CHECK-FORRANGE: 142:11 DeclRefExpr=lv:141:13 Extent=[142:11 - 142:13] Spelling=lv ([142:11 - 142:13])
+// RUN: c-index-test -cursor-at=%s:157:18 -std=c++11 %s | FileCheck -check-prefix=CHECK-INCLASSINITIALIZER %s
+// CHECK-INCLASSINITIALIZER: 157:18 DeclRefExpr=Enumerator:155:17 Extent=[157:18 - 157:28] Spelling=Enumerator ([157:18 - 157:28])
+
diff --git a/test/Index/index-pch.cpp b/test/Index/index-pch.cpp
index caab2d7f97bd..e86e446ef026 100644
--- a/test/Index/index-pch.cpp
+++ b/test/Index/index-pch.cpp
@@ -1,4 +1,4 @@
-// RUN: c-index-test -write-pch %t.pch -fshort-wchar %s
+// RUN: c-index-test -write-pch %t.pch -fwchar-type=short -fno-signed-wchar %s
// RUN: env LIBCLANG_NOTHREADS=1 c-index-test -index-tu %t.pch | FileCheck %s
// CHECK: [indexDeclaration]: kind: variable | name: wideStr
diff --git a/test/Index/index-template-template-param.cpp b/test/Index/index-template-template-param.cpp
new file mode 100644
index 000000000000..af1c4634adb5
--- /dev/null
+++ b/test/Index/index-template-template-param.cpp
@@ -0,0 +1,7 @@
+// RUN: c-index-test -index-file %s -x objective-c++ | FileCheck %s
+
+template <typename T> class Template1 {};
+
+template <template <class> class TMPL = Template1> class Template2;
+
+// CHECK: [indexEntityReference]: kind: c++-class-template | name: Template1 |
diff --git a/test/Index/index-templates.cpp b/test/Index/index-templates.cpp
index 966cc4f5ea7f..424a638ffbb8 100644
--- a/test/Index/index-templates.cpp
+++ b/test/Index/index-templates.cpp
@@ -219,6 +219,6 @@ using alias = T;
// CHECK-USRS: index-templates.cpp c:@ST>2#T#T@Y Extent=[27:1 - 31:2]
// CHECK-USRS: index-templates.cpp c:index-templates.cpp@443 Extent=[27:10 - 27:20]
// CHECK-USRS: index-templates.cpp c:index-templates.cpp@455 Extent=[27:22 - 27:32]
-// CHECK-USRS-NOT: type
+// CHECK-USRS: index-templates.cpp c:index-templates.cpp@ST>2#T#T@Y@UUT@T::type Extent=[29:3 - 29:25]
// CHECK-USRS: index-templates.cpp c:@S@Z3 Extent=[33:1 - 33:14]
// CHECK-USRS: index-templates.cpp c:@F@f#$@S@map>#$@S@Z4#$@S@Pair>#I#S1_#$@S@compare>#$@S@Pair>#S1_#S2_#$@S@allocator>#S4_#
diff --git a/test/Index/load-classes.cpp b/test/Index/load-classes.cpp
index 8b1ed317e3be..b6c25b4f7517 100644
--- a/test/Index/load-classes.cpp
+++ b/test/Index/load-classes.cpp
@@ -29,7 +29,7 @@ X::X(int value) {
}
// RUN: c-index-test -test-load-source all %s | FileCheck %s
-// CHECK: load-classes.cpp:3:8: StructDecl=X:3:8 (Definition) Extent=[3:1 - 26:2]
+// CHECK: load-classes.cpp:3:8: StructDecl=X:3:8 (Definition) (abstract) Extent=[3:1 - 26:2]
// CHECK: load-classes.cpp:4:3: CXXConstructor=X:4:3 (converting constructor) Extent=[4:3 - 4:15] [access=public]
// FIXME: missing TypeRef in the constructor name
// CHECK: load-classes.cpp:4:9: ParmDecl=value:4:9 (Definition) Extent=[4:5 - 4:14]
diff --git a/test/Index/preamble-conditionals-inverted-with-error.cpp b/test/Index/preamble-conditionals-inverted-with-error.cpp
new file mode 100644
index 000000000000..95b0695b8733
--- /dev/null
+++ b/test/Index/preamble-conditionals-inverted-with-error.cpp
@@ -0,0 +1,8 @@
+// RUN: env CINDEXTEST_EDITING=1 c-index-test -test-load-source-reparse 5 \
+// RUN: local -std=c++14 %s 2>&1 \
+// RUN: | FileCheck %s
+#ifdef FOO_H
+
+void foo();
+
+// CHECK: preamble-conditionals-inverted-with-error.cpp:4:2: error: unterminated conditional directive
diff --git a/test/Index/preamble-conditionals-inverted.cpp b/test/Index/preamble-conditionals-inverted.cpp
new file mode 100644
index 000000000000..f5cf1205e37d
--- /dev/null
+++ b/test/Index/preamble-conditionals-inverted.cpp
@@ -0,0 +1,10 @@
+// RUN: env CINDEXTEST_EDITING=1 c-index-test -test-load-source-reparse 5 \
+// RUN: local -std=c++14 %s 2>&1 \
+// RUN: | FileCheck %s --implicit-check-not "error:"
+#ifdef FOO_H
+
+void foo() {}
+
+#endif
+
+int foo() { return 0; }
diff --git a/test/Index/preamble-conditionals-skipping.cpp b/test/Index/preamble-conditionals-skipping.cpp
new file mode 100644
index 000000000000..fa5764cd5de9
--- /dev/null
+++ b/test/Index/preamble-conditionals-skipping.cpp
@@ -0,0 +1,16 @@
+// RUN: env CINDEXTEST_EDITING=1 c-index-test -test-load-source-reparse 5 \
+// RUN: local -std=c++14 %s 2>&1 \
+// RUN: | FileCheck %s --implicit-check-not "error:"
+
+#ifdef MYCPLUSPLUS
+extern "C" {
+#endif
+
+#ifdef MYCPLUSPLUS
+}
+#endif
+
+int main()
+{
+ return 0;
+}
diff --git a/test/Index/print-objc-manglings.m b/test/Index/print-objc-manglings.m
new file mode 100644
index 000000000000..1e7983ec6170
--- /dev/null
+++ b/test/Index/print-objc-manglings.m
@@ -0,0 +1,18 @@
+// RUN: c-index-test -write-pch %t.macho.ast -target i686-apple-darwin %s
+// RUN: c-index-test -test-print-manglings %t.macho.ast | FileCheck --check-prefix=MACHO %s
+
+// RUN: c-index-test -write-pch %t.itanium.ast -target i686-pc-linux-gnu %s
+// RUN: c-index-test -test-print-manglings %t.itanium.ast | FileCheck --check-prefix=ITANIUM %s
+
+@interface C
+@end
+
+// MACHO: ObjCInterfaceDecl=C{{.*}} [mangled=_OBJC_CLASS_$_C] [mangled=_OBJC_METACLASS_$_C]
+// ITANIUM: ObjCInterfaceDecl=C{{.*}} [mangled=_OBJC_CLASS_C] [mangled=_OBJC_METACLASS_C]
+
+@implementation C
+@end
+
+// MACHO: ObjCImplementationDecl=C{{.*}} (Definition) [mangled=_OBJC_CLASS_$_C] [mangled=_OBJC_METACLASS_$_C]
+// ITANIUM: ObjCImplementationDecl=C{{.*}} (Definition) [mangled=_OBJC_CLASS_C] [mangled=_OBJC_METACLASS_C]
+
diff --git a/test/Index/record-completion-invocation.c b/test/Index/record-completion-invocation.c
new file mode 100644
index 000000000000..c249565a4b68
--- /dev/null
+++ b/test/Index/record-completion-invocation.c
@@ -0,0 +1,11 @@
+// RUN: rm -rf %t
+// RUN: mkdir %t
+// RUN: env CINDEXTEST_INVOCATION_EMISSION_PATH=%t not c-index-test -code-completion-at=%s:10:1 "-remap-file=%s,%S/Inputs/record-parsing-invocation-remap.c" %s
+// RUN: cat %t/libclang-* | FileCheck %s
+
+// RUN: rm -rf %t
+// RUN: mkdir %t
+// RUN: env LIBCLANG_DISABLE_CRASH_RECOVERY=1 CINDEXTEST_INVOCATION_EMISSION_PATH=%t not --crash c-index-test -code-completion-at=%s:10:1 "-remap-file=%s,%S/Inputs/record-parsing-invocation-remap.c" %s
+// RUN: cat %t/libclang-* | FileCheck %s
+
+// CHECK: {"toolchain":"{{.*}}","libclang.operation":"complete","libclang.opts":1,"args":["clang","-fno-spell-checking","{{.*}}record-completion-invocation.c","-Xclang","-detailed-preprocessing-record","-fallow-editor-placeholders"],"invocation-args":["-code-completion-at={{.*}}record-completion-invocation.c:10:1"],"unsaved_file_hashes":[{"name":"{{.*}}record-completion-invocation.c","md5":"aee23773de90e665992b48209351d70e"}]}
diff --git a/test/Index/record-parsing-invocation.c b/test/Index/record-parsing-invocation.c
new file mode 100644
index 000000000000..3254e58aef04
--- /dev/null
+++ b/test/Index/record-parsing-invocation.c
@@ -0,0 +1,28 @@
+// RUN: rm -rf %t
+// RUN: mkdir %t
+// RUN: env CINDEXTEST_INVOCATION_EMISSION_PATH=%t not c-index-test -test-load-source all %s
+// RUN: cat %t/libclang-* | FileCheck %s
+
+// RUN: rm -rf %t
+// RUN: mkdir %t
+// RUN: env LIBCLANG_DISABLE_CRASH_RECOVERY=1 CINDEXTEST_INVOCATION_EMISSION_PATH=%t not --crash c-index-test -test-load-source all %s
+// RUN: cat %t/libclang-* | FileCheck %s
+
+// Verify that the file is removed for successful operation:
+// RUN: rm -rf %t
+// RUN: mkdir %t
+// RUN: env CINDEXTEST_INVOCATION_EMISSION_PATH=%t c-index-test -test-load-source all %s -DAVOID_CRASH
+// RUN: ls %t | count 0
+
+// Make sure we record the unsaved file hash.
+// RUN: rm -rf %t
+// RUN: mkdir %t
+// RUN: env CINDEXTEST_INVOCATION_EMISSION_PATH=%t not c-index-test -test-load-source all "-remap-file=%s,%S/Inputs/record-parsing-invocation-remap.c" %s
+// RUN: cat %t/libclang-* | FileCheck --check-prefix=CHECK-UNSAVED %s
+
+#ifndef AVOID_CRASH
+# pragma clang __debug parser_crash
+#endif
+
+// CHECK: {"toolchain":"{{.*}}","libclang.operation":"parse","libclang.opts":1,"args":["clang","-fno-spell-checking","{{.*}}record-parsing-invocation.c","-Xclang","-detailed-preprocessing-record","-fallow-editor-placeholders"]}
+// CHECK-UNSAVED: {"toolchain":"{{.*}}","libclang.operation":"parse","libclang.opts":1,"args":["clang","-fno-spell-checking","{{.*}}record-parsing-invocation.c","-Xclang","-detailed-preprocessing-record","-fallow-editor-placeholders"],"unsaved_file_hashes":[{"name":"{{.*}}record-parsing-invocation.c","md5":"aee23773de90e665992b48209351d70e"}]}
diff --git a/test/Index/recover-bad-code-rdar_7487294.c b/test/Index/recover-bad-code-rdar_7487294.c
index c2803006ac43..bbbc035a0a9b 100644
--- a/test/Index/recover-bad-code-rdar_7487294.c
+++ b/test/Index/recover-bad-code-rdar_7487294.c
@@ -1,4 +1,4 @@
-// RUN: not %clang-cc1 -fsyntax-only %s 2>&1 | FileCheck %s
+// RUN: not %clang_cc1 -fsyntax-only %s 2>&1 | FileCheck %s
// IMPORTANT: This test case intentionally DOES NOT use --disable-free. It
// tests that we are properly reclaiming the ASTs and we do not have a double free.
diff --git a/test/Index/skipped-function-bodies.cpp b/test/Index/skipped-function-bodies.cpp
new file mode 100644
index 000000000000..9378f664bb6f
--- /dev/null
+++ b/test/Index/skipped-function-bodies.cpp
@@ -0,0 +1,9 @@
+// RUN: env CINDEXTEST_SKIP_FUNCTION_BODIES=1 c-index-test -test-load-source all %s 2>&1 \
+// RUN: | FileCheck %s
+
+inline int with_body() { return 10; }
+inline int without_body();
+
+int x = with_body() + without_body();
+// CHECK-NOT: warning: inline function 'with_body' is not defined
+// CHECK: warning: inline function 'without_body' is not defined
diff --git a/test/Index/skipped-ranges.c b/test/Index/skipped-ranges.c
index bd16fb3856b2..f6c6c7f638ec 100644
--- a/test/Index/skipped-ranges.c
+++ b/test/Index/skipped-ranges.c
@@ -20,6 +20,6 @@ int probably_hot = 1;
#endif // cool
// RUN: env CINDEXTEST_SHOW_SKIPPED_RANGES=1 c-index-test -test-annotate-tokens=%s:1:1:16:1 %s | FileCheck %s
-// CHECK: Skipping: [5:2 - 6:7]
-// CHECK: Skipping: [8:2 - 12:7]
-// CHECK: Skipping: [14:2 - 20:7]
+// CHECK: Skipping: [5:1 - 6:7]
+// CHECK: Skipping: [8:1 - 12:7]
+// CHECK: Skipping: [14:1 - 20:7]
diff --git a/test/Integration/thinlto_profile_sample_accurate.c b/test/Integration/thinlto_profile_sample_accurate.c
new file mode 100644
index 000000000000..ac7274cee2d2
--- /dev/null
+++ b/test/Integration/thinlto_profile_sample_accurate.c
@@ -0,0 +1,9 @@
+// Test to ensure -emit-llvm profile-sample-accurate is honored in ThinLTO.
+// RUN: %clang -O2 %s -flto=thin -fprofile-sample-accurate -c -o %t.o
+// RUN: llvm-lto -thinlto -o %t %t.o
+// RUN: %clang_cc1 -O2 -x ir %t.o -fthinlto-index=%t.thinlto.bc -emit-llvm -o - | FileCheck %s
+
+// CHECK: define{{.*}} void @foo()
+// CHECK: attributes{{.*}} "profile-sample-accurate"
+void foo() {
+}
diff --git a/test/Lexer/case-insensitive-include-ms.c b/test/Lexer/case-insensitive-include-ms.c
index 86bd8bba68eb..a7101544fe2f 100644
--- a/test/Lexer/case-insensitive-include-ms.c
+++ b/test/Lexer/case-insensitive-include-ms.c
@@ -1,10 +1,10 @@
// REQUIRES: case-insensitive-filesystem
-// RUN: mkdir -p %T/apath
-// RUN: cp %S/Inputs/case-insensitive-include.h %T
-// RUN: cd %T
-// RUN: %clang_cc1 -fsyntax-only -fms-compatibility %s -include %s -I %T -verify
-// RUN: %clang_cc1 -fsyntax-only -fms-compatibility -fdiagnostics-parseable-fixits %s -include %s -I %T 2>&1 | FileCheck %s
+// RUN: mkdir -p %t/Output/apath
+// RUN: cp %S/Inputs/case-insensitive-include.h %t/Output
+// RUN: cd %t/Output
+// RUN: %clang_cc1 -fsyntax-only -fms-compatibility %s -include %s -I %t/Output -verify
+// RUN: %clang_cc1 -fsyntax-only -fms-compatibility -fdiagnostics-parseable-fixits %s -include %s -I %t/Output 2>&1 | FileCheck %s
#include "..\Output\.\case-insensitive-include.h"
#include "..\Output\.\Case-Insensitive-Include.h" // expected-warning {{non-portable path}}
diff --git a/test/Lexer/case-insensitive-include-pr31836.sh b/test/Lexer/case-insensitive-include-pr31836.sh
index a419f26faf8f..e842badc7f28 100755
--- a/test/Lexer/case-insensitive-include-pr31836.sh
+++ b/test/Lexer/case-insensitive-include-pr31836.sh
@@ -1,9 +1,9 @@
// REQUIRES: case-insensitive-filesystem
// UNSUPPORTED: system-windows
-// RUN: mkdir -p %T
-// RUN: touch %T/case-insensitive-include-pr31836.h
-// RUN: echo "#include \"%T/Case-Insensitive-Include-Pr31836.h\"" | %clang_cc1 -E - 2>&1 | FileCheck %s
+// RUN: mkdir -p %t
+// RUN: touch %t/case-insensitive-include-pr31836.h
+// RUN: echo "#include \"%t/Case-Insensitive-Include-Pr31836.h\"" | %clang_cc1 -E - 2>&1 | FileCheck %s
// CHECK: warning: non-portable path to file
// CHECK-SAME: /case-insensitive-include-pr31836.h
diff --git a/test/Lexer/case-insensitive-include.c b/test/Lexer/case-insensitive-include.c
index 13e5b5994269..099555de5f5c 100644
--- a/test/Lexer/case-insensitive-include.c
+++ b/test/Lexer/case-insensitive-include.c
@@ -1,12 +1,12 @@
// REQUIRES: case-insensitive-filesystem
-// RUN: mkdir -p %T/apath
-// RUN: mkdir -p %T/asystempath
-// RUN: cp %S/Inputs/case-insensitive-include.h %T
-// RUN: cp %S/Inputs/case-insensitive-include.h %T/asystempath/case-insensitive-include2.h
-// RUN: cd %T
-// RUN: %clang_cc1 -fsyntax-only %s -include %s -I %T -isystem %T/asystempath -verify
-// RUN: %clang_cc1 -fsyntax-only -fdiagnostics-parseable-fixits %s -include %s -I %T -isystem %T/asystempath 2>&1 | FileCheck %s
+// RUN: mkdir -p %t/Output/apath
+// RUN: mkdir -p %t/Output/asystempath
+// RUN: cp %S/Inputs/case-insensitive-include.h %t/Output
+// RUN: cp %S/Inputs/case-insensitive-include.h %t/Output/asystempath/case-insensitive-include2.h
+// RUN: cd %t/Output
+// RUN: %clang_cc1 -fsyntax-only %s -include %s -I %t/Output -isystem %t/Output/asystempath -verify
+// RUN: %clang_cc1 -fsyntax-only -fdiagnostics-parseable-fixits %s -include %s -I %t/Output -isystem %t/Output/asystempath 2>&1 | FileCheck %s
// Known standard header, so warn:
#include <StdDef.h> // expected-warning {{non-portable path}}
diff --git a/test/Lexer/case-insensitive-system-include.c b/test/Lexer/case-insensitive-system-include.c
index 9d5289cda2da..20e0fc645620 100644
--- a/test/Lexer/case-insensitive-system-include.c
+++ b/test/Lexer/case-insensitive-system-include.c
@@ -1,10 +1,10 @@
// REQUIRES: case-insensitive-filesystem
-// RUN: mkdir -p %T/asystempath
-// RUN: cp %S/Inputs/case-insensitive-include.h %T/asystempath/
-// RUN: cd %T
-// RUN: %clang_cc1 -fsyntax-only %s -include %s -isystem %T/asystempath -verify -Wnonportable-system-include-path
-// RUN: %clang_cc1 -fsyntax-only -fdiagnostics-parseable-fixits %s -include %s -isystem %T/asystempath -Wnonportable-system-include-path 2>&1 | FileCheck %s
+// RUN: mkdir -p %t/asystempath
+// RUN: cp %S/Inputs/case-insensitive-include.h %t/asystempath/
+// RUN: cd %t
+// RUN: %clang_cc1 -fsyntax-only %s -include %s -isystem %t/asystempath -verify -Wnonportable-system-include-path
+// RUN: %clang_cc1 -fsyntax-only -fdiagnostics-parseable-fixits %s -include %s -isystem %t/asystempath -Wnonportable-system-include-path 2>&1 | FileCheck %s
#include "CASE-INSENSITIVE-INCLUDE.H" // expected-warning {{non-portable path}}
// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:10-[[@LINE-1]]:38}:"\"case-insensitive-include.h\""
diff --git a/test/Lexer/cxx-features.cpp b/test/Lexer/cxx-features.cpp
index 04821bdb2277..a7d12e2e14f2 100644
--- a/test/Lexer/cxx-features.cpp
+++ b/test/Lexer/cxx-features.cpp
@@ -4,8 +4,8 @@
// RUN: %clang_cc1 -std=c++14 -fcxx-exceptions -fsized-deallocation -verify %s
// RUN: %clang_cc1 -std=c++1z -fcxx-exceptions -fsized-deallocation -verify %s
// RUN: %clang_cc1 -std=c++1z -fcxx-exceptions -fsized-deallocation -fconcepts-ts -DCONCEPTS_TS=1 -verify %s
-// RUN: %clang_cc1 -fno-rtti -fno-threadsafe-statics -verify %s -DNO_EXCEPTIONS -DNO_RTTI -DNO_THREADSAFE_STATICS
-// RUN: %clang_cc1 -fcoroutines-ts -DNO_EXCEPTIONS -DCOROUTINES -verify %s
+// RUN: %clang_cc1 -fno-rtti -fno-threadsafe-statics -verify %s -DNO_EXCEPTIONS -DNO_RTTI -DNO_THREADSAFE_STATICS -fsized-deallocation
+// RUN: %clang_cc1 -fcoroutines-ts -DNO_EXCEPTIONS -DCOROUTINES -verify -fsized-deallocation %s
// expected-no-diagnostics
diff --git a/test/Lexer/cxx2a-spaceship.cpp b/test/Lexer/cxx2a-spaceship.cpp
new file mode 100644
index 000000000000..604575ee976b
--- /dev/null
+++ b/test/Lexer/cxx2a-spaceship.cpp
@@ -0,0 +1,73 @@
+// RUN: %clang_cc1 -std=c++17 %s -verify
+// RUN: %clang_cc1 -std=c++2a %s -verify
+// RUN: %clang_cc1 -std=c++2a %s -verify -Wc++17-compat -DCOMPAT
+//
+// RUN: %clang_cc1 -std=c++17 %s -E -o - | FileCheck %s --check-prefix=CXX17
+// RUN: %clang_cc1 -std=c++2a %s -E -o - | FileCheck %s --check-prefix=CXX20
+
+namespace N {
+
+struct A {};
+void operator<=(A, A);
+#if __cplusplus > 201703L
+void operator<=>(A, A);
+#ifdef COMPAT
+// expected-warning@-2 {{'<=>' operator is incompatible with C++ standards before C++2a}}
+#endif
+#endif
+
+template<auto> struct X {};
+X<operator<=>
+#if __cplusplus <= 201703L
+ // expected-warning@-2 {{'<=>' is a single token in C++2a; add a space to avoid a change in behavior}}
+#else
+ >
+#endif
+#ifdef COMPAT
+// expected-warning@-7 {{'<=>' operator is incompatible with C++ standards before C++2a}}
+#endif
+ x;
+}
+
+// <=> can be formed by pasting other comparison operators.
+#if __cplusplus > 201703L
+#define STR(x) #x
+#define STR_EXPANDED(x) STR(x)
+#define PASTE(x, y) x ## y
+constexpr char a[] = STR_EXPANDED(PASTE(<, =>));
+constexpr char b[] = STR_EXPANDED(PASTE(<=, >));
+static_assert(__builtin_strcmp(a, "<=>") == 0);
+static_assert(__builtin_strcmp(b, "<=>") == 0);
+#endif
+
+// -E must not accidentally form a <=> token.
+
+// CXX17: preprocess1: < =>
+// CXX17: preprocess2: <=>
+// CXX17: preprocess3: < =>
+// CXX17: preprocess4: <=>=
+// CXX17: preprocess5: <=>>
+// CXX17: preprocess6: <=>>=
+// CXX17: preprocess7: <=>
+// CXX17: preprocess8: <=>=
+//
+// CXX20: preprocess1: < =>
+// CXX20: preprocess2: <= >
+// CXX20: preprocess3: < =>
+// CXX20: preprocess4: <= >=
+// CXX20: preprocess5: <= >>
+// CXX20: preprocess6: <= >>=
+// CXX20: preprocess7: <=>
+// CXX20: preprocess8: <=>=
+
+#define ID(x) x
+[[some_vendor::some_attribute( // expected-warning {{unknown attribute}}
+preprocess1: ID(<)ID(=>),
+preprocess2: ID(<=)ID(>),
+preprocess3: ID(<)ID(=)ID(>),
+preprocess4: ID(<=)ID(>=),
+preprocess5: ID(<=)ID(>>),
+preprocess6: ID(<=)ID(>>=),
+preprocess7: ID(<=>) // expected-warning 0-1{{'<=>'}}
+preprocess8: ID(<=>=) // expected-warning 0-1{{'<=>'}}
+)]];
diff --git a/test/Lexer/cxx2a_keyword_as_cxx17.cpp b/test/Lexer/cxx2a_keyword_as_cxx17.cpp
new file mode 100644
index 000000000000..c6a821be0ea7
--- /dev/null
+++ b/test/Lexer/cxx2a_keyword_as_cxx17.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only -Wc++2a-compat -std=c++17
+
+#define concept constexpr bool
+template<typename T>
+concept x = 0;
+#undef concept
+
+int concept = 0; // expected-warning {{'concept' is a keyword in C++2a}}
+int requires = 0; // expected-warning {{'requires' is a keyword in C++2a}}
diff --git a/test/Lexer/half-literal.cpp b/test/Lexer/half-literal.cpp
index 32af3faef9aa..8e0034d491dd 100644
--- a/test/Lexer/half-literal.cpp
+++ b/test/Lexer/half-literal.cpp
@@ -1,3 +1,6 @@
// RUN: %clang_cc1 -fsyntax-only -verify -pedantic %s
-float a = 1.0h; // expected-error{{invalid suffix 'h' on floating constant}}
+float a = 1.0h; // expected-error{{no matching literal operator for call to 'operator""h' with argument of type 'long double' or 'const char *', and no matching literal operator template}}
float b = 1.0H; // expected-error{{invalid suffix 'H' on floating constant}}
+
+_Float16 c = 1.f166; // expected-error{{invalid suffix 'f166' on floating constant}}
+_Float16 d = 1.f1; // expected-error{{invalid suffix 'f1' on floating constant}}
diff --git a/test/Lexer/has_feature_address_sanitizer.cpp b/test/Lexer/has_feature_address_sanitizer.cpp
index 406a2ab179a8..b5b4de845be5 100644
--- a/test/Lexer/has_feature_address_sanitizer.cpp
+++ b/test/Lexer/has_feature_address_sanitizer.cpp
@@ -1,5 +1,6 @@
// RUN: %clang_cc1 -E -fsanitize=address %s -o - | FileCheck --check-prefix=CHECK-ASAN %s
// RUN: %clang_cc1 -E -fsanitize=kernel-address %s -o - | FileCheck --check-prefix=CHECK-ASAN %s
+// RUN: %clang_cc1 -E -fsanitize=hwaddress %s -o - | FileCheck --check-prefix=CHECK-HWASAN %s
// RUN: %clang_cc1 -E %s -o - | FileCheck --check-prefix=CHECK-NO-ASAN %s
#if __has_feature(address_sanitizer)
@@ -8,5 +9,17 @@ int AddressSanitizerEnabled();
int AddressSanitizerDisabled();
#endif
+#if __has_feature(hwaddress_sanitizer)
+int HWAddressSanitizerEnabled();
+#else
+int HWAddressSanitizerDisabled();
+#endif
+
// CHECK-ASAN: AddressSanitizerEnabled
+// CHECK-ASAN: HWAddressSanitizerDisabled
+
+// CHECK-HWASAN: AddressSanitizerDisabled
+// CHECK-HWASAN: HWAddressSanitizerEnabled
+
// CHECK-NO-ASAN: AddressSanitizerDisabled
+// CHECK-NO-ASAN: HWAddressSanitizerDisabled
diff --git a/test/Lexer/keywords_test.cpp b/test/Lexer/keywords_test.cpp
index aba8d023c761..e7edf96d937e 100644
--- a/test/Lexer/keywords_test.cpp
+++ b/test/Lexer/keywords_test.cpp
@@ -1,6 +1,7 @@
// RUN: %clang_cc1 -std=c++03 -fsyntax-only %s
// RUN: %clang_cc1 -std=c++11 -DCXX11 -fsyntax-only %s
// RUN: %clang_cc1 -std=c++14 -fconcepts-ts -DCXX11 -DCONCEPTS -fsyntax-only %s
+// RUN: %clang_cc1 -std=c++2a -DCXX11 -DCXX2A -fsyntax-only %s
// RUN: %clang_cc1 -std=c++03 -fdeclspec -DDECLSPEC -fsyntax-only %s
// RUN: %clang_cc1 -std=c++03 -fms-extensions -DDECLSPEC -fsyntax-only %s
// RUN: %clang_cc1 -std=c++03 -fborland-extensions -DDECLSPEC -fsyntax-only %s
@@ -19,7 +20,7 @@
#define NOT_KEYWORD(NAME) _Static_assert(__is_identifier(NAME), #NAME)
#define IS_TYPE(NAME) void is_##NAME##_type() { int f(NAME); }
-#ifdef CONCEPTS
+#if defined(CONCEPTS) || defined(CXX2A)
#define CONCEPTS_KEYWORD(NAME) IS_KEYWORD(NAME)
#else
#define CONCEPTS_KEYWORD(NAME) NOT_KEYWORD(NAME)
diff --git a/test/Lexer/unicode.c b/test/Lexer/unicode.c
index 30805d1acb2c..30e353fa797e 100644
--- a/test/Lexer/unicode.c
+++ b/test/Lexer/unicode.c
@@ -33,3 +33,8 @@ int main () {
int 🌷 = 🌵(🌹);
return 🌷;
}
+
+int n; = 3; // expected-warning {{treating Unicode character <U+037E> as identifier character rather than as ';' symbol}}
+int *n꞉꞉v = &n;; // expected-warning 2{{treating Unicode character <U+A789> as identifier character rather than as ':' symbol}}
+ // expected-warning@-1 {{treating Unicode character <U+037E> as identifier character rather than as ';' symbol}}
+int v=[=](auto){return~x;}(); // expected-warning 12{{treating Unicode character}}
diff --git a/test/Lexer/wchar.c b/test/Lexer/wchar.c
index de00c02f1315..47417382c954 100644
--- a/test/Lexer/wchar.c
+++ b/test/Lexer/wchar.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -fshort-wchar -verify %s
+// RUN: %clang_cc1 -fsyntax-only -fwchar-type=short -fno-signed-wchar -verify %s
void f() {
(void)L"\U00010000"; // unicode escape produces UTF-16 sequence, so no warning
diff --git a/test/Misc/ast-dump-attr.cpp b/test/Misc/ast-dump-attr.cpp
index 07f91605e71c..bf942959a85c 100644
--- a/test/Misc/ast-dump-attr.cpp
+++ b/test/Misc/ast-dump-attr.cpp
@@ -180,6 +180,14 @@ __attribute__((external_source_symbol(generated_declaration, defined_in="module"
// CHECK: FunctionDecl{{.*}} TestExternalSourceSymbolAttr5
// CHECK-NEXT: ExternalSourceSymbolAttr{{.*}} "Swift" "module" GeneratedDeclaration
+namespace TestNoEscape {
+ void noescapeFunc(int *p0, __attribute__((noescape)) int *p1) {}
+ // CHECK: `-FunctionDecl{{.*}} noescapeFunc 'void (int *, __attribute__((noescape)) int *)'
+ // CHECK-NEXT: ParmVarDecl
+ // CHECK-NEXT: ParmVarDecl
+ // CHECK-NEXT: NoEscapeAttr
+}
+
namespace TestSuppress {
[[gsl::suppress("at-namespace")]];
// CHECK: NamespaceDecl{{.*}} TestSuppress
diff --git a/test/Misc/ast-dump-c-attr.c b/test/Misc/ast-dump-c-attr.c
new file mode 100644
index 000000000000..df9c347bb412
--- /dev/null
+++ b/test/Misc/ast-dump-c-attr.c
@@ -0,0 +1,46 @@
+// RUN: %clang_cc1 -triple x86_64-pc-linux -fdouble-square-bracket-attributes -Wno-deprecated-declarations -ast-dump -ast-dump-filter Test %s | FileCheck --strict-whitespace %s
+
+int Test1 [[deprecated]];
+// CHECK: VarDecl{{.*}}Test1
+// CHECK-NEXT: DeprecatedAttr 0x{{[^ ]*}} <col:13> "" ""
+
+enum [[deprecated("Frobble")]] Test2 {
+ Test3 [[deprecated]]
+};
+// CHECK: EnumDecl{{.*}}Test2
+// CHECK-NEXT: DeprecatedAttr 0x{{[^ ]*}} <col:8, col:28> "Frobble" ""
+// CHECK-NEXT: EnumConstantDecl{{.*}}Test3
+// CHECK-NEXT: DeprecatedAttr 0x{{[^ ]*}} <col:11> "" ""
+
+struct [[deprecated]] Test4 {
+ [[deprecated("Frobble")]] int Test5, Test6;
+ int Test7 [[deprecated]] : 12;
+};
+// CHECK: RecordDecl{{.*}}Test4
+// CHECK-NEXT: DeprecatedAttr 0x{{[^ ]*}} <col:10> "" ""
+// CHECK-NEXT: FieldDecl{{.*}}Test5
+// CHECK-NEXT: DeprecatedAttr 0x{{[^ ]*}} <col:5, col:25> "Frobble" ""
+// CHECK-NEXT: FieldDecl{{.*}}Test6
+// CHECK-NEXT: DeprecatedAttr 0x{{[^ ]*}} <col:5, col:25> "Frobble" ""
+// CHECK-NEXT: FieldDecl{{.*}}Test7
+// CHECK-NEXT: IntegerLiteral{{.*}}'int' 12
+// CHECK-NEXT: DeprecatedAttr 0x{{[^ ]*}} <col:15> "" ""
+
+struct [[deprecated]] Test8;
+// CHECK: RecordDecl{{.*}}Test8
+// CHECK-NEXT: DeprecatedAttr 0x{{[^ ]*}} <col:10> "" ""
+
+[[deprecated]] void Test9(int Test10 [[deprecated]]);
+// CHECK: FunctionDecl{{.*}}Test9
+// CHECK-NEXT: ParmVarDecl{{.*}}Test10
+// CHECK-NEXT: DeprecatedAttr 0x{{[^ ]*}} <col:40> "" ""
+// CHECK-NEXT: DeprecatedAttr 0x{{[^ ]*}} <col:3> "" ""
+
+void Test11 [[deprecated]](void);
+// CHECK: FunctionDecl{{.*}}Test11
+// CHECK-NEXT: DeprecatedAttr 0x{{[^ ]*}} <col:15> "" ""
+
+void Test12(void) [[deprecated]] {}
+// CHECK: FunctionDecl{{.*}}Test12
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: DeprecatedAttr 0x{{[^ ]*}} <col:21> "" ""
diff --git a/test/Misc/ast-dump-decl.cpp b/test/Misc/ast-dump-decl.cpp
index a48261d367d9..0df8a5a2b8fb 100644
--- a/test/Misc/ast-dump-decl.cpp
+++ b/test/Misc/ast-dump-decl.cpp
@@ -73,6 +73,16 @@ namespace testTypeAliasTemplateDecl {
// CHECK-NEXT: TypeAliasDecl{{.*}} TestTypeAliasTemplateDecl 'A<T>'
namespace testCXXRecordDecl {
+ class TestEmpty {};
+// CHECK: CXXRecordDecl{{.*}} class TestEmpty
+// CHECK-NEXT: DefinitionData pass_in_registers empty aggregate standard_layout trivially_copyable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init
+// CHECK-NEXT: DefaultConstructor exists trivial constexpr
+// CHECK-NEXT: CopyConstructor simple trivial has_const_param
+// CHECK-NEXT: MoveConstructor exists simple trivial
+// CHECK-NEXT: CopyAssignment trivial has_const_param
+// CHECK-NEXT: MoveAssignment exists simple trivial
+// CHECK-NEXT: Destructor simple irrelevant trivial
+
class A { };
class B { };
class TestCXXRecordDecl : virtual A, public B {
@@ -80,6 +90,13 @@ namespace testCXXRecordDecl {
};
}
// CHECK: CXXRecordDecl{{.*}} class TestCXXRecordDecl
+// CHECK-NEXT: DefinitionData{{$}}
+// CHECK-NEXT: DefaultConstructor exists non_trivial
+// CHECK-NEXT: CopyConstructor simple non_trivial has_const_param
+// CHECK-NEXT: MoveConstructor exists simple non_trivial
+// CHECK-NEXT: CopyAssignment non_trivial has_const_param
+// CHECK-NEXT: MoveAssignment exists simple non_trivial
+// CHECK-NEXT: Destructor simple irrelevant trivial
// CHECK-NEXT: virtual private 'class testCXXRecordDecl::A'
// CHECK-NEXT: public 'class testCXXRecordDecl::B'
// CHECK-NEXT: CXXRecordDecl{{.*}} class TestCXXRecordDecl
@@ -89,7 +106,7 @@ template<class...T>
class TestCXXRecordDeclPack : public T... {
};
// CHECK: CXXRecordDecl{{.*}} class TestCXXRecordDeclPack
-// CHECK-NEXT: public 'T'...
+// CHECK: public 'T'...
// CHECK-NEXT: CXXRecordDecl{{.*}} class TestCXXRecordDeclPack
thread_local int TestThreadLocalInt;
@@ -250,14 +267,14 @@ namespace testClassTemplateDecl {
// CHECK: ClassTemplateDecl{{.*}} TestClassTemplate
// CHECK-NEXT: TemplateTypeParmDecl
// CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplate
-// CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplate
+// CHECK: CXXRecordDecl{{.*}} class TestClassTemplate
// CHECK-NEXT: AccessSpecDecl{{.*}} public
// CHECK-NEXT: CXXConstructorDecl{{.*}} <line:{{.*}}:5, col:23>
// CHECK-NEXT: CXXDestructorDecl{{.*}} <line:{{.*}}:5, col:24>
// CHECK-NEXT: CXXMethodDecl{{.*}} <line:{{.*}}:5, col:11>
// CHECK-NEXT: FieldDecl{{.*}} i
// CHECK-NEXT: ClassTemplateSpecializationDecl{{.*}} class TestClassTemplate
-// CHECK-NEXT: TemplateArgument{{.*}}A
+// CHECK: TemplateArgument{{.*}}A
// CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplate
// CHECK-NEXT: AccessSpecDecl{{.*}} public
// CHECK-NEXT: CXXConstructorDecl{{.*}} <line:{{.*}}:5, col:23>
@@ -269,12 +286,13 @@ namespace testClassTemplateDecl {
// CHECK-NEXT: ClassTemplateSpecialization{{.*}} 'TestClassTemplate'
// CHECK: ClassTemplateSpecializationDecl{{.*}} class TestClassTemplate
-// CHECK-NEXT: TemplateArgument{{.*}}B
+// CHECK-NEXT: DefinitionData
+// CHECK: TemplateArgument{{.*}}B
// CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplate
// CHECK-NEXT: FieldDecl{{.*}} j
// CHECK: ClassTemplateSpecializationDecl{{.*}} class TestClassTemplate
-// CHECK-NEXT: TemplateArgument{{.*}}C
+// CHECK: TemplateArgument{{.*}}C
// CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplate
// CHECK-NEXT: AccessSpecDecl{{.*}} public
// CHECK-NEXT: CXXConstructorDecl{{.*}} <line:{{.*}}:5, col:23>
@@ -283,7 +301,7 @@ namespace testClassTemplateDecl {
// CHECK-NEXT: FieldDecl{{.*}} i
// CHECK: ClassTemplateSpecializationDecl{{.*}} class TestClassTemplate
-// CHECK-NEXT: TemplateArgument{{.*}}D
+// CHECK: TemplateArgument{{.*}}D
// CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplate
// CHECK-NEXT: AccessSpecDecl{{.*}} public
// CHECK-NEXT: CXXConstructorDecl{{.*}} <line:{{.*}}:5, col:23>
@@ -292,7 +310,7 @@ namespace testClassTemplateDecl {
// CHECK-NEXT: FieldDecl{{.*}} i
// CHECK: ClassTemplatePartialSpecializationDecl{{.*}} class TestClassTemplatePartial
-// CHECK-NEXT: TemplateArgument
+// CHECK: TemplateArgument
// CHECK-NEXT: TemplateArgument{{.*}}A
// CHECK-NEXT: TemplateTypeParmDecl
// CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplatePartial
@@ -326,13 +344,13 @@ namespace testCanonicalTemplate {
// CHECK: ClassTemplateDecl{{.*}} TestClassTemplate
// CHECK-NEXT: TemplateTypeParmDecl
// CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplate
- // CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplate
+ // CHECK: CXXRecordDecl{{.*}} class TestClassTemplate
// CHECK-NEXT: FriendDecl
// CHECK-NEXT: ClassTemplateDecl{{.*}} TestClassTemplate
// CHECK-NEXT: TemplateTypeParmDecl
// CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplate
// CHECK-NEXT: ClassTemplateSpecializationDecl{{.*}} class TestClassTemplate
- // CHECK-NEXT: TemplateArgument{{.*}}A
+ // CHECK: TemplateArgument{{.*}}A
// CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplate
}
@@ -384,27 +402,27 @@ namespace TestTemplateArgument {
template<typename> class testType { };
template class testType<int>;
// CHECK: ClassTemplateSpecializationDecl{{.*}} class testType
- // CHECK-NEXT: TemplateArgument{{.*}} type 'int'
+ // CHECK: TemplateArgument{{.*}} type 'int'
template<int fp(void)> class testDecl { };
template class testDecl<foo>;
// CHECK: ClassTemplateSpecializationDecl{{.*}} class testDecl
- // CHECK-NEXT: TemplateArgument{{.*}} decl
+ // CHECK: TemplateArgument{{.*}} decl
// CHECK-NEXT: Function{{.*}}foo
template class testDecl<nullptr>;
// CHECK: ClassTemplateSpecializationDecl{{.*}} class testDecl
- // CHECK-NEXT: TemplateArgument{{.*}} nullptr
+ // CHECK: TemplateArgument{{.*}} nullptr
template<int> class testIntegral { };
template class testIntegral<1>;
// CHECK: ClassTemplateSpecializationDecl{{.*}} class testIntegral
- // CHECK-NEXT: TemplateArgument{{.*}} integral 1
+ // CHECK: TemplateArgument{{.*}} integral 1
template<template<typename> class> class testTemplate { };
template class testTemplate<A>;
// CHECK: ClassTemplateSpecializationDecl{{.*}} class testTemplate
- // CHECK-NEXT: TemplateArgument{{.*}} A
+ // CHECK: TemplateArgument{{.*}} A
template<template<typename> class ...T> class C {
B<T...> testTemplateExpansion;
@@ -414,13 +432,13 @@ namespace TestTemplateArgument {
template<int, int = 0> class testExpr;
template<int I> class testExpr<I> { };
// CHECK: ClassTemplatePartialSpecializationDecl{{.*}} class testExpr
- // CHECK-NEXT: TemplateArgument{{.*}} expr
+ // CHECK: TemplateArgument{{.*}} expr
// CHECK-NEXT: DeclRefExpr{{.*}}I
template<int, int ...> class testPack { };
template class testPack<0, 1, 2>;
// CHECK: ClassTemplateSpecializationDecl{{.*}} class testPack
- // CHECK-NEXT: TemplateArgument{{.*}} integral 0
+ // CHECK: TemplateArgument{{.*}} integral 0
// CHECK-NEXT: TemplateArgument{{.*}} pack
// CHECK-NEXT: TemplateArgument{{.*}} integral 1
// CHECK-NEXT: TemplateArgument{{.*}} integral 2
@@ -467,7 +485,7 @@ private:
protected:
};
// CHECK: CXXRecordDecl{{.*}} class TestAccessSpecDecl
-// CHECK-NEXT: CXXRecordDecl{{.*}} class TestAccessSpecDecl
+// CHECK: CXXRecordDecl{{.*}} class TestAccessSpecDecl
// CHECK-NEXT: AccessSpecDecl{{.*}} public
// CHECK-NEXT: AccessSpecDecl{{.*}} private
// CHECK-NEXT: AccessSpecDecl{{.*}} protected
@@ -478,7 +496,7 @@ template<typename T> class TestFriendDecl {
friend T;
};
// CHECK: CXXRecord{{.*}} TestFriendDecl
-// CHECK-NEXT: CXXRecord{{.*}} TestFriendDecl
+// CHECK: CXXRecord{{.*}} TestFriendDecl
// CHECK-NEXT: FriendDecl
// CHECK-NEXT: FunctionDecl{{.*}} foo
// CHECK-NEXT: FriendDecl{{.*}} 'class A':'class A'
diff --git a/test/Misc/ast-dump-invalid.cpp b/test/Misc/ast-dump-invalid.cpp
index aa6cd526929f..842b057a4a54 100644
--- a/test/Misc/ast-dump-invalid.cpp
+++ b/test/Misc/ast-dump-invalid.cpp
@@ -51,7 +51,7 @@ double Str::foo1(double, invalid_type)
}
// CHECK: NamespaceDecl {{.*}} <{{.*}}> {{.*}} TestInvalidFunctionDecl
// CHECK-NEXT: |-CXXRecordDecl {{.*}} <line:46:1, line:48:1> line:46:8 struct Str definition
-// CHECK-NEXT: | |-CXXRecordDecl {{.*}} <col:1, col:8> col:8 implicit struct Str
+// CHECK: | |-CXXRecordDecl {{.*}} <col:1, col:8> col:8 implicit struct Str
// CHECK-NEXT: | `-CXXMethodDecl {{.*}} <line:47:4, col:36> col:11 invalid foo1 'double (double, int)'
// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:16> col:22 'double'
// CHECK-NEXT: | `-ParmVarDecl {{.*}} <col:24, <invalid sloc>> col:36 invalid 'int'
diff --git a/test/Misc/find-diagnostic-id.c b/test/Misc/find-diagnostic-id.c
index bef66178f96f..1cddde747f7d 100644
--- a/test/Misc/find-diagnostic-id.c
+++ b/test/Misc/find-diagnostic-id.c
@@ -1,5 +1,7 @@
-// RUN: diagtool find-diagnostic-id warn_unused_variable | FileCheck %s
+// RUN: diagtool find-diagnostic-id warn_unused_variable > %t; FileCheck %s < %t
+// RUN: cat %t | xargs diagtool find-diagnostic-id | FileCheck %s --check-prefix=INVERSE
// RUN: not diagtool find-diagnostic-id warn_unused_vars 2>&1 | FileCheck --check-prefix=ERROR %s
// CHECK: {{^[0-9]+$}}
+// INVERSE: warn_unused_variable
// ERROR: error: invalid diagnostic 'warn_unused_vars'
diff --git a/test/Misc/pragma-attribute-cxx-subject-match-rules.cpp b/test/Misc/pragma-attribute-cxx-subject-match-rules.cpp
index b7741343ad45..18dfb43a384d 100644
--- a/test/Misc/pragma-attribute-cxx-subject-match-rules.cpp
+++ b/test/Misc/pragma-attribute-cxx-subject-match-rules.cpp
@@ -44,9 +44,9 @@ struct testStructRecord {
int testStructRecordField;
};
// CHECK-RECORD: CXXRecordDecl{{.*}} testStructRecord
-// CHECK-RECORD-NEXT: AnnotateAttr{{.*}} "test"
+// CHECK-RECORD: AnnotateAttr{{.*}} "test"
// CHECK-RECORD_UNLESS_IS_UNION-LABEL: CXXRecordDecl{{.*}} testStructRecord
-// CHECK-RECORD_UNLESS_IS_UNION-NEXT: AnnotateAttr{{.*}} "test"
+// CHECK-RECORD_UNLESS_IS_UNION: AnnotateAttr{{.*}} "test"
// CHECK-FIELD: FieldDecl{{.*}} testStructRecordField
// CHECK-FIELD-NEXT: AnnotateAttr{{.*}} "test"
@@ -54,9 +54,9 @@ class testClassRecord {
int testClassRecordField;
};
// CHECK-RECORD: CXXRecordDecl{{.*}} testClassRecord
-// CHECK-RECORD-NEXT: AnnotateAttr{{.*}} "test"
+// CHECK-RECORD: AnnotateAttr{{.*}} "test"
// CHECK-RECORD_UNLESS_IS_UNION-LABEL: CXXRecordDecl{{.*}} testClassRecord
-// CHECK-RECORD_UNLESS_IS_UNION-NEXT: AnnotateAttr{{.*}} "test"
+// CHECK-RECORD_UNLESS_IS_UNION: AnnotateAttr{{.*}} "test"
// CHECK-FIELD: FieldDecl{{.*}} testClassRecordField
// CHECK-FIELD-NEXT: AnnotateAttr{{.*}} "test"
@@ -64,7 +64,7 @@ union testUnionRecord {
int testUnionRecordField;
};
// CHECK-RECORD: CXXRecordDecl{{.*}} testUnionRecord
-// CHECK-RECORD-NEXT: AnnotateAttr{{.*}} "test"
+// CHECK-RECORD: AnnotateAttr{{.*}} "test"
// CHECK-RECORD_UNLESS_IS_UNION-LABEL: CXXRecordDecl{{.*}} testUnionRecord
// CHECK-RECORD_UNLESS_IS_UNION-NOT: AnnotateAttr{{.*}} "test"
// CHECK-FIELD: FieldDecl{{.*}} testUnionRecordField
diff --git a/test/Misc/pragma-attribute-cxx.cpp b/test/Misc/pragma-attribute-cxx.cpp
index c241c4e4bdba..a8a3bdebc654 100644
--- a/test/Misc/pragma-attribute-cxx.cpp
+++ b/test/Misc/pragma-attribute-cxx.cpp
@@ -17,7 +17,7 @@ class testClass2 {
testClass2 *operator -> ();
};
// CHECK-LABEL: CXXRecordDecl{{.*}} testClass2
-// CHECK-NEXT: AnnotateAttr{{.*}} "test"
+// CHECK: AnnotateAttr{{.*}} "test"
// CHECK: CXXMethodDecl{{.*}} testMethod1
// CHECK-NEXT: ParmVarDecl{{.*}} param
// CHECK-NEXT: AnnotateAttr{{.*}} "test"
@@ -76,7 +76,7 @@ void testLambdaMethod() {
// CHECK-LABEL: FunctionDecl{{.*}} testLambdaMethod
// CHECK: LambdaExpr
// CHECK-NEXT: CXXRecordDecl
-// CHECK-NEXT: CXXMethodDecl{{.*}} operator()
+// CHECK: CXXMethodDecl{{.*}} operator()
// CHECK-NEXT: CompoundStmt
// CHECK-NEXT: AnnotateAttr{{.*}} "test"
diff --git a/test/Misc/pragma-attribute-supported-attributes-list.test b/test/Misc/pragma-attribute-supported-attributes-list.test
index d698276f7dc4..1171a2d3709a 100644
--- a/test/Misc/pragma-attribute-supported-attributes-list.test
+++ b/test/Misc/pragma-attribute-supported-attributes-list.test
@@ -2,7 +2,7 @@
// The number of supported attributes should never go down!
-// CHECK: #pragma clang attribute supports 62 attributes:
+// CHECK: #pragma clang attribute supports 66 attributes:
// CHECK-NEXT: AMDGPUFlatWorkGroupSize (SubjectMatchRule_function)
// CHECK-NEXT: AMDGPUNumSGPR (SubjectMatchRule_function)
// CHECK-NEXT: AMDGPUNumVGPR (SubjectMatchRule_function)
@@ -31,12 +31,16 @@
// CHECK-NEXT: InternalLinkage (SubjectMatchRule_variable, SubjectMatchRule_function, SubjectMatchRule_record)
// CHECK-NEXT: LTOVisibilityPublic (SubjectMatchRule_record)
// CHECK-NEXT: MicroMips (SubjectMatchRule_function)
+// CHECK-NEXT: MipsLongCall (SubjectMatchRule_function)
+// CHECK-NEXT: MipsShortCall (SubjectMatchRule_function)
// CHECK-NEXT: NoDebug (SubjectMatchRule_hasType_functionType, SubjectMatchRule_objc_method, SubjectMatchRule_variable_not_is_parameter)
// CHECK-NEXT: NoDuplicate (SubjectMatchRule_function)
+// CHECK-NEXT: NoEscape (SubjectMatchRule_variable_is_parameter)
// CHECK-NEXT: NoMicroMips (SubjectMatchRule_function)
// CHECK-NEXT: NoSanitize (SubjectMatchRule_function, SubjectMatchRule_objc_method, SubjectMatchRule_variable_is_global)
// CHECK-NEXT: NoSanitizeSpecific (SubjectMatchRule_function, SubjectMatchRule_variable_is_global)
// CHECK-NEXT: NoSplitStack (SubjectMatchRule_function)
+// CHECK-NEXT: NoThrow (SubjectMatchRule_function)
// CHECK-NEXT: NotTailCalled (SubjectMatchRule_function)
// CHECK-NEXT: ObjCBoxable (SubjectMatchRule_record)
// CHECK-NEXT: ObjCMethodFamily (SubjectMatchRule_objc_method)
@@ -63,5 +67,5 @@
// CHECK-NEXT: Target (SubjectMatchRule_function)
// CHECK-NEXT: TestTypestate (SubjectMatchRule_function_is_member)
// CHECK-NEXT: WarnUnusedResult (SubjectMatchRule_objc_method, SubjectMatchRule_enum, SubjectMatchRule_record, SubjectMatchRule_hasType_functionType)
-// CHECK-NEXT: XRayInstrument (SubjectMatchRule_function_is_member, SubjectMatchRule_objc_method, SubjectMatchRule_function)
-// CHECK-NEXT: XRayLogArgs (SubjectMatchRule_function_is_member, SubjectMatchRule_objc_method, SubjectMatchRule_function)
+// CHECK-NEXT: XRayInstrument (SubjectMatchRule_function, SubjectMatchRule_objc_method)
+// CHECK-NEXT: XRayLogArgs (SubjectMatchRule_function, SubjectMatchRule_objc_method)
diff --git a/test/Misc/warning-flags-tree.c b/test/Misc/warning-flags-tree.c
index d71c9f618b42..01ba4971ee06 100644
--- a/test/Misc/warning-flags-tree.c
+++ b/test/Misc/warning-flags-tree.c
@@ -1,6 +1,6 @@
-// RUN: diagtool tree | FileCheck -strict-whitespace %s
-// RUN: diagtool tree -Weverything | FileCheck -strict-whitespace %s
-// RUN: diagtool tree everything | FileCheck -strict-whitespace %s
+// RUN: diagtool tree --internal | FileCheck -strict-whitespace %s
+// RUN: diagtool tree --internal -Weverything | FileCheck -strict-whitespace %s
+// RUN: diagtool tree --internal everything | FileCheck -strict-whitespace %s
//
// These three ways of running diagtool tree are the same:
// they produce a tree for every top-level diagnostic flag.
@@ -29,8 +29,7 @@
// RUN: not diagtool tree -Wthis-is-not-a-valid-flag
-
-// RUN: diagtool tree -Wgnu | FileCheck -strict-whitespace -check-prefix CHECK-GNU %s
+// RUN: diagtool tree --internal -Wgnu | FileCheck -strict-whitespace -check-prefix CHECK-GNU %s
// CHECK-GNU: -Wgnu
// CHECK-GNU: -Wgnu-designator
// CHECK-GNU: ext_gnu_array_range
@@ -40,7 +39,7 @@
// CHECK-GNU: ext_vla
// There are more GNU extensions but we don't need to check them all.
-// RUN: diagtool tree --flags-only -Wgnu | FileCheck -check-prefix CHECK-FLAGS-ONLY %s
+// RUN: diagtool tree -Wgnu | FileCheck -check-prefix CHECK-FLAGS-ONLY %s
// CHECK-FLAGS-ONLY: -Wgnu
// CHECK-FLAGS-ONLY: -Wgnu-designator
// CHECK-FLAGS-ONLY-NOT: ext_gnu_array_range
diff --git a/test/Misc/warning-flags.c b/test/Misc/warning-flags.c
index 5172d3b15a90..2c48fa4dbf39 100644
--- a/test/Misc/warning-flags.c
+++ b/test/Misc/warning-flags.c
@@ -18,7 +18,7 @@ This test serves two purposes:
The list of warnings below should NEVER grow. It should gradually shrink to 0.
-CHECK: Warnings without flags (78):
+CHECK: Warnings without flags (77):
CHECK-NEXT: ext_excess_initializers
CHECK-NEXT: ext_excess_initializers_in_char_array_initializer
CHECK-NEXT: ext_expected_semi_decl_list
@@ -94,7 +94,6 @@ CHECK-NEXT: warn_typecheck_function_qualifiers
CHECK-NEXT: warn_undef_interface
CHECK-NEXT: warn_undef_interface_suggest
CHECK-NEXT: warn_undef_protocolref
-CHECK-NEXT: warn_use_out_of_scope_declaration
CHECK-NEXT: warn_weak_identifier_undeclared
CHECK-NEXT: warn_weak_import
diff --git a/test/Modules/ExtDebugInfo.cpp b/test/Modules/ExtDebugInfo.cpp
index ed9d1e859d83..97386bc4d007 100644
--- a/test/Modules/ExtDebugInfo.cpp
+++ b/test/Modules/ExtDebugInfo.cpp
@@ -69,6 +69,8 @@ WithSpecializedBase<int> definedLocally4;
void foo() {
anon.i = GlobalStruct.i = GlobalUnion.i = GlobalEnum;
+ A a;
+ Virtual virt;
}
// CHECK: ![[CPP:.*]] = !DIFile(filename: {{.*}}ExtDebugInfo.cpp"
@@ -210,3 +212,10 @@ void foo() {
// CHECK-SAME: dwoId:
// CHECK-PCH: !DICompileUnit({{.*}}splitDebugFilename:
// CHECK-PCH: dwoId: 18446744073709551614
+
+// CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "A",
+// CHECK-SAME: DIFlagFwdDecl, identifier: "_ZTS1A")
+
+// There is a full definition of the type available in the module.
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "Virtual",
+// CHECK-SAME: DIFlagFwdDecl, identifier: "_ZTS7Virtual")
diff --git a/test/Modules/Inputs/DebugCXX.h b/test/Modules/Inputs/DebugCXX.h
index c9cd68f30c46..1ccf8d302f13 100644
--- a/test/Modules/Inputs/DebugCXX.h
+++ b/test/Modules/Inputs/DebugCXX.h
@@ -54,9 +54,9 @@ namespace DebugCXX {
}
// Virtual class with a forward declaration.
-class FwdVirtual;
-class FwdVirtual {
- virtual ~FwdVirtual() {}
+struct Virtual;
+struct Virtual {
+ virtual ~Virtual() {}
};
struct PureForwardDecl;
diff --git a/test/Modules/Inputs/codegen/foo.h b/test/Modules/Inputs/codegen/foo.h
index bd3b6489e710..76ad6559cca0 100644
--- a/test/Modules/Inputs/codegen/foo.h
+++ b/test/Modules/Inputs/codegen/foo.h
@@ -29,4 +29,7 @@ inline void inst_decl() {
inst<float>();
}
+__attribute__((always_inline)) inline void always_inl() {
+}
+
asm("narf");
diff --git a/test/Modules/Inputs/codegen/use.cpp b/test/Modules/Inputs/codegen/use.cpp
index cd1a4a642d09..3e551881f636 100644
--- a/test/Modules/Inputs/codegen/use.cpp
+++ b/test/Modules/Inputs/codegen/use.cpp
@@ -6,3 +6,6 @@ void non_modular_use_of_implicit_dtor() {
void use_of_instantiated_declaration_without_definition() {
inst<int>();
}
+void call_always_inline() {
+ always_inl();
+}
diff --git a/test/Modules/Inputs/export_as_test.modulemap b/test/Modules/Inputs/export_as_test.modulemap
new file mode 100644
index 000000000000..4aaec4194ef5
--- /dev/null
+++ b/test/Modules/Inputs/export_as_test.modulemap
@@ -0,0 +1,9 @@
+module PrivateFoo {
+ export_as Foo
+ export_as Bar
+ export_as Bar
+
+ module Sub {
+ export_as Wibble
+ }
+}
diff --git a/test/Modules/ModuleDebugInfo.cpp b/test/Modules/ModuleDebugInfo.cpp
index 71b05e5aeb8b..008b3e4f2bab 100644
--- a/test/Modules/ModuleDebugInfo.cpp
+++ b/test/Modules/ModuleDebugInfo.cpp
@@ -86,10 +86,10 @@
// CHECK-SAME: flags: DIFlagFwdDecl
// CHECK-SAME: identifier: "_ZTSN8DebugCXX8TemplateIfNS_6traitsIfEEEE")
-// CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "FwdVirtual"
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "Virtual"
// CHECK-SAME: elements:
-// CHECK-SAME: identifier: "_ZTS10FwdVirtual")
-// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "_vptr$FwdVirtual"
+// CHECK-SAME: identifier: "_ZTS7Virtual")
+// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "_vptr$Virtual"
// CHECK: !DICompositeType(tag: DW_TAG_union_type,
// CHECK-NOT: name:
@@ -111,6 +111,11 @@
// CHECK-SAME: name: "InAnonymousNamespace",
// CHECK-SAME: elements: !{{[0-9]+}})
+// CHECK: ![[A:.*]] = {{.*}}!DICompositeType(tag: DW_TAG_class_type, name: "A",
+// CHECK-SAME: elements:
+// CHECK-SAME: vtableHolder: ![[A]],
+// CHECK-SAME: identifier: "_ZTS1A")
+
// CHECK: ![[DERIVED:.*]] = {{.*}}!DICompositeType(tag: DW_TAG_class_type, name: "Derived",
// CHECK-SAME: identifier: "_ZTS7Derived")
// CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "B", scope: ![[DERIVED]],
diff --git a/test/Modules/adl.cpp b/test/Modules/adl.cpp
new file mode 100644
index 000000000000..a1055a889d00
--- /dev/null
+++ b/test/Modules/adl.cpp
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -fmodules -verify -fno-modules-error-recovery -fno-spell-checking %s
+// RUN: %clang_cc1 -fmodules -verify -fno-modules-error-recovery -DONLY_Y %s
+
+#pragma clang module build a
+module a {
+ explicit module x {}
+ explicit module y {}
+}
+#pragma clang module contents
+#pragma clang module begin a.x
+namespace N {
+ template<typename T> extern int f(T) { return 0; }
+}
+#pragma clang module end
+
+#pragma clang module begin a.y
+#pragma clang module import a.x
+using N::f;
+#pragma clang module end
+#pragma clang module endbuild
+
+namespace N { struct A {}; }
+struct B {};
+
+#ifndef ONLY_Y
+#pragma clang module import a.x
+void test1() {
+ f(N::A());
+ f(B()); // expected-error {{use of undeclared identifier 'f'}}
+}
+#else
+// expected-no-diagnostics
+#endif
+
+#pragma clang module import a.y
+void test2() {
+ // These are OK even if a.x is not imported.
+ f(N::A());
+ f(B());
+}
diff --git a/test/Modules/anon-linkage.cpp b/test/Modules/anon-linkage.cpp
new file mode 100644
index 000000000000..590638292b5e
--- /dev/null
+++ b/test/Modules/anon-linkage.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -std=c++17 -fmodules-ts %s
+
+typedef struct {
+ int c;
+ union {
+ int n;
+ char c[4];
+ } v;
+} mbstate;
+
+export module M;
+export using ::mbstate;
diff --git a/test/Modules/builtin-import.mm b/test/Modules/builtin-import.mm
index 2536ac51c42f..cbc312b05904 100644
--- a/test/Modules/builtin-import.mm
+++ b/test/Modules/builtin-import.mm
@@ -1,7 +1,5 @@
-// REQUIRES: system-darwin
-
// RUN: rm -rf %t
-// RUN: %clang -cc1 -fsyntax-only -nostdinc++ -isysroot %S/Inputs/libc-libcxx/sysroot -isystem %S/Inputs/libc-libcxx/sysroot/usr/include/c++/v1 -std=c++11 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -x objective-c++ -fmodules-local-submodule-visibility %s
+// RUN: %clang -cc1 -fsyntax-only -nobuiltininc -nostdinc++ -isysroot %S/Inputs/libc-libcxx/sysroot -isystem %S/Inputs/libc-libcxx/sysroot/usr/include/c++/v1 -isystem %S/Inputs/libc-libcxx/sysroot/usr/include -std=c++11 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -x objective-c++ -fmodules-local-submodule-visibility %s
#include <stdio.h>
#include <stddef.h>
diff --git a/test/Modules/codegen-opt.test b/test/Modules/codegen-opt.test
index 2f4997a7c73f..f62cf38a5356 100644
--- a/test/Modules/codegen-opt.test
+++ b/test/Modules/codegen-opt.test
@@ -25,7 +25,13 @@ FOO-NOT: {{define|declare}}
FOO: declare void @_Z2f1Ri(i32*
FOO-NOT: {{define|declare}}
-FIXME: this internal function should be weak_odr, comdat, and with a new mangling
+Internal functions are not modularly code generated - they are
+internal wherever they're used. This might not be ideal, but
+continues to workaround/support some oddities that backwards
+compatible modules have seen and supported in the wild. To remove
+the duplication here, the internal functions would need to be
+promoted to weak_odr, placed in comdat and given a new mangling -
+this would be needed for the C++ Modules TS anyway.
FOO: define internal void @_ZL2f2v() #{{[0-9]+}}
FOO-NOT: {{define|declare}}
@@ -45,7 +51,7 @@ BAR-OPT: define available_externally void @_Z3foov()
BAR-CMN-NOT: {{define|declare}}
BAR-OPT: declare void @_Z2f1Ri(i32*
BAR-OPT-NOT: {{define|declare}}
-BAR-OPT: define available_externally void @_ZL2f2v()
+BAR-OPT: define internal void @_ZL2f2v()
BAR-OPT-NOT: {{define|declare}}
@@ -61,5 +67,5 @@ USE-OPT: define available_externally void @_Z3foov()
USE-OPT-NOT: {{define|declare}}
USE-OPT: declare void @_Z2f1Ri(i32*
USE-OPT-NOT: {{define|declare}}
-USE-OPT: define available_externally void @_ZL2f2v()
+USE-OPT: define internal void @_ZL2f2v()
USE-OPT-NOT: {{define|declare}}
diff --git a/test/Modules/codegen.test b/test/Modules/codegen.test
index 1bdea5df4317..a919933da2d2 100644
--- a/test/Modules/codegen.test
+++ b/test/Modules/codegen.test
@@ -4,7 +4,7 @@ REQUIRES: x86-registered-target
RUN: %clang_cc1 -triple=x86_64-linux-gnu -fmodules-codegen -fmodules-debuginfo -x c++ -fmodules -emit-module -fmodule-name=foo %S/Inputs/codegen/foo.modulemap -o %t/foo.pcm
RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -debug-info-kind=limited -o - %t/foo.pcm | FileCheck --check-prefix=FOO --check-prefix=BOTH %s
-RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -debug-info-kind=limited -o - -fmodules -fmodule-file=%t/foo.pcm %S/Inputs/codegen/use.cpp | FileCheck --check-prefix=BOTH --check-prefix=USE %s
+RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -debug-info-kind=limited -o - -fmodules -disable-llvm-passes -fmodule-file=%t/foo.pcm %S/Inputs/codegen/use.cpp | FileCheck --check-prefix=BOTH --check-prefix=USE %s
For want of any better definition, inline asm goes "everywhere" the same as it
if it were in a header (with the disadvantage that the inline asm will be
@@ -23,6 +23,7 @@ USE: module asm "narf"
FOO: $_Z2f1PKcz = comdat any
FOO: $_ZN13implicit_dtorD1Ev = comdat any
USE: $_Z4instIiEvv = comdat any
+USE: $_Z10always_inlv = comdat any
FOO: $_ZN13implicit_dtorD2Ev = comdat any
FOO: define weak_odr void @_Z2f1PKcz(i8* %fmt, ...) #{{[0-9]+}} comdat
FOO: call void @llvm.va_start(i8* %{{[a-zA-Z0-9]*}})
@@ -38,6 +39,7 @@ FOO: define weak_odr void @_ZN13implicit_dtorD2Ev
USE: define linkonce_odr void @_ZN20uninst_implicit_dtorD1Ev
USE: define linkonce_odr void @_Z4instIiEvv
+USE: define linkonce_odr void @_Z10always_inlv
USE: define linkonce_odr void @_ZN20uninst_implicit_dtorD2Ev
Modular debug info puts the definition of a class defined in a module in that
diff --git a/test/Modules/crash-typo-correction-visibility.cpp b/test/Modules/crash-typo-correction-visibility.cpp
index 518293026a63..9f0ed3b7b132 100644
--- a/test/Modules/crash-typo-correction-visibility.cpp
+++ b/test/Modules/crash-typo-correction-visibility.cpp
@@ -1,5 +1,6 @@
-// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fmodule-name=module -o %T/module.pcm -emit-module %S/Inputs/crash-typo-correction-visibility/module.modulemap
-// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fmodule-file=%T/module.pcm %s -verify
+// RUN: mkdir -p %t
+// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fmodule-name=module -o %t/module.pcm -emit-module %S/Inputs/crash-typo-correction-visibility/module.modulemap
+// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fmodule-file=%t/module.pcm %s -verify
struct S {
int member; // expected-note {{declared here}}
diff --git a/test/Modules/crash-vfs-ivfsoverlay.m b/test/Modules/crash-vfs-ivfsoverlay.m
index abbc0151a8cf..85aaeaef67a5 100644
--- a/test/Modules/crash-vfs-ivfsoverlay.m
+++ b/test/Modules/crash-vfs-ivfsoverlay.m
@@ -7,6 +7,7 @@
// RUN: %S/../VFS/Inputs/vfsoverlay2.yaml > %t/srcvfs.yaml
// RUN: not env FORCE_CLANG_DIAGNOSTICS_CRASH= TMPDIR=%t TEMP=%t TMP=%t \
+// RUN: ASAN_OPTIONS=detect_leaks=0 \
// RUN: %clang -fsyntax-only -nostdinc %s \
// RUN: -I %S/Inputs/crash-recovery/usr/include \
// RUN: -ivfsoverlay %t/srcvfs.yaml \
diff --git a/test/Modules/cxx-templates.cpp b/test/Modules/cxx-templates.cpp
index 401b7704900b..25f8a9992585 100644
--- a/test/Modules/cxx-templates.cpp
+++ b/test/Modules/cxx-templates.cpp
@@ -251,8 +251,22 @@ namespace Std {
// CHECK-DUMP: ClassTemplateSpecializationDecl {{.*}} prev {{.*}} SomeTemplate
// CHECK-DUMP-NEXT: TemplateArgument type 'char [2]'
// CHECK-DUMP: ClassTemplateSpecializationDecl {{.*}} SomeTemplate definition
+// CHECK-DUMP-NEXT: DefinitionData
+// CHECK-DUMP-NEXT: DefaultConstructor
+// CHECK-DUMP-NEXT: CopyConstructor
+// CHECK-DUMP-NEXT: MoveConstructor
+// CHECK-DUMP-NEXT: CopyAssignment
+// CHECK-DUMP-NEXT: MoveAssignment
+// CHECK-DUMP-NEXT: Destructor
// CHECK-DUMP-NEXT: TemplateArgument type 'char [2]'
// CHECK-DUMP: ClassTemplateSpecializationDecl {{.*}} prev {{.*}} SomeTemplate
// CHECK-DUMP-NEXT: TemplateArgument type 'char [1]'
// CHECK-DUMP: ClassTemplateSpecializationDecl {{.*}} SomeTemplate definition
+// CHECK-DUMP-NEXT: DefinitionData
+// CHECK-DUMP-NEXT: DefaultConstructor
+// CHECK-DUMP-NEXT: CopyConstructor
+// CHECK-DUMP-NEXT: MoveConstructor
+// CHECK-DUMP-NEXT: CopyAssignment
+// CHECK-DUMP-NEXT: MoveAssignment
+// CHECK-DUMP-NEXT: Destructor
// CHECK-DUMP-NEXT: TemplateArgument type 'char [1]'
diff --git a/test/Modules/cxx17-inline-variables.cpp b/test/Modules/cxx17-inline-variables.cpp
new file mode 100644
index 000000000000..be6a190a256b
--- /dev/null
+++ b/test/Modules/cxx17-inline-variables.cpp
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only -fmodules %s
+
+#pragma clang module build a
+module a {}
+#pragma clang module contents
+#pragma clang module begin a
+
+template <class c, c e> struct ak { static constexpr c value = e; };
+ak<bool, true> instantiate_class_definition;
+
+#pragma clang module end /* a */
+#pragma clang module endbuild
+
+
+#pragma clang module build o
+module o {}
+#pragma clang module contents
+#pragma clang module begin o
+#pragma clang module import a
+
+inline int instantiate_var_definition() { return ak<bool, true>::value; }
+
+#pragma clang module end
+#pragma clang module endbuild
+
+
+#pragma clang module import o
+#pragma clang module import a
+
+int main() { return ak<bool, true>::value; }
diff --git a/test/Modules/export_as_test.c b/test/Modules/export_as_test.c
new file mode 100644
index 000000000000..a73d6bfc460d
--- /dev/null
+++ b/test/Modules/export_as_test.c
@@ -0,0 +1,9 @@
+// RUN: rm -rf %t
+// RUN: not %clang_cc1 -fmodules -fmodules-cache-path=%t -fmodule-map-file=%S/Inputs/export_as_test.modulemap %s 2> %t.err
+// RUN: FileCheck %s < %t.err
+
+// CHECK: export_as_test.modulemap:3:13: error: conflicting re-export of module 'PrivateFoo' as 'Foo' or 'Bar'
+// CHECK: export_as_test.modulemap:4:13: warning: module 'PrivateFoo' already re-exported as 'Bar'
+// CHECK: export_as_test.modulemap:7:15: error: only top-level modules can be re-exported as public
+
+
diff --git a/test/Modules/merge-anon-in-extern_c.cpp b/test/Modules/merge-anon-in-extern_c.cpp
new file mode 100644
index 000000000000..1443251f7e61
--- /dev/null
+++ b/test/Modules/merge-anon-in-extern_c.cpp
@@ -0,0 +1,19 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -verify %s
+// expected-no-diagnostics
+
+#pragma clang module build sys_types
+module sys_types {}
+#pragma clang module contents
+#pragma clang module begin sys_types
+extern "C" {
+ typedef union { bool b; } pthread_mutex_t;
+}
+#pragma clang module end
+#pragma clang module endbuild
+
+typedef union { bool b; } pthread_mutex_t;
+#pragma clang module import sys_types
+
+const pthread_mutex_t *m;
+
diff --git a/test/Modules/module-imported-by-pch-path.m b/test/Modules/module-imported-by-pch-path.m
new file mode 100644
index 000000000000..04c6caf24dec
--- /dev/null
+++ b/test/Modules/module-imported-by-pch-path.m
@@ -0,0 +1,17 @@
+// RUN: rm -rf %t.dst %t.cache
+// RUN: mkdir -p %t.dst/folder-with-modulemap %t.dst/pch-folder
+// RUN: echo '#import "folder-with-modulemap/included.h"' > %t.dst/header.h
+// RUN: echo 'extern int MyModuleVersion;' > %t.dst/folder-with-modulemap/MyModule.h
+// RUN: echo '@import MyModule;' > %t.dst/folder-with-modulemap/included.h
+// RUN: echo 'module MyModule { header "MyModule.h" }' > %t.dst/folder-with-modulemap/module.modulemap
+
+// RUN: %clang -o %t.dst/pch-folder/header.pch -x objective-c-header -fmodules-cache-path=%t.cache -fmodules %t.dst/header.h
+// RUN: not %clang -fsyntax-only -fmodules-cache-path=%t.cache -fmodules %s -include-pch %t.dst/pch-folder/header.pch 2>&1 | FileCheck %s
+
+void test() {
+ (void)MyModuleVersion; // should be found by implicit import
+}
+
+// CHECK: module 'MyModule' in AST file '{{.*MyModule.*pcm}}' (imported by AST file '[[PCH:.*header.pch]]') is not defined in any loaded module map file; maybe you need to load '[[PATH:.*folder-with-modulemap]]
+// CHECK: consider adding '[[PATH]]' to the header search path
+// CHECK: imported by '[[PCH]]'
diff --git a/test/Modules/modules-cache-path-canonicalization.m b/test/Modules/modules-cache-path-canonicalization.m
index 9d68cb06faf8..a9d3e3478604 100644
--- a/test/Modules/modules-cache-path-canonicalization.m
+++ b/test/Modules/modules-cache-path-canonicalization.m
@@ -1,4 +1,4 @@
-// RUN: rm -rf %t/cache %T/rel
+// RUN: rm -rf %t/cache %t/rel
// This testcase reproduces a use-after-free after looking up a PCM in
// a non-canonical modules-cache-path.
@@ -22,7 +22,7 @@
// Unrelated to the above: Check that a relative path is resolved correctly.
//
-// RUN: %clang_cc1 -working-directory %T/rel -fmodules-cache-path=./cache \
+// RUN: %clang_cc1 -working-directory %t/rel -fmodules-cache-path=./cache \
// RUN: -fmodules -fimplicit-module-maps -I %S/Inputs/outofdate-rebuild \
// RUN: -fdisable-module-hash %t.m -fsyntax-only -Rmodule-build 2>&1 \
// RUN: | FileCheck %s
diff --git a/test/Modules/odr_hash.cpp b/test/Modules/odr_hash.cpp
index 68a988dc8e78..b672695dce15 100644
--- a/test/Modules/odr_hash.cpp
+++ b/test/Modules/odr_hash.cpp
@@ -12,6 +12,10 @@
// RUN: echo "#define SECOND" >> %t/Inputs/second.h
// RUN: cat %s >> %t/Inputs/second.h
+// Test that each header can compile
+// RUN: %clang_cc1 -fsyntax-only -x c++ -std=c++1z %t/Inputs/first.h
+// RUN: %clang_cc1 -fsyntax-only -x c++ -std=c++1z %t/Inputs/second.h
+
// Build module map file
// RUN: echo "module FirstModule {" >> %t/Inputs/module.map
// RUN: echo " header \"first.h\"" >> %t/Inputs/module.map
@@ -28,6 +32,13 @@
#include "second.h"
#endif
+// Used for testing
+#if defined(FIRST)
+#define ACCESS public:
+#elif defined(SECOND)
+#define ACCESS private:
+#endif
+
namespace AccessSpecifiers {
#if defined(FIRST)
struct S1 {
@@ -55,6 +66,32 @@ S2 s2;
// expected-error@second.h:* {{'AccessSpecifiers::S2' has different definitions in different modules; first difference is definition in module 'SecondModule' found protected access specifier}}
// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}
#endif
+
+#define DECLS \
+public: \
+private: \
+protected:
+
+#if defined(FIRST) || defined(SECOND)
+struct Valid1 {
+ DECLS
+};
+#else
+Valid1 v1;
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+struct Invalid1 {
+ DECLS
+ ACCESS
+};
+#else
+Invalid1 i1;
+// expected-error@second.h:* {{'AccessSpecifiers::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
+// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}
+#endif
+
+#undef DECLS
} // namespace AccessSpecifiers
namespace StaticAssert {
@@ -113,7 +150,31 @@ S4 s4;
// expected-error@second.h:* {{'StaticAssert::S4' has different definitions in different modules; first difference is definition in module 'SecondModule' found public access specifier}}
// expected-note@first.h:* {{but in 'FirstModule' found static assert}}
#endif
-}
+
+#define DECLS \
+ static_assert(4 == 4, "Message"); \
+ static_assert(5 == 5);
+
+#if defined(FIRST) || defined(SECOND)
+struct Valid1 {
+ DECLS
+};
+#else
+Valid1 v1;
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+struct Invalid1 {
+ DECLS
+ ACCESS
+};
+#else
+Invalid1 i1;
+// expected-error@second.h:* {{'StaticAssert::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
+// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}
+#endif
+#undef DECLS
+} // namespace StaticAssert
namespace Field {
#if defined(FIRST)
@@ -302,6 +363,38 @@ S13 s13;
// expected-error@first.h:* {{'Field::S13::x' from module 'FirstModule' is not present in definition of 'Field::S13' in module 'SecondModule'}}
// expected-note@second.h:* {{declaration of 'x' does not match}}
#endif
+
+#define DECLS \
+ int a; \
+ int b : 3; \
+ unsigned c : 1 + 2; \
+ s d; \
+ double e = 1.0; \
+ long f[5];
+
+#if defined(FIRST) || defined(SECOND)
+typedef short s;
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+struct Valid1 {
+ DECLS
+};
+#else
+Valid1 v1;
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+struct Invalid1 {
+ DECLS
+ ACCESS
+};
+#else
+Invalid1 i1;
+// expected-error@second.h:* {{'Field::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
+// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}
+#endif
+#undef DECLS
} // namespace Field
namespace Method {
@@ -531,6 +624,40 @@ S15 s15;
// expected-error@first.h:* {{'Method::S15::A' from module 'FirstModule' is not present in definition of 'Method::S15' in module 'SecondModule'}}
// expected-note@second.h:* {{declaration of 'A' does not match}}
#endif
+
+#define DECLS \
+ void A(); \
+ static void B(); \
+ virtual void C(); \
+ virtual void D() = 0; \
+ inline void E(); \
+ void F() const; \
+ void G() volatile; \
+ void H(int x); \
+ void I(int x = 5 + 5); \
+ void J(int); \
+ void K(int x[2]); \
+ int L();
+
+#if defined(FIRST) || defined(SECOND)
+struct Valid1 {
+ DECLS
+};
+#else
+Valid1* v1;
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+struct Invalid1 {
+ DECLS
+ ACCESS
+};
+#else
+Invalid1* i1;
+// expected-error@second.h:* {{'Method::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
+// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}
+#endif
+#undef DECLS
} // namespace Method
namespace Constructor {
@@ -565,6 +692,31 @@ S2* s2;
// expected-error@second.h:* {{'Constructor::S2' has different definitions in different modules; first difference is definition in module 'SecondModule' found constructor that has 2 parameters}}
// expected-note@first.h:* {{but in 'FirstModule' found constructor that has 1 parameter}}
#endif
+
+#define DECLS(CLASS) \
+ CLASS(int); \
+ CLASS(double); \
+ CLASS(int, int);
+
+#if defined(FIRST) || defined(SECOND)
+struct Valid1 {
+ DECLS(Valid1)
+};
+#else
+Valid1* v1;
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+struct Invalid1 {
+ DECLS(Invalid1)
+ ACCESS
+};
+#else
+Invalid1* i1;
+// expected-error@second.h:* {{'Constructor::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
+// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}
+#endif
+#undef DECLS
} // namespace Constructor
namespace Destructor {
@@ -600,32 +752,44 @@ S2 s2;
// expected-note@first.h:* {{but in 'FirstModule' found destructor is virtual}}
#endif
-} // namespace Destructor
-
-// Naive parsing of AST can lead to cycles in processing. Ensure
-// self-references don't trigger an endless cycles of AST node processing.
-namespace SelfReference {
-#if defined(FIRST)
-template <template <int> class T> class Wrapper {};
-
-template <int N> class S {
- S(Wrapper<::SelfReference::S> &Ref) {}
+#if defined(FIRST) || defined(SECOND)
+struct Valid1 {
+ ~Valid1();
};
+#else
+Valid1 v1;
+#endif
-struct Xx {
- struct Yy {
- };
+#if defined(FIRST) || defined(SECOND)
+struct Invalid1 {
+ ~Invalid1();
+ ACCESS
};
+#else
+Invalid1 i1;
+// expected-error@second.h:* {{'Destructor::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
+// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}
+#endif
-Xx::Xx::Xx::Yy yy;
+#if defined(FIRST) || defined(SECOND)
+struct Valid2 {
+ virtual ~Valid2();
+};
+#else
+Valid2 v2;
+#endif
-namespace NNS {
-template <typename> struct Foo;
-template <template <class> class T = NNS::Foo>
-struct NestedNamespaceSpecifier {};
-}
+#if defined(FIRST) || defined(SECOND)
+struct Invalid2 {
+ virtual ~Invalid2();
+ ACCESS
+};
+#else
+Invalid2 i2;
+// expected-error@second.h:* {{'Destructor::Invalid2' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
+// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}
#endif
-} // namespace SelfReference
+} // namespace Destructor
namespace TypeDef {
#if defined(FIRST)
@@ -722,6 +886,35 @@ S6 s6;
// expected-error@second.h:* {{'TypeDef::S6' has different definitions in different modules; first difference is definition in module 'SecondModule' found typedef 'b' with underlying type 'float'}}
// expected-note@first.h:* {{but in 'FirstModule' found typedef 'b' with different underlying type 'TypeDef::F' (aka 'float')}}
#endif
+
+#define DECLS \
+ typedef int A; \
+ typedef double B; \
+ typedef I C;
+
+#if defined(FIRST) || defined(SECOND)
+typedef int I;
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+struct Valid1 {
+ DECLS
+};
+#else
+Valid1 v1;
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+struct Invalid1 {
+ DECLS
+ ACCESS
+};
+#else
+Invalid1 i1;
+// expected-error@second.h:* {{'TypeDef::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
+// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}
+#endif
+#undef DECLS
} // namespace TypeDef
namespace Using {
@@ -819,6 +1012,35 @@ S6 s6;
// expected-error@second.h:* {{'Using::S6' has different definitions in different modules; first difference is definition in module 'SecondModule' found type alias 'b' with underlying type 'float'}}
// expected-note@first.h:* {{but in 'FirstModule' found type alias 'b' with different underlying type 'Using::F' (aka 'float')}}
#endif
+
+#if defined(FIRST) || defined(SECOND)
+using I = int;
+#endif
+
+#define DECLS \
+ using A = int; \
+ using B = double; \
+ using C = I;
+
+#if defined(FIRST) || defined(SECOND)
+struct Valid1 {
+ DECLS
+};
+#else
+Valid1 v1;
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+struct Invalid1 {
+ DECLS
+ ACCESS
+};
+#else
+Invalid1 i1;
+// expected-error@second.h:* {{'Using::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
+// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}
+#endif
+#undef DECLS
} // namespace Using
namespace RecordType {
@@ -837,7 +1059,34 @@ S1 s1;
// expected-error@first.h:* {{'RecordType::S1::x' from module 'FirstModule' is not present in definition of 'RecordType::S1' in module 'SecondModule'}}
// expected-note@second.h:* {{declaration of 'x' does not match}}
#endif
-}
+
+#define DECLS \
+ Foo F;
+
+#if defined(FIRST) || defined(SECOND)
+struct Foo {};
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+struct Valid1 {
+ DECLS
+};
+#else
+Valid1 v1;
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+struct Invalid1 {
+ DECLS
+ ACCESS
+};
+#else
+Invalid1 i1;
+// expected-error@second.h:* {{'RecordType::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
+// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}
+#endif
+#undef DECLS
+} // namespace RecordType
namespace DependentType {
#if defined(FIRST)
@@ -856,7 +1105,34 @@ using U1 = S1<T>;
// expected-error@first.h:* {{'DependentType::S1::x' from module 'FirstModule' is not present in definition of 'S1<T>' in module 'SecondModule'}}
// expected-note@second.h:* {{declaration of 'x' does not match}}
#endif
-}
+
+#define DECLS \
+ typename T::typeA x;
+
+#if defined(FIRST) || defined(SECOND)
+template <class T>
+struct Valid1 {
+ DECLS
+};
+#else
+template <class T>
+using V1 = Valid1<T>;
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+template <class T>
+struct Invalid1 {
+ DECLS
+ ACCESS
+};
+#else
+template <class T>
+using I1 = Invalid1<T>;
+// expected-error@second.h:* {{'DependentType::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
+// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}
+#endif
+#undef DECLS
+} // namespace DependentType
namespace ElaboratedType {
#if defined(FIRST)
@@ -874,7 +1150,34 @@ S1 s1;
// expected-error@first.h:* {{'ElaboratedType::S1::x' from module 'FirstModule' is not present in definition of 'ElaboratedType::S1' in module 'SecondModule'}}
// expected-note@second.h:* {{declaration of 'x' does not match}}
#endif
-}
+
+#define DECLS \
+ NS::type x;
+
+#if defined(FIRST) || defined(SECOND)
+namespace NS { using type = float; }
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+struct Valid1 {
+ DECLS
+};
+#else
+Valid1 v1;
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+struct Invalid1 {
+ DECLS
+ ACCESS
+};
+#else
+Invalid1 i1;
+// expected-error@second.h:* {{'ElaboratedType::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
+// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}
+#endif
+#undef DECLS
+} // namespace ElaboratedType
namespace Enum {
#if defined(FIRST)
@@ -892,6 +1195,33 @@ S1 s1;
// expected-error@first.h:* {{'Enum::S1::x' from module 'FirstModule' is not present in definition of 'Enum::S1' in module 'SecondModule'}}
// expected-note@second.h:* {{declaration of 'x' does not match}}
#endif
+
+#define DECLS \
+ E e = E1;
+
+#if defined(FIRST) || defined(SECOND)
+enum E { E1, E2 };
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+struct Valid1 {
+ DECLS
+};
+#else
+Valid1 v1;
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+struct Invalid1 {
+ DECLS
+ ACCESS
+};
+#else
+Invalid1 i1;
+// expected-error@second.h:* {{'Enum::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
+// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}
+#endif
+#undef DECLS
}
namespace NestedNamespaceSpecifier {
@@ -1069,7 +1399,73 @@ S10 s10;
// expected-note@first.h:* {{declaration of 'x' does not match}}
#endif
}
+
+#define DECLS \
+ NS1::Type a; \
+ NS1::NS2::Type b; \
+ NS1::S c; \
+ NS3::Type d;
+
+#if defined(FIRST) || defined(SECOND)
+namespace NS1 {
+ using Type = int;
+ namespace NS2 {
+ using Type = double;
+ }
+ struct S {};
}
+namespace NS3 = NS1;
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+struct Valid1 {
+ DECLS
+};
+#else
+Valid1 v1;
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+struct Invalid1 {
+ DECLS
+ ACCESS
+};
+#else
+Invalid1 i1;
+// expected-error@second.h:* {{'NestedNamespaceSpecifier::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
+// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}
+#endif
+#undef DECLS
+
+#define DECLS \
+ typename T::type *x = {}; \
+ int y = x->T::foo(); \
+ int z = U::template X<int>::value;
+
+#if defined(FIRST) || defined(SECOND)
+template <class T, class U>
+struct Valid2 {
+ DECLS
+};
+#else
+template <class T, class U>
+using V2 = Valid2<T, U>;
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+template <class T, class U>
+struct Invalid2 {
+ DECLS
+ ACCESS
+};
+#else
+template <class T, class U>
+using I2 = Invalid2<T, U>;
+// expected-error@second.h:* {{'NestedNamespaceSpecifier::Invalid2' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
+// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}
+#endif
+#undef DECLS
+} // namespace NestedNamespaceSpecifier
namespace TemplateSpecializationType {
#if defined(FIRST)
@@ -1103,7 +1499,40 @@ S2 s2;
// expected-error@first.h:* {{'TemplateSpecializationType::S2::u' from module 'FirstModule' is not present in definition of 'TemplateSpecializationType::S2' in module 'SecondModule'}}
// expected-note@second.h:* {{declaration of 'u' does not match}}
#endif
-}
+
+#define DECLS \
+ OneTemplateArg<int> x; \
+ OneTemplateArg<double> y; \
+ OneTemplateArg<char *> z; \
+ TwoTemplateArgs<int, int> a; \
+ TwoTemplateArgs<double, float> b; \
+ TwoTemplateArgs<short *, char> c;
+
+#if defined(FIRST) || defined(SECOND)
+template <class T> struct OneTemplateArg {};
+template <class T, class U> struct TwoTemplateArgs {};
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+struct Valid1 {
+DECLS
+};
+#else
+Valid1 v1;
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+struct Invalid1 {
+DECLS
+ACCESS
+};
+#else
+Invalid1 i1;
+// expected-error@second.h:* {{'TemplateSpecializationType::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
+// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}
+#endif
+#undef DECLS
+} // namespace TemplateSpecializationType
namespace TemplateArgument {
#if defined(FIRST)
@@ -1205,7 +1634,43 @@ S6 s6;
// expected-error@second.h:* {{'TemplateArgument::S6' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'y'}}
// expected-note@first.h:* {{but in 'FirstModule' found field 'x'}}
#endif
-}
+
+#define DECLS \
+ OneClass<int> a; \
+ OneInt<1> b; \
+ using c = OneClass<float>; \
+ using d = OneInt<2>; \
+ using e = OneInt<2 + 2>; \
+ OneTemplateClass<OneClass> f; \
+ OneTemplateInt<OneInt> g;
+
+#if defined(FIRST) || defined(SECOND)
+template <class> struct OneClass{};
+template <int> struct OneInt{};
+template <template <class> class> struct OneTemplateClass{};
+template <template <int> class> struct OneTemplateInt{};
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+struct Valid1 {
+DECLS
+};
+#else
+Valid1 v1;
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+struct Invalid1 {
+DECLS
+ACCESS
+};
+#else
+Invalid1 i1;
+// expected-error@second.h:* {{'TemplateArgument::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
+// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}
+#endif
+#undef DECLS
+} // namespace TemplateArgument
namespace TemplateTypeParmType {
#if defined(FIRST)
@@ -1247,7 +1712,41 @@ using TemplateTypeParmType::S2;
// expected-error@first.h:* {{'TemplateTypeParmType::S2::type' from module 'FirstModule' is not present in definition of 'S2<T, U>' in module 'SecondModule'}}
// expected-note@second.h:* {{declaration of 'type' does not match}}
#endif
-}
+
+#define DECLS \
+ T t; \
+ U u; \
+ ParameterPack<T> a; \
+ ParameterPack<T, U> b; \
+ ParameterPack<U> c; \
+ ParameterPack<U, T> d;
+
+#if defined(FIRST) || defined(SECOND)
+template <class ...Ts> struct ParameterPack {};
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+template <class T, class U>
+struct Valid1 {
+ DECLS
+};
+#else
+using TemplateTypeParmType::Valid1;
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+template <class T, class U>
+struct Invalid1 {
+ DECLS
+ ACCESS
+};
+#else
+using TemplateTypeParmType::Invalid1;
+// expected-error@second.h:* {{'TemplateTypeParmType::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
+// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}
+#endif
+#undef DECLS
+} // namespace TemplateTypeParmType
namespace VarDecl {
#if defined(FIRST)
@@ -1381,46 +1880,36 @@ S9 s9;
// expected-note@second.h:* {{declaration of 'x' does not match}}
#endif
-#if defined(FIRST)
-template <typename T>
-struct S {
- struct R {
- void foo(T x = 0) {}
- };
-};
-#elif defined(SECOND)
-template <typename T>
-struct S {
- struct R {
- void foo(T x = 1) {}
- };
+#define DECLS \
+ static int a; \
+ static I b; \
+ static const int c = 1; \
+ static constexpr int d = 5;
+
+#if defined(FIRST) || defined(SECOND)
+using I = int;
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+struct Valid1 {
+ DECLS
};
#else
-void run() {
- S<int>::R().foo();
-}
-// expected-error@second.h:* {{'VarDecl::S::R' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'foo' with 1st parameter with a default argument}}
-// expected-note@first.h:* {{but in 'FirstModule' found method 'foo' with 1st parameter with a different default argument}}
+Valid1 v1;
#endif
-#if defined(FIRST)
-template <typename alpha> struct Bravo {
- void charlie(bool delta = false) {}
-};
-typedef Bravo<char> echo;
-echo foxtrot;
-#elif defined(SECOND)
-template <typename alpha> struct Bravo {
- void charlie(bool delta = (false)) {}
+#if defined(FIRST) || defined(SECOND)
+struct Invalid1 {
+ DECLS
+ ACCESS
};
-typedef Bravo<char> echo;
-echo foxtrot;
#else
-Bravo<char> golf;
-// expected-error@second.h:* {{'VarDecl::Bravo' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'charlie' with 1st parameter with a default argument}}
-// expected-note@first.h:* {{but in 'FirstModule' found method 'charlie' with 1st parameter with a different default argument}}
+Invalid1 i1;
+// expected-error@second.h:* {{'VarDecl::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
+// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}
#endif
-}
+#undef DECLS
+} // namespace VarDecl
namespace Friend {
#if defined(FIRST)
@@ -1499,67 +1988,331 @@ S5 s5;
// expected-error@second.h:* {{'Friend::S5' has different definitions in different modules; first difference is definition in module 'SecondModule' found friend function 'T5b'}}
// expected-note@first.h:* {{but in 'FirstModule' found friend function 'T5a'}}
#endif
-}
-// Interesting cases that should not cause errors. struct S should not error
-// while struct T should error at the access specifier mismatch at the end.
-namespace AllDecls {
-#define CREATE_ALL_DECL_STRUCT(NAME, ACCESS) \
- typedef int INT; \
- struct NAME { \
- public: \
- private: \
- protected: \
- static_assert(1 == 1, "Message"); \
- static_assert(2 == 2); \
- \
- int x; \
- double y; \
- \
- INT z; \
- \
- unsigned a : 1; \
- unsigned b : 2 * 2 + 5 / 2; \
- \
- mutable int c = sizeof(x + y); \
- \
- void method() {} \
- static void static_method() {} \
- virtual void virtual_method() {} \
- virtual void pure_virtual_method() = 0; \
- inline void inline_method() {} \
- void volatile_method() volatile {} \
- void const_method() const {} \
- \
- typedef int typedef_int; \
- using using_int = int; \
- \
- void method_one_arg(int x) {} \
- void method_one_arg_default_argument(int x = 5 + 5) {} \
- void method_decayed_type(int x[5]) {} \
- \
- int constant_arr[5]; \
- \
- ACCESS: \
- };
+#define DECLS \
+ friend class FriendA; \
+ friend struct FriendB; \
+ friend FriendC; \
+ friend const FriendD; \
+ friend void Function();
+
+#if defined(FIRST) || defined(SECOND)
+class FriendA {};
+class FriendB {};
+class FriendC {};
+class FriendD {};
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+struct Valid1 {
+ DECLS
+};
+#else
+Valid1 v1;
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+struct Invalid1 {
+ DECLS
+ ACCESS
+};
+#else
+Invalid1 i1;
+// expected-error@second.h:* {{'Friend::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
+// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}
+#endif
+#undef DECLS
+} // namespace Friend
+
+namespace TemplateParameters {
#if defined(FIRST)
-CREATE_ALL_DECL_STRUCT(S, public)
+template <class A>
+struct S1 {};
#elif defined(SECOND)
-CREATE_ALL_DECL_STRUCT(S, public)
+template <class B>
+struct S1 {};
#else
-S *s;
+using TemplateParameters::S1;
+// expected-error@second.h:* {{'TemplateParameters::S1' has different definitions in different modules; first difference is definition in module 'SecondModule' found template parameter 'B'}}
+// expected-note@first.h:* {{but in 'FirstModule' found template parameter 'A'}}
#endif
#if defined(FIRST)
-CREATE_ALL_DECL_STRUCT(T, private)
+template <class A = double>
+struct S2 {};
#elif defined(SECOND)
-CREATE_ALL_DECL_STRUCT(T, public)
+template <class A = int>
+struct S2 {};
#else
-T *t;
-// expected-error@second.h:* {{'AllDecls::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found public access specifier}}
-// expected-note@first.h:* {{but in 'FirstModule' found private access specifier}}
+using TemplateParameters::S2;
+// expected-error@second.h:* {{'TemplateParameters::S2' has different definitions in different modules; first difference is definition in module 'SecondModule' found template parameter with default argument}}
+// expected-note@first.h:* {{but in 'FirstModule' found template parameter with different default argument}}
+#endif
+
+#if defined(FIRST)
+template <class A = int>
+struct S3 {};
+#elif defined(SECOND)
+template <class A>
+struct S3 {};
+#else
+using TemplateParameters::S3;
+// expected-error@second.h:* {{'TemplateParameters::S3' has different definitions in different modules; first difference is definition in module 'SecondModule' found template parameter with no default argument}}
+// expected-note@first.h:* {{but in 'FirstModule' found template parameter with default argument}}
+#endif
+
+#if defined(FIRST)
+template <int A>
+struct S4 {};
+#elif defined(SECOND)
+template <int A = 2>
+struct S4 {};
+#else
+using TemplateParameters::S4;
+// expected-error@second.h:* {{'TemplateParameters::S4' has different definitions in different modules; first difference is definition in module 'SecondModule' found template parameter with default argument}}
+// expected-note@first.h:* {{but in 'FirstModule' found template parameter with no default argument}}
+#endif
+
+#if defined(FIRST)
+template <int> class S5_first {};
+template <template<int> class A = S5_first>
+struct S5 {};
+#elif defined(SECOND)
+template <int> class S5_second {};
+template <template<int> class A = S5_second>
+struct S5 {};
+#else
+using TemplateParameters::S5;
+// expected-error@second.h:* {{'TemplateParameters::S5' has different definitions in different modules; first difference is definition in module 'SecondModule' found template parameter with default argument}}
+// expected-note@first.h:* {{but in 'FirstModule' found template parameter with different default argument}}
+#endif
+
+#if defined(FIRST)
+template <class A>
+struct S6 {};
+#elif defined(SECOND)
+template <class>
+struct S6 {};
+#else
+using TemplateParameters::S6;
+// expected-error@second.h:* {{'TemplateParameters::S6' has different definitions in different modules; first difference is definition in module 'SecondModule' found unnamed template parameter}}
+// expected-note@first.h:* {{but in 'FirstModule' found template parameter 'A'}}
+#endif
+
+#define DECLS
+
+#if defined(FIRST) || defined(SECOND)
+template <class> class DefaultArg;
#endif
+
+#if defined(FIRST) || defined(SECOND)
+template <int, class, template <class> class,
+ int A, class B, template <int> class C,
+ int D = 1, class E = int, template <class F> class = DefaultArg>
+struct Valid1 {
+ DECLS
+};
+#else
+using TemplateParameters::Valid1;
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+template <int, class, template <class> class,
+ int A, class B, template <int> class C,
+ int D = 1, class E = int, template <class F> class = DefaultArg>
+struct Invalid1 {
+ DECLS
+ ACCESS
+};
+#else
+using TemplateParameters::Invalid1;
+// expected-error@second.h:* {{'TemplateParameters::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
+// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}
+#endif
+#undef DECLS
+} // namespace TemplateParameters
+
+namespace BaseClass {
+#if defined(FIRST)
+struct B1 {};
+struct S1 : B1 {};
+#elif defined(SECOND)
+struct S1 {};
+#else
+S1 s1;
+// expected-error@second.h:* {{'BaseClass::S1' has different definitions in different modules; first difference is definition in module 'SecondModule' found 0 base classes}}
+// expected-note@first.h:* {{but in 'FirstModule' found 1 base class}}
+#endif
+
+#if defined(FIRST)
+struct S2 {};
+#elif defined(SECOND)
+struct B2 {};
+struct S2 : virtual B2 {};
+#else
+S2 s2;
+// expected-error@second.h:* {{'BaseClass::S2' has different definitions in different modules; first difference is definition in module 'SecondModule' found 1 base class}}
+// expected-note@first.h:* {{but in 'FirstModule' found 0 base classes}}
+#endif
+
+#if defined(FIRST)
+struct B3a {};
+struct S3 : B3a {};
+#elif defined(SECOND)
+struct B3b {};
+struct S3 : virtual B3b {};
+#else
+S3 s3;
+// expected-error@second.h:* {{'BaseClass::S3' has different definitions in different modules; first difference is definition in module 'SecondModule' found 1 virtual base class}}
+// expected-note@first.h:* {{but in 'FirstModule' found 0 virtual base classes}}
+#endif
+
+#if defined(FIRST)
+struct B4a {};
+struct S4 : B4a {};
+#elif defined(SECOND)
+struct B4b {};
+struct S4 : B4b {};
+#else
+S4 s4;
+// expected-error@second.h:* {{'BaseClass::S4' has different definitions in different modules; first difference is definition in module 'SecondModule' found 1st base class with type 'BaseClass::B4b'}}
+// expected-note@first.h:* {{but in 'FirstModule' found 1st base class with different type 'BaseClass::B4a'}}
+#endif
+
+#if defined(FIRST)
+struct B5a {};
+struct S5 : virtual B5a {};
+#elif defined(SECOND)
+struct B5a {};
+struct S5 : B5a {};
+#else
+S5 s5;
+// expected-error@second.h:* {{'BaseClass::S5' has different definitions in different modules; first difference is definition in module 'SecondModule' found 0 virtual base classes}}
+// expected-note@first.h:* {{but in 'FirstModule' found 1 virtual base class}}
+#endif
+
+#if defined(FIRST)
+struct B6a {};
+struct S6 : B6a {};
+#elif defined(SECOND)
+struct B6a {};
+struct S6 : virtual B6a {};
+#else
+S6 s6;
+// expected-error@second.h:* {{'BaseClass::S6' has different definitions in different modules; first difference is definition in module 'SecondModule' found 1 virtual base class}}
+// expected-note@first.h:* {{but in 'FirstModule' found 0 virtual base classes}}
+#endif
+
+#if defined(FIRST)
+struct B7a {};
+struct S7 : protected B7a {};
+#elif defined(SECOND)
+struct B7a {};
+struct S7 : B7a {};
+#else
+S7 s7;
+// expected-error@second.h:* {{'BaseClass::S7' has different definitions in different modules; first difference is definition in module 'SecondModule' found 1st base class 'BaseClass::B7a' with no access specifier}}
+// expected-note@first.h:* {{but in 'FirstModule' found 1st base class 'BaseClass::B7a' with protected access specifier}}
+#endif
+
+#if defined(FIRST)
+struct B8a {};
+struct S8 : public B8a {};
+#elif defined(SECOND)
+struct B8a {};
+struct S8 : private B8a {};
+#else
+S8 s8;
+// expected-error@second.h:* {{'BaseClass::S8' has different definitions in different modules; first difference is definition in module 'SecondModule' found 1st base class 'BaseClass::B8a' with private access specifier}}
+// expected-note@first.h:* {{but in 'FirstModule' found 1st base class 'BaseClass::B8a' with public access specifier}}
+#endif
+
+#if defined(FIRST)
+struct B9a {};
+struct S9 : private B9a {};
+#elif defined(SECOND)
+struct B9a {};
+struct S9 : public B9a {};
+#else
+S9 s9;
+// expected-error@second.h:* {{'BaseClass::S9' has different definitions in different modules; first difference is definition in module 'SecondModule' found 1st base class 'BaseClass::B9a' with public access specifier}}
+// expected-note@first.h:* {{but in 'FirstModule' found 1st base class 'BaseClass::B9a' with private access specifier}}
+#endif
+
+#if defined(FIRST)
+struct B10a {};
+struct S10 : B10a {};
+#elif defined(SECOND)
+struct B10a {};
+struct S10 : protected B10a {};
+#else
+S10 s10;
+// expected-error@second.h:* {{'BaseClass::S10' has different definitions in different modules; first difference is definition in module 'SecondModule' found 1st base class 'BaseClass::B10a' with protected access specifier}}
+// expected-note@first.h:* {{but in 'FirstModule' found 1st base class 'BaseClass::B10a' with no access specifier}}
+#endif
+
+#define DECLS
+
+#if defined(FIRST) || defined(SECOND)
+struct Base1 {};
+struct Base2 {};
+struct Base3 {};
+struct Base4 {};
+struct Base5 {};
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+struct Valid1 :
+ Base1, virtual Base2, protected Base3, public Base4, private Base5 {
+
+ DECLS
+};
+#else
+Valid1 v1;
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+struct Invalid1 :
+ Base1, virtual Base2, protected Base3, public Base4, private Base5 {
+
+ DECLS
+ ACCESS
+};
+#else
+Invalid1 i1;
+// expected-error@second.h:* {{'BaseClass::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
+// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}
+#endif
+#undef DECLS
+} // namespace BaseClass
+
+
+// Collection of interesting cases below.
+
+// Naive parsing of AST can lead to cycles in processing. Ensure
+// self-references don't trigger an endless cycles of AST node processing.
+namespace SelfReference {
+#if defined(FIRST)
+template <template <int> class T> class Wrapper {};
+
+template <int N> class S {
+ S(Wrapper<::SelfReference::S> &Ref) {}
+};
+
+struct Xx {
+ struct Yy {
+ };
+};
+
+Xx::Xx::Xx::Yy yy;
+
+namespace NNS {
+template <typename> struct Foo;
+template <template <class> class T = NNS::Foo>
+struct NestedNamespaceSpecifier {};
}
+#endif
+} // namespace SelfReference
namespace FriendFunction {
#if defined(FIRST)
@@ -1628,7 +2381,7 @@ T t;
// expected-note@second.h:* {{but in 'SecondModule' found public access specifier}}
#endif
-} // namespace ImplicitDelc
+} // namespace ImplicitDecl
namespace TemplatedClass {
#if defined(FIRST)
@@ -1854,7 +2607,7 @@ void run() {
S<int>::R().foo();
}
#endif
-}
+} // namespace LateParsedDefaultArgument
namespace LateParsedDefaultArgument {
#if defined(FIRST)
@@ -1868,7 +2621,7 @@ Bravo<char> golf;
#elif defined(SECOND)
#else
#endif
-}
+} // LateParsedDefaultArgument
namespace DifferentParameterNameInTemplate {
#if defined(FIRST) || defined(SECOND)
@@ -1914,7 +2667,7 @@ struct BetaHelper {
#else
Alpha::Alpha() {}
#endif
-}
+} // DifferentParameterNameInTemplate
namespace ParameterTest {
#if defined(FIRST)
@@ -1941,7 +2694,7 @@ G* S<G>::Foo(const G* asdf, int*) {}
#else
S<X> s;
#endif
-}
+} // ParameterTest
namespace MultipleTypedefs {
#if defined(FIRST)
@@ -1991,12 +2744,59 @@ struct S3 {
#else
S3 s3;
#endif
+} // MultipleTypedefs
+
+namespace DefaultArguments {
+#if defined(FIRST)
+template <typename T>
+struct S {
+ struct R {
+ void foo(T x = 0) {}
+ };
+};
+#elif defined(SECOND)
+template <typename T>
+struct S {
+ struct R {
+ void foo(T x = 1) {}
+ };
+};
+#else
+void run() {
+ S<int>::R().foo();
}
+// expected-error@second.h:* {{'DefaultArguments::S::R' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'foo' with 1st parameter with a default argument}}
+// expected-note@first.h:* {{but in 'FirstModule' found method 'foo' with 1st parameter with a different default argument}}
+#endif
+
+#if defined(FIRST)
+template <typename alpha> struct Bravo {
+ void charlie(bool delta = false) {}
+};
+typedef Bravo<char> echo;
+echo foxtrot;
+#elif defined(SECOND)
+template <typename alpha> struct Bravo {
+ void charlie(bool delta = (false)) {}
+};
+typedef Bravo<char> echo;
+echo foxtrot;
+#else
+Bravo<char> golf;
+// expected-error@second.h:* {{'DefaultArguments::Bravo' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'charlie' with 1st parameter with a default argument}}
+// expected-note@first.h:* {{but in 'FirstModule' found method 'charlie' with 1st parameter with a different default argument}}
+#endif
+} // namespace DefaultArguments
// Keep macros contained to one file.
#ifdef FIRST
#undef FIRST
#endif
+
#ifdef SECOND
#undef SECOND
#endif
+
+#ifdef ACCESS
+#undef ACCESS
+#endif
diff --git a/test/Modules/path-resolution.modulemap b/test/Modules/path-resolution.modulemap
new file mode 100644
index 000000000000..72f5f142c326
--- /dev/null
+++ b/test/Modules/path-resolution.modulemap
@@ -0,0 +1,70 @@
+// RUN: rm -rf %t
+//
+// First, create two modules a and b, with a dependency b -> a, both within
+// the same directory p1.
+//
+// RUN: mkdir -p %t/p1
+// RUN: cd %t/p1
+//
+// RUN: grep "<AM>" %s > %t/p1/a.modulemap
+// RUN: %clang_cc1 -x c++ -fmodules -emit-module -fmodule-map-file-home-is-cwd \
+// RUN: -fmodules-embed-all-files -fmodules-local-submodule-visibility \
+// RUN: -fmodule-name="a" -o a.pcm a.modulemap
+//
+// RUN: grep "<BM>" %s > %t/p1/b.modulemap
+// RUN: %clang_cc1 -x c++ -fmodules -emit-module -fmodule-map-file-home-is-cwd \
+// RUN: -fmodules-embed-all-files -fmodules-local-submodule-visibility \
+// RUN: -fmodule-name="b" -o b.pcm b.modulemap
+//
+// Next, move the whole tree p1 -> p2.
+//
+// RUN: cd %t
+// RUN: mv %t/p1 %t/p2
+// RUN: cd %t/p2
+//
+// Compile a new module c in the newly generated tree that depends on b; c.pcm
+// has to be within a subdirectory so a.modulemap will be one step up (../) from
+// c.pcm.
+//
+// RUN: mkdir %t/p2/c
+// RUN: grep "<CM>" %s > %t/p2/c/c.modulemap
+// RUN: grep "<CH>" %s > %t/p2/c/c.h
+// RUN: %clang_cc1 -x c++ -fmodules -emit-module -fmodule-map-file-home-is-cwd \
+// RUN: -fmodules-embed-all-files -fmodules-local-submodule-visibility \
+// RUN: -fmodule-name="c" -fmodule-file=b.pcm -o c/c.pcm c/c.modulemap
+//
+// Delete a.modulemap from its original location, and instead inject a different
+// (unrelated) a.modulemap in the path p2/p2.
+//
+// RUN: rm %t/p2/a.modulemap
+// RUN: mkdir -p %t/p2/p2
+// RUN: touch %t/p2/p2/a.modulemap
+//
+// Now compile a file c.cpp that uses c.h and the module c; it is important
+// to first load b.pcm and a.pcm before c.pcm on the command line to trigger
+// the right order of module loading. This used to trigger clang to find the
+// p2/p2/a.modulemap via the path c/../p2/a.modulemap, which is not the correct
+// relative path from c.
+//
+// RUN: grep "<CC>" %s > %t/p2/c/c.cpp
+// RUN: %clang_cc1 -I. -x c++ -fmodules \
+// RUN: -fmodule-file=b.pcm -fmodule-file=a.pcm -fmodule-file=c/c.pcm \
+// RUN: -o c/c.o -emit-obj c/c.cpp
+
+module "a" { // <AM>
+} // <AM>
+
+module "b" { // <BM>
+ use "a" // <BM>
+} // <BM>
+
+module "c" { // <CM>
+ header "c/c.h" // <CM>
+ use "a" // <CM>
+ use "b" // <CM>
+} // <CM>
+
+inline void c() {} // <CH>
+
+#include "c/c.h" // <CC>
+void foo() { c(); } // <CC>
diff --git a/test/Modules/umbrella-header-include-builtin.mm b/test/Modules/umbrella-header-include-builtin.mm
index da21779683cf..b14c73705ca8 100644
--- a/test/Modules/umbrella-header-include-builtin.mm
+++ b/test/Modules/umbrella-header-include-builtin.mm
@@ -1,7 +1,5 @@
-// REQUIRES: system-darwin
-
// RUN: rm -rf %t
-// RUN: %clang -cc1 -fsyntax-only -nostdinc++ -isysroot %S/Inputs/libc-libcxx/sysroot -isystem %S/Inputs/libc-libcxx/sysroot/usr/include/c++/v1 -F%S/Inputs/libc-libcxx/sysroot/Frameworks -std=c++11 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -x objective-c++ %s
+// RUN: %clang -cc1 -fsyntax-only -nobuiltininc -nostdinc++ -isysroot %S/Inputs/libc-libcxx/sysroot -isystem %S/Inputs/libc-libcxx/sysroot/usr/include/c++/v1 -isystem %S/Inputs/libc-libcxx/sysroot/usr/include -F%S/Inputs/libc-libcxx/sysroot/Frameworks -std=c++11 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -x objective-c++ %s
#include <A/A.h>
diff --git a/test/Modules/using-decl-inheritance.cpp b/test/Modules/using-decl-inheritance.cpp
new file mode 100644
index 000000000000..eba9636b75ef
--- /dev/null
+++ b/test/Modules/using-decl-inheritance.cpp
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -x c++ -fmodules -fmodules-local-submodule-visibility -fmodules-cache-path=%t %s -verify
+// RUN: %clang_cc1 -x c++ -fmodules -fmodules-cache-path=%t %s -verify
+
+// expected-no-diagnostics
+
+#pragma clang module build A
+ module A { }
+#pragma clang module contents
+#pragma clang module begin A
+struct A {
+ virtual void Foo(double x) const;
+};
+#pragma clang module end
+#pragma clang module endbuild
+
+#pragma clang module build B
+ module B { }
+#pragma clang module contents
+#pragma clang module begin B
+#pragma clang module import A
+struct B : A {
+ using A::Foo;
+ virtual void Foo(double x) const;
+};
+#pragma clang module end
+#pragma clang module endbuild
+
+#pragma clang module import B
+
+int main() {
+ B b;
+ b.Foo(1.0);
+}
+
diff --git a/test/Modules/using-directive-redecl.cpp b/test/Modules/using-directive-redecl.cpp
new file mode 100644
index 000000000000..94772f30a3d4
--- /dev/null
+++ b/test/Modules/using-directive-redecl.cpp
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1 -fmodules -fmodules-local-submodule-visibility -verify %s
+// expected-no-diagnostics
+#pragma clang module build M
+module M { module TDFNodes {} module TDFInterface {} }
+#pragma clang module contents
+ // TDFNodes
+ #pragma clang module begin M.TDFNodes
+ namespace Detail {
+ namespace TDF {
+ class TLoopManager {};
+ }
+ }
+ namespace Internal {
+ namespace TDF {
+ using namespace Detail::TDF;
+ }
+ }
+ #pragma clang module end
+
+ // TDFInterface
+ #pragma clang module begin M.TDFInterface
+ #pragma clang module import M.TDFNodes
+ namespace Internal {
+ namespace TDF {
+ using namespace Detail::TDF;
+ }
+ }
+ #pragma clang module end
+
+#pragma clang module endbuild
+
+#pragma clang module import M.TDFNodes
+namespace Internal {
+ namespace TDF {
+ TLoopManager * use;
+ }
+}
diff --git a/test/Modules/using-directive.cpp b/test/Modules/using-directive.cpp
new file mode 100644
index 000000000000..6ca5c6eab4f9
--- /dev/null
+++ b/test/Modules/using-directive.cpp
@@ -0,0 +1,62 @@
+// RUN: %clang_cc1 -fmodules -fmodules-local-submodule-visibility -fno-modules-error-recovery -fno-spell-checking -verify %s
+
+#pragma clang module build a
+module a { explicit module b {} explicit module c {} }
+#pragma clang module contents
+
+#pragma clang module begin a.b
+namespace b { int n; }
+#pragma clang module end
+
+#pragma clang module begin a.c
+#pragma clang module import a.b
+namespace c { using namespace b; }
+#pragma clang module end
+
+#pragma clang module begin a
+#pragma clang module import a.c
+using namespace c;
+#pragma clang module end
+
+#pragma clang module endbuild
+
+#pragma clang module import a.b
+void use1() {
+ (void)n; // expected-error {{use of undeclared identifier}}
+ (void)::n; // expected-error {{no member named 'n' in the global namespace}}
+ (void)b::n;
+}
+namespace b {
+ void use1_in_b() { (void)n; }
+}
+namespace c {
+ void use1_in_c() { (void)n; } // expected-error {{use of undeclared identifier}}
+}
+
+#pragma clang module import a.c
+void use2() {
+ (void)n; // expected-error {{use of undeclared identifier}}
+ (void)::n; // expected-error {{no member named 'n' in the global namespace}}
+ (void)b::n;
+ (void)c::n;
+}
+namespace b {
+ void use2_in_b() { (void)n; }
+}
+namespace c {
+ void use2_in_c() { (void)n; }
+}
+
+#pragma clang module import a
+void use3() {
+ (void)n;
+ (void)::n;
+ (void)b::n;
+ (void)c::n;
+}
+namespace b {
+ void use3_in_b() { (void)n; }
+}
+namespace c {
+ void use3_in_c() { (void)n; }
+}
diff --git a/test/Modules/var-templates.cpp b/test/Modules/var-templates.cpp
new file mode 100644
index 000000000000..eca242873969
--- /dev/null
+++ b/test/Modules/var-templates.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -fmodules -std=c++14 -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s
+
+#pragma clang module build A
+module A {}
+#pragma clang module contents
+#pragma clang module begin A
+template<int> int n = 42;
+decltype(n<0>) f();
+#pragma clang module end
+#pragma clang module endbuild
+
+#pragma clang module build B
+module B {}
+#pragma clang module contents
+#pragma clang module begin B
+#pragma clang module import A
+inline int f() { return n<0>; }
+#pragma clang module end
+#pragma clang module endbuild
+
+#pragma clang module import B
+
+// CHECK: @_Z1nILi0EE = linkonce_odr global i32 42, comdat
+int g() { return f(); }
diff --git a/test/Modules/visibility-in-instantiation.cpp b/test/Modules/visibility-in-instantiation.cpp
new file mode 100644
index 000000000000..8689758a42ba
--- /dev/null
+++ b/test/Modules/visibility-in-instantiation.cpp
@@ -0,0 +1,51 @@
+// RUN: %clang_cc1 -std=c++11 -fmodules %s -verify
+
+#pragma clang module build M
+ module M { module A {} module B {} module C {} }
+#pragma clang module contents
+
+ #pragma clang module begin M.A
+ template<typename U> struct X {
+ template<typename T> void f();
+ };
+ #pragma clang module end
+
+ #pragma clang module begin M.B
+ template<typename T, typename U = void> struct ST { static void f(); };
+ #pragma clang module end
+
+ #pragma clang module begin M.C
+ template<typename U> struct X;
+ void foo(X<int>);
+ #pragma clang module end
+#pragma clang module endbuild
+
+#pragma clang module build N
+ module N {}
+#pragma clang module contents
+ #pragma clang module begin N
+ #pragma clang module import M.B // not re-exported
+
+ template<typename U> struct X {
+ template<typename T> void f();
+ template<typename T> void g();
+ };
+
+ template<typename U> template<typename T>
+ void X<U>::f() {
+ ST<T>::f(); // definition and default argument found in M.B
+ foo(*this); // found by ADL in M.C
+ };
+
+ #pragma clang module import M.C // not re-exported
+ #pragma clang module end
+#pragma clang module endbuild
+
+#pragma clang module import N
+void g() {
+ X<int>().f<int>();
+
+ ST<int>::f(); // expected-error {{must be imported from module 'M.B'}}
+ foo(X<int>()); // expected-error {{must be imported from module 'M.C'}}
+ // expected-note@* 2{{previous declaration is here}}
+}
diff --git a/test/OpenMP/atomic_capture_codegen.cpp b/test/OpenMP/atomic_capture_codegen.cpp
index 0a22e4276b53..306b83f62463 100644
--- a/test/OpenMP/atomic_capture_codegen.cpp
+++ b/test/OpenMP/atomic_capture_codegen.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp -x c -emit-llvm %s -o - | FileCheck %s
-// RUN: %clang_cc1 -fopenmp -x c -triple x86_64-apple-darwin10 -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -x c -triple x86_64-apple-darwin10 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -target-cpu core2 -fopenmp -x c -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c -triple x86_64-apple-darwin10 -target-cpu core2 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c -triple x86_64-apple-darwin10 -target-cpu core2 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
// expected-no-diagnostics
#ifndef HEADER
#define HEADER
@@ -611,50 +611,6 @@ int main() {
// CHECK: store i8 [[DESIRED_I8]], i8* @{{.+}},
#pragma omp atomic capture
{bx = civ - bx; bv = bx;}
-// CHECK: [[EXPR_RE:%.+]] = load float, float* getelementptr inbounds ({ float, float }, { float, float }* @{{.+}}, i32 0, i32 0)
-// CHECK: [[EXPR_IM:%.+]] = load float, float* getelementptr inbounds ({ float, float }, { float, float }* @{{.+}}, i32 0, i32 1)
-// CHECK: [[X:%.+]] = load atomic i16, i16* [[X_ADDR:@.+]] monotonic
-// CHECK: br label %[[CONT:.+]]
-// CHECK: [[CONT]]
-// CHECK: [[EXPECTED:%.+]] = phi i16 [ [[X]], %{{.+}} ], [ [[OLD_X:%.+]], %[[CONT]] ]
-// CHECK: [[CONV:%.+]] = zext i16 [[EXPECTED]] to i32
-// CHECK: [[X_RVAL:%.+]] = sitofp i32 [[CONV]] to float
-// <Skip checks for complex calculations>
-// CHECK: [[X_RE_ADDR:%.+]] = getelementptr inbounds { float, float }, { float, float }* [[TEMP:%.+]], i32 0, i32 0
-// CHECK: [[X_RE:%.+]] = load float, float* [[X_RE_ADDR]]
-// CHECK: [[X_IM_ADDR:%.+]] = getelementptr inbounds { float, float }, { float, float }* [[TEMP]], i32 0, i32 1
-// CHECK: [[X_IM:%.+]] = load float, float* [[X_IM_ADDR]]
-// CHECK: [[NEW:%.+]] = fptoui float [[X_RE]] to i16
-// CHECK: store i16 [[NEW]], i16* [[TEMP:%.+]],
-// CHECK: [[DESIRED:%.+]] = load i16, i16* [[TEMP]],
-// CHECK: [[RES:%.+]] = cmpxchg i16* [[X_ADDR]], i16 [[EXPECTED]], i16 [[DESIRED]] monotonic monotonic
-// CHECK: [[OLD_X]] = extractvalue { i16, i1 } [[RES]], 0
-// CHECK: [[SUCCESS_FAIL:%.+]] = extractvalue { i16, i1 } [[RES]], 1
-// CHECK: br i1 [[SUCCESS_FAIL]], label %[[EXIT:.+]], label %[[CONT]]
-// CHECK: [[EXIT]]
-// CHECK: store i16 [[NEW]], i16* @{{.+}},
-#pragma omp atomic capture
- usv = usx /= cfv;
-// CHECK: [[EXPR_RE:%.+]] = load double, double* getelementptr inbounds ({ double, double }, { double, double }* @{{.+}}, i32 0, i32 0)
-// CHECK: [[EXPR_IM:%.+]] = load double, double* getelementptr inbounds ({ double, double }, { double, double }* @{{.+}}, i32 0, i32 1)
-// CHECK: [[X:%.+]] = load atomic i64, i64* [[X_ADDR:@.+]] monotonic
-// CHECK: br label %[[CONT:.+]]
-// CHECK: [[CONT]]
-// CHECK: [[EXPECTED:%.+]] = phi i64 [ [[X]], %{{.+}} ], [ [[OLD_X:%.+]], %[[CONT]] ]
-// CHECK: [[X_RVAL:%.+]] = sitofp i64 [[EXPECTED]] to double
-// CHECK: [[ADD_RE:%.+]] = fadd double [[X_RVAL]], [[EXPR_RE]]
-// CHECK: [[ADD_IM:%.+]] = fadd double 0.000000e+00, [[EXPR_IM]]
-// CHECK: [[DESIRED:%.+]] = fptosi double [[ADD_RE]] to i64
-// CHECK: store i64 [[DESIRED]], i64* [[TEMP:%.+]],
-// CHECK: [[DESIRED:%.+]] = load i64, i64* [[TEMP]],
-// CHECK: [[RES:%.+]] = cmpxchg i64* [[X_ADDR]], i64 [[EXPECTED]], i64 [[DESIRED]] monotonic monotonic
-// CHECK: [[OLD_X]] = extractvalue { i64, i1 } [[RES]], 0
-// CHECK: [[SUCCESS_FAIL:%.+]] = extractvalue { i64, i1 } [[RES]], 1
-// CHECK: br i1 [[SUCCESS_FAIL]], label %[[EXIT:.+]], label %[[CONT]]
-// CHECK: [[EXIT]]
-// CHECK: store i64 [[EXPECTED]], i64* @{{.+}},
-#pragma omp atomic capture
- {llv = llx; llx += cdv;}
// CHECK: [[IDX:%.+]] = load i16, i16* @{{.+}}
// CHECK: load i8, i8*
// CHECK: [[VEC_ITEM_VAL:%.+]] = zext i1 %{{.+}} to i32
diff --git a/test/OpenMP/atomic_read_codegen.c b/test/OpenMP/atomic_read_codegen.c
index 0cd46e3821fd..0cfb2d26f243 100644
--- a/test/OpenMP/atomic_read_codegen.c
+++ b/test/OpenMP/atomic_read_codegen.c
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp -x c -emit-llvm %s -o - | FileCheck %s
-// RUN: %clang_cc1 -fopenmp -x c -triple x86_64-apple-darwin10 -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -x c -triple x86_64-apple-darwin10 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -target-cpu core2 -fopenmp -x c -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c -triple x86_64-apple-darwin10 -target-cpu core2 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c -triple x86_64-apple-darwin10 -target-cpu core2 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
// expected-no-diagnostics
// REQUIRES: x86-registered-target
#ifndef HEADER
diff --git a/test/OpenMP/atomic_update_codegen.cpp b/test/OpenMP/atomic_update_codegen.cpp
index 8c02a43d64e3..1343cd8ad2cd 100644
--- a/test/OpenMP/atomic_update_codegen.cpp
+++ b/test/OpenMP/atomic_update_codegen.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp -x c -emit-llvm %s -o - | FileCheck %s
-// RUN: %clang_cc1 -fopenmp -x c -triple x86_64-apple-darwin10 -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -x c -triple x86_64-apple-darwin10 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -target-cpu core2 -fopenmp -x c -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c -triple x86_64-apple-darwin10 -target-cpu core2 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c -triple x86_64-apple-darwin10 -target-cpu core2 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
// expected-no-diagnostics
#ifndef HEADER
#define HEADER
@@ -554,48 +554,6 @@ int main() {
// CHECK: [[EXIT]]
#pragma omp atomic
bx = civ - bx;
-// CHECK: [[EXPR_RE:%.+]] = load float, float* getelementptr inbounds ({ float, float }, { float, float }* @{{.+}}, i32 0, i32 0)
-// CHECK: [[EXPR_IM:%.+]] = load float, float* getelementptr inbounds ({ float, float }, { float, float }* @{{.+}}, i32 0, i32 1)
-// CHECK: [[X:%.+]] = load atomic i16, i16* [[X_ADDR:@.+]] monotonic
-// CHECK: br label %[[CONT:.+]]
-// CHECK: [[CONT]]
-// CHECK: [[EXPECTED:%.+]] = phi i16 [ [[X]], %{{.+}} ], [ [[OLD_X:%.+]], %[[CONT]] ]
-// CHECK: [[CONV:%.+]] = zext i16 [[EXPECTED]] to i32
-// CHECK: [[X_RVAL:%.+]] = sitofp i32 [[CONV]] to float
-// <Skip checks for complex calculations>
-// CHECK: [[X_RE_ADDR:%.+]] = getelementptr inbounds { float, float }, { float, float }* [[TEMP:%.+]], i32 0, i32 0
-// CHECK: [[X_RE:%.+]] = load float, float* [[X_RE_ADDR]]
-// CHECK: [[X_IM_ADDR:%.+]] = getelementptr inbounds { float, float }, { float, float }* [[TEMP]], i32 0, i32 1
-// CHECK: [[X_IM:%.+]] = load float, float* [[X_IM_ADDR]]
-// CHECK: [[DESIRED:%.+]] = fptoui float [[X_RE]] to i16
-// CHECK: store i16 [[DESIRED]], i16* [[TEMP:%.+]]
-// CHECK: [[DESIRED:%.+]] = load i16, i16* [[TEMP]]
-// CHECK: [[RES:%.+]] = cmpxchg i16* [[X_ADDR]], i16 [[EXPECTED]], i16 [[DESIRED]] monotonic monotonic
-// CHECK: [[OLD_X]] = extractvalue { i16, i1 } [[RES]], 0
-// CHECK: [[SUCCESS_FAIL:%.+]] = extractvalue { i16, i1 } [[RES]], 1
-// CHECK: br i1 [[SUCCESS_FAIL]], label %[[EXIT:.+]], label %[[CONT]]
-// CHECK: [[EXIT]]
-#pragma omp atomic update
- usx /= cfv;
-// CHECK: [[EXPR_RE:%.+]] = load double, double* getelementptr inbounds ({ double, double }, { double, double }* @{{.+}}, i32 0, i32 0)
-// CHECK: [[EXPR_IM:%.+]] = load double, double* getelementptr inbounds ({ double, double }, { double, double }* @{{.+}}, i32 0, i32 1)
-// CHECK: [[X:%.+]] = load atomic i64, i64* [[X_ADDR:@.+]] monotonic
-// CHECK: br label %[[CONT:.+]]
-// CHECK: [[CONT]]
-// CHECK: [[EXPECTED:%.+]] = phi i64 [ [[X]], %{{.+}} ], [ [[OLD_X:%.+]], %[[CONT]] ]
-// CHECK: [[X_RVAL:%.+]] = sitofp i64 [[EXPECTED]] to double
-// CHECK: [[ADD_RE:%.+]] = fadd double [[X_RVAL]], [[EXPR_RE]]
-// CHECK: [[ADD_IM:%.+]] = fadd double 0.000000e+00, [[EXPR_IM]]
-// CHECK: [[DESIRED:%.+]] = fptosi double [[ADD_RE]] to i64
-// CHECK: store i64 [[DESIRED]], i64* [[TEMP:%.+]]
-// CHECK: [[DESIRED:%.+]] = load i64, i64* [[TEMP]]
-// CHECK: [[RES:%.+]] = cmpxchg i64* [[X_ADDR]], i64 [[EXPECTED]], i64 [[DESIRED]] monotonic monotonic
-// CHECK: [[OLD_X]] = extractvalue { i64, i1 } [[RES]], 0
-// CHECK: [[SUCCESS_FAIL:%.+]] = extractvalue { i64, i1 } [[RES]], 1
-// CHECK: br i1 [[SUCCESS_FAIL]], label %[[EXIT:.+]], label %[[CONT]]
-// CHECK: [[EXIT]]
-#pragma omp atomic
- llx += cdv;
// CHECK: [[IDX:%.+]] = load i16, i16* @{{.+}}
// CHECK: load i8, i8*
// CHECK: [[VEC_ITEM_VAL:%.+]] = zext i1 %{{.+}} to i32
diff --git a/test/OpenMP/atomic_write_codegen.c b/test/OpenMP/atomic_write_codegen.c
index 050d7a510566..0c85b6e88a3f 100644
--- a/test/OpenMP/atomic_write_codegen.c
+++ b/test/OpenMP/atomic_write_codegen.c
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp -x c -emit-llvm %s -o - | FileCheck %s
-// RUN: %clang_cc1 -fopenmp -x c -triple x86_64-apple-darwin10 -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -x c -triple x86_64-apple-darwin10 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -target-cpu core2 -fopenmp -x c -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c -triple x86_64-apple-darwin10 -target-cpu core2 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c -triple x86_64-apple-darwin10 -target-cpu core2 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
// expected-no-diagnostics
// REQUIRES: x86-registered-target
#ifndef HEADER
diff --git a/test/OpenMP/capturing_in_templates.cpp b/test/OpenMP/capturing_in_templates.cpp
index a4dcbee8fab9..9b2d9d304e0a 100644
--- a/test/OpenMP/capturing_in_templates.cpp
+++ b/test/OpenMP/capturing_in_templates.cpp
@@ -15,7 +15,7 @@ pair<T1, T2> make_pair(T1 &&t1, T2 &&t2) {
// CHECK-LABEL: @main
int main(int argc, char **argv) {
-// CHECK: call i32 @__tgt_target(i32 -1, i8* @{{.+}}.region_id, i32 0, i8** null, i8** null, i64* null, i32* null)
+// CHECK: call i32 @__tgt_target(i64 -1, i8* @{{.+}}.region_id, i32 0, i8** null, i8** null, i64* null, i64* null)
#pragma omp target
{
for (int i = 0; i < 64; ++i) {
diff --git a/test/OpenMP/declare_reduction_messages.cpp b/test/OpenMP/declare_reduction_messages.cpp
index 198d7756d035..3e5a15ee3dd9 100644
--- a/test/OpenMP/declare_reduction_messages.cpp
+++ b/test/OpenMP/declare_reduction_messages.cpp
@@ -134,3 +134,21 @@ int main() {
}
return fun(15) + foo(15); // expected-note {{in instantiation of function template specialization 'foo<int>' requested here}}
}
+
+#if __cplusplus == 201103L
+struct A {
+ A() {}
+ // expected-note@+1 {{copy constructor is implicitly deleted because 'A' has a user-declared move assignment operator}}
+ A& operator=(A&&) = default;
+};
+
+int A_TEST() {
+ A test;
+// expected-error@+1 {{call to implicitly-deleted copy constructor of 'A'}}
+#pragma omp declare reduction(+ : A : omp_out) initializer(omp_priv = A())
+// expected-error@+1 {{invalid operands to binary expression ('A' and 'A')}}
+#pragma omp parallel reduction(+ : test)
+ {}
+ return 0;
+}
+#endif
diff --git a/test/OpenMP/declare_simd_codegen.cpp b/test/OpenMP/declare_simd_codegen.cpp
index 47e951999b6a..9ae476677c42 100644
--- a/test/OpenMP/declare_simd_codegen.cpp
+++ b/test/OpenMP/declare_simd_codegen.cpp
@@ -8,11 +8,22 @@
#pragma omp declare simd linear(d : 8)
#pragma omp declare simd inbranch simdlen(32)
#pragma omp declare simd notinbranch
+void add_1(float *d);
+
+#pragma omp declare simd linear(d : 8)
+#pragma omp declare simd inbranch simdlen(32)
+#pragma omp declare simd notinbranch
void add_1(float *d) {}
+#pragma omp declare simd linear(d : 8)
+#pragma omp declare simd inbranch simdlen(32)
+#pragma omp declare simd notinbranch
+void add_2(float *d);
+
#pragma omp declare simd aligned(hp, hp2)
template <class C>
void h(C *hp, C *hp2, C *hq, C *lin) {
+ add_2(0);
}
// Explicit specialization with <C=int>.
@@ -110,6 +121,7 @@ double foo(double x) { return 0; }
// CHECK-DAG: define {{.+}}@_Z3bax2VVPdi(
// CHECK-DAG: define {{.+}}@_Z3fooPffi(
// CHECK-DAG: define {{.+}}@_Z3food(
+// CHECK-DAG: declare {{.+}}@_Z5add_2Pf(
// CHECK-DAG: "_ZGVbM4l8__Z5add_1Pf"
// CHECK-DAG: "_ZGVbN4l8__Z5add_1Pf"
@@ -277,6 +289,23 @@ double foo(double x) { return 0; }
// CHECK-DAG: "_ZGVeM16ua16vl1__Z3fooPffi"
// CHECK-DAG: "_ZGVeN16ua16vl1__Z3fooPffi"
+// CHECK-DAG: "_ZGVbM4l8__Z5add_2Pf"
+// CHECK-DAG: "_ZGVbN4l8__Z5add_2Pf"
+// CHECK-DAG: "_ZGVcM8l8__Z5add_2Pf"
+// CHECK-DAG: "_ZGVcN8l8__Z5add_2Pf"
+// CHECK-DAG: "_ZGVdM8l8__Z5add_2Pf"
+// CHECK-DAG: "_ZGVdN8l8__Z5add_2Pf"
+// CHECK-DAG: "_ZGVeM16l8__Z5add_2Pf"
+// CHECK-DAG: "_ZGVeN16l8__Z5add_2Pf"
+// CHECK-DAG: "_ZGVbM32v__Z5add_2Pf"
+// CHECK-DAG: "_ZGVcM32v__Z5add_2Pf"
+// CHECK-DAG: "_ZGVdM32v__Z5add_2Pf"
+// CHECK-DAG: "_ZGVeM32v__Z5add_2Pf"
+// CHECK-DAG: "_ZGVbN2v__Z5add_2Pf"
+// CHECK-DAG: "_ZGVcN4v__Z5add_2Pf"
+// CHECK-DAG: "_ZGVdN4v__Z5add_2Pf"
+// CHECK-DAG: "_ZGVeN8v__Z5add_2Pf"
+
// CHECK-DAG: "_ZGVbN2v__Z3food"
// CHECK-DAG: "_ZGVcN4v__Z3food"
// CHECK-DAG: "_ZGVdN4v__Z3food"
diff --git a/test/OpenMP/declare_simd_messages.cpp b/test/OpenMP/declare_simd_messages.cpp
index 15971eb14de5..af46283f9a57 100644
--- a/test/OpenMP/declare_simd_messages.cpp
+++ b/test/OpenMP/declare_simd_messages.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple=x86_64-pc-win32 -verify -fopenmp -x c++ -std=c++11 -fms-extensions %s
+// RUN: %clang_cc1 -triple=x86_64-pc-win32 -verify -fopenmp -x c++ -std=c++11 -fms-extensions -Wno-pragma-pack %s
// expected-error@+1 {{expected an OpenMP directive}}
#pragma omp declare
diff --git a/test/OpenMP/declare_target_ast_print.cpp b/test/OpenMP/declare_target_ast_print.cpp
index 591844b79498..6c59563d1d1e 100644
--- a/test/OpenMP/declare_target_ast_print.cpp
+++ b/test/OpenMP/declare_target_ast_print.cpp
@@ -108,9 +108,7 @@ void f2() {
// CHECK: #pragma omp end declare target
int c1, c2, c3;
-void f3() {
-}
-#pragma omp declare target link(c1) link(c2), link(c3, f3)
+#pragma omp declare target link(c1) link(c2), link(c3)
// CHECK: #pragma omp declare target link
// CHECK: int c1;
// CHECK: #pragma omp end declare target
@@ -120,9 +118,33 @@ void f3() {
// CHECK: #pragma omp declare target link
// CHECK: int c3;
// CHECK: #pragma omp end declare target
-// CHECK: #pragma omp declare target link
-// CHECK: void f3()
+
+struct SSSt {
+#pragma omp declare target
+ static int a;
+ int b;
+#pragma omp end declare target
+};
+
+// CHECK: struct SSSt {
+// CHECK: #pragma omp declare target
+// CHECK: static int a;
+// CHECK: #pragma omp end declare target
+// CHECK: int b;
+
+template <class T>
+struct SSSTt {
+#pragma omp declare target
+ static T a;
+ int b;
+#pragma omp end declare target
+};
+
+// CHECK: template <class T> struct SSSTt {
+// CHECK: #pragma omp declare target
+// CHECK: static T a;
// CHECK: #pragma omp end declare target
+// CHECK: int b;
int main (int argc, char **argv) {
foo();
diff --git a/test/OpenMP/declare_target_messages.cpp b/test/OpenMP/declare_target_messages.cpp
index b858d53c1ecf..c1c03951a3c1 100644
--- a/test/OpenMP/declare_target_messages.cpp
+++ b/test/OpenMP/declare_target_messages.cpp
@@ -13,8 +13,16 @@ void f();
#pragma omp declare target map(a) // expected-error {{unexpected 'map' clause, only 'to' or 'link' clauses expected}}
+#pragma omp declare target to(foo1) // expected-error {{use of undeclared identifier 'foo1'}}
+
+#pragma omp declare target link(foo2) // expected-error {{use of undeclared identifier 'foo2'}}
+
void c(); // expected-warning {{declaration is not declared in any declare target region}}
+void func() {} // expected-note {{'func' defined here}}
+
+#pragma omp declare target link(func) // expected-error {{function name is not allowed in 'link' clause}}
+
extern int b;
struct NonT {
@@ -28,16 +36,16 @@ typedef int sint;
extern int b;
int g;
-struct T { // expected-note {{mappable type cannot be polymorphic}}
+struct T {
int a;
virtual int method();
};
-class VC { // expected-note {{mappable type cannot be polymorphic}}
+class VC {
T member;
NonT member1;
public:
- virtual int method() { T a; return 0; } // expected-error {{type 'T' is not mappable to target}}
+ virtual int method() { T a; return 0; }
};
struct C {
@@ -56,7 +64,7 @@ void foo() {
b = 0; // expected-note {{used here}}
t = 1; // expected-error {{threadprivate variables cannot be used in target constructs}}
C object;
- VC object1; // expected-error {{type 'VC' is not mappable to target}}
+ VC object1;
g = object.method();
g += object.method1();
g += object1.method();
@@ -73,9 +81,9 @@ int C::method() {
}
struct S {
-#pragma omp declare target // expected-error {{directive must be at file or namespace scope}}
+#pragma omp declare target
int v;
-#pragma omp end declare target // expected-error {{unexpected OpenMP directive '#pragma omp end declare target'}}
+#pragma omp end declare target
};
int main (int argc, char **argv) {
diff --git a/test/OpenMP/distribute_codegen.cpp b/test/OpenMP/distribute_codegen.cpp
index 37f00f09178b..7ea17b116c88 100644
--- a/test/OpenMP/distribute_codegen.cpp
+++ b/test/OpenMP/distribute_codegen.cpp
@@ -23,6 +23,7 @@
// CHECK-DAG: %ident_t = type { i32, i32, i32, i32, i8* }
// CHECK-DAG: [[STR:@.+]] = private unnamed_addr constant [23 x i8] c";unknown;unknown;0;0;;\00"
// CHECK-DAG: [[DEF_LOC_0:@.+]] = private unnamed_addr constant %ident_t { i32 0, i32 2, i32 0, i32 0, i8* getelementptr inbounds ([23 x i8], [23 x i8]* [[STR]], i32 0, i32 0) }
+// CHECK-DAG: [[DEF_LOC_DISTRIBUTE_0:@.+]] = private unnamed_addr constant %ident_t { i32 0, i32 2050, i32 0, i32 0, i8* getelementptr inbounds ([23 x i8], [23 x i8]* [[STR]], i32 0, i32 0) }
// CHECK-LABEL: define {{.*void}} @{{.*}}without_schedule_clause{{.*}}(float* {{.+}}, float* {{.+}}, float* {{.+}}, float* {{.+}})
void without_schedule_clause(float *a, float *b, float *c, float *d) {
@@ -34,7 +35,7 @@ void without_schedule_clause(float *a, float *b, float *c, float *d) {
}
}
-// CHECK: define {{.*}}void @.omp_outlined.(i32* noalias [[GBL_TIDP:%.+]], i32* noalias [[BND_TID:%.+]], float** dereferenceable({{[0-9]+}}) [[APTR:%.+]], float** dereferenceable({{[0-9]+}}) [[BPTR:%.+]], float** dereferenceable({{[0-9]+}}) [[CPTR:%.+]], float** dereferenceable({{[0-9]+}}) [[DPTR:%.+]])
+// CHECK: define {{.*}}void @{{.+}}(i32* noalias [[GBL_TIDP:%.+]], i32* noalias [[BND_TID:%.+]], float** dereferenceable({{[0-9]+}}) [[APTR:%.+]], float** dereferenceable({{[0-9]+}}) [[BPTR:%.+]], float** dereferenceable({{[0-9]+}}) [[CPTR:%.+]], float** dereferenceable({{[0-9]+}}) [[DPTR:%.+]])
// CHECK: [[TID_ADDR:%.+]] = alloca i32*
// CHECK: [[IV:%.+iv]] = alloca i32
// CHECK: [[LB:%.+lb]] = alloca i32
@@ -48,7 +49,7 @@ void without_schedule_clause(float *a, float *b, float *c, float *d) {
// CHECK-DAG: store i32 0, i32* [[LAST]]
// CHECK-DAG: [[GBL_TID:%.+]] = load i32*, i32** [[TID_ADDR]]
// CHECK-DAG: [[GBL_TIDV:%.+]] = load i32, i32* [[GBL_TID]]
-// CHECK: call void @__kmpc_for_static_init_{{.+}}(%ident_t* [[DEF_LOC_0]], i32 [[GBL_TIDV]], i32 92, i32* %.omp.is_last, i32* %.omp.lb, i32* %.omp.ub, i32* %.omp.stride, i32 1, i32 1)
+// CHECK: call void @__kmpc_for_static_init_{{.+}}(%ident_t* [[DEF_LOC_DISTRIBUTE_0]], i32 [[GBL_TIDV]], i32 92, i32* %.omp.is_last, i32* %.omp.lb, i32* %.omp.ub, i32* %.omp.stride, i32 1, i32 1)
// CHECK-DAG: [[UBV0:%.+]] = load i32, i32* [[UB]]
// CHECK-DAG: [[USWITCH:%.+]] = icmp sgt i32 [[UBV0]], 4571423
// CHECK: br i1 [[USWITCH]], label %[[BBCT:.+]], label %[[BBCF:.+]]
@@ -82,7 +83,7 @@ void without_schedule_clause(float *a, float *b, float *c, float *d) {
// CHECK: [[BBINNEND]]:
// CHECK: br label %[[LPEXIT:.+]]
// CHECK: [[LPEXIT]]:
-// CHECK: call void @__kmpc_for_static_fini(%ident_t* [[DEF_LOC_0]], i32 [[GBL_TIDV]])
+// CHECK: call void @__kmpc_for_static_fini(%ident_t* [[DEF_LOC_DISTRIBUTE_0]], i32 [[GBL_TIDV]])
// CHECK: ret void
@@ -110,7 +111,7 @@ void static_not_chunked(float *a, float *b, float *c, float *d) {
// CHECK-DAG: store i32 0, i32* [[LAST]]
// CHECK-DAG: [[GBL_TID:%.+]] = load i32*, i32** [[TID_ADDR]]
// CHECK-DAG: [[GBL_TIDV:%.+]] = load i32, i32* [[GBL_TID]]
-// CHECK: call void @__kmpc_for_static_init_{{.+}}(%ident_t* [[DEF_LOC_0]], i32 [[GBL_TIDV]], i32 92, i32* %.omp.is_last, i32* %.omp.lb, i32* %.omp.ub, i32* %.omp.stride, i32 1, i32 1)
+// CHECK: call void @__kmpc_for_static_init_{{.+}}(%ident_t* [[DEF_LOC_DISTRIBUTE_0]], i32 [[GBL_TIDV]], i32 92, i32* %.omp.is_last, i32* %.omp.lb, i32* %.omp.ub, i32* %.omp.stride, i32 1, i32 1)
// CHECK-DAG: [[UBV0:%.+]] = load i32, i32* [[UB]]
// CHECK-DAG: [[USWITCH:%.+]] = icmp sgt i32 [[UBV0]], 4571423
// CHECK: br i1 [[USWITCH]], label %[[BBCT:.+]], label %[[BBCF:.+]]
@@ -144,7 +145,7 @@ void static_not_chunked(float *a, float *b, float *c, float *d) {
// CHECK: [[BBINNEND]]:
// CHECK: br label %[[LPEXIT:.+]]
// CHECK: [[LPEXIT]]:
-// CHECK: call void @__kmpc_for_static_fini(%ident_t* [[DEF_LOC_0]], i32 [[GBL_TIDV]])
+// CHECK: call void @__kmpc_for_static_fini(%ident_t* [[DEF_LOC_DISTRIBUTE_0]], i32 [[GBL_TIDV]])
// CHECK: ret void
@@ -172,7 +173,7 @@ void static_chunked(float *a, float *b, float *c, float *d) {
// CHECK-DAG: store i32 0, i32* [[LAST]]
// CHECK-DAG: [[GBL_TID:%.+]] = load i32*, i32** [[TID_ADDR]]
// CHECK-DAG: [[GBL_TIDV:%.+]] = load i32, i32* [[GBL_TID]]
-// CHECK: call void @__kmpc_for_static_init_{{.+}}(%ident_t* [[DEF_LOC_0]], i32 [[GBL_TIDV]], i32 91, i32* %.omp.is_last, i32* %.omp.lb, i32* %.omp.ub, i32* %.omp.stride, i32 1, i32 5)
+// CHECK: call void @__kmpc_for_static_init_{{.+}}(%ident_t* [[DEF_LOC_DISTRIBUTE_0]], i32 [[GBL_TIDV]], i32 91, i32* %.omp.is_last, i32* %.omp.lb, i32* %.omp.ub, i32* %.omp.stride, i32 1, i32 5)
// CHECK-DAG: [[UBV0:%.+]] = load i32, i32* [[UB]]
// CHECK-DAG: [[USWITCH:%.+]] = icmp ugt i32 [[UBV0]], 16908288
// CHECK: br i1 [[USWITCH]], label %[[BBCT:.+]], label %[[BBCF:.+]]
@@ -206,7 +207,7 @@ void static_chunked(float *a, float *b, float *c, float *d) {
// CHECK: [[BBINNEND]]:
// CHECK: br label %[[LPEXIT:.+]]
// CHECK: [[LPEXIT]]:
-// CHECK: call void @__kmpc_for_static_fini(%ident_t* [[DEF_LOC_0]], i32 [[GBL_TIDV]])
+// CHECK: call void @__kmpc_for_static_fini(%ident_t* [[DEF_LOC_DISTRIBUTE_0]], i32 [[GBL_TIDV]])
// CHECK: ret void
// CHECK-LABEL: test_precond
diff --git a/test/OpenMP/distribute_firstprivate_codegen.cpp b/test/OpenMP/distribute_firstprivate_codegen.cpp
index 718fc875254c..98c99d805ed5 100644
--- a/test/OpenMP/distribute_firstprivate_codegen.cpp
+++ b/test/OpenMP/distribute_firstprivate_codegen.cpp
@@ -63,16 +63,13 @@ int main() {
#pragma omp teams
#pragma omp distribute firstprivate(g, g1, svar, sfvar)
for (int i = 0; i < 2; ++i) {
- // LAMBDA-64: define{{.*}} internal{{.*}} void [[OMP_OUTLINED]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, i{{[0-9]+}} [[G_IN:%.+]], i{{[0-9]+}} [[G1_IN:%.+]], i{{[0-9]+}} [[SVAR_IN:%.+]], i{{[0-9]+}} [[SFVAR_IN:%.+]])
- // LAMBDA-32: define internal{{.*}} void [[OMP_OUTLINED]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, double*{{.*}} [[G_IN:%.+]], i{{[0-9]+}} [[G1_IN:%.+]], i{{[0-9]+}} [[SVAR_IN:%.+]], i{{[0-9]+}} [[SFVAR_IN:%.+]])
+ // LAMBDA: define internal{{.*}} void [[OMP_OUTLINED]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, double*{{.*}} [[G_IN:%.+]], double*{{.*}} [[G1_IN:%.+]], i32*{{.*}} [[SVAR_IN:%.+]], float*{{.*}} [[SFVAR_IN:%.+]])
// Private alloca's for conversion
- // LAMBDA-64: [[G_ADDR:%.+]] = alloca i{{[0-9]+}},
- // LAMBDA-32: [[G_ADDR:%.+]] = alloca double*,
- // LAMBDA: [[G1_ADDR:%.+]] = alloca i{{[0-9]+}},
- // LAMBDA: [[SVAR_ADDR:%.+]] = alloca i{{[0-9]+}},
- // LAMBDA: [[SFVAR_ADDR:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[G_ADDR:%.+]] = alloca double*,
+ // LAMBDA: [[G1_ADDR:%.+]] = alloca double*,
+ // LAMBDA: [[SVAR_ADDR:%.+]] = alloca i{{[0-9]+}}*,
+ // LAMBDA: [[SFVAR_ADDR:%.+]] = alloca float*,
// LAMBDA: [[G1_REF:%.+]] = alloca double*,
- // LAMBDA: [[TMP:%.+]] = alloca double*,
// Actual private variables to be used in the body (tmp is used for the reference type)
// LAMBDA: [[G_PRIVATE:%.+]] = alloca double,
@@ -82,31 +79,25 @@ int main() {
// LAMBDA: [[SFVAR_PRIVATE:%.+]] = alloca float,
// Store input parameter addresses into private alloca's for conversion
- // LAMBDA-64: store i{{[0-9]+}} [[G_IN]], i{{[0-9]+}}* [[G_ADDR]],
- // LAMBDA-32: store double* [[G_IN]], double** [[G_ADDR]],
- // LAMBDA: store i{{[0-9]+}} [[G1_IN]], i{{[0-9]+}}* [[G1_ADDR]],
- // LAMBDA: store i{{[0-9]+}} [[SVAR_IN]], i{{[0-9]+}}* [[SVAR_ADDR]],
- // LAMBDA: store i{{[0-9]+}} [[SFVAR_IN]], i{{[0-9]+}}* [[SFVAR_ADDR]],
-
- // LAMBDA-64-DAG: [[G_CONV:%.+]] = bitcast i{{[0-9]+}}* [[G_ADDR]] to double*
- // LAMBDA-32-DAG: [[G_ADDR_VAL:%.+]] = load double*, double** [[G_ADDR]],
- // LAMBDA-DAG: [[G1_CONV:%.+]] = bitcast i{{[0-9]+}}* [[G1_ADDR]] to double*
- // LAMBDA-DAG: store double* [[G1_CONV]], double** [[G1_REF]],
- // LAMBDA-64-DAG: [[SVAR_CONV:%.+]] = bitcast i{{[0-9]+}}* [[SVAR_ADDR]] to i{{[0-9]+}}*
- // LAMBDA-DAG: [[SFVAR_CONV:%.+]] = bitcast i{{[0-9]+}}* [[SFVAR_ADDR]] to float*
- // LAMBDA-DAG: [[G1_REF_VAL:%.+]] = load double*, double** [[G1_REF]],
- // LAMBDA-DAG: store double* [[G1_REF_VAL]], double** [[TMP]],
- // LAMBDA-64-DAG: [[G_CONV_VAL:%.+]] = load{{.*}} double, double* [[G_CONV]],
- // LAMBDA-32-DAG: [[G_CONV_VAL:%.+]] = load{{.*}} double, double* [[G_ADDR_VAL]],
+ // LAMBDA: store double* [[G_IN]], double** [[G_ADDR]],
+ // LAMBDA: store double* [[G1_IN]], double** [[G1_ADDR]],
+ // LAMBDA: store i{{[0-9]+}}* [[SVAR_IN]], i{{[0-9]+}}** [[SVAR_ADDR]],
+ // LAMBDA: store float* [[SFVAR_IN]], float** [[SFVAR_ADDR]],
+
+ // LAMBDA-DAG: [[G_ADDR_VAL:%.+]] = load double*, double** [[G_ADDR]],
+ // LAMBDA-DAG: [[SVAR_ADDR_VAL:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SVAR_ADDR]],
+ // LAMBDA-DAG: [[SFVAR_ADDR_VAL:%.+]] = load float*, float** [[SFVAR_ADDR]],
+ // LAMBDA-DAG: [[G1_ADDR_VAL:%.+]] = load double*, double** [[G1_ADDR]],
+ // LAMBDA-DAG: store double* [[G1_ADDR_VAL]], double** [[G1_REF]],
+ // LAMBDA-DAG: [[G_CONV_VAL:%.+]] = load{{.*}} double, double* [[G_ADDR_VAL]],
// LAMBDA-DAG: store double [[G_CONV_VAL]], double* [[G_PRIVATE]],
- // LAMBDA-DAG: [[TMP_VAL:%.+]] = load double*, double** [[TMP]],
+ // LAMBDA-DAG: [[TMP_VAL:%.+]] = load double*, double** [[G1_REF]],
// LAMBDA-DAG: [[TMP_VAL_VAL:%.+]] = load{{.*}} double, double* [[TMP_VAL]],
// LAMBDA-DAG: store double [[TMP_VAL_VAL]], double* [[G1_PRIVATE]],
// LAMBDA-DAG: store double* [[G1_PRIVATE]], double** [[TMP_PRIVATE]],
- // LAMBDA-64-DAG: [[SVAR_CONV_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SVAR_CONV]],
- // LAMBDA-32-DAG: [[SVAR_CONV_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SVAR_ADDR]],
+ // LAMBDA-DAG: [[SVAR_CONV_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SVAR_ADDR_VAL]],
// LAMBDA-DAG: store i{{[0-9]+}} [[SVAR_CONV_VAL]], i{{[0-9]+}}* [[SVAR_PRIVATE]],
- // LAMBDA-DAG: [[SFVAR_CONV_VAL:%.+]] = load float, float* [[SFVAR_CONV]],
+ // LAMBDA-DAG: [[SFVAR_CONV_VAL:%.+]] = load float, float* [[SFVAR_ADDR_VAL]],
// LAMBDA-DAG: store float [[SFVAR_CONV_VAL]], float* [[SFVAR_PRIVATE]],
// LAMBDA: call {{.*}}void @__kmpc_for_static_init_4(
g += 1;
@@ -204,16 +195,18 @@ int main() {
// CHECK: ret
// CHECK: define{{.+}} [[OFFLOAD_FUN]](
-// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_teams(%{{.+}}* @{{.+}}, i{{[0-9]+}} 5, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, i{{[0-9]+}}, [2 x i{{[0-9]+}}]*, [2 x [[S_FLOAT_TY]]]*, [[S_FLOAT_TY]]*, i{{[0-9]+}})* [[OMP_OUTLINED:@.+]] to void
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_teams(%{{.+}}* @{{.+}}, i{{[0-9]+}} 5, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, i{{[0-9]+}}*, [2 x i{{[0-9]+}}]*, [2 x [[S_FLOAT_TY]]]*, [[S_FLOAT_TY]]*, i{{[0-9]+}}*)* [[OMP_OUTLINED:@.+]] to void
// CHECK: ret
//
-// CHECK: define internal void [[OMP_OUTLINED]](i{{[0-9]+}}*{{.+}}, i{{[0-9]+}}*{{.+}}, i{{[0-9]+}} [[T_VAR_IN:%.+]], [2 x i{{[0-9]+}}]*{{.*}} [[VEC_IN:%.+]], [2 x [[S_FLOAT_TY]]]*{{.*}} [[S_ARR_IN:%.+]], [[S_FLOAT_TY]]*{{.*}} [[VAR_IN:%.+]], i{{[0-9]+}} [[SVAR_IN:%.+]])
+// CHECK: define internal void [[OMP_OUTLINED]](i{{[0-9]+}}*{{.+}}, i{{[0-9]+}}*{{.+}}, i{{[0-9]+}}*{{.+}} [[T_VAR_IN:%.+]], [2 x i{{[0-9]+}}]*{{.*}} [[VEC_IN:%.+]], [2 x [[S_FLOAT_TY]]]*{{.*}} [[S_ARR_IN:%.+]], [[S_FLOAT_TY]]*{{.*}} [[VAR_IN:%.+]], i{{[0-9]+}}*{{.+}} [[SVAR_IN:%.+]])
-// CHECK: [[T_VAR_ADDR:%.+]] = alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}}*,
+// CHECK: alloca i{{[0-9]+}}*,
+// CHECK: [[T_VAR_ADDR:%.+]] = alloca i{{[0-9]+}}*,
// CHECK: [[VEC_ADDR:%.+]] = alloca [2 x i{{[0-9]+}}]*,
// CHECK: [[S_ARR_ADDR:%.+]] = alloca [2 x [[S_FLOAT_TY]]]*,
// CHECK: [[VAR_ADDR:%.+]] = alloca [[S_FLOAT_TY]]*,
-// CHECK: [[SVAR_ADDR:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[SVAR_ADDR:%.+]] = alloca i{{[0-9]+}}*,
// CHECK: [[TMP:%.+]] = alloca [[S_FLOAT_TY]]*,
// discard omp loop variables
@@ -222,6 +215,7 @@ int main() {
// CHECK: {{.*}} = alloca i{{[0-9]+}},
// CHECK: {{.*}} = alloca i{{[0-9]+}},
// CHECK: {{.*}} = alloca i{{[0-9]+}},
+// CHECK: {{.*}} = alloca i{{[0-9]+}},
// CHECK-DAG: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
// CHECK-DAG: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
@@ -230,17 +224,16 @@ int main() {
// CHECK-DAG: [[TMP_PRIV:%.+]] = alloca [[S_FLOAT_TY]]*,
// CHECK: [[SVAR_PRIV:%.+]] = alloca i{{[0-9]+}},
-// CHECK: store i{{[0-9]+}} [[T_VAR_IN]], i{{[0-9]+}}* [[T_VAR_ADDR]],
+// CHECK: store i{{[0-9]+}}* [[T_VAR_IN]], i{{[0-9]+}}** [[T_VAR_ADDR]],
// CHECK: store [2 x i{{[0-9]+}}]* [[VEC_IN]], [2 x i{{[0-9]+}}]** [[VEC_ADDR]],
// CHECK: store [2 x [[S_FLOAT_TY]]]* [[S_ARR_IN]], [2 x [[S_FLOAT_TY]]]** [[S_ARR_ADDR]],
// CHECK: store [[S_FLOAT_TY]]* [[VAR_IN]], [[S_FLOAT_TY]]** [[VAR_ADDR]],
-// CHECK: store i{{[0-9]+}} [[SVAR_IN]], i{{[0-9]+}}* [[SVAR_ADDR]],
+// CHECK: store i{{[0-9]+}}* [[SVAR_IN]], i{{[0-9]+}}** [[SVAR_ADDR]],
// init t_var
-// CHECK-64-DAG: [[T_VAR_ADDR_CONV:%.+]] = bitcast i{{[0-9]+}}* [[T_VAR_ADDR]] to i{{[0-9]+}}*
-// CHECK-64-DAG: [[T_VAR_ADDR_CONV_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_ADDR_CONV]],
-// CHECK-32-DAG: [[T_VAR_ADDR_CONV_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_ADDR]],
-// CHECK-DAG: store i{{[0-9]+}} [[T_VAR_ADDR_CONV_VAL]], i{{[0-9]+}}* [[T_VAR_PRIV]],
+// CHECK-DAG: [[T_VAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[T_VAR_ADDR]],
+// CHECK-DAG: [[T_VAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_REF]],
+// CHECK-DAG: store i{{[0-9]+}} [[T_VAR_VAL]], i{{[0-9]+}}* [[T_VAR_PRIV]],
// init vec
// CHECK-DAG: [[VEC_ADDR_VAL:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** [[VEC_ADDR]],
@@ -278,10 +271,9 @@ int main() {
// CHECK-DAG: store [[S_FLOAT_TY]]* [[VAR_PRIV]], [[S_FLOAT_TY]]** [[TMP_PRIV]],
// init svar
-// CHECK-64-DAG: [[SVAR_ADDR_CONV:%.+]] = bitcast{{.+}} [[SVAR_ADDR]] to{{.+}}
-// CHECK-64-DAG: [[SVAR_CONV_VAL:%.+]] = load{{.+}},{{.+}} [[SVAR_ADDR_CONV]],
-// CHECK-32-DAG: [[SVAR_CONV_VAL:%.+]] = load{{.+}},{{.+}} [[SVAR_ADDR]],
-// CHECK-DAG: store{{.+}} [[SVAR_CONV_VAL]],{{.+}} [[SVAR_PRIV]],
+// CHECK-DAG: [[SVAR_REF:%.+]] = load{{.+}},{{.+}} [[SVAR_ADDR]],
+// CHECK-DAG: [[SVAR_VAL:%.+]] = load{{.+}},{{.+}} [[SVAR_REF]],
+// CHECK-DAG: store{{.+}} [[SVAR_VAL]],{{.+}} [[SVAR_PRIV]],
// CHECK-DAG: store i{{[0-9]+}} 0, i{{[0-9]+}}* %.omp{{.+}},
// CHECK-DAG: store i{{[0-9]+}} 1, i{{[0-9]+}}* %.omp{{.+}},
@@ -301,12 +293,14 @@ int main() {
// CHECK: ret
// CHECK: define{{.+}} [[OFFLOAD_FUN_1]](
-// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_teams(%{{.+}}* @{{.+}}, i{{[0-9]+}} 4, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, i{{[0-9]+}}, [2 x i{{[0-9]+}}]*, [2 x [[S_INT_TY]]]*, [[S_INT_TY]]*)* [[OMP_OUTLINED_1:@.+]] to void
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_teams(%{{.+}}* @{{.+}}, i{{[0-9]+}} 4, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, i{{[0-9]+}}*, [2 x i{{[0-9]+}}]*, [2 x [[S_INT_TY]]]*, [[S_INT_TY]]*)* [[OMP_OUTLINED_1:@.+]] to void
// CHECK: ret
//
-// CHECK: define internal void [[OMP_OUTLINED_1]](i{{[0-9]+}}*{{.+}}, i{{[0-9]+}}*{{.+}}, i{{[0-9]+}} [[T_VAR_IN:%.+]], [2 x i{{[0-9]+}}]*{{.*}} [[VEC_IN:%.+]], [2 x [[S_INT_TY]]]*{{.*}} [[S_ARR_IN:%.+]], [[S_INT_TY]]*{{.*}} [[VAR_IN:%.+]])
+// CHECK: define internal void [[OMP_OUTLINED_1]](i{{[0-9]+}}*{{.+}}, i{{[0-9]+}}*{{.+}}, i{{[0-9]+}}*{{.+}} [[T_VAR_IN:%.+]], [2 x i{{[0-9]+}}]*{{.*}} [[VEC_IN:%.+]], [2 x [[S_INT_TY]]]*{{.*}} [[S_ARR_IN:%.+]], [[S_INT_TY]]*{{.*}} [[VAR_IN:%.+]])
-// CHECK: [[T_VAR_ADDR:%.+]] = alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}}*,
+// CHECK: alloca i{{[0-9]+}}*,
+// CHECK: [[T_VAR_ADDR:%.+]] = alloca i{{[0-9]+}}*,
// CHECK: [[VEC_ADDR:%.+]] = alloca [2 x i{{[0-9]+}}]*,
// CHECK: [[S_ARR_ADDR:%.+]] = alloca [2 x [[S_INT_TY]]]*,
// CHECK: [[VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*,
@@ -318,6 +312,7 @@ int main() {
// CHECK: {{.*}} = alloca i{{[0-9]+}},
// CHECK: {{.*}} = alloca i{{[0-9]+}},
// CHECK: {{.*}} = alloca i{{[0-9]+}},
+// CHECK: {{.*}} = alloca i{{[0-9]+}},
// CHECK-DAG: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
// CHECK-DAG: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
@@ -325,16 +320,15 @@ int main() {
// CHECK-DAG: [[VAR_PRIV:%.+]] = alloca [[S_INT_TY]],
// CHECK-DAG: [[TMP_PRIV:%.+]] = alloca [[S_INT_TY]]*,
-// CHECK: store i{{[0-9]+}} [[T_VAR_IN]], i{{[0-9]+}}* [[T_VAR_ADDR]],
+// CHECK: store i{{[0-9]+}}* [[T_VAR_IN]], i{{[0-9]+}}** [[T_VAR_ADDR]],
// CHECK: store [2 x i{{[0-9]+}}]* [[VEC_IN]], [2 x i{{[0-9]+}}]** [[VEC_ADDR]],
// CHECK: store [2 x [[S_INT_TY]]]* [[S_ARR_IN]], [2 x [[S_INT_TY]]]** [[S_ARR_ADDR]],
// CHECK: store [[S_INT_TY]]* [[VAR_IN]], [[S_INT_TY]]** [[VAR_ADDR]],
// init t_var
-// CHECK-64-DAG: [[T_VAR_ADDR_CONV:%.+]] = bitcast i{{[0-9]+}}* [[T_VAR_ADDR]] to i{{[0-9]+}}*
-// CHECK-64-DAG: [[T_VAR_ADDR_CONV_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_ADDR_CONV]],
-// CHECK-32-DAG: [[T_VAR_ADDR_CONV_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_ADDR]],
-// CHECK-DAG: store i{{[0-9]+}} [[T_VAR_ADDR_CONV_VAL]], i{{[0-9]+}}* [[T_VAR_PRIV]],
+// CHECK-DAG: [[T_VAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[T_VAR_ADDR]],
+// CHECK-DAG: [[T_VAR:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_REF]],
+// CHECK-DAG: store i{{[0-9]+}} [[T_VAR]], i{{[0-9]+}}* [[T_VAR_PRIV]],
// init vec
// CHECK-DAG: [[VEC_ADDR_VAL:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** [[VEC_ADDR]],
diff --git a/test/OpenMP/distribute_firstprivate_messages.cpp b/test/OpenMP/distribute_firstprivate_messages.cpp
index 5d371abbfa8e..a59c9528090f 100644
--- a/test/OpenMP/distribute_firstprivate_messages.cpp
+++ b/test/OpenMP/distribute_firstprivate_messages.cpp
@@ -135,11 +135,11 @@ int main(int argc, char **argv) {
for (i = 0; i < argc; ++i) foo(); // expected-error {{loop iteration variable in the associated loop of 'omp distribute' directive may not be firstprivate, predetermined as private}}
#pragma omp target
#pragma omp teams private(argc) // expected-note {{defined as private}}
- #pragma omp distribute firstprivate(argc) // expected-error {{private variable in '#pragma omp teams' cannot be firstprivate in '#pragma omp distribute'}}
+ #pragma omp distribute firstprivate(argc) // expected-error {{firstprivate variable must be shared}}
for (i = 0; i < argc; ++i) foo();
#pragma omp target
#pragma omp teams reduction(+:argc) // expected-note {{defined as reduction}}
- #pragma omp distribute firstprivate(argc) // expected-error {{reduction variable in '#pragma omp teams' cannot be firstprivate in '#pragma omp distribute'}}
+ #pragma omp distribute firstprivate(argc) // expected-error {{firstprivate variable must be shared}}
for (i = 0; i < argc; ++i) foo();
#pragma omp target
#pragma omp teams
@@ -147,11 +147,11 @@ int main(int argc, char **argv) {
for (i = 0; i < argc; ++i) foo();
#pragma omp target
#pragma omp teams
- #pragma omp distribute lastprivate(argc), firstprivate(argc) // expected-error {{lastprivate variable cannot be firstprivate in '#pragma omp distribute'}} expected-note{{defined as lastprivate}}
+ #pragma omp distribute lastprivate(argc), firstprivate(argc) // expected-error {{lastprivate variable cannot be firstprivate}} expected-note{{defined as lastprivate}}
for (i = 0; i < argc; ++i) foo();
#pragma omp target
#pragma omp teams
-#pragma omp distribute firstprivate(argc), lastprivate(argc) // expected-error {{lastprivate variable cannot be firstprivate in '#pragma omp distribute'}} expected-note{{defined as firstprivate}}
+#pragma omp distribute firstprivate(argc), lastprivate(argc) // expected-error {{firstprivate variable cannot be lastprivate}} expected-note{{defined as firstprivate}}
for (i = 0; i < argc; ++i) foo();
return 0;
}
diff --git a/test/OpenMP/distribute_lastprivate_codegen.cpp b/test/OpenMP/distribute_lastprivate_codegen.cpp
index abcbfd8d69c4..bd9dae956f1c 100644
--- a/test/OpenMP/distribute_lastprivate_codegen.cpp
+++ b/test/OpenMP/distribute_lastprivate_codegen.cpp
@@ -74,6 +74,7 @@ int main() {
// LAMBDA: {{.+}} = alloca i{{[0-9]+}},
// LAMBDA: {{.+}} = alloca i{{[0-9]+}},
// LAMBDA: {{.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: {{.+}} = alloca i{{[0-9]+}},
// LAMBDA: [[OMP_IS_LAST:%.+]] = alloca i{{[0-9]+}},
// LAMBDA: [[G_PRIVATE:%.+]] = alloca double,
// LAMBDA: [[G1_PRIVATE:%.+]] = alloca double,
@@ -202,6 +203,7 @@ int main() {
// CHECK: {{.+}} = alloca i{{[0-9]+}},
// CHECK: {{.+}} = alloca i{{[0-9]+}},
// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
// CHECK: [[OMP_IS_LAST:%.+]] = alloca i{{[0-9]+}},
// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
@@ -303,6 +305,7 @@ int main() {
// CHECK: {{.+}} = alloca i{{[0-9]+}},
// CHECK: {{.+}} = alloca i{{[0-9]+}},
// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
// CHECK: [[OMP_IS_LAST1:%.+]] = alloca i{{[0-9]+}},
// CHECK: [[T_VAR_PRIV1:%.+]] = alloca i{{[0-9]+}},
// CHECK: [[VEC_PRIV1:%.+]] = alloca [2 x i{{[0-9]+}}],
diff --git a/test/OpenMP/distribute_parallel_for_ast_print.cpp b/test/OpenMP/distribute_parallel_for_ast_print.cpp
index 54a3649e578b..351e15803c09 100644
--- a/test/OpenMP/distribute_parallel_for_ast_print.cpp
+++ b/test/OpenMP/distribute_parallel_for_ast_print.cpp
@@ -82,7 +82,7 @@ T tmain(T argc) {
// CHECK-NEXT: a = 2;
#pragma omp target
#pragma omp teams
-#pragma omp distribute parallel for private(argc, b), firstprivate(c, d), lastprivate(d, f) collapse(N) schedule(static, N) if (parallel :argc) num_threads(N) default(shared) shared(e) reduction(+ : h) dist_schedule(static,N)
+#pragma omp distribute parallel for private(argc, b), firstprivate(c, d), lastprivate(f) collapse(N) schedule(static, N) if (parallel :argc) num_threads(N) default(shared) shared(e) reduction(+ : h) dist_schedule(static,N)
for (int i = 0; i < 2; ++i)
for (int j = 0; j < 2; ++j)
for (int j = 0; j < 2; ++j)
@@ -93,8 +93,8 @@ T tmain(T argc) {
for (int j = 0; j < 2; ++j)
for (int j = 0; j < 2; ++j)
for (int j = 0; j < 2; ++j)
- a++;
- // CHECK: #pragma omp distribute parallel for private(argc,b) firstprivate(c,d) lastprivate(d,f) collapse(N) schedule(static, N) if(parallel: argc) num_threads(N) default(shared) shared(e) reduction(+: h) dist_schedule(static, N)
+ a++;
+ // CHECK: #pragma omp distribute parallel for private(argc,b) firstprivate(c,d) lastprivate(f) collapse(N) schedule(static, N) if(parallel: argc) num_threads(N) default(shared) shared(e) reduction(+: h) dist_schedule(static, N)
// CHECK-NEXT: for (int i = 0; i < 2; ++i)
// CHECK-NEXT: for (int j = 0; j < 2; ++j)
// CHECK-NEXT: for (int j = 0; j < 2; ++j)
diff --git a/test/OpenMP/distribute_parallel_for_codegen.cpp b/test/OpenMP/distribute_parallel_for_codegen.cpp
index 62c38f188851..4fbca7d2f29a 100644
--- a/test/OpenMP/distribute_parallel_for_codegen.cpp
+++ b/test/OpenMP/distribute_parallel_for_codegen.cpp
@@ -28,6 +28,7 @@ T tmain() {
#pragma omp teams
#pragma omp distribute parallel for
for (int i = 0; i < n; ++i) {
+ #pragma omp cancel for
a[i] = b[i] + c[i];
}
diff --git a/test/OpenMP/distribute_parallel_for_firstprivate_codegen.cpp b/test/OpenMP/distribute_parallel_for_firstprivate_codegen.cpp
index d12c0aa11cf2..de348272950c 100644
--- a/test/OpenMP/distribute_parallel_for_firstprivate_codegen.cpp
+++ b/test/OpenMP/distribute_parallel_for_firstprivate_codegen.cpp
@@ -63,17 +63,14 @@ int main() {
#pragma omp teams
#pragma omp distribute parallel for firstprivate(g, g1, svar, sfvar)
for (int i = 0; i < 2; ++i) {
- // LAMBDA-64: define{{.*}} internal{{.*}} void [[OMP_OUTLINED]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, i{{[0-9]+}} [[G_IN:%.+]], i{{[0-9]+}} [[G1_IN:%.+]], i{{[0-9]+}} [[SVAR_IN:%.+]], i{{[0-9]+}} [[SFVAR_IN:%.+]])
- // LAMBDA-32: define{{.*}} internal{{.*}} void [[OMP_OUTLINED]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, double* {{.+}} [[G_IN:%.+]], i{{[0-9]+}} [[G1_IN:%.+]], i{{[0-9]+}} [[SVAR_IN:%.+]], i{{[0-9]+}} [[SFVAR_IN:%.+]])
+ // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_OUTLINED]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, double* {{.+}} [[G_IN:%.+]], double*{{.+}} [[G1_IN:%.+]], i{{[0-9]+}}*{{.+}} [[SVAR_IN:%.+]], float*{{.+}} [[SFVAR_IN:%.+]])
// addr alloca's
- // LAMBDA-64: [[G_ADDR:%.+]] = alloca i{{[0-9]+}},
- // LAMBDA-32: [[G_ADDR:%.+]] = alloca double*,
- // LAMBDA: [[G1_ADDR:%.+]] = alloca i{{[0-9]+}},
- // LAMBDA: [[SVAR_ADDR:%.+]] = alloca i{{[0-9]+}},
- // LAMBDA: [[SFVAR_ADDR:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[G_ADDR:%.+]] = alloca double*,
+ // LAMBDA: [[G1_ADDR:%.+]] = alloca double*,
+ // LAMBDA: [[SVAR_ADDR:%.+]] = alloca i{{[0-9]+}}*,
+ // LAMBDA: [[SFVAR_ADDR:%.+]] = alloca float*,
// LAMBDA: [[G1_REF:%.+]] = alloca double*,
- // LAMBDA: [[TMP:%.+]] = alloca double*,
// private alloca's
// LAMBDA: [[G_PRIV:%.+]] = alloca double,
@@ -88,31 +85,27 @@ int main() {
// LAMBDA-DAG: store {{.+}} [[SVAR_IN]], {{.+}} [[SVAR_ADDR]],
// LAMBDA-DAG: store {{.+}} [[SFVAR_IN]], {{.+}} [[SFVAR_ADDR]],
+ // LAMBDA-DAG: [[G_CONV:%.+]] = load {{.+}}*, {{.+}}** [[G_ADDR]]
+ // LAMBDA-DAG: [[G1_CONV:%.+]] = load {{.+}}*, {{.+}}** [[G1_ADDR]]
+ // LAMBDA-DAG: [[SVAR_CONV:%.+]] = load {{.+}}*, {{.+}}** [[SVAR_ADDR]]
+ // LAMBDA-DAG: [[SFVAR_CONV:%.+]] = load {{.+}}*, {{.+}}** [[SFVAR_ADDR]]
+
// init private alloca's with addr alloca's
// g
- // LAMBDA-64-DAG: [[G_CONV:%.+]] = bitcast {{.+}}* [[G_ADDR]] to
- // LAMBDA-32-DAG: [[G_CONV:%.+]] = load {{.+}}*, {{.+}}** [[G_ADDR]]
// LAMBDA-DAG: [[G_ADDR_VAL:%.+]] = load {{.+}}, {{.+}}* [[G_CONV]],
// LAMBDA-DAG: store {{.+}} [[G_ADDR_VAL]], {{.+}}* [[G_PRIV]],
// g1
- // LAMBDA-DAG: [[G1_CONV:%.+]] = bitcast {{.+}}* [[G1_ADDR]] to
- // LAMBDA-DAG: store {{.+}}* [[G1_CONV]], {{.+}}** [[G1_REF]],
- // LAMBDA-DAG: [[G1_REF_VAL:%.+]] = load {{.+}}*, {{.+}}** [[G1_REF]],
- // LAMBDA-DAG: store {{.+}}* [[G1_REF_VAL]], {{.+}}** [[TMP]],
- // LAMBDA-DAG: [[TMP_REF:%.+]] = load {{.+}}*, {{.+}}** [[TMP]],
+ // LAMBDA-DAG: [[TMP_REF:%.+]] = load {{.+}}*, {{.+}}** [[G1_REF]],
// LAMBDA-DAG: [[TMP_VAL:%.+]] = load {{.+}}, {{.+}}* [[TMP_REF]],
// LAMBDA-DAG: store {{.+}} [[TMP_VAL]], {{.+}}* [[G1_PRIV]]
// LAMBDA-DAG: store {{.+}}* [[G1_PRIV]], {{.+}}** [[TMP_PRIV]],
// svar
- // LAMBDA-64-DAG: [[SVAR_CONV:%.+]] = bitcast {{.+}}* [[SVAR_ADDR]] to
- // LAMBDA-64-DAG: [[SVAR_VAL:%.+]] = load {{.+}}, {{.+}}* [[SVAR_CONV]],
- // LAMBDA-32-DAG: [[SVAR_VAL:%.+]] = load {{.+}}, {{.+}}* [[SVAR_ADDR]],
+ // LAMBDA-DAG: [[SVAR_VAL:%.+]] = load {{.+}}, {{.+}}* [[SVAR_CONV]],
// LAMBDA-DAG: store {{.+}} [[SVAR_VAL]], {{.+}}* [[SVAR_PRIV]],
// sfvar
- // LAMBDA-DAG: [[SFVAR_CONV:%.+]] = bitcast {{.+}}* [[SFVAR_ADDR]] to
// LAMBDA-DAG: [[SFVAR_VAL:%.+]] = load {{.+}}, {{.+}}* [[SFVAR_CONV]],
// LAMBDA-DAG: store {{.+}} [[SFVAR_VAL]], {{.+}}* [[SFVAR_PRIV]],
@@ -271,17 +264,19 @@ int main() {
// CHECK: call {{.*}} [[S_FLOAT_TY_DEF_DESTR:@.+]]([[S_FLOAT_TY]]* [[TEST]])
// CHECK: define{{.+}} [[OFFLOAD_FUN_0]](i{{[0-9]+}} [[T_VAR_IN:%.+]], [2 x i{{[0-9]+}}]* {{.+}} [[VEC_IN:%.+]], [2 x [[S_FLOAT_TY]]]* {{.+}} [[S_ARR_IN:%.+]], [[S_FLOAT_TY]]* {{.+}} [[VAR_IN:%.+]], i{{[0-9]+}} [[SVAR_IN:%.+]])
-// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_teams(%{{.+}}* @{{.+}}, i{{[0-9]+}} 5, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, i{{[0-9]+}}, [2 x i{{[0-9]+}}]*, [2 x [[S_FLOAT_TY]]]*, [[S_FLOAT_TY]]*, i{{[0-9]+}})* [[OMP_OUTLINED_0:@.+]] to void
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_teams(%{{.+}}* @{{.+}}, i{{[0-9]+}} 5, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, i{{[0-9]+}}*, [2 x i{{[0-9]+}}]*, [2 x [[S_FLOAT_TY]]]*, [[S_FLOAT_TY]]*, i{{[0-9]+}}*)* [[OMP_OUTLINED_0:@.+]] to void
// CHECK: ret
-// CHECK: define internal void [[OMP_OUTLINED_0]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i{{[0-9]+}} [[T_VAR_IN:%.+]], [2 x i{{[0-9]+}}]* {{.+}} [[VEC_IN:%.+]], [2 x [[S_FLOAT_TY]]]* {{.+}} [[S_ARR_IN:%.+]], [[S_FLOAT_TY]]* {{.+}} [[VAR_IN:%.+]], i{{[0-9]+}} [[SVAR_IN:%.+]])
+// CHECK: define internal void [[OMP_OUTLINED_0]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i{{[0-9]+}}*{{.+}} [[T_VAR_IN:%.+]], [2 x i{{[0-9]+}}]* {{.+}} [[VEC_IN:%.+]], [2 x [[S_FLOAT_TY]]]* {{.+}} [[S_ARR_IN:%.+]], [[S_FLOAT_TY]]* {{.+}} [[VAR_IN:%.+]], i{{[0-9]+}}*{{.+}} [[SVAR_IN:%.+]])
+// CHECK: alloca i{{[0-9]+}}*,
+// CHECK: alloca i{{[0-9]+}}*,
// addr alloca's
-// CHECK: [[T_VAR_ADDR:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[T_VAR_ADDR:%.+]] = alloca i{{[0-9]+}}*,
// CHECK: [[VEC_ADDR:%.+]] = alloca [2 x i{{[0-9]+}}]*,
// CHECK: [[S_ARR_ADDR:%.+]] = alloca [2 x [[S_FLOAT_TY]]]*,
// CHECK: [[VAR_ADDR:%.+]] = alloca [[S_FLOAT_TY]]*,
-// CHECK: [[SVAR_ADDR:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[SVAR_ADDR:%.+]] = alloca i{{[0-9]+}}*,
// CHECK: [[TMP:%.+]] = alloca [[S_FLOAT_TY]]*,
// skip loop alloca's
@@ -310,9 +305,8 @@ int main() {
// init private alloca's with addr alloca's
// t-var
-// CHECK-64-DAG: [[T_VAR_CONV:%.+]] = bitcast {{.+}} [[T_VAR_ADDR]] to
-// CHECK-64-DAG: [[T_VAR_ADDR_VAL:%.+]] = load {{.+}}, {{.+}}* [[T_VAR_CONV]],
-// CHECK-32-DAG: [[T_VAR_ADDR_VAL:%.+]] = load {{.+}}, {{.+}}* [[T_VAR_ADDR]],
+// CHECK-DAG: [[T_VAR_REF:%.+]] = load {{.+}}, {{.+}}** [[T_VAR_ADDR]],
+// CHECK-DAG: [[T_VAR_ADDR_VAL:%.+]] = load {{.+}}, {{.+}}* [[T_VAR_REF]],
// CHECK-DAG: store {{.+}} [[T_VAR_ADDR_VAL]], {{.+}} [[T_VAR_PRIV]],
// vec
@@ -340,10 +334,9 @@ int main() {
// CHECK-DAG: store {{.+}}* [[VAR_PRIV]], {{.+}}** [[TMP_PRIV]],
// svar
-// CHECK-64-DAG: [[SVAR_CONV:%.+]] = bitcast {{.+}}* [[SVAR_ADDR]] to
-// CHECK-64-DAG: [[SVAR_CONV_VAL:%.+]] = load {{.+}}, {{.+}}* [[SVAR_CONV]],
-// CHECK-32-DAG: [[SVAR_CONV_VAL:%.+]] = load {{.+}}, {{.+}}* [[SVAR_ADDR]],
-// CHECK-DAG: store {{.+}} [[SVAR_CONV_VAL]], {{.+}}* [[SVAR_PRIV]],
+// CHECK-DAG: [[SVAR_REF:%.+]] = load {{.+}}*, {{.+}}** [[SVAR_ADDR]],
+// CHECK-DAG: [[SVAR:%.+]] = load {{.+}}, {{.+}}* [[SVAR_REF]],
+// CHECK-DAG: store {{.+}} [[SVAR]], {{.+}}* [[SVAR_PRIV]],
// CHECK: call void @__kmpc_for_static_init_4(
// pass private alloca's to fork
@@ -456,13 +449,15 @@ int main() {
// CHECK: call {{.*}} [[S_INT_TY_DEF_DESTR:@.+]]([[S_INT_TY]]* [[TEST]])
// CHECK: define{{.+}} [[OFFLOAD_FUN_0]](i{{[0-9]+}} [[T_VAR_IN:%.+]], [2 x i{{[0-9]+}}]* {{.+}} [[VEC_IN:%.+]], [2 x [[S_INT_TY]]]* {{.+}} [[S_ARR_IN:%.+]], [[S_INT_TY]]* {{.+}} [[VAR_IN:%.+]])
-// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_teams(%{{.+}}* @{{.+}}, i{{[0-9]+}} 4, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, i{{[0-9]+}}, [2 x i{{[0-9]+}}]*, [2 x [[S_INT_TY]]]*, [[S_INT_TY]]*)* [[OMP_OUTLINED_0:@.+]] to void
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_teams(%{{.+}}* @{{.+}}, i{{[0-9]+}} 4, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, i{{[0-9]+}}*, [2 x i{{[0-9]+}}]*, [2 x [[S_INT_TY]]]*, [[S_INT_TY]]*)* [[OMP_OUTLINED_0:@.+]] to void
// CHECK: ret
-// CHECK: define internal void [[OMP_OUTLINED_0]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i{{[0-9]+}} [[T_VAR_IN:%.+]], [2 x i{{[0-9]+}}]* {{.+}} [[VEC_IN:%.+]], [2 x [[S_INT_TY]]]* {{.+}} [[S_ARR_IN:%.+]], [[S_INT_TY]]* {{.+}} [[VAR_IN:%.+]])
+// CHECK: define internal void [[OMP_OUTLINED_0]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i{{[0-9]+}}*{{.+}} [[T_VAR_IN:%.+]], [2 x i{{[0-9]+}}]* {{.+}} [[VEC_IN:%.+]], [2 x [[S_INT_TY]]]* {{.+}} [[S_ARR_IN:%.+]], [[S_INT_TY]]* {{.+}} [[VAR_IN:%.+]])
// addr alloca's
-// CHECK: [[T_VAR_ADDR:%.+]] = alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}}*,
+// CHECK: alloca i{{[0-9]+}}*,
+// CHECK: [[T_VAR_ADDR:%.+]] = alloca i{{[0-9]+}}*,
// CHECK: [[VEC_ADDR:%.+]] = alloca [2 x i{{[0-9]+}}]*,
// CHECK: [[S_ARR_ADDR:%.+]] = alloca [2 x [[S_INT_TY]]]*,
// CHECK: [[VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*,
@@ -492,9 +487,8 @@ int main() {
// init private alloca's with addr alloca's
// t-var
-// CHECK-64-DAG: [[T_VAR_CONV:%.+]] = bitcast {{.+}} [[T_VAR_ADDR]] to
-// CHECK-64-DAG: [[T_VAR_ADDR_VAL:%.+]] = load {{.+}}, {{.+}}* [[T_VAR_CONV]],
-// CHECK-32-DAG: [[T_VAR_ADDR_VAL:%.+]] = load {{.+}}, {{.+}}* [[T_VAR_ADDR]],
+// CHECK-DAG: [[T_VAR_ADDR_REF:%.+]] = load {{.+}}*, {{.+}}** [[T_VAR_ADDR]],
+// CHECK-DAG: [[T_VAR_ADDR_VAL:%.+]] = load {{.+}}, {{.+}}* [[T_VAR_ADDR_REF]],
// CHECK-DAG: store {{.+}} [[T_VAR_ADDR_VAL]], {{.+}} [[T_VAR_PRIV]],
// vec
diff --git a/test/OpenMP/distribute_parallel_for_firstprivate_messages.cpp b/test/OpenMP/distribute_parallel_for_firstprivate_messages.cpp
index 3e288c37d42c..67075ca12939 100644
--- a/test/OpenMP/distribute_parallel_for_firstprivate_messages.cpp
+++ b/test/OpenMP/distribute_parallel_for_firstprivate_messages.cpp
@@ -42,7 +42,7 @@ public:
};
class S5 {
int a;
- S5(const S5 &s5) : a(s5.a) {} // expected-note 4 {{implicitly declared private here}}
+ S5(const S5 &s5) : a(s5.a) {} // expected-note 2 {{implicitly declared private here}}
public:
S5() : a(0) {}
@@ -50,7 +50,7 @@ public:
};
class S6 {
int a;
- S6() : a(0) {}
+ S6() : a(0) {} // expected-note {{implicitly declared private here}}
public:
S6(const S6 &s6) : a(s6.a) {}
@@ -150,9 +150,10 @@ int foomain(int argc, char **argv) {
#pragma omp distribute parallel for firstprivate(i)
for (int k = 0; k < argc; ++k)
++k;
+// expected-error@+3 {{lastprivate variable cannot be firstprivate}} expected-note@+3 {{defined as lastprivate}}
#pragma omp target
#pragma omp teams
-#pragma omp distribute parallel for lastprivate(g) firstprivate(g) // expected-error {{calling a private constructor of class 'S5'}}
+#pragma omp distribute parallel for lastprivate(g) firstprivate(g)
for (i = 0; i < argc; ++i)
foo();
#pragma omp parallel private(i)
@@ -314,14 +315,16 @@ int main(int argc, char **argv) {
#pragma omp distribute parallel for firstprivate(j)
for (i = 0; i < argc; ++i)
foo();
+// expected-error@+3 {{lastprivate variable cannot be firstprivate}} expected-note@+3 {{defined as lastprivate}}
#pragma omp target
#pragma omp teams
-#pragma omp distribute parallel for lastprivate(g) firstprivate(g) // expected-error {{calling a private constructor of class 'S5'}}
+#pragma omp distribute parallel for lastprivate(g) firstprivate(g)
for (i = 0; i < argc; ++i)
foo();
+// expected-error@+3 {{lastprivate variable cannot be firstprivate}} expected-note@+3 {{defined as lastprivate}}
#pragma omp target
#pragma omp teams
-#pragma omp distribute parallel for lastprivate(n) firstprivate(n) // OK
+#pragma omp distribute parallel for lastprivate(n) firstprivate(n) // expected-error {{calling a private constructor of class 'S6'}}
for (i = 0; i < argc; ++i)
foo();
#pragma omp parallel
diff --git a/test/OpenMP/distribute_parallel_for_lastprivate_codegen.cpp b/test/OpenMP/distribute_parallel_for_lastprivate_codegen.cpp
index 2e8da79c03bd..fccb0cfdb3d8 100644
--- a/test/OpenMP/distribute_parallel_for_lastprivate_codegen.cpp
+++ b/test/OpenMP/distribute_parallel_for_lastprivate_codegen.cpp
@@ -74,6 +74,7 @@ int main() {
// LAMBDA: {{.+}} = alloca i{{[0-9]+}},
// LAMBDA: {{.+}} = alloca i{{[0-9]+}},
// LAMBDA: {{.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: {{.+}} = alloca i{{[0-9]+}},
// LAMBDA: [[OMP_IS_LAST:%.+]] = alloca i{{[0-9]+}},
// LAMBDA: [[G_PRIVATE:%.+]] = alloca double,
// LAMBDA: [[G1_PRIVATE:%.+]] = alloca double,
@@ -141,6 +142,7 @@ int main() {
// LAMBDA: {{.+}} = alloca i{{[0-9]+}},
// LAMBDA: {{.+}} = alloca i{{[0-9]+}},
// LAMBDA: {{.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: {{.+}} = alloca i{{[0-9]+}},
// private alloca's
// LAMBDA: [[OMP_IS_LAST:%.+]] = alloca i{{[0-9]+}},
@@ -162,7 +164,7 @@ int main() {
// LAMBDA: [[SFVAR_IN_REF:%.+]] = load float*, float** [[SFVAR_PRIVATE_ADDR]],
// LAMBDA: [[G1_IN_REF:%.+]] = load double*, double** [[G1_PRIVATE_ADDR]],
- // LAMBDA: store double* [[G1_PRIVATE]], double** [[TMP_G1]],
+ // LAMBDA: store double* [[G1_PRIVATE]], double** [[TMP_G1_PRIVATE]],
// LAMBDA: call {{.*}}void @__kmpc_for_static_init_4(
@@ -273,6 +275,7 @@ int main() {
// CHECK: {{.+}} = alloca i{{[0-9]+}},
// CHECK: {{.+}} = alloca i{{[0-9]+}},
// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
// CHECK: [[OMP_IS_LAST:%.+]] = alloca i{{[0-9]+}},
// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
@@ -371,6 +374,7 @@ int main() {
// CHECK: {{.+}} = alloca i{{[0-9]+}},
// CHECK: {{.+}} = alloca i{{[0-9]+}},
// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
// CHECK: [[OMP_IS_LAST:%.+]] = alloca i{{[0-9]+}},
// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
@@ -486,6 +490,7 @@ int main() {
// CHECK: {{.+}} = alloca i{{[0-9]+}},
// CHECK: {{.+}} = alloca i{{[0-9]+}},
// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
// CHECK: [[OMP_IS_LAST:%.+]] = alloca i{{[0-9]+}},
// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
@@ -566,6 +571,7 @@ int main() {
// CHECK: {{.+}} = alloca i{{[0-9]+}},
// CHECK: {{.+}} = alloca i{{[0-9]+}},
// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
// CHECK: [[OMP_IS_LAST:%.+]] = alloca i{{[0-9]+}},
// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
diff --git a/test/OpenMP/distribute_parallel_for_lastprivate_messages.cpp b/test/OpenMP/distribute_parallel_for_lastprivate_messages.cpp
index 745007fc48a8..b38d978cca03 100644
--- a/test/OpenMP/distribute_parallel_for_lastprivate_messages.cpp
+++ b/test/OpenMP/distribute_parallel_for_lastprivate_messages.cpp
@@ -18,14 +18,14 @@ public:
const S2 &operator =(const S2&) const;
S2 &operator =(const S2&);
static float S2s; // expected-note {{static data member is predetermined as shared}}
- static const float S2sc;
+ static const float S2sc; // expected-note {{static data member is predetermined as shared}}
};
-const float S2::S2sc = 0; // expected-note {{static data member is predetermined as shared}}
+const float S2::S2sc = 0;
const S2 b;
const S2 ba[5];
class S3 {
int a;
- S3 &operator=(const S3 &s3); // expected-note 2 {{implicitly declared private here}}
+ S3 &operator=(const S3 &s3); // expected-note {{implicitly declared private here}}
public:
S3() : a(0) {}
@@ -52,7 +52,7 @@ public:
};
class S6 {
int a;
- S6() : a(0) {}
+ S6() : a(0) {} // expected-note {{implicitly declared private here}}
public:
S6(const S6 &s6) : a(s6.a) {}
@@ -313,14 +313,16 @@ int main(int argc, char **argv) {
#pragma omp distribute parallel for lastprivate(j)
for (i = 0; i < argc; ++i)
foo();
+// expected-error@+3 {{firstprivate variable cannot be lastprivate}} expected-note@+3 {{defined as firstprivate}}
#pragma omp target
#pragma omp teams
-#pragma omp distribute parallel for firstprivate(m) lastprivate(m) // expected-error {{'operator=' is a private member of 'S3'}}
+#pragma omp distribute parallel for firstprivate(m) lastprivate(m)
for (i = 0; i < argc; ++i)
foo();
+// expected-error@+3 {{lastprivate variable cannot be firstprivate}} expected-note@+3 {{defined as lastprivate}}
#pragma omp target
#pragma omp teams
-#pragma omp distribute parallel for lastprivate(n) firstprivate(n) // OK
+#pragma omp distribute parallel for lastprivate(n) firstprivate(n) // expected-error {{calling a private constructor of class 'S6'}}
for (i = 0; i < argc; ++i)
foo();
static int si;
diff --git a/test/OpenMP/distribute_parallel_for_messages.cpp b/test/OpenMP/distribute_parallel_for_messages.cpp
index 35a61df39e40..b1bb8d088e90 100644
--- a/test/OpenMP/distribute_parallel_for_messages.cpp
+++ b/test/OpenMP/distribute_parallel_for_messages.cpp
@@ -38,7 +38,7 @@ int main(int argc, char **argv) {
foo();
#pragma omp target
#pragma omp teams
-#pragma omp distribute parallel for
+#pragma omp distribute parallel for linear(argc) // expected-error {{unexpected OpenMP clause 'linear' in directive '#pragma omp distribute parallel for'}}
for (int i = 0; i < argc; ++i)
foo();
#pragma omp target
@@ -116,3 +116,14 @@ void test_ordered() {
;
}
+void test_cancel() {
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+ for (int i = 0; i < 16; ++i)
+ for (int j = 0; j < 16; ++j) {
+#pragma omp cancel for
+ ;
+ }
+}
+
diff --git a/test/OpenMP/distribute_parallel_for_reduction_messages.cpp b/test/OpenMP/distribute_parallel_for_reduction_messages.cpp
index 95654a9e5018..0bf1bc0472eb 100644
--- a/test/OpenMP/distribute_parallel_for_reduction_messages.cpp
+++ b/test/OpenMP/distribute_parallel_for_reduction_messages.cpp
@@ -27,9 +27,9 @@ public:
S2() : a(0) {}
S2(S2 &s2) : a(s2.a) {}
static float S2s; // expected-note 2 {{static data member is predetermined as shared}}
- static const float S2sc;
+ static const float S2sc; // expected-note 2 {{'S2sc' declared here}}
};
-const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}}
+const float S2::S2sc = 0;
S2 b; // expected-note 3 {{'b' defined here}}
const S2 ba[5]; // expected-note 2 {{'ba' defined here}}
class S3 {
diff --git a/test/OpenMP/distribute_parallel_for_simd_ast_print.cpp b/test/OpenMP/distribute_parallel_for_simd_ast_print.cpp
index 6ed3f2192258..21010638be15 100644
--- a/test/OpenMP/distribute_parallel_for_simd_ast_print.cpp
+++ b/test/OpenMP/distribute_parallel_for_simd_ast_print.cpp
@@ -28,17 +28,18 @@ public:
++this->a.a;
}
S7 &operator=(S7 &s) {
+ int k;
#pragma omp target
#pragma omp teams
-#pragma omp distribute parallel for simd private(a) private(this->a)
- for (int k = 0; k < s.a.a; ++k)
+#pragma omp distribute parallel for simd private(a) private(this->a) linear(k)
+ for (k = 0; k < s.a.a; ++k)
++s.a.a;
return *this;
}
};
// CHECK: #pragma omp distribute parallel for simd private(this->a) private(this->a) private(T::a)
-// CHECK: #pragma omp distribute parallel for simd private(this->a) private(this->a)
+// CHECK: #pragma omp distribute parallel for simd private(this->a) private(this->a) linear(k)
// CHECK: #pragma omp distribute parallel for simd private(this->a) private(this->a) private(this->S::a)
class S8 : public S7<S> {
@@ -82,7 +83,7 @@ T tmain(T argc) {
// CHECK-NEXT: a = 2;
#pragma omp target
#pragma omp teams
-#pragma omp distribute parallel for simd private(argc, b), firstprivate(c, d), lastprivate(d, f) collapse(N) schedule(static, N) if (parallel :argc) num_threads(N) default(shared) shared(e) reduction(+ : h) dist_schedule(static,N)
+#pragma omp distribute parallel for simd private(argc, b), firstprivate(c, d), lastprivate(f) collapse(N) schedule(static, N) if (parallel :argc) num_threads(N) default(shared) shared(e) reduction(+ : h) dist_schedule(static,N)
for (int i = 0; i < 2; ++i)
for (int j = 0; j < 2; ++j)
for (int j = 0; j < 2; ++j)
@@ -93,8 +94,8 @@ T tmain(T argc) {
for (int j = 0; j < 2; ++j)
for (int j = 0; j < 2; ++j)
for (int j = 0; j < 2; ++j)
- a++;
- // CHECK: #pragma omp distribute parallel for simd private(argc,b) firstprivate(c,d) lastprivate(d,f) collapse(N) schedule(static, N) if(parallel: argc) num_threads(N) default(shared) shared(e) reduction(+: h) dist_schedule(static, N)
+ a++;
+ // CHECK: #pragma omp distribute parallel for simd private(argc,b) firstprivate(c,d) lastprivate(f) collapse(N) schedule(static, N) if(parallel: argc) num_threads(N) default(shared) shared(e) reduction(+: h) dist_schedule(static, N)
// CHECK-NEXT: for (int i = 0; i < 2; ++i)
// CHECK-NEXT: for (int j = 0; j < 2; ++j)
// CHECK-NEXT: for (int j = 0; j < 2; ++j)
@@ -135,14 +136,15 @@ int main(int argc, char **argv) {
// CHECK-NEXT: for (int j = 0; j < 10; ++j)
// CHECK-NEXT: a++;
+ int i;
#pragma omp target
#pragma omp teams
-#pragma omp distribute parallel for simd aligned(x:8) linear(h:2) safelen(8) simdlen(8)
- for (int i = 0; i < 100; i++)
+#pragma omp distribute parallel for simd aligned(x:8) linear(i:2) safelen(8) simdlen(8)
+ for (i = 0; i < 100; i++)
for (int j = 0; j < 200; j++)
a += h + x[j];
- // CHECK: #pragma omp distribute parallel for simd aligned(x: 8) linear(h: 2) safelen(8) simdlen(8)
- // CHECK-NEXT: for (int i = 0; i < 100; i++)
+ // CHECK: #pragma omp distribute parallel for simd aligned(x: 8) linear(i: 2) safelen(8) simdlen(8)
+ // CHECK-NEXT: for (i = 0; i < 100; i++)
// CHECK-NEXT: for (int j = 0; j < 200; j++)
// CHECK-NEXT: a += h + x[j];
diff --git a/test/OpenMP/distribute_parallel_for_simd_codegen.cpp b/test/OpenMP/distribute_parallel_for_simd_codegen.cpp
new file mode 100644
index 000000000000..59e6df90bbcb
--- /dev/null
+++ b/test/OpenMP/distribute_parallel_for_simd_codegen.cpp
@@ -0,0 +1,2262 @@
+// Test host code gen
+// RUN: %clang_cc1 -DLAMBDA -verify -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+// RUN: %clang_cc1 -DLAMBDA -verify -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-32
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-32
+
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+
+template <typename T>
+T tmain() {
+ T *a, *b, *c;
+ int n = 10000;
+ int ch = 100;
+
+ // no schedule clauses
+ #pragma omp target
+ #pragma omp teams
+ #pragma omp distribute parallel for simd
+ for (int i = 0; i < n; ++i) {
+ a[i] = b[i] + c[i];
+ }
+
+ // dist_schedule: static no chunk
+ #pragma omp target
+ #pragma omp teams
+ #pragma omp distribute parallel for simd dist_schedule(static)
+ for (int i = 0; i < n; ++i) {
+ a[i] = b[i] + c[i];
+ }
+
+ // dist_schedule: static chunk
+ #pragma omp target
+ #pragma omp teams
+ #pragma omp distribute parallel for simd dist_schedule(static, ch)
+ for (int i = 0; i < n; ++i) {
+ a[i] = b[i] + c[i];
+ }
+
+ // schedule: static no chunk
+ #pragma omp target
+ #pragma omp teams
+ #pragma omp distribute parallel for simd schedule(static)
+ for (int i = 0; i < n; ++i) {
+ a[i] = b[i] + c[i];
+ }
+
+ // schedule: static chunk
+ #pragma omp target
+ #pragma omp teams
+ #pragma omp distribute parallel for simd schedule(static, ch)
+ for (int i = 0; i < n; ++i) {
+ a[i] = b[i] + c[i];
+ }
+
+ // schedule: dynamic no chunk
+ #pragma omp target
+ #pragma omp teams
+ #pragma omp distribute parallel for simd schedule(dynamic)
+ for (int i = 0; i < n; ++i) {
+ a[i] = b[i] + c[i];
+ }
+
+ // schedule: dynamic chunk
+ #pragma omp target
+ #pragma omp teams
+ #pragma omp distribute parallel for simd schedule(dynamic, ch)
+ for (int i = 0; i < n; ++i) {
+ a[i] = b[i] + c[i];
+ }
+
+ return T();
+}
+
+int main() {
+ double *a, *b, *c;
+ int n = 10000;
+ int ch = 100;
+
+#ifdef LAMBDA
+ // LAMBDA-LABEL: @main
+ // LAMBDA: call{{.*}} void [[OUTER_LAMBDA:@.+]](
+ [&]() {
+ // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
+
+ // LAMBDA: call i{{[0-9]+}} @__tgt_target_teams(
+ // LAMBDA: call void [[OFFLOADING_FUN_1:@.+]](
+
+ // LAMBDA: call i{{[0-9]+}} @__tgt_target_teams(
+ // LAMBDA: call void [[OFFLOADING_FUN_2:@.+]](
+
+ // LAMBDA: call i{{[0-9]+}} @__tgt_target_teams(
+ // LAMBDA: call void [[OFFLOADING_FUN_3:@.+]](
+
+ // LAMBDA: call i{{[0-9]+}} @__tgt_target_teams(
+ // LAMBDA: call void [[OFFLOADING_FUN_4:@.+]](
+
+ // LAMBDA: call i{{[0-9]+}} @__tgt_target_teams(
+ // LAMBDA: call void [[OFFLOADING_FUN_5:@.+]](
+
+ // LAMBDA: call i{{[0-9]+}} @__tgt_target_teams(
+ // LAMBDA: call void [[OFFLOADING_FUN_6:@.+]](
+
+ // LAMBDA: call i{{[0-9]+}} @__tgt_target_teams(
+ // LAMBDA: call void [[OFFLOADING_FUN_7:@.+]](
+
+ // no schedule clauses
+ #pragma omp target
+ #pragma omp teams
+ // LAMBDA: define{{.+}} void [[OFFLOADING_FUN_1]](
+ // LAMBDA: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, i32 4, {{.+}}* [[OMP_OUTLINED_1:@.+]] to {{.+}})
+
+ #pragma omp distribute parallel for simd
+ for (int i = 0; i < n; ++i) {
+ a[i] = b[i] + c[i];
+ // LAMBDA: define{{.+}} void [[OMP_OUTLINED_1]](
+ // LAMBDA-DAG: [[OMP_IV:%.omp.iv]] = alloca
+ // LAMBDA-DAG: [[OMP_LB:%.omp.comb.lb]] = alloca
+ // LAMBDA-DAG: [[OMP_UB:%.omp.comb.ub]] = alloca
+ // LAMBDA-DAG: [[OMP_ST:%.omp.stride]] = alloca
+
+ // LAMBDA: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 92,
+
+ // check EUB for distribute
+ // LAMBDA-DAG: [[OMP_UB_VAL_1:%.+]] = load{{.+}} [[OMP_UB]],
+ // LAMBDA: [[NUM_IT_1:%.+]] = load{{.+}},
+ // LAMBDA-DAG: [[CMP_UB_NUM_IT:%.+]] = icmp sgt {{.+}} [[OMP_UB_VAL_1]], [[NUM_IT_1]]
+ // LAMBDA: br {{.+}} [[CMP_UB_NUM_IT]], label %[[EUB_TRUE:.+]], label %[[EUB_FALSE:.+]]
+ // LAMBDA-DAG: [[EUB_TRUE]]:
+ // LAMBDA: [[NUM_IT_2:%.+]] = load{{.+}},
+ // LAMBDA: br label %[[EUB_END:.+]]
+ // LAMBDA-DAG: [[EUB_FALSE]]:
+ // LAMBDA: [[OMP_UB_VAL2:%.+]] = load{{.+}} [[OMP_UB]],
+ // LAMBDA: br label %[[EUB_END]]
+ // LAMBDA-DAG: [[EUB_END]]:
+ // LAMBDA-DAG: [[EUB_RES:%.+]] = phi{{.+}} [ [[NUM_IT_2]], %[[EUB_TRUE]] ], [ [[OMP_UB_VAL2]], %[[EUB_FALSE]] ]
+ // LAMBDA: store{{.+}} [[EUB_RES]], {{.+}}* [[OMP_UB]],
+
+ // initialize omp.iv
+ // LAMBDA: [[OMP_LB_VAL_1:%.+]] = load{{.+}}, {{.+}}* [[OMP_LB]],
+ // LAMBDA: store {{.+}} [[OMP_LB_VAL_1]], {{.+}}* [[OMP_IV]],
+ // LAMBDA: br label %[[OMP_JUMP_BACK:.+]]
+
+ // check exit condition
+ // LAMBDA: [[OMP_JUMP_BACK]]:
+ // LAMBDA-DAG: [[OMP_IV_VAL_1:%.+]] = load {{.+}} [[OMP_IV]],
+ // LAMBDA-DAG: [[OMP_UB_VAL_3:%.+]] = load {{.+}} [[OMP_UB]],
+ // LAMBDA: [[CMP_IV_UB:%.+]] = icmp sle {{.+}} [[OMP_IV_VAL_1]], [[OMP_UB_VAL_3]]
+ // LAMBDA: br {{.+}} [[CMP_IV_UB]], label %[[DIST_BODY:.+]], label %[[DIST_END:.+]]
+
+ // check that PrevLB and PrevUB are passed to the 'for'
+ // LAMBDA: [[DIST_BODY]]:
+ // LAMBDA-DAG: [[OMP_PREV_LB:%.+]] = load {{.+}}, {{.+}} [[OMP_LB]],
+ // LAMBDA-64-DAG: [[OMP_PREV_LB_EXT:%.+]] = zext {{.+}} [[OMP_PREV_LB]] to
+ // LAMBDA-DAG: [[OMP_PREV_UB:%.+]] = load {{.+}}, {{.+}} [[OMP_UB]],
+ // LAMBDA-64-DAG: [[OMP_PREV_UB_EXT:%.+]] = zext {{.+}} [[OMP_PREV_UB]] to
+ // check that distlb and distub are properly passed to fork_call
+ // LAMBDA-32: call{{.+}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}}[[OMP_PARFOR_OUTLINED_1:@.+]] to {{.+}}, i{{[0-9]+}} [[OMP_PREV_LB]], i{{[0-9]+}} [[OMP_PREV_UB]], {{.+}})
+ // LAMBDA-64: call{{.+}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}}[[OMP_PARFOR_OUTLINED_1:@.+]] to {{.+}}, i{{[0-9]+}} [[OMP_PREV_LB_EXT]], i{{[0-9]+}} [[OMP_PREV_UB_EXT]], {{.+}})
+ // LAMBDA: br label %[[DIST_INC:.+]]
+
+ // increment by stride (distInc - 'parallel for' executes the whole chunk) and latch
+ // LAMBDA: [[DIST_INC]]:
+ // LAMBDA-DAG: [[OMP_IV_VAL_2:%.+]] = load {{.+}}, {{.+}}* [[OMP_IV]],
+ // LAMBDA-DAG: [[OMP_ST_VAL_1:%.+]] = load {{.+}}, {{.+}}* [[OMP_ST]],
+ // LAMBDA: [[OMP_IV_INC:%.+]] = add{{.+}} [[OMP_IV_VAL_2]], [[OMP_ST_VAL_1]]
+ // LAMBDA: store{{.+}} [[OMP_IV_INC]], {{.+}}* [[OMP_IV]],
+ // LAMBDA: br label %[[OMP_JUMP_BACK]]
+
+ // LAMBDA-DAG: call void @__kmpc_for_static_fini(
+ // LAMBDA: ret
+
+ // implementation of 'parallel for'
+ // LAMBDA: define{{.+}} void [[OMP_PARFOR_OUTLINED_1]]({{.+}}, {{.+}}, i{{[0-9]+}} [[OMP_PREV_LB_IN:%.+]], i{{[0-9]+}} [[OMP_PREV_UB_IN:%.+]], {{.+}}, {{.+}}, {{.+}}, {{.+}})
+
+ // LAMBDA-DAG: [[OMP_PF_LB:%.omp.lb]] = alloca{{.+}},
+ // LAMBDA-DAG: [[OMP_PF_UB:%.omp.ub]] = alloca{{.+}},
+ // LAMBDA-DAG: [[OMP_PF_IV:%.omp.iv]] = alloca{{.+}},
+
+ // initialize lb and ub to PrevLB and PrevUB
+ // LAMBDA-DAG: store{{.+}} [[OMP_PREV_LB_IN]], {{.+}}* [[PREV_LB_ADDR:%.+]],
+ // LAMBDA-DAG: store{{.+}} [[OMP_PREV_UB_IN]], {{.+}}* [[PREV_UB_ADDR:%.+]],
+ // LAMBDA-DAG: [[OMP_PREV_LB_VAL:%.+]] = load{{.+}}, {{.+}}* [[PREV_LB_ADDR]],
+ // LAMBDA-64-DAG: [[OMP_PREV_LB_TRC:%.+]] = trunc{{.+}} [[OMP_PREV_LB_VAL]] to {{.+}}
+ // LAMBDA-DAG: [[OMP_PREV_UB_VAL:%.+]] = load{{.+}}, {{.+}}* [[PREV_UB_ADDR]],
+ // LAMBDA-64-DAG: [[OMP_PREV_UB_TRC:%.+]] = trunc{{.+}} [[OMP_PREV_UB_VAL]] to {{.+}}
+ // LAMBDA-64-DAG: store{{.+}} [[OMP_PREV_LB_TRC]], {{.+}}* [[OMP_PF_LB]],
+ // LAMBDA-32-DAG: store{{.+}} [[OMP_PREV_LB_VAL]], {{.+}}* [[OMP_PF_LB]],
+ // LAMBDA-64-DAG: store{{.+}} [[OMP_PREV_UB_TRC]], {{.+}}* [[OMP_PF_UB]],
+ // LAMBDA-32-DAG: store{{.+}} [[OMP_PREV_UB_VAL]], {{.+}}* [[OMP_PF_UB]],
+ // LAMBDA: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, {{.+}} 34, {{.+}}, {{.+}}* [[OMP_PF_LB]], {{.+}}* [[OMP_PF_UB]],{{.+}})
+
+ // PrevEUB is only used when 'for' has a chunked schedule, otherwise EUB is used
+ // In this case we use EUB
+ // LAMBDA-DAG: [[OMP_PF_UB_VAL_1:%.+]] = load{{.+}} [[OMP_PF_UB]],
+ // LAMBDA: [[PF_NUM_IT_1:%.+]] = load{{.+}},
+ // LAMBDA-DAG: [[PF_CMP_UB_NUM_IT:%.+]] = icmp{{.+}} [[OMP_PF_UB_VAL_1]], [[PF_NUM_IT_1]]
+ // LAMBDA: br i1 [[PF_CMP_UB_NUM_IT]], label %[[PF_EUB_TRUE:.+]], label %[[PF_EUB_FALSE:.+]]
+ // LAMBDA: [[PF_EUB_TRUE]]:
+ // LAMBDA: [[PF_NUM_IT_2:%.+]] = load{{.+}},
+ // LAMBDA: br label %[[PF_EUB_END:.+]]
+ // LAMBDA-DAG: [[PF_EUB_FALSE]]:
+ // LAMBDA: [[OMP_PF_UB_VAL2:%.+]] = load{{.+}} [[OMP_PF_UB]],
+ // LAMBDA: br label %[[PF_EUB_END]]
+ // LAMBDA-DAG: [[PF_EUB_END]]:
+ // LAMBDA-DAG: [[PF_EUB_RES:%.+]] = phi{{.+}} [ [[PF_NUM_IT_2]], %[[PF_EUB_TRUE]] ], [ [[OMP_PF_UB_VAL2]], %[[PF_EUB_FALSE]] ]
+ // LAMBDA: store{{.+}} [[PF_EUB_RES]],{{.+}} [[OMP_PF_UB]],
+
+ // initialize omp.iv
+ // LAMBDA: [[OMP_PF_LB_VAL_1:%.+]] = load{{.+}}, {{.+}} [[OMP_PF_LB]],
+ // LAMBDA: store {{.+}} [[OMP_PF_LB_VAL_1]], {{.+}}* [[OMP_PF_IV]],
+ // LAMBDA: br label %[[OMP_PF_JUMP_BACK:.+]]
+
+ // check exit condition
+ // LAMBDA: [[OMP_PF_JUMP_BACK]]:
+ // LAMBDA-DAG: [[OMP_PF_IV_VAL_1:%.+]] = load {{.+}} [[OMP_PF_IV]],
+ // LAMBDA-DAG: [[OMP_PF_UB_VAL_3:%.+]] = load {{.+}} [[OMP_PF_UB]],
+ // LAMBDA: [[PF_CMP_IV_UB:%.+]] = icmp sle {{.+}} [[OMP_PF_IV_VAL_1]], [[OMP_PF_UB_VAL_3]]
+ // LAMBDA: br {{.+}} [[PF_CMP_IV_UB]], label %[[PF_BODY:.+]], label %[[PF_END:.+]]
+
+ // check that PrevLB and PrevUB are passed to the 'for'
+ // LAMBDA: [[PF_BODY]]:
+ // LAMBDA-DAG: {{.+}} = load{{.+}}, {{.+}}* [[OMP_PF_IV]],
+ // LAMBDA: br label {{.+}}
+
+ // check stride 1 for 'for' in 'distribute parallel for simd'
+ // LAMBDA-DAG: [[OMP_PF_IV_VAL_2:%.+]] = load {{.+}}, {{.+}}* [[OMP_PF_IV]],
+ // LAMBDA: [[OMP_PF_IV_INC:%.+]] = add{{.+}} [[OMP_PF_IV_VAL_2]], 1
+ // LAMBDA: store{{.+}} [[OMP_PF_IV_INC]], {{.+}}* [[OMP_PF_IV]],
+ // LAMBDA: br label %[[OMP_PF_JUMP_BACK]]
+
+ // LAMBDA-DAG: call void @__kmpc_for_static_fini(
+ // LAMBDA: ret
+
+ [&]() {
+ a[i] = b[i] + c[i];
+ }();
+ }
+
+ // dist_schedule: static no chunk (same sa default - no dist_schedule)
+ #pragma omp target
+ #pragma omp teams
+ // LAMBDA: define{{.+}} void [[OFFLOADING_FUN_2]](
+ // LAMBDA: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, i32 4, {{.+}}* [[OMP_OUTLINED_2:@.+]] to {{.+}})
+
+ #pragma omp distribute parallel for simd dist_schedule(static)
+ for (int i = 0; i < n; ++i) {
+ a[i] = b[i] + c[i];
+ // LAMBDA: define{{.+}} void [[OMP_OUTLINED_2]](
+ // LAMBDA-DAG: [[OMP_IV:%.omp.iv]] = alloca
+ // LAMBDA-DAG: [[OMP_LB:%.omp.comb.lb]] = alloca
+ // LAMBDA-DAG: [[OMP_UB:%.omp.comb.ub]] = alloca
+ // LAMBDA-DAG: [[OMP_ST:%.omp.stride]] = alloca
+
+ // LAMBDA: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 92,
+
+ // check EUB for distribute
+ // LAMBDA-DAG: [[OMP_UB_VAL_1:%.+]] = load{{.+}} [[OMP_UB]],
+ // LAMBDA: [[NUM_IT_1:%.+]] = load{{.+}},
+ // LAMBDA-DAG: [[CMP_UB_NUM_IT:%.+]] = icmp sgt {{.+}} [[OMP_UB_VAL_1]], [[NUM_IT_1]]
+ // LAMBDA: br {{.+}} [[CMP_UB_NUM_IT]], label %[[EUB_TRUE:.+]], label %[[EUB_FALSE:.+]]
+ // LAMBDA-DAG: [[EUB_TRUE]]:
+ // LAMBDA: [[NUM_IT_2:%.+]] = load{{.+}},
+ // LAMBDA: br label %[[EUB_END:.+]]
+ // LAMBDA-DAG: [[EUB_FALSE]]:
+ // LAMBDA: [[OMP_UB_VAL2:%.+]] = load{{.+}} [[OMP_UB]],
+ // LAMBDA: br label %[[EUB_END]]
+ // LAMBDA-DAG: [[EUB_END]]:
+ // LAMBDA-DAG: [[EUB_RES:%.+]] = phi{{.+}} [ [[NUM_IT_2]], %[[EUB_TRUE]] ], [ [[OMP_UB_VAL2]], %[[EUB_FALSE]] ]
+ // LAMBDA: store{{.+}} [[EUB_RES]], {{.+}}* [[OMP_UB]],
+
+ // initialize omp.iv
+ // LAMBDA: [[OMP_LB_VAL_1:%.+]] = load{{.+}}, {{.+}}* [[OMP_LB]],
+ // LAMBDA: store {{.+}} [[OMP_LB_VAL_1]], {{.+}}* [[OMP_IV]],
+ // LAMBDA: br label %[[OMP_JUMP_BACK:.+]]
+
+ // check exit condition
+ // LAMBDA: [[OMP_JUMP_BACK]]:
+ // LAMBDA-DAG: [[OMP_IV_VAL_1:%.+]] = load {{.+}} [[OMP_IV]],
+ // LAMBDA-DAG: [[OMP_UB_VAL_3:%.+]] = load {{.+}} [[OMP_UB]],
+ // LAMBDA: [[CMP_IV_UB:%.+]] = icmp sle {{.+}} [[OMP_IV_VAL_1]], [[OMP_UB_VAL_3]]
+ // LAMBDA: br {{.+}} [[CMP_IV_UB]], label %[[DIST_BODY:.+]], label %[[DIST_END:.+]]
+
+ // check that PrevLB and PrevUB are passed to the 'for'
+ // LAMBDA: [[DIST_BODY]]:
+ // LAMBDA-DAG: [[OMP_PREV_LB:%.+]] = load {{.+}}, {{.+}} [[OMP_LB]],
+ // LAMBDA-64-DAG: [[OMP_PREV_LB_EXT:%.+]] = zext {{.+}} [[OMP_PREV_LB]] to
+ // LAMBDA-DAG: [[OMP_PREV_UB:%.+]] = load {{.+}}, {{.+}} [[OMP_UB]],
+ // LAMBDA-64-DAG: [[OMP_PREV_UB_EXT:%.+]] = zext {{.+}} [[OMP_PREV_UB]] to
+ // check that distlb and distub are properly passed to fork_call
+ // LAMBDA-64: call{{.+}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}}[[OMP_PARFOR_OUTLINED_2:@.+]] to {{.+}}, i{{[0-9]+}} [[OMP_PREV_LB_EXT]], i{{[0-9]+}} [[OMP_PREV_UB_EXT]], {{.+}})
+ // LAMBDA-32: call{{.+}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}}[[OMP_PARFOR_OUTLINED_2:@.+]] to {{.+}}, i{{[0-9]+}} [[OMP_PREV_LB]], i{{[0-9]+}} [[OMP_PREV_UB]], {{.+}})
+ // LAMBDA: br label %[[DIST_INC:.+]]
+
+ // increment by stride (distInc - 'parallel for' executes the whole chunk) and latch
+ // LAMBDA: [[DIST_INC]]:
+ // LAMBDA-DAG: [[OMP_IV_VAL_2:%.+]] = load {{.+}}, {{.+}}* [[OMP_IV]],
+ // LAMBDA-DAG: [[OMP_ST_VAL_1:%.+]] = load {{.+}}, {{.+}}* [[OMP_ST]],
+ // LAMBDA: [[OMP_IV_INC:%.+]] = add{{.+}} [[OMP_IV_VAL_2]], [[OMP_ST_VAL_1]]
+ // LAMBDA: store{{.+}} [[OMP_IV_INC]], {{.+}}* [[OMP_IV]],
+ // LAMBDA: br label %[[OMP_JUMP_BACK]]
+
+ // LAMBDA-DAG: call void @__kmpc_for_static_fini(
+ // LAMBDA: ret
+
+ // implementation of 'parallel for'
+ // LAMBDA: define{{.+}} void [[OMP_PARFOR_OUTLINED_2]]({{.+}}, {{.+}}, i{{[0-9]+}} [[OMP_PREV_LB_IN:%.+]], i{{[0-9]+}} [[OMP_PREV_UB_IN:%.+]], {{.+}}, {{.+}}, {{.+}}, {{.+}})
+
+ // LAMBDA-DAG: [[OMP_PF_LB:%.omp.lb]] = alloca{{.+}},
+ // LAMBDA-DAG: [[OMP_PF_UB:%.omp.ub]] = alloca{{.+}},
+ // LAMBDA-DAG: [[OMP_PF_IV:%.omp.iv]] = alloca{{.+}},
+
+ // initialize lb and ub to PrevLB and PrevUB
+ // LAMBDA-DAG: store{{.+}} [[OMP_PREV_LB_IN]], {{.+}}* [[PREV_LB_ADDR:%.+]],
+ // LAMBDA-DAG: store{{.+}} [[OMP_PREV_UB_IN]], {{.+}}* [[PREV_UB_ADDR:%.+]],
+ // LAMBDA-DAG: [[OMP_PREV_LB_VAL:%.+]] = load{{.+}}, {{.+}}* [[PREV_LB_ADDR]],
+ // LAMBDA-64-DAG: [[OMP_PREV_LB_TRC:%.+]] = trunc{{.+}} [[OMP_PREV_LB_VAL]] to {{.+}}
+ // LAMBDA-DAG: [[OMP_PREV_UB_VAL:%.+]] = load{{.+}}, {{.+}}* [[PREV_UB_ADDR]],
+ // LAMBDA-64-DAG: [[OMP_PREV_UB_TRC:%.+]] = trunc{{.+}} [[OMP_PREV_UB_VAL]] to {{.+}}
+ // LAMBDA-64-DAG: store{{.+}} [[OMP_PREV_LB_TRC]], {{.+}}* [[OMP_PF_LB]],
+ // LAMBDA-32-DAG: store{{.+}} [[OMP_PREV_LB_VAL]], {{.+}}* [[OMP_PF_LB]],
+ // LAMBDA-64-DAG: store{{.+}} [[OMP_PREV_UB_TRC]], {{.+}}* [[OMP_PF_UB]],
+ // LAMBDA-32-DAG: store{{.+}} [[OMP_PREV_UB_VAL]], {{.+}}* [[OMP_PF_UB]],
+ // LAMBDA: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, {{.+}} 34, {{.+}}, {{.+}}* [[OMP_PF_LB]], {{.+}}* [[OMP_PF_UB]],{{.+}})
+
+ // PrevEUB is only used when 'for' has a chunked schedule, otherwise EUB is used
+ // In this case we use EUB
+ // LAMBDA-DAG: [[OMP_PF_UB_VAL_1:%.+]] = load{{.+}} [[OMP_PF_UB]],
+ // LAMBDA: [[PF_NUM_IT_1:%.+]] = load{{.+}},
+ // LAMBDA-DAG: [[PF_CMP_UB_NUM_IT:%.+]] = icmp{{.+}} [[OMP_PF_UB_VAL_1]], [[PF_NUM_IT_1]]
+ // LAMBDA: br i1 [[PF_CMP_UB_NUM_IT]], label %[[PF_EUB_TRUE:.+]], label %[[PF_EUB_FALSE:.+]]
+ // LAMBDA: [[PF_EUB_TRUE]]:
+ // LAMBDA: [[PF_NUM_IT_2:%.+]] = load{{.+}},
+ // LAMBDA: br label %[[PF_EUB_END:.+]]
+ // LAMBDA-DAG: [[PF_EUB_FALSE]]:
+ // LAMBDA: [[OMP_PF_UB_VAL2:%.+]] = load{{.+}} [[OMP_PF_UB]],
+ // LAMBDA: br label %[[PF_EUB_END]]
+ // LAMBDA-DAG: [[PF_EUB_END]]:
+ // LAMBDA-DAG: [[PF_EUB_RES:%.+]] = phi{{.+}} [ [[PF_NUM_IT_2]], %[[PF_EUB_TRUE]] ], [ [[OMP_PF_UB_VAL2]], %[[PF_EUB_FALSE]] ]
+ // LAMBDA: store{{.+}} [[PF_EUB_RES]],{{.+}} [[OMP_PF_UB]],
+
+ // initialize omp.iv
+ // LAMBDA: [[OMP_PF_LB_VAL_1:%.+]] = load{{.+}}, {{.+}} [[OMP_PF_LB]],
+ // LAMBDA: store {{.+}} [[OMP_PF_LB_VAL_1]], {{.+}}* [[OMP_PF_IV]],
+ // LAMBDA: br label %[[OMP_PF_JUMP_BACK:.+]]
+
+ // check exit condition
+ // LAMBDA: [[OMP_PF_JUMP_BACK]]:
+ // LAMBDA-DAG: [[OMP_PF_IV_VAL_1:%.+]] = load {{.+}} [[OMP_PF_IV]],
+ // LAMBDA-DAG: [[OMP_PF_UB_VAL_3:%.+]] = load {{.+}} [[OMP_PF_UB]],
+ // LAMBDA: [[PF_CMP_IV_UB:%.+]] = icmp sle {{.+}} [[OMP_PF_IV_VAL_1]], [[OMP_PF_UB_VAL_3]]
+ // LAMBDA: br {{.+}} [[PF_CMP_IV_UB]], label %[[PF_BODY:.+]], label %[[PF_END:.+]]
+
+ // check that PrevLB and PrevUB are passed to the 'for'
+ // LAMBDA: [[PF_BODY]]:
+ // LAMBDA-DAG: {{.+}} = load{{.+}}, {{.+}}* [[OMP_PF_IV]],
+ // LAMBDA: br label {{.+}}
+
+ // check stride 1 for 'for' in 'distribute parallel for simd'
+ // LAMBDA-DAG: [[OMP_PF_IV_VAL_2:%.+]] = load {{.+}}, {{.+}}* [[OMP_PF_IV]],
+ // LAMBDA: [[OMP_PF_IV_INC:%.+]] = add{{.+}} [[OMP_PF_IV_VAL_2]], 1
+ // LAMBDA: store{{.+}} [[OMP_PF_IV_INC]], {{.+}}* [[OMP_PF_IV]],
+ // LAMBDA: br label %[[OMP_PF_JUMP_BACK]]
+
+ // LAMBDA-DAG: call void @__kmpc_for_static_fini(
+ // LAMBDA: ret
+ [&]() {
+ a[i] = b[i] + c[i];
+ }();
+ }
+
+ // dist_schedule: static chunk
+ #pragma omp target
+ #pragma omp teams
+ // LAMBDA: define{{.+}} void [[OFFLOADING_FUN_3]](
+ // LAMBDA: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, i32 5, {{.+}}* [[OMP_OUTLINED_3:@.+]] to {{.+}})
+
+ #pragma omp distribute parallel for simd dist_schedule(static, ch)
+ for (int i = 0; i < n; ++i) {
+ a[i] = b[i] + c[i];
+ // LAMBDA: define{{.+}} void [[OMP_OUTLINED_3]](
+ // LAMBDA-DAG: [[OMP_IV:%.omp.iv]] = alloca
+ // LAMBDA-DAG: [[OMP_LB:%.omp.comb.lb]] = alloca
+ // LAMBDA-DAG: [[OMP_UB:%.omp.comb.ub]] = alloca
+ // LAMBDA-DAG: [[OMP_ST:%.omp.stride]] = alloca
+
+ // unlike the previous tests, in this one we have a outer and inner loop for 'distribute'
+ // LAMBDA: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 91,
+ // LAMBDA: br label %[[DIST_OUTER_LOOP_HEADER:.+]]
+
+ // LAMBDA: [[DIST_OUTER_LOOP_HEADER]]:
+ // check EUB for distribute
+ // LAMBDA-DAG: [[OMP_UB_VAL_1:%.+]] = load{{.+}} [[OMP_UB]],
+ // LAMBDA: [[NUM_IT_1:%.+]] = load{{.+}},
+ // LAMBDA-DAG: [[CMP_UB_NUM_IT:%.+]] = icmp sgt {{.+}} [[OMP_UB_VAL_1]], [[NUM_IT_1]]
+ // LAMBDA: br {{.+}} [[CMP_UB_NUM_IT]], label %[[EUB_TRUE:.+]], label %[[EUB_FALSE:.+]]
+ // LAMBDA-DAG: [[EUB_TRUE]]:
+ // LAMBDA: [[NUM_IT_2:%.+]] = load{{.+}},
+ // LAMBDA: br label %[[EUB_END:.+]]
+ // LAMBDA-DAG: [[EUB_FALSE]]:
+ // LAMBDA: [[OMP_UB_VAL2:%.+]] = load{{.+}} [[OMP_UB]],
+ // LAMBDA: br label %[[EUB_END]]
+ // LAMBDA-DAG: [[EUB_END]]:
+ // LAMBDA-DAG: [[EUB_RES:%.+]] = phi{{.+}} [ [[NUM_IT_2]], %[[EUB_TRUE]] ], [ [[OMP_UB_VAL2]], %[[EUB_FALSE]] ]
+ // LAMBDA: store{{.+}} [[EUB_RES]], {{.+}}* [[OMP_UB]],
+
+ // initialize omp.iv
+ // LAMBDA: [[OMP_LB_VAL_1:%.+]] = load{{.+}}, {{.+}}* [[OMP_LB]],
+ // LAMBDA: store {{.+}} [[OMP_LB_VAL_1]], {{.+}}* [[OMP_IV]],
+
+ // check exit condition
+ // LAMBDA-DAG: [[OMP_IV_VAL_1:%.+]] = load {{.+}} [[OMP_IV]],
+ // LAMBDA-DAG: [[OMP_UB_VAL_3:%.+]] = load {{.+}} [[OMP_UB]],
+ // LAMBDA: [[CMP_IV_UB:%.+]] = icmp sle {{.+}} [[OMP_IV_VAL_1]], [[OMP_UB_VAL_3]]
+ // LAMBDA: br {{.+}} [[CMP_IV_UB]], label %[[DIST_OUTER_LOOP_BODY:.+]], label %[[DIST_OUTER_LOOP_END:.+]]
+
+ // LAMBDA: [[DIST_OUTER_LOOP_BODY]]:
+ // LAMBDA: br label %[[DIST_INNER_LOOP_HEADER:.+]]
+
+ // LAMBDA: [[DIST_INNER_LOOP_HEADER]]:
+ // LAMBDA-DAG: [[OMP_IV_VAL_2:%.+]] = load {{.+}} [[OMP_IV]],
+ // LAMBDA-DAG: [[OMP_UB_VAL_4:%.+]] = load {{.+}} [[OMP_UB]],
+ // LAMBDA: [[CMP_IV_UB_2:%.+]] = icmp sle {{.+}} [[OMP_IV_VAL_2]], [[OMP_UB_VAL_4]]
+ // LAMBDA: br{{.+}} [[CMP_IV_UB_2]], label %[[DIST_INNER_LOOP_BODY:.+]], label %[[DIST_INNER_LOOP_END:.+]]
+
+ // check that PrevLB and PrevUB are passed to the 'for'
+ // LAMBDA: [[DIST_INNER_LOOP_BODY]]:
+ // LAMBDA-DAG: [[OMP_PREV_LB:%.+]] = load {{.+}}, {{.+}} [[OMP_LB]],
+ // LAMBDA-64-DAG: [[OMP_PREV_LB_EXT:%.+]] = zext {{.+}} [[OMP_PREV_LB]] to {{.+}}
+ // LAMBDA-DAG: [[OMP_PREV_UB:%.+]] = load {{.+}}, {{.+}} [[OMP_UB]],
+ // LAMBDA-64-DAG: [[OMP_PREV_UB_EXT:%.+]] = zext {{.+}} [[OMP_PREV_UB]] to {{.+}}
+ // check that distlb and distub are properly passed to fork_call
+ // LAMBDA-64: call{{.+}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}}[[OMP_PARFOR_OUTLINED_3:@.+]] to {{.+}}, i{{[0-9]+}} [[OMP_PREV_LB_EXT]], i{{[0-9]+}} [[OMP_PREV_UB_EXT]], {{.+}})
+ // LAMBDA-32: call{{.+}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}}[[OMP_PARFOR_OUTLINED_3:@.+]] to {{.+}}, i{{[0-9]+}} [[OMP_PREV_LB]], i{{[0-9]+}} [[OMP_PREV_UB]], {{.+}})
+ // LAMBDA: br label %[[DIST_INNER_LOOP_INC:.+]]
+
+ // check DistInc
+ // LAMBDA: [[DIST_INNER_LOOP_INC]]:
+ // LAMBDA-DAG: [[OMP_IV_VAL_3:%.+]] = load {{.+}}, {{.+}}* [[OMP_IV]],
+ // LAMBDA-DAG: [[OMP_ST_VAL_1:%.+]] = load {{.+}}, {{.+}}* [[OMP_ST]],
+ // LAMBDA: [[OMP_IV_INC:%.+]] = add{{.+}} [[OMP_IV_VAL_3]], [[OMP_ST_VAL_1]]
+ // LAMBDA: store{{.+}} [[OMP_IV_INC]], {{.+}}* [[OMP_IV]],
+ // LAMBDA: br label %[[DIST_INNER_LOOP_HEADER]]
+
+ // LAMBDA: [[DIST_INNER_LOOP_END]]:
+ // LAMBDA: br label %[[DIST_OUTER_LOOP_INC:.+]]
+
+ // LAMBDA: [[DIST_OUTER_LOOP_INC]]:
+ // check NextLB and NextUB
+ // LAMBDA-DAG: [[OMP_LB_VAL_2:%.+]] = load{{.+}}, {{.+}} [[OMP_LB]],
+ // LAMBDA-DAG: [[OMP_ST_VAL_2:%.+]] = load{{.+}}, {{.+}} [[OMP_ST]],
+ // LAMBDA-DAG: [[OMP_LB_NEXT:%.+]] = add{{.+}} [[OMP_LB_VAL_2]], [[OMP_ST_VAL_2]]
+ // LAMBDA: store{{.+}} [[OMP_LB_NEXT]], {{.+}}* [[OMP_LB]],
+ // LAMBDA-DAG: [[OMP_UB_VAL_5:%.+]] = load{{.+}}, {{.+}} [[OMP_UB]],
+ // LAMBDA-DAG: [[OMP_ST_VAL_3:%.+]] = load{{.+}}, {{.+}} [[OMP_ST]],
+ // LAMBDA-DAG: [[OMP_UB_NEXT:%.+]] = add{{.+}} [[OMP_UB_VAL_5]], [[OMP_ST_VAL_3]]
+ // LAMBDA: store{{.+}} [[OMP_UB_NEXT]], {{.+}}* [[OMP_UB]],
+ // LAMBDA: br label %[[DIST_OUTER_LOOP_HEADER]]
+
+ // outer loop exit
+ // LAMBDA: [[DIST_OUTER_LOOP_END]]:
+ // LAMBDA-DAG: call void @__kmpc_for_static_fini(
+ // LAMBDA: ret
+
+ // skip implementation of 'parallel for': using default scheduling and was tested above
+ [&]() {
+ a[i] = b[i] + c[i];
+ }();
+ }
+
+ // schedule: static no chunk
+ #pragma omp target
+ #pragma omp teams
+ // LAMBDA: define{{.+}} void [[OFFLOADING_FUN_4]](
+ // LAMBDA: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, i32 4, {{.+}}* [[OMP_OUTLINED_4:@.+]] to {{.+}})
+
+ #pragma omp distribute parallel for simd schedule(static)
+ for (int i = 0; i < n; ++i) {
+ a[i] = b[i] + c[i];
+ // LAMBDA: define{{.+}} void [[OMP_OUTLINED_4]](
+ // LAMBDA-DAG: [[OMP_IV:%.omp.iv]] = alloca
+ // LAMBDA-DAG: [[OMP_LB:%.omp.comb.lb]] = alloca
+ // LAMBDA-DAG: [[OMP_UB:%.omp.comb.ub]] = alloca
+ // LAMBDA-DAG: [[OMP_ST:%.omp.stride]] = alloca
+
+ // LAMBDA: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 92,
+ // LAMBDA: call{{.+}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}}[[OMP_PARFOR_OUTLINED_4:@.+]] to {{.+}},
+ // skip rest of implementation of 'distribute' as it is tested above for default dist_schedule case
+ // LAMBDA: ret
+
+ // 'parallel for' implementation is the same as the case without schedule clase (static no chunk is the default)
+ // LAMBDA: define{{.+}} void [[OMP_PARFOR_OUTLINED_4]]({{.+}}, {{.+}}, i{{[0-9]+}} [[OMP_PREV_LB_IN:%.+]], i{{[0-9]+}} [[OMP_PREV_UB_IN:%.+]], {{.+}}, {{.+}}, {{.+}}, {{.+}})
+
+ // LAMBDA-DAG: [[OMP_PF_LB:%.omp.lb]] = alloca{{.+}},
+ // LAMBDA-DAG: [[OMP_PF_UB:%.omp.ub]] = alloca{{.+}},
+ // LAMBDA-DAG: [[OMP_PF_IV:%.omp.iv]] = alloca{{.+}},
+
+ // initialize lb and ub to PrevLB and PrevUB
+ // LAMBDA-DAG: store{{.+}} [[OMP_PREV_LB_IN]], {{.+}}* [[PREV_LB_ADDR:%.+]],
+ // LAMBDA-DAG: store{{.+}} [[OMP_PREV_UB_IN]], {{.+}}* [[PREV_UB_ADDR:%.+]],
+ // LAMBDA-DAG: [[OMP_PREV_LB_VAL:%.+]] = load{{.+}}, {{.+}}* [[PREV_LB_ADDR]],
+ // LAMBDA-64-DAG: [[OMP_PREV_LB_TRC:%.+]] = trunc{{.+}} [[OMP_PREV_LB_VAL]] to {{.+}}
+ // LAMBDA-DAG: [[OMP_PREV_UB_VAL:%.+]] = load{{.+}}, {{.+}}* [[PREV_UB_ADDR]],
+ // LAMBDA-64-DAG: [[OMP_PREV_UB_TRC:%.+]] = trunc{{.+}} [[OMP_PREV_UB_VAL]] to {{.+}}
+ // LAMBDA-64-DAG: store{{.+}} [[OMP_PREV_LB_TRC]], {{.+}}* [[OMP_PF_LB]],
+ // LAMBDA-32-DAG: store{{.+}} [[OMP_PREV_LB_VAL]], {{.+}}* [[OMP_PF_LB]],
+ // LAMBDA-64-DAG: store{{.+}} [[OMP_PREV_UB_TRC]], {{.+}}* [[OMP_PF_UB]],
+ // LAMBDA-32-DAG: store{{.+}} [[OMP_PREV_UB_VAL]], {{.+}}* [[OMP_PF_UB]],
+ // LAMBDA: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, {{.+}} 34, {{.+}}, {{.+}}* [[OMP_PF_LB]], {{.+}}* [[OMP_PF_UB]],{{.+}})
+
+ // PrevEUB is only used when 'for' has a chunked schedule, otherwise EUB is used
+ // In this case we use EUB
+ // LAMBDA-DAG: [[OMP_PF_UB_VAL_1:%.+]] = load{{.+}} [[OMP_PF_UB]],
+ // LAMBDA: [[PF_NUM_IT_1:%.+]] = load{{.+}},
+ // LAMBDA-DAG: [[PF_CMP_UB_NUM_IT:%.+]] = icmp{{.+}} [[OMP_PF_UB_VAL_1]], [[PF_NUM_IT_1]]
+ // LAMBDA: br i1 [[PF_CMP_UB_NUM_IT]], label %[[PF_EUB_TRUE:.+]], label %[[PF_EUB_FALSE:.+]]
+ // LAMBDA: [[PF_EUB_TRUE]]:
+ // LAMBDA: [[PF_NUM_IT_2:%.+]] = load{{.+}},
+ // LAMBDA: br label %[[PF_EUB_END:.+]]
+ // LAMBDA-DAG: [[PF_EUB_FALSE]]:
+ // LAMBDA: [[OMP_PF_UB_VAL2:%.+]] = load{{.+}} [[OMP_PF_UB]],
+ // LAMBDA: br label %[[PF_EUB_END]]
+ // LAMBDA-DAG: [[PF_EUB_END]]:
+ // LAMBDA-DAG: [[PF_EUB_RES:%.+]] = phi{{.+}} [ [[PF_NUM_IT_2]], %[[PF_EUB_TRUE]] ], [ [[OMP_PF_UB_VAL2]], %[[PF_EUB_FALSE]] ]
+ // LAMBDA: store{{.+}} [[PF_EUB_RES]],{{.+}} [[OMP_PF_UB]],
+
+ // initialize omp.iv
+ // LAMBDA: [[OMP_PF_LB_VAL_1:%.+]] = load{{.+}}, {{.+}} [[OMP_PF_LB]],
+ // LAMBDA: store {{.+}} [[OMP_PF_LB_VAL_1]], {{.+}}* [[OMP_PF_IV]],
+ // LAMBDA: br label %[[OMP_PF_JUMP_BACK:.+]]
+
+ // check exit condition
+ // LAMBDA: [[OMP_PF_JUMP_BACK]]:
+ // LAMBDA-DAG: [[OMP_PF_IV_VAL_1:%.+]] = load {{.+}} [[OMP_PF_IV]],
+ // LAMBDA-DAG: [[OMP_PF_UB_VAL_3:%.+]] = load {{.+}} [[OMP_PF_UB]],
+ // LAMBDA: [[PF_CMP_IV_UB:%.+]] = icmp sle {{.+}} [[OMP_PF_IV_VAL_1]], [[OMP_PF_UB_VAL_3]]
+ // LAMBDA: br {{.+}} [[PF_CMP_IV_UB]], label %[[PF_BODY:.+]], label %[[PF_END:.+]]
+
+ // check that PrevLB and PrevUB are passed to the 'for'
+ // LAMBDA: [[PF_BODY]]:
+ // LAMBDA-DAG: {{.+}} = load{{.+}}, {{.+}}* [[OMP_PF_IV]],
+ // LAMBDA: br label {{.+}}
+
+ // check stride 1 for 'for' in 'distribute parallel for simd'
+ // LAMBDA-DAG: [[OMP_PF_IV_VAL_2:%.+]] = load {{.+}}, {{.+}}* [[OMP_PF_IV]],
+ // LAMBDA: [[OMP_PF_IV_INC:%.+]] = add{{.+}} [[OMP_PF_IV_VAL_2]], 1
+ // LAMBDA: store{{.+}} [[OMP_PF_IV_INC]], {{.+}}* [[OMP_PF_IV]],
+ // LAMBDA: br label %[[OMP_PF_JUMP_BACK]]
+
+ // LAMBDA-DAG: call void @__kmpc_for_static_fini(
+ // LAMBDA: ret
+
+ [&]() {
+ a[i] = b[i] + c[i];
+ }();
+ }
+
+ // schedule: static chunk
+ #pragma omp target
+ #pragma omp teams
+ // LAMBDA: define{{.+}} void [[OFFLOADING_FUN_5]](
+ // LAMBDA: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, i32 5, {{.+}}* [[OMP_OUTLINED_5:@.+]] to {{.+}})
+
+ #pragma omp distribute parallel for simd schedule(static, ch)
+ for (int i = 0; i < n; ++i) {
+ a[i] = b[i] + c[i];
+ // LAMBDA: define{{.+}} void [[OMP_OUTLINED_5]](
+ // LAMBDA: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 92,
+ // LAMBDA: call{{.+}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}}[[OMP_PARFOR_OUTLINED_5:@.+]] to {{.+}},
+ // skip rest of implementation of 'distribute' as it is tested above for default dist_schedule case
+ // LAMBDA: ret
+
+ // 'parallel for' implementation using outer and inner loops and PrevEUB
+ // LAMBDA: define{{.+}} void [[OMP_PARFOR_OUTLINED_5]]({{.+}}, {{.+}}, i{{[0-9]+}} [[OMP_PREV_LB_IN:%.+]], i{{[0-9]+}} [[OMP_PREV_UB_IN:%.+]], {{.+}}, {{.+}}, {{.+}}, {{.+}}, {{.+}})
+ // LAMBDA-DAG: [[OMP_PF_LB:%.omp.lb]] = alloca{{.+}},
+ // LAMBDA-DAG: [[OMP_PF_UB:%.omp.ub]] = alloca{{.+}},
+ // LAMBDA-DAG: [[OMP_PF_IV:%.omp.iv]] = alloca{{.+}},
+ // LAMBDA-DAG: [[OMP_PF_ST:%.omp.stride]] = alloca{{.+}},
+
+ // initialize lb and ub to PrevLB and PrevUB
+ // LAMBDA-DAG: store{{.+}} [[OMP_PREV_LB_IN]], {{.+}}* [[PREV_LB_ADDR:%.+]],
+ // LAMBDA-DAG: store{{.+}} [[OMP_PREV_UB_IN]], {{.+}}* [[PREV_UB_ADDR:%.+]],
+ // LAMBDA-DAG: [[OMP_PREV_LB_VAL:%.+]] = load{{.+}}, {{.+}}* [[PREV_LB_ADDR]],
+ // LAMBDA-64-DAG: [[OMP_PREV_LB_TRC:%.+]] = trunc{{.+}} [[OMP_PREV_LB_VAL]] to {{.+}}
+ // LAMBDA-DAG: [[OMP_PREV_UB_VAL:%.+]] = load{{.+}}, {{.+}}* [[PREV_UB_ADDR]],
+ // LAMBDA-64-DAG: [[OMP_PREV_UB_TRC:%.+]] = trunc{{.+}} [[OMP_PREV_UB_VAL]] to {{.+}}
+ // LAMBDA-64-DAG: store{{.+}} [[OMP_PREV_LB_TRC]], {{.+}}* [[OMP_PF_LB]],
+ // LAMBDA-32-DAG: store{{.+}} [[OMP_PREV_LB_VAL]], {{.+}}* [[OMP_PF_LB]],
+ // LAMBDA-64-DAG: store{{.+}} [[OMP_PREV_UB_TRC]], {{.+}}* [[OMP_PF_UB]],
+ // LAMBDA-32-DAG: store{{.+}} [[OMP_PREV_UB_VAL]], {{.+}}* [[OMP_PF_UB]],
+ // LAMBDA: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, {{.+}} 33, {{.+}}, {{.+}}* [[OMP_PF_LB]], {{.+}}* [[OMP_PF_UB]],{{.+}})
+ // LAMBDA: br label %[[OMP_PF_OUTER_LOOP_HEADER:.+]]
+
+ // check PrevEUB (using PrevUB instead of NumIt as upper bound)
+ // LAMBDA: [[OMP_PF_OUTER_LOOP_HEADER]]:
+ // LAMBDA-DAG: [[OMP_PF_UB_VAL_1:%.+]] = load{{.+}} [[OMP_PF_UB]],
+ // LAMBDA-64-DAG: [[OMP_PF_UB_VAL_CONV:%.+]] = sext{{.+}} [[OMP_PF_UB_VAL_1]] to
+ // LAMBDA: [[PF_PREV_UB_VAL_1:%.+]] = load{{.+}}, {{.+}}* [[PREV_UB_ADDR]],
+ // LAMBDA-64-DAG: [[PF_CMP_UB_NUM_IT:%.+]] = icmp{{.+}} [[OMP_PF_UB_VAL_CONV]], [[PF_PREV_UB_VAL_1]]
+ // LAMBDA-32-DAG: [[PF_CMP_UB_NUM_IT:%.+]] = icmp{{.+}} [[OMP_PF_UB_VAL_1]], [[PF_PREV_UB_VAL_1]]
+ // LAMBDA: br i1 [[PF_CMP_UB_NUM_IT]], label %[[PF_EUB_TRUE:.+]], label %[[PF_EUB_FALSE:.+]]
+ // LAMBDA: [[PF_EUB_TRUE]]:
+ // LAMBDA: [[PF_PREV_UB_VAL_2:%.+]] = load{{.+}}, {{.+}}* [[PREV_UB_ADDR]],
+ // LAMBDA: br label %[[PF_EUB_END:.+]]
+ // LAMBDA-DAG: [[PF_EUB_FALSE]]:
+ // LAMBDA: [[OMP_PF_UB_VAL_2:%.+]] = load{{.+}} [[OMP_PF_UB]],
+ // LAMBDA-64: [[OMP_PF_UB_VAL_2_CONV:%.+]] = sext{{.+}} [[OMP_PF_UB_VAL_2]] to
+ // LAMBDA: br label %[[PF_EUB_END]]
+ // LAMBDA-DAG: [[PF_EUB_END]]:
+ // LAMBDA-64-DAG: [[PF_EUB_RES:%.+]] = phi{{.+}} [ [[PF_PREV_UB_VAL_2]], %[[PF_EUB_TRUE]] ], [ [[OMP_PF_UB_VAL_2_CONV]], %[[PF_EUB_FALSE]] ]
+ // LAMBDA-32-DAG: [[PF_EUB_RES:%.+]] = phi{{.+}} [ [[PF_PREV_UB_VAL_2]], %[[PF_EUB_TRUE]] ], [ [[OMP_PF_UB_VAL_2]], %[[PF_EUB_FALSE]] ]
+ // LAMBDA-64-DAG: [[PF_EUB_RES_CONV:%.+]] = trunc{{.+}} [[PF_EUB_RES]] to
+ // LAMBDA-64: store{{.+}} [[PF_EUB_RES_CONV]],{{.+}} [[OMP_PF_UB]],
+ // LAMBDA-32: store{{.+}} [[PF_EUB_RES]], {{.+}} [[OMP_PF_UB]],
+
+ // initialize omp.iv (IV = LB)
+ // LAMBDA: [[OMP_PF_LB_VAL_1:%.+]] = load{{.+}}, {{.+}} [[OMP_PF_LB]],
+ // LAMBDA: store {{.+}} [[OMP_PF_LB_VAL_1]], {{.+}}* [[OMP_PF_IV]],
+
+ // outer loop: while (IV < UB) {
+ // LAMBDA-DAG: [[OMP_PF_IV_VAL_1:%.+]] = load{{.+}}, {{.+}}* [[OMP_PF_IV]],
+ // LAMBDA-DAG: [[OMP_PF_UB_VAL_3:%.+]] = load{{.+}}, {{.+}}* [[OMP_PF_UB]],
+ // LAMBDA: [[PF_CMP_IV_UB_1:%.+]] = icmp{{.+}} [[OMP_PF_IV_VAL_1]], [[OMP_PF_UB_VAL_3]]
+ // LAMBDA: br{{.+}} [[PF_CMP_IV_UB_1]], label %[[OMP_PF_OUTER_LOOP_BODY:.+]], label %[[OMP_PF_OUTER_LOOP_END:.+]]
+
+ // LAMBDA: [[OMP_PF_OUTER_LOOP_BODY]]:
+ // LAMBDA: br label %[[OMP_PF_INNER_FOR_HEADER:.+]]
+
+ // LAMBDA: [[OMP_PF_INNER_FOR_HEADER]]:
+ // LAMBDA-DAG: [[OMP_PF_IV_VAL_2:%.+]] = load{{.+}}, {{.+}}* [[OMP_PF_IV]],
+ // LAMBDA-DAG: [[OMP_PF_UB_VAL_4:%.+]] = load{{.+}}, {{.+}}* [[OMP_PF_UB]],
+ // LAMBDA: [[PF_CMP_IV_UB_2:%.+]] = icmp{{.+}} [[OMP_PF_IV_VAL_2]], [[OMP_PF_UB_VAL_4]]
+ // LAMBDA: br{{.+}} [[PF_CMP_IV_UB_2]], label %[[OMP_PF_INNER_LOOP_BODY:.+]], label %[[OMP_PF_INNER_LOOP_END:.+]]
+
+ // LAMBDA: [[OMP_PF_INNER_LOOP_BODY]]:
+ // LAMBDA-DAG: {{.+}} = load{{.+}}, {{.+}}* [[OMP_PF_IV]],
+ // skip body branch
+ // LAMBDA: br{{.+}}
+ // LAMBDA: br label %[[OMP_PF_INNER_LOOP_INC:.+]]
+
+ // IV = IV + 1 and inner loop latch
+ // LAMBDA: [[OMP_PF_INNER_LOOP_INC]]:
+ // LAMBDA-DAG: [[OMP_PF_IV_VAL_3:%.+]] = load{{.+}}, {{.+}}* [[OMP_IV]],
+ // LAMBDA-DAG: [[OMP_PF_NEXT_IV:%.+]] = add{{.+}} [[OMP_PF_IV_VAL_3]], 1
+ // LAMBDA-DAG: store{{.+}} [[OMP_PF_NEXT_IV]], {{.+}}* [[OMP_IV]],
+ // LAMBDA: br label %[[OMP_PF_INNER_FOR_HEADER]]
+
+ // check NextLB and NextUB
+ // LAMBDA: [[OMP_PF_INNER_LOOP_END]]:
+ // LAMBDA: br label %[[OMP_PF_OUTER_LOOP_INC:.+]]
+
+ // LAMBDA: [[OMP_PF_OUTER_LOOP_INC]]:
+ // LAMBDA-DAG: [[OMP_PF_LB_VAL_2:%.+]] = load{{.+}}, {{.+}} [[OMP_PF_LB]],
+ // LAMBDA-DAG: [[OMP_PF_ST_VAL_1:%.+]] = load{{.+}}, {{.+}} [[OMP_PF_ST]],
+ // LAMBDA-DAG: [[OMP_PF_LB_NEXT:%.+]] = add{{.+}} [[OMP_PF_LB_VAL_2]], [[OMP_PF_ST_VAL_1]]
+ // LAMBDA: store{{.+}} [[OMP_PF_LB_NEXT]], {{.+}}* [[OMP_PF_LB]],
+ // LAMBDA-DAG: [[OMP_PF_UB_VAL_5:%.+]] = load{{.+}}, {{.+}} [[OMP_PF_UB]],
+ // LAMBDA-DAG: [[OMP_PF_ST_VAL_2:%.+]] = load{{.+}}, {{.+}} [[OMP_PF_ST]],
+ // LAMBDA-DAG: [[OMP_PF_UB_NEXT:%.+]] = add{{.+}} [[OMP_PF_UB_VAL_5]], [[OMP_PF_ST_VAL_2]]
+ // LAMBDA: store{{.+}} [[OMP_PF_UB_NEXT]], {{.+}}* [[OMP_PF_UB]],
+ // LAMBDA: br label %[[OMP_PF_OUTER_LOOP_HEADER]]
+
+ // LAMBDA: [[OMP_PF_OUTER_LOOP_END]]:
+ // LAMBDA-DAG: call void @__kmpc_for_static_fini(
+ // LAMBDA: ret
+ [&]() {
+ a[i] = b[i] + c[i];
+ }();
+ }
+
+ // schedule: dynamic no chunk
+ #pragma omp target
+ #pragma omp teams
+ // LAMBDA: define{{.+}} void [[OFFLOADING_FUN_6]](
+ // LAMBDA: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, i32 4, {{.+}}* [[OMP_OUTLINED_6:@.+]] to {{.+}})
+
+ #pragma omp distribute parallel for simd schedule(dynamic)
+ for (int i = 0; i < n; ++i) {
+ a[i] = b[i] + c[i];
+ // LAMBDA: define{{.+}} void [[OMP_OUTLINED_6]](
+ // LAMBDA: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 92,
+ // LAMBDA: call{{.+}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}}[[OMP_PARFOR_OUTLINED_6:@.+]] to {{.+}},
+ // skip rest of implementation of 'distribute' as it is tested above for default dist_schedule case
+ // LAMBDA: ret
+
+ // 'parallel for' implementation using outer and inner loops and PrevEUB
+ // LAMBDA: define{{.+}} void [[OMP_PARFOR_OUTLINED_6]]({{.+}}, {{.+}}, i{{[0-9]+}} [[OMP_PREV_LB_IN:%.+]], i{{[0-9]+}} [[OMP_PREV_UB_IN:%.+]], {{.+}}, {{.+}}, {{.+}}, {{.+}})
+ // LAMBDA-DAG: [[OMP_PF_LB:%.omp.lb]] = alloca{{.+}},
+ // LAMBDA-DAG: [[OMP_PF_UB:%.omp.ub]] = alloca{{.+}},
+ // LAMBDA-DAG: [[OMP_PF_IV:%.omp.iv]] = alloca{{.+}},
+ // LAMBDA-DAG: [[OMP_PF_ST:%.omp.stride]] = alloca{{.+}},
+
+ // initialize lb and ub to PrevLB and PrevUB
+ // LAMBDA-DAG: store{{.+}} [[OMP_PREV_LB_IN]], {{.+}}* [[PREV_LB_ADDR:%.+]],
+ // LAMBDA-DAG: store{{.+}} [[OMP_PREV_UB_IN]], {{.+}}* [[PREV_UB_ADDR:%.+]],
+ // LAMBDA-DAG: [[OMP_PREV_LB_VAL:%.+]] = load{{.+}}, {{.+}}* [[PREV_LB_ADDR]],
+ // LAMBDA-64-DAG: [[OMP_PREV_LB_TRC:%.+]] = trunc{{.+}} [[OMP_PREV_LB_VAL]] to {{.+}}
+ // LAMBDA-DAG: [[OMP_PREV_UB_VAL:%.+]] = load{{.+}}, {{.+}}* [[PREV_UB_ADDR]],
+ // LAMBDA-64-DAG: [[OMP_PREV_UB_TRC:%.+]] = trunc{{.+}} [[OMP_PREV_UB_VAL]] to {{.+}}
+ // LAMBDA-64-DAG: store{{.+}} [[OMP_PREV_LB_TRC]], {{.+}}* [[OMP_PF_LB]],
+ // LAMBDA-64-DAG: store{{.+}} [[OMP_PREV_UB_TRC]], {{.+}}* [[OMP_PF_UB]],
+ // LAMBDA-32-DAG: store{{.+}} [[OMP_PREV_LB_VAL]], {{.+}}* [[OMP_PF_LB]],
+ // LAMBDA-32-DAG: store{{.+}} [[OMP_PREV_UB_VAL]], {{.+}}* [[OMP_PF_UB]],
+ // LAMBDA-DAG: [[OMP_PF_LB_VAL:%.+]] = load{{.+}}, {{.+}} [[OMP_PF_LB]],
+ // LAMBDA-DAG: [[OMP_PF_UB_VAL:%.+]] = load{{.+}}, {{.+}} [[OMP_PF_UB]],
+ // LAMBDA: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, {{.+}} 35, {{.+}} [[OMP_PF_LB_VAL]], {{.+}} [[OMP_PF_UB_VAL]], {{.+}}, {{.+}})
+ // LAMBDA: br label %[[OMP_PF_OUTER_LOOP_HEADER:.+]]
+
+ // LAMBDA: [[OMP_PF_OUTER_LOOP_HEADER]]:
+ // LAMBDA: [[IS_FIN:%.+]] = call{{.+}} @__kmpc_dispatch_next_4({{.+}}, {{.+}}, {{.+}}, {{.+}}* [[OMP_PF_LB]], {{.+}}* [[OMP_PF_UB]], {{.+}}* [[OMP_PF_ST]])
+ // LAMBDA: [[IS_FIN_CMP:%.+]] = icmp{{.+}} [[IS_FIN]], 0
+ // LAMBDA: br{{.+}} [[IS_FIN_CMP]], label %[[OMP_PF_OUTER_LOOP_BODY:.+]], label %[[OMP_PF_OUTER_LOOP_END:.+]]
+
+ // initialize omp.iv (IV = LB)
+ // LAMBDA: [[OMP_PF_OUTER_LOOP_BODY]]:
+ // LAMBDA-DAG: [[OMP_PF_LB_VAL_1:%.+]] = load{{.+}}, {{.+}} [[OMP_PF_LB]],
+ // LAMBDA-DAG: store {{.+}} [[OMP_PF_LB_VAL_1]], {{.+}}* [[OMP_PF_IV]],
+ // LAMBDA: br label %[[OMP_PF_INNER_LOOP_HEADER:.+]]
+
+ // LAMBDA: [[OMP_PF_INNER_LOOP_HEADER]]:
+ // LAMBDA-DAG: [[OMP_PF_IV_VAL_2:%.+]] = load{{.+}}, {{.+}}* [[OMP_PF_IV]],
+ // LAMBDA-DAG: [[OMP_PF_UB_VAL_4:%.+]] = load{{.+}}, {{.+}}* [[OMP_PF_UB]],
+ // LAMBDA: [[PF_CMP_IV_UB_2:%.+]] = icmp{{.+}} [[OMP_PF_IV_VAL_2]], [[OMP_PF_UB_VAL_4]]
+ // LAMBDA: br{{.+}} [[PF_CMP_IV_UB_2]], label %[[OMP_PF_INNER_LOOP_BODY:.+]], label %[[OMP_PF_INNER_LOOP_END:.+]]
+
+ // LAMBDA: [[OMP_PF_INNER_LOOP_BODY]]:
+ // LAMBDA-DAG: {{.+}} = load{{.+}}, {{.+}}* [[OMP_PF_IV]],
+ // skip body branch
+ // LAMBDA: br{{.+}}
+ // LAMBDA: br label %[[OMP_PF_INNER_LOOP_INC:.+]]
+
+ // IV = IV + 1 and inner loop latch
+ // LAMBDA: [[OMP_PF_INNER_LOOP_INC]]:
+ // LAMBDA-DAG: [[OMP_PF_IV_VAL_3:%.+]] = load{{.+}}, {{.+}}* [[OMP_IV]],
+ // LAMBDA-DAG: [[OMP_PF_NEXT_IV:%.+]] = add{{.+}} [[OMP_PF_IV_VAL_3]], 1
+ // LAMBDA-DAG: store{{.+}} [[OMP_PF_NEXT_IV]], {{.+}}* [[OMP_IV]],
+ // LAMBDA: br label %[[OMP_PF_INNER_LOOP_HEADER]]
+
+ // check NextLB and NextUB
+ // LAMBDA: [[OMP_PF_INNER_LOOP_END]]:
+ // LAMBDA: br label %[[OMP_PF_OUTER_LOOP_INC:.+]]
+
+ // LAMBDA: [[OMP_PF_OUTER_LOOP_INC]]:
+ // LAMBDA: br label %[[OMP_PF_OUTER_LOOP_HEADER]]
+
+ // LAMBDA: [[OMP_PF_OUTER_LOOP_END]]:
+ // LAMBDA: ret
+ [&]() {
+ a[i] = b[i] + c[i];
+ }();
+ }
+
+ // schedule: dynamic chunk
+ #pragma omp target
+ #pragma omp teams
+ // LAMBDA: define{{.+}} void [[OFFLOADING_FUN_7]](
+ // LAMBDA: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, i32 5, {{.+}}* [[OMP_OUTLINED_7:@.+]] to {{.+}})
+
+ #pragma omp distribute parallel for simd schedule(dynamic, ch)
+ for (int i = 0; i < n; ++i) {
+ a[i] = b[i] + c[i];
+ // LAMBDA: define{{.+}} void [[OMP_OUTLINED_7]](
+ // LAMBDA: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 92,
+ // LAMBDA: call{{.+}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}}[[OMP_PARFOR_OUTLINED_7:@.+]] to {{.+}},
+ // skip rest of implementation of 'distribute' as it is tested above for default dist_schedule case
+ // LAMBDA: ret
+
+ // 'parallel for' implementation using outer and inner loops and PrevEUB
+ // LAMBDA: define{{.+}} void [[OMP_PARFOR_OUTLINED_7]]({{.+}}, {{.+}}, i{{[0-9]+}} [[OMP_PREV_LB_IN:%.+]], i{{[0-9]+}} [[OMP_PREV_UB_IN:%.+]], {{.+}}, {{.+}}, {{.+}}, {{.+}}, {{.+}})
+ // LAMBDA-DAG: [[OMP_PF_LB:%.omp.lb]] = alloca{{.+}},
+ // LAMBDA-DAG: [[OMP_PF_UB:%.omp.ub]] = alloca{{.+}},
+ // LAMBDA-DAG: [[OMP_PF_IV:%.omp.iv]] = alloca{{.+}},
+ // LAMBDA-DAG: [[OMP_PF_ST:%.omp.stride]] = alloca{{.+}},
+
+ // initialize lb and ub to PrevLB and PrevUB
+ // LAMBDA-DAG: store{{.+}} [[OMP_PREV_LB_IN]], {{.+}}* [[PREV_LB_ADDR:%.+]],
+ // LAMBDA-DAG: store{{.+}} [[OMP_PREV_UB_IN]], {{.+}}* [[PREV_UB_ADDR:%.+]],
+ // LAMBDA-DAG: [[OMP_PREV_LB_VAL:%.+]] = load{{.+}}, {{.+}}* [[PREV_LB_ADDR]],
+ // LAMBDA-64-DAG: [[OMP_PREV_LB_TRC:%.+]] = trunc{{.+}} [[OMP_PREV_LB_VAL]] to {{.+}}
+ // LAMBDA-DAG: [[OMP_PREV_UB_VAL:%.+]] = load{{.+}}, {{.+}}* [[PREV_UB_ADDR]],
+ // LAMBDA-64-DAG: [[OMP_PREV_UB_TRC:%.+]] = trunc{{.+}} [[OMP_PREV_UB_VAL]] to {{.+}}
+ // LAMBDA-64-DAG: store{{.+}} [[OMP_PREV_LB_TRC]], {{.+}}* [[OMP_PF_LB]],
+ // LAMBDA-64-DAG: store{{.+}} [[OMP_PREV_UB_TRC]], {{.+}}* [[OMP_PF_UB]],
+ // LAMBDA-32-DAG: store{{.+}} [[OMP_PREV_LB_VAL]], {{.+}}* [[OMP_PF_LB]],
+ // LAMBDA-32-DAG: store{{.+}} [[OMP_PREV_UB_VAL]], {{.+}}* [[OMP_PF_UB]],
+ // LAMBDA-DAG: [[OMP_PF_LB_VAL:%.+]] = load{{.+}}, {{.+}} [[OMP_PF_LB]],
+ // LAMBDA-DAG: [[OMP_PF_UB_VAL:%.+]] = load{{.+}}, {{.+}} [[OMP_PF_UB]],
+ // LAMBDA: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, {{.+}} 35, {{.+}} [[OMP_PF_LB_VAL]], {{.+}} [[OMP_PF_UB_VAL]], {{.+}}, {{.+}})
+ // LAMBDA: br label %[[OMP_PF_OUTER_LOOP_HEADER:.+]]
+
+ // LAMBDA: [[OMP_PF_OUTER_LOOP_HEADER]]:
+ // LAMBDA: [[IS_FIN:%.+]] = call{{.+}} @__kmpc_dispatch_next_4({{.+}}, {{.+}}, {{.+}}, {{.+}}* [[OMP_PF_LB]], {{.+}}* [[OMP_PF_UB]], {{.+}}* [[OMP_PF_ST]])
+ // LAMBDA: [[IS_FIN_CMP:%.+]] = icmp{{.+}} [[IS_FIN]], 0
+ // LAMBDA: br{{.+}} [[IS_FIN_CMP]], label %[[OMP_PF_OUTER_LOOP_BODY:.+]], label %[[OMP_PF_OUTER_LOOP_END:.+]]
+
+ // initialize omp.iv (IV = LB)
+ // LAMBDA: [[OMP_PF_OUTER_LOOP_BODY]]:
+ // LAMBDA-DAG: [[OMP_PF_LB_VAL_1:%.+]] = load{{.+}}, {{.+}} [[OMP_PF_LB]],
+ // LAMBDA-DAG: store {{.+}} [[OMP_PF_LB_VAL_1]], {{.+}}* [[OMP_PF_IV]],
+ // LAMBDA: br label %[[OMP_PF_INNER_LOOP_HEADER:.+]]
+
+ // LAMBDA: [[OMP_PF_INNER_LOOP_HEADER]]:
+ // LAMBDA-DAG: [[OMP_PF_IV_VAL_2:%.+]] = load{{.+}}, {{.+}}* [[OMP_PF_IV]],
+ // LAMBDA-DAG: [[OMP_PF_UB_VAL_4:%.+]] = load{{.+}}, {{.+}}* [[OMP_PF_UB]],
+ // LAMBDA: [[PF_CMP_IV_UB_2:%.+]] = icmp{{.+}} [[OMP_PF_IV_VAL_2]], [[OMP_PF_UB_VAL_4]]
+ // LAMBDA: br{{.+}} [[PF_CMP_IV_UB_2]], label %[[OMP_PF_INNER_LOOP_BODY:.+]], label %[[OMP_PF_INNER_LOOP_END:.+]]
+
+ // LAMBDA: [[OMP_PF_INNER_LOOP_BODY]]:
+ // LAMBDA-DAG: {{.+}} = load{{.+}}, {{.+}}* [[OMP_PF_IV]],
+ // skip body branch
+ // LAMBDA: br{{.+}}
+ // LAMBDA: br label %[[OMP_PF_INNER_LOOP_INC:.+]]
+
+ // IV = IV + 1 and inner loop latch
+ // LAMBDA: [[OMP_PF_INNER_LOOP_INC]]:
+ // LAMBDA-DAG: [[OMP_PF_IV_VAL_3:%.+]] = load{{.+}}, {{.+}}* [[OMP_IV]],
+ // LAMBDA-DAG: [[OMP_PF_NEXT_IV:%.+]] = add{{.+}} [[OMP_PF_IV_VAL_3]], 1
+ // LAMBDA-DAG: store{{.+}} [[OMP_PF_NEXT_IV]], {{.+}}* [[OMP_IV]],
+ // LAMBDA: br label %[[OMP_PF_INNER_LOOP_HEADER]]
+
+ // check NextLB and NextUB
+ // LAMBDA: [[OMP_PF_INNER_LOOP_END]]:
+ // LAMBDA: br label %[[OMP_PF_OUTER_LOOP_INC:.+]]
+
+ // LAMBDA: [[OMP_PF_OUTER_LOOP_INC]]:
+ // LAMBDA: br label %[[OMP_PF_OUTER_LOOP_HEADER]]
+
+ // LAMBDA: [[OMP_PF_OUTER_LOOP_END]]:
+ // LAMBDA: ret
+ [&]() {
+ a[i] = b[i] + c[i];
+ }();
+ }
+ }();
+ return 0;
+#else
+ // CHECK-LABEL: @main
+
+ // CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+ // CHECK: call void [[OFFLOADING_FUN_1:@.+]](
+
+ // CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+ // CHECK: call void [[OFFLOADING_FUN_2:@.+]](
+
+ // CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+ // CHECK: call void [[OFFLOADING_FUN_3:@.+]](
+
+ // CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+ // CHECK: call void [[OFFLOADING_FUN_4:@.+]](
+
+ // CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+ // CHECK: call void [[OFFLOADING_FUN_5:@.+]](
+
+ // CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+ // CHECK: call void [[OFFLOADING_FUN_6:@.+]](
+
+ // CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+ // CHECK: call void [[OFFLOADING_FUN_7:@.+]](
+
+ // CHECK: call{{.+}} [[TMAIN:@.+]]()
+
+ // no schedule clauses
+ #pragma omp target
+ #pragma omp teams
+ // CHECK: define internal void [[OFFLOADING_FUN_1]](
+ // CHECK: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, i32 4, {{.+}}* [[OMP_OUTLINED_1:@.+]] to {{.+}})
+
+ #pragma omp distribute parallel for simd
+ for (int i = 0; i < n; ++i) {
+ a[i] = b[i] + c[i];
+ // CHECK: define{{.+}} void [[OMP_OUTLINED_1]](
+ // CHECK-DAG: [[OMP_IV:%.omp.iv]] = alloca
+ // CHECK-DAG: [[OMP_LB:%.omp.comb.lb]] = alloca
+ // CHECK-DAG: [[OMP_UB:%.omp.comb.ub]] = alloca
+ // CHECK-DAG: [[OMP_ST:%.omp.stride]] = alloca
+
+ // CHECK: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 92,
+
+ // check EUB for distribute
+ // CHECK-DAG: [[OMP_UB_VAL_1:%.+]] = load{{.+}} [[OMP_UB]],
+ // CHECK: [[NUM_IT_1:%.+]] = load{{.+}},
+ // CHECK-DAG: [[CMP_UB_NUM_IT:%.+]] = icmp sgt {{.+}} [[OMP_UB_VAL_1]], [[NUM_IT_1]]
+ // CHECK: br {{.+}} [[CMP_UB_NUM_IT]], label %[[EUB_TRUE:.+]], label %[[EUB_FALSE:.+]]
+ // CHECK-DAG: [[EUB_TRUE]]:
+ // CHECK: [[NUM_IT_2:%.+]] = load{{.+}},
+ // CHECK: br label %[[EUB_END:.+]]
+ // CHECK-DAG: [[EUB_FALSE]]:
+ // CHECK: [[OMP_UB_VAL2:%.+]] = load{{.+}} [[OMP_UB]],
+ // CHECK: br label %[[EUB_END]]
+ // CHECK-DAG: [[EUB_END]]:
+ // CHECK-DAG: [[EUB_RES:%.+]] = phi{{.+}} [ [[NUM_IT_2]], %[[EUB_TRUE]] ], [ [[OMP_UB_VAL2]], %[[EUB_FALSE]] ]
+ // CHECK: store{{.+}} [[EUB_RES]], {{.+}}* [[OMP_UB]],
+
+ // initialize omp.iv
+ // CHECK: [[OMP_LB_VAL_1:%.+]] = load{{.+}}, {{.+}}* [[OMP_LB]],
+ // CHECK: store {{.+}} [[OMP_LB_VAL_1]], {{.+}}* [[OMP_IV]],
+ // CHECK: br label %[[OMP_JUMP_BACK:.+]]
+
+ // check exit condition
+ // CHECK: [[OMP_JUMP_BACK]]:
+ // CHECK-DAG: [[OMP_IV_VAL_1:%.+]] = load {{.+}} [[OMP_IV]],
+ // CHECK-DAG: [[OMP_UB_VAL_3:%.+]] = load {{.+}} [[OMP_UB]],
+ // CHECK: [[CMP_IV_UB:%.+]] = icmp sle {{.+}} [[OMP_IV_VAL_1]], [[OMP_UB_VAL_3]]
+ // CHECK: br {{.+}} [[CMP_IV_UB]], label %[[DIST_BODY:.+]], label %[[DIST_END:.+]]
+
+ // check that PrevLB and PrevUB are passed to the 'for'
+ // CHECK: [[DIST_BODY]]:
+ // CHECK-DAG: [[OMP_PREV_LB:%.+]] = load {{.+}}, {{.+}} [[OMP_LB]],
+ // CHECK-64-DAG: [[OMP_PREV_LB_EXT:%.+]] = zext {{.+}} [[OMP_PREV_LB]] to {{.+}}
+ // CHECK-DAG: [[OMP_PREV_UB:%.+]] = load {{.+}}, {{.+}} [[OMP_UB]],
+ // CHECK-64-DAG: [[OMP_PREV_UB_EXT:%.+]] = zext {{.+}} [[OMP_PREV_UB]] to {{.+}}
+ // check that distlb and distub are properly passed to fork_call
+ // CHECK-64: call{{.+}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}}[[OMP_PARFOR_OUTLINED_1:@.+]] to {{.+}}, i{{[0-9]+}} [[OMP_PREV_LB_EXT]], i{{[0-9]+}} [[OMP_PREV_UB_EXT]], {{.+}})
+ // CHECK-32: call{{.+}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}}[[OMP_PARFOR_OUTLINED_1:@.+]] to {{.+}}, i{{[0-9]+}} [[OMP_PREV_LB]], i{{[0-9]+}} [[OMP_PREV_UB]], {{.+}})
+ // CHECK: br label %[[DIST_INC:.+]]
+
+ // increment by stride (distInc - 'parallel for' executes the whole chunk) and latch
+ // CHECK: [[DIST_INC]]:
+ // CHECK-DAG: [[OMP_IV_VAL_2:%.+]] = load {{.+}}, {{.+}}* [[OMP_IV]],
+ // CHECK-DAG: [[OMP_ST_VAL_1:%.+]] = load {{.+}}, {{.+}}* [[OMP_ST]],
+ // CHECK: [[OMP_IV_INC:%.+]] = add{{.+}} [[OMP_IV_VAL_2]], [[OMP_ST_VAL_1]]
+ // CHECK: store{{.+}} [[OMP_IV_INC]], {{.+}}* [[OMP_IV]],
+ // CHECK: br label %[[OMP_JUMP_BACK]]
+
+ // CHECK-DAG: call void @__kmpc_for_static_fini(
+ // CHECK: ret
+
+ // implementation of 'parallel for'
+ // CHECK: define{{.+}} void [[OMP_PARFOR_OUTLINED_1]]({{.+}}, {{.+}}, i{{[0-9]+}} [[OMP_PREV_LB_IN:%.+]], i{{[0-9]+}} [[OMP_PREV_UB_IN:%.+]], {{.+}}, {{.+}}, {{.+}}, {{.+}})
+
+ // CHECK-DAG: [[OMP_PF_LB:%.omp.lb]] = alloca{{.+}},
+ // CHECK-DAG: [[OMP_PF_UB:%.omp.ub]] = alloca{{.+}},
+ // CHECK-DAG: [[OMP_PF_IV:%.omp.iv]] = alloca{{.+}},
+
+ // initialize lb and ub to PrevLB and PrevUB
+ // CHECK-DAG: store{{.+}} [[OMP_PREV_LB_IN]], {{.+}}* [[PREV_LB_ADDR:%.+]],
+ // CHECK-DAG: store{{.+}} [[OMP_PREV_UB_IN]], {{.+}}* [[PREV_UB_ADDR:%.+]],
+ // CHECK-DAG: [[OMP_PREV_LB_VAL:%.+]] = load{{.+}}, {{.+}}* [[PREV_LB_ADDR]],
+ // CHECK-64-DAG: [[OMP_PREV_LB_TRC:%.+]] = trunc{{.+}} [[OMP_PREV_LB_VAL]] to {{.+}}
+ // CHECK-DAG: [[OMP_PREV_UB_VAL:%.+]] = load{{.+}}, {{.+}}* [[PREV_UB_ADDR]],
+ // CHECK-64-DAG: [[OMP_PREV_UB_TRC:%.+]] = trunc{{.+}} [[OMP_PREV_UB_VAL]] to {{.+}}
+ // CHECK-64-DAG: store{{.+}} [[OMP_PREV_LB_TRC]], {{.+}}* [[OMP_PF_LB]],
+ // CHECK-32-DAG: store{{.+}} [[OMP_PREV_LB_VAL]], {{.+}}* [[OMP_PF_LB]],
+ // CHECK-64-DAG: store{{.+}} [[OMP_PREV_UB_TRC]], {{.+}}* [[OMP_PF_UB]],
+ // CHECK-32-DAG: store{{.+}} [[OMP_PREV_UB_VAL]], {{.+}}* [[OMP_PF_UB]],
+ // CHECK: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, {{.+}} 34, {{.+}}, {{.+}}* [[OMP_PF_LB]], {{.+}}* [[OMP_PF_UB]],{{.+}})
+
+ // PrevEUB is only used when 'for' has a chunked schedule, otherwise EUB is used
+ // In this case we use EUB
+ // CHECK-DAG: [[OMP_PF_UB_VAL_1:%.+]] = load{{.+}} [[OMP_PF_UB]],
+ // CHECK: [[PF_NUM_IT_1:%.+]] = load{{.+}},
+ // CHECK-DAG: [[PF_CMP_UB_NUM_IT:%.+]] = icmp{{.+}} [[OMP_PF_UB_VAL_1]], [[PF_NUM_IT_1]]
+ // CHECK: br i1 [[PF_CMP_UB_NUM_IT]], label %[[PF_EUB_TRUE:.+]], label %[[PF_EUB_FALSE:.+]]
+ // CHECK: [[PF_EUB_TRUE]]:
+ // CHECK: [[PF_NUM_IT_2:%.+]] = load{{.+}},
+ // CHECK: br label %[[PF_EUB_END:.+]]
+ // CHECK-DAG: [[PF_EUB_FALSE]]:
+ // CHECK: [[OMP_PF_UB_VAL2:%.+]] = load{{.+}} [[OMP_PF_UB]],
+ // CHECK: br label %[[PF_EUB_END]]
+ // CHECK-DAG: [[PF_EUB_END]]:
+ // CHECK-DAG: [[PF_EUB_RES:%.+]] = phi{{.+}} [ [[PF_NUM_IT_2]], %[[PF_EUB_TRUE]] ], [ [[OMP_PF_UB_VAL2]], %[[PF_EUB_FALSE]] ]
+ // CHECK: store{{.+}} [[PF_EUB_RES]],{{.+}} [[OMP_PF_UB]],
+
+ // initialize omp.iv
+ // CHECK: [[OMP_PF_LB_VAL_1:%.+]] = load{{.+}}, {{.+}} [[OMP_PF_LB]],
+ // CHECK: store {{.+}} [[OMP_PF_LB_VAL_1]], {{.+}}* [[OMP_PF_IV]],
+ // CHECK: br label %[[OMP_PF_JUMP_BACK:.+]]
+
+ // check exit condition
+ // CHECK: [[OMP_PF_JUMP_BACK]]:
+ // CHECK-DAG: [[OMP_PF_IV_VAL_1:%.+]] = load {{.+}} [[OMP_PF_IV]],
+ // CHECK-DAG: [[OMP_PF_UB_VAL_3:%.+]] = load {{.+}} [[OMP_PF_UB]],
+ // CHECK: [[PF_CMP_IV_UB:%.+]] = icmp sle {{.+}} [[OMP_PF_IV_VAL_1]], [[OMP_PF_UB_VAL_3]]
+ // CHECK: br {{.+}} [[PF_CMP_IV_UB]], label %[[PF_BODY:.+]], label %[[PF_END:.+]]
+
+ // check that PrevLB and PrevUB are passed to the 'for'
+ // CHECK: [[PF_BODY]]:
+ // CHECK-DAG: {{.+}} = load{{.+}}, {{.+}}* [[OMP_PF_IV]],
+ // CHECK: br label {{.+}}
+
+ // check stride 1 for 'for' in 'distribute parallel for simd'
+ // CHECK-DAG: [[OMP_PF_IV_VAL_2:%.+]] = load {{.+}}, {{.+}}* [[OMP_PF_IV]],
+ // CHECK: [[OMP_PF_IV_INC:%.+]] = add{{.+}} [[OMP_PF_IV_VAL_2]], 1
+ // CHECK: store{{.+}} [[OMP_PF_IV_INC]], {{.+}}* [[OMP_PF_IV]],
+ // CHECK: br label %[[OMP_PF_JUMP_BACK]]
+
+ // CHECK-DAG: call void @__kmpc_for_static_fini(
+ // CHECK: ret
+ }
+
+ // dist_schedule: static no chunk
+ #pragma omp target
+ #pragma omp teams
+ // CHECK: define{{.+}} void [[OFFLOADING_FUN_2]](
+ // CHECK: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, i32 4, {{.+}}* [[OMP_OUTLINED_2:@.+]] to {{.+}})
+
+ #pragma omp distribute parallel for simd dist_schedule(static)
+ for (int i = 0; i < n; ++i) {
+ a[i] = b[i] + c[i];
+ // CHECK: define{{.+}} void [[OMP_OUTLINED_2]](
+ // CHECK-DAG: [[OMP_IV:%.omp.iv]] = alloca
+ // CHECK-DAG: [[OMP_LB:%.omp.comb.lb]] = alloca
+ // CHECK-DAG: [[OMP_UB:%.omp.comb.ub]] = alloca
+ // CHECK-DAG: [[OMP_ST:%.omp.stride]] = alloca
+
+ // CHECK: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 92,
+
+ // check EUB for distribute
+ // CHECK-DAG: [[OMP_UB_VAL_1:%.+]] = load{{.+}} [[OMP_UB]],
+ // CHECK: [[NUM_IT_1:%.+]] = load{{.+}},
+ // CHECK-DAG: [[CMP_UB_NUM_IT:%.+]] = icmp sgt {{.+}} [[OMP_UB_VAL_1]], [[NUM_IT_1]]
+ // CHECK: br {{.+}} [[CMP_UB_NUM_IT]], label %[[EUB_TRUE:.+]], label %[[EUB_FALSE:.+]]
+ // CHECK-DAG: [[EUB_TRUE]]:
+ // CHECK: [[NUM_IT_2:%.+]] = load{{.+}},
+ // CHECK: br label %[[EUB_END:.+]]
+ // CHECK-DAG: [[EUB_FALSE]]:
+ // CHECK: [[OMP_UB_VAL2:%.+]] = load{{.+}} [[OMP_UB]],
+ // CHECK: br label %[[EUB_END]]
+ // CHECK-DAG: [[EUB_END]]:
+ // CHECK-DAG: [[EUB_RES:%.+]] = phi{{.+}} [ [[NUM_IT_2]], %[[EUB_TRUE]] ], [ [[OMP_UB_VAL2]], %[[EUB_FALSE]] ]
+ // CHECK: store{{.+}} [[EUB_RES]], {{.+}}* [[OMP_UB]],
+
+ // initialize omp.iv
+ // CHECK: [[OMP_LB_VAL_1:%.+]] = load{{.+}}, {{.+}}* [[OMP_LB]],
+ // CHECK: store {{.+}} [[OMP_LB_VAL_1]], {{.+}}* [[OMP_IV]],
+ // CHECK: br label %[[OMP_JUMP_BACK:.+]]
+
+ // check exit condition
+ // CHECK: [[OMP_JUMP_BACK]]:
+ // CHECK-DAG: [[OMP_IV_VAL_1:%.+]] = load {{.+}} [[OMP_IV]],
+ // CHECK-DAG: [[OMP_UB_VAL_3:%.+]] = load {{.+}} [[OMP_UB]],
+ // CHECK: [[CMP_IV_UB:%.+]] = icmp sle {{.+}} [[OMP_IV_VAL_1]], [[OMP_UB_VAL_3]]
+ // CHECK: br {{.+}} [[CMP_IV_UB]], label %[[DIST_BODY:.+]], label %[[DIST_END:.+]]
+
+ // check that PrevLB and PrevUB are passed to the 'for'
+ // CHECK: [[DIST_BODY]]:
+ // CHECK-DAG: [[OMP_PREV_LB:%.+]] = load {{.+}}, {{.+}} [[OMP_LB]],
+ // CHECK-64-DAG: [[OMP_PREV_LB_EXT:%.+]] = zext {{.+}} [[OMP_PREV_LB]] to {{.+}}
+ // CHECK-DAG: [[OMP_PREV_UB:%.+]] = load {{.+}}, {{.+}} [[OMP_UB]],
+ // CHECK-64-DAG: [[OMP_PREV_UB_EXT:%.+]] = zext {{.+}} [[OMP_PREV_UB]] to {{.+}}
+ // check that distlb and distub are properly passed to fork_call
+ // CHECK-64: call{{.+}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}}[[OMP_PARFOR_OUTLINED_2:@.+]] to {{.+}}, i{{[0-9]+}} [[OMP_PREV_LB_EXT]], i{{[0-9]+}} [[OMP_PREV_UB_EXT]], {{.+}})
+ // CHECK-32: call{{.+}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}}[[OMP_PARFOR_OUTLINED_2:@.+]] to {{.+}}, i{{[0-9]+}} [[OMP_PREV_LB]], i{{[0-9]+}} [[OMP_PREV_UB]], {{.+}})
+ // CHECK: br label %[[DIST_INC:.+]]
+
+ // increment by stride (distInc - 'parallel for' executes the whole chunk) and latch
+ // CHECK: [[DIST_INC]]:
+ // CHECK-DAG: [[OMP_IV_VAL_2:%.+]] = load {{.+}}, {{.+}}* [[OMP_IV]],
+ // CHECK-DAG: [[OMP_ST_VAL_1:%.+]] = load {{.+}}, {{.+}}* [[OMP_ST]],
+ // CHECK: [[OMP_IV_INC:%.+]] = add{{.+}} [[OMP_IV_VAL_2]], [[OMP_ST_VAL_1]]
+ // CHECK: store{{.+}} [[OMP_IV_INC]], {{.+}}* [[OMP_IV]],
+ // CHECK: br label %[[OMP_JUMP_BACK]]
+
+ // CHECK-DAG: call void @__kmpc_for_static_fini(
+ // CHECK: ret
+
+ // implementation of 'parallel for'
+ // CHECK: define{{.+}} void [[OMP_PARFOR_OUTLINED_2]]({{.+}}, {{.+}}, i{{[0-9]+}} [[OMP_PREV_LB_IN:%.+]], i{{[0-9]+}} [[OMP_PREV_UB_IN:%.+]], {{.+}}, {{.+}}, {{.+}}, {{.+}})
+
+ // CHECK-DAG: [[OMP_PF_LB:%.omp.lb]] = alloca{{.+}},
+ // CHECK-DAG: [[OMP_PF_UB:%.omp.ub]] = alloca{{.+}},
+ // CHECK-DAG: [[OMP_PF_IV:%.omp.iv]] = alloca{{.+}},
+
+ // initialize lb and ub to PrevLB and PrevUB
+ // CHECK-DAG: store{{.+}} [[OMP_PREV_LB_IN]], {{.+}}* [[PREV_LB_ADDR:%.+]],
+ // CHECK-DAG: store{{.+}} [[OMP_PREV_UB_IN]], {{.+}}* [[PREV_UB_ADDR:%.+]],
+ // CHECK-DAG: [[OMP_PREV_LB_VAL:%.+]] = load{{.+}}, {{.+}}* [[PREV_LB_ADDR]],
+ // CHECK-64-DAG: [[OMP_PREV_LB_TRC:%.+]] = trunc{{.+}} [[OMP_PREV_LB_VAL]] to {{.+}}
+ // CHECK-DAG: [[OMP_PREV_UB_VAL:%.+]] = load{{.+}}, {{.+}}* [[PREV_UB_ADDR]],
+ // CHECK-64-DAG: [[OMP_PREV_UB_TRC:%.+]] = trunc{{.+}} [[OMP_PREV_UB_VAL]] to {{.+}}
+ // CHECK-64-DAG: store{{.+}} [[OMP_PREV_LB_TRC]], {{.+}}* [[OMP_PF_LB]],
+ // CHECK-32-DAG: store{{.+}} [[OMP_PREV_LB_VAL]], {{.+}}* [[OMP_PF_LB]],
+ // CHECK-64-DAG: store{{.+}} [[OMP_PREV_UB_TRC]], {{.+}}* [[OMP_PF_UB]],
+ // CHECK-32-DAG: store{{.+}} [[OMP_PREV_UB_VAL]], {{.+}}* [[OMP_PF_UB]],
+ // CHECK: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, {{.+}} 34, {{.+}}, {{.+}}* [[OMP_PF_LB]], {{.+}}* [[OMP_PF_UB]],{{.+}})
+
+ // PrevEUB is only used when 'for' has a chunked schedule, otherwise EUB is used
+ // In this case we use EUB
+ // CHECK-DAG: [[OMP_PF_UB_VAL_1:%.+]] = load{{.+}} [[OMP_PF_UB]],
+ // CHECK: [[PF_NUM_IT_1:%.+]] = load{{.+}},
+ // CHECK-DAG: [[PF_CMP_UB_NUM_IT:%.+]] = icmp{{.+}} [[OMP_PF_UB_VAL_1]], [[PF_NUM_IT_1]]
+ // CHECK: br i1 [[PF_CMP_UB_NUM_IT]], label %[[PF_EUB_TRUE:.+]], label %[[PF_EUB_FALSE:.+]]
+ // CHECK: [[PF_EUB_TRUE]]:
+ // CHECK: [[PF_NUM_IT_2:%.+]] = load{{.+}},
+ // CHECK: br label %[[PF_EUB_END:.+]]
+ // CHECK-DAG: [[PF_EUB_FALSE]]:
+ // CHECK: [[OMP_PF_UB_VAL2:%.+]] = load{{.+}} [[OMP_PF_UB]],
+ // CHECK: br label %[[PF_EUB_END]]
+ // CHECK-DAG: [[PF_EUB_END]]:
+ // CHECK-DAG: [[PF_EUB_RES:%.+]] = phi{{.+}} [ [[PF_NUM_IT_2]], %[[PF_EUB_TRUE]] ], [ [[OMP_PF_UB_VAL2]], %[[PF_EUB_FALSE]] ]
+ // CHECK: store{{.+}} [[PF_EUB_RES]],{{.+}} [[OMP_PF_UB]],
+
+ // initialize omp.iv
+ // CHECK: [[OMP_PF_LB_VAL_1:%.+]] = load{{.+}}, {{.+}} [[OMP_PF_LB]],
+ // CHECK: store {{.+}} [[OMP_PF_LB_VAL_1]], {{.+}}* [[OMP_PF_IV]],
+ // CHECK: br label %[[OMP_PF_JUMP_BACK:.+]]
+
+ // check exit condition
+ // CHECK: [[OMP_PF_JUMP_BACK]]:
+ // CHECK-DAG: [[OMP_PF_IV_VAL_1:%.+]] = load {{.+}} [[OMP_PF_IV]],
+ // CHECK-DAG: [[OMP_PF_UB_VAL_3:%.+]] = load {{.+}} [[OMP_PF_UB]],
+ // CHECK: [[PF_CMP_IV_UB:%.+]] = icmp sle {{.+}} [[OMP_PF_IV_VAL_1]], [[OMP_PF_UB_VAL_3]]
+ // CHECK: br {{.+}} [[PF_CMP_IV_UB]], label %[[PF_BODY:.+]], label %[[PF_END:.+]]
+
+ // check that PrevLB and PrevUB are passed to the 'for'
+ // CHECK: [[PF_BODY]]:
+ // CHECK-DAG: {{.+}} = load{{.+}}, {{.+}}* [[OMP_PF_IV]],
+ // CHECK: br label {{.+}}
+
+ // check stride 1 for 'for' in 'distribute parallel for simd'
+ // CHECK-DAG: [[OMP_PF_IV_VAL_2:%.+]] = load {{.+}}, {{.+}}* [[OMP_PF_IV]],
+ // CHECK: [[OMP_PF_IV_INC:%.+]] = add{{.+}} [[OMP_PF_IV_VAL_2]], 1
+ // CHECK: store{{.+}} [[OMP_PF_IV_INC]], {{.+}}* [[OMP_PF_IV]],
+ // CHECK: br label %[[OMP_PF_JUMP_BACK]]
+
+ // CHECK-DAG: call void @__kmpc_for_static_fini(
+ // CHECK: ret
+ }
+
+ // dist_schedule: static chunk
+ #pragma omp target
+ #pragma omp teams
+ // CHECK: define{{.+}} void [[OFFLOADING_FUN_3]](
+ // CHECK: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, i32 5, {{.+}}* [[OMP_OUTLINED_3:@.+]] to {{.+}})
+
+ #pragma omp distribute parallel for simd dist_schedule(static, ch)
+ for (int i = 0; i < n; ++i) {
+ a[i] = b[i] + c[i];
+ // CHECK: define{{.+}} void [[OMP_OUTLINED_3]](
+ // CHECK-DAG: [[OMP_IV:%.omp.iv]] = alloca
+ // CHECK-DAG: [[OMP_LB:%.omp.comb.lb]] = alloca
+ // CHECK-DAG: [[OMP_UB:%.omp.comb.ub]] = alloca
+ // CHECK-DAG: [[OMP_ST:%.omp.stride]] = alloca
+
+ // unlike the previous tests, in this one we have a outer and inner loop for 'distribute'
+ // CHECK: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 91,
+ // CHECK: br label %[[DIST_OUTER_LOOP_HEADER:.+]]
+
+ // CHECK: [[DIST_OUTER_LOOP_HEADER]]:
+ // check EUB for distribute
+ // CHECK-DAG: [[OMP_UB_VAL_1:%.+]] = load{{.+}} [[OMP_UB]],
+ // CHECK: [[NUM_IT_1:%.+]] = load{{.+}},
+ // CHECK-DAG: [[CMP_UB_NUM_IT:%.+]] = icmp sgt {{.+}} [[OMP_UB_VAL_1]], [[NUM_IT_1]]
+ // CHECK: br {{.+}} [[CMP_UB_NUM_IT]], label %[[EUB_TRUE:.+]], label %[[EUB_FALSE:.+]]
+ // CHECK-DAG: [[EUB_TRUE]]:
+ // CHECK: [[NUM_IT_2:%.+]] = load{{.+}},
+ // CHECK: br label %[[EUB_END:.+]]
+ // CHECK-DAG: [[EUB_FALSE]]:
+ // CHECK: [[OMP_UB_VAL2:%.+]] = load{{.+}} [[OMP_UB]],
+ // CHECK: br label %[[EUB_END]]
+ // CHECK-DAG: [[EUB_END]]:
+ // CHECK-DAG: [[EUB_RES:%.+]] = phi{{.+}} [ [[NUM_IT_2]], %[[EUB_TRUE]] ], [ [[OMP_UB_VAL2]], %[[EUB_FALSE]] ]
+ // CHECK: store{{.+}} [[EUB_RES]], {{.+}}* [[OMP_UB]],
+
+ // initialize omp.iv
+ // CHECK: [[OMP_LB_VAL_1:%.+]] = load{{.+}}, {{.+}}* [[OMP_LB]],
+ // CHECK: store {{.+}} [[OMP_LB_VAL_1]], {{.+}}* [[OMP_IV]],
+
+ // check exit condition
+ // CHECK-DAG: [[OMP_IV_VAL_1:%.+]] = load {{.+}} [[OMP_IV]],
+ // CHECK-DAG: [[OMP_UB_VAL_3:%.+]] = load {{.+}} [[OMP_UB]],
+ // CHECK: [[CMP_IV_UB:%.+]] = icmp sle {{.+}} [[OMP_IV_VAL_1]], [[OMP_UB_VAL_3]]
+ // CHECK: br {{.+}} [[CMP_IV_UB]], label %[[DIST_OUTER_LOOP_BODY:.+]], label %[[DIST_OUTER_LOOP_END:.+]]
+
+ // CHECK: [[DIST_OUTER_LOOP_BODY]]:
+ // CHECK: br label %[[DIST_INNER_LOOP_HEADER:.+]]
+
+ // CHECK: [[DIST_INNER_LOOP_HEADER]]:
+ // CHECK-DAG: [[OMP_IV_VAL_2:%.+]] = load {{.+}} [[OMP_IV]],
+ // CHECK-DAG: [[OMP_UB_VAL_4:%.+]] = load {{.+}} [[OMP_UB]],
+ // CHECK: [[CMP_IV_UB_2:%.+]] = icmp sle {{.+}} [[OMP_IV_VAL_2]], [[OMP_UB_VAL_4]]
+ // CHECK: br{{.+}} [[CMP_IV_UB_2]], label %[[DIST_INNER_LOOP_BODY:.+]], label %[[DIST_INNER_LOOP_END:.+]]
+
+ // check that PrevLB and PrevUB are passed to the 'for'
+ // CHECK: [[DIST_INNER_LOOP_BODY]]:
+ // CHECK-DAG: [[OMP_PREV_LB:%.+]] = load {{.+}}, {{.+}} [[OMP_LB]],
+ // CHECK-64-DAG: [[OMP_PREV_LB_EXT:%.+]] = zext {{.+}} [[OMP_PREV_LB]] to {{.+}}
+ // CHECK-DAG: [[OMP_PREV_UB:%.+]] = load {{.+}}, {{.+}} [[OMP_UB]],
+ // CHECK-64-DAG: [[OMP_PREV_UB_EXT:%.+]] = zext {{.+}} [[OMP_PREV_UB]] to {{.+}}
+ // check that distlb and distub are properly passed to fork_call
+ // CHECK-64: call{{.+}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}}[[OMP_PARFOR_OUTLINED_3:@.+]] to {{.+}}, i{{[0-9]+}} [[OMP_PREV_LB_EXT]], i{{[0-9]+}} [[OMP_PREV_UB_EXT]], {{.+}})
+ // CHECK-32: call{{.+}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}}[[OMP_PARFOR_OUTLINED_3:@.+]] to {{.+}}, i{{[0-9]+}} [[OMP_PREV_LB]], i{{[0-9]+}} [[OMP_PREV_UB]], {{.+}})
+ // CHECK: br label %[[DIST_INNER_LOOP_INC:.+]]
+
+ // check DistInc
+ // CHECK: [[DIST_INNER_LOOP_INC]]:
+ // CHECK-DAG: [[OMP_IV_VAL_3:%.+]] = load {{.+}}, {{.+}}* [[OMP_IV]],
+ // CHECK-DAG: [[OMP_ST_VAL_1:%.+]] = load {{.+}}, {{.+}}* [[OMP_ST]],
+ // CHECK: [[OMP_IV_INC:%.+]] = add{{.+}} [[OMP_IV_VAL_3]], [[OMP_ST_VAL_1]]
+ // CHECK: store{{.+}} [[OMP_IV_INC]], {{.+}}* [[OMP_IV]],
+ // CHECK: br label %[[DIST_INNER_LOOP_HEADER]]
+
+ // CHECK: [[DIST_INNER_LOOP_END]]:
+ // CHECK: br label %[[DIST_OUTER_LOOP_INC:.+]]
+
+ // CHECK: [[DIST_OUTER_LOOP_INC]]:
+ // check NextLB and NextUB
+ // CHECK-DAG: [[OMP_LB_VAL_2:%.+]] = load{{.+}}, {{.+}} [[OMP_LB]],
+ // CHECK-DAG: [[OMP_ST_VAL_2:%.+]] = load{{.+}}, {{.+}} [[OMP_ST]],
+ // CHECK-DAG: [[OMP_LB_NEXT:%.+]] = add{{.+}} [[OMP_LB_VAL_2]], [[OMP_ST_VAL_2]]
+ // CHECK: store{{.+}} [[OMP_LB_NEXT]], {{.+}}* [[OMP_LB]],
+ // CHECK-DAG: [[OMP_UB_VAL_5:%.+]] = load{{.+}}, {{.+}} [[OMP_UB]],
+ // CHECK-DAG: [[OMP_ST_VAL_3:%.+]] = load{{.+}}, {{.+}} [[OMP_ST]],
+ // CHECK-DAG: [[OMP_UB_NEXT:%.+]] = add{{.+}} [[OMP_UB_VAL_5]], [[OMP_ST_VAL_3]]
+ // CHECK: store{{.+}} [[OMP_UB_NEXT]], {{.+}}* [[OMP_UB]],
+ // CHECK: br label %[[DIST_OUTER_LOOP_HEADER]]
+
+ // outer loop exit
+ // CHECK: [[DIST_OUTER_LOOP_END]]:
+ // CHECK-DAG: call void @__kmpc_for_static_fini(
+ // CHECK: ret
+
+ // skip implementation of 'parallel for': using default scheduling and was tested above
+ }
+
+ // schedule: static no chunk
+ #pragma omp target
+ #pragma omp teams
+ // CHECK: define{{.+}} void [[OFFLOADING_FUN_4]](
+ // CHECK: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, i32 4, {{.+}}* [[OMP_OUTLINED_4:@.+]] to {{.+}})
+
+ #pragma omp distribute parallel for simd schedule(static)
+ for (int i = 0; i < n; ++i) {
+ a[i] = b[i] + c[i];
+ // CHECK: define{{.+}} void [[OMP_OUTLINED_4]](
+ // CHECK-DAG: [[OMP_IV:%.omp.iv]] = alloca
+ // CHECK-DAG: [[OMP_LB:%.omp.comb.lb]] = alloca
+ // CHECK-DAG: [[OMP_UB:%.omp.comb.ub]] = alloca
+ // CHECK-DAG: [[OMP_ST:%.omp.stride]] = alloca
+
+ // CHECK: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 92,
+ // CHECK: call{{.+}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}}[[OMP_PARFOR_OUTLINED_4:@.+]] to {{.+}},
+ // skip rest of implementation of 'distribute' as it is tested above for default dist_schedule case
+ // CHECK: ret
+
+ // 'parallel for' implementation is the same as the case without schedule clase (static no chunk is the default)
+ // CHECK: define{{.+}} void [[OMP_PARFOR_OUTLINED_4]]({{.+}}, {{.+}}, i{{[0-9]+}} [[OMP_PREV_LB_IN:%.+]], i{{[0-9]+}} [[OMP_PREV_UB_IN:%.+]], {{.+}}, {{.+}}, {{.+}}, {{.+}})
+
+ // CHECK-DAG: [[OMP_PF_LB:%.omp.lb]] = alloca{{.+}},
+ // CHECK-DAG: [[OMP_PF_UB:%.omp.ub]] = alloca{{.+}},
+ // CHECK-DAG: [[OMP_PF_IV:%.omp.iv]] = alloca{{.+}},
+
+ // initialize lb and ub to PrevLB and PrevUB
+ // CHECK-DAG: store{{.+}} [[OMP_PREV_LB_IN]], {{.+}}* [[PREV_LB_ADDR:%.+]],
+ // CHECK-DAG: store{{.+}} [[OMP_PREV_UB_IN]], {{.+}}* [[PREV_UB_ADDR:%.+]],
+ // CHECK-DAG: [[OMP_PREV_LB_VAL:%.+]] = load{{.+}}, {{.+}}* [[PREV_LB_ADDR]],
+ // CHECK-64-DAG: [[OMP_PREV_LB_TRC:%.+]] = trunc{{.+}} [[OMP_PREV_LB_VAL]] to {{.+}}
+ // CHECK-DAG: [[OMP_PREV_UB_VAL:%.+]] = load{{.+}}, {{.+}}* [[PREV_UB_ADDR]],
+ // CHECK-64-DAG: [[OMP_PREV_UB_TRC:%.+]] = trunc{{.+}} [[OMP_PREV_UB_VAL]] to {{.+}}
+ // CHECK-64-DAG: store{{.+}} [[OMP_PREV_LB_TRC]], {{.+}}* [[OMP_PF_LB]],
+ // CHECK-32-DAG: store{{.+}} [[OMP_PREV_LB_VAL]], {{.+}}* [[OMP_PF_LB]],
+ // CHECK-64-DAG: store{{.+}} [[OMP_PREV_UB_TRC]], {{.+}}* [[OMP_PF_UB]],
+ // CHECK-32-DAG: store{{.+}} [[OMP_PREV_UB_VAL]], {{.+}}* [[OMP_PF_UB]],
+ // CHECK: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, {{.+}} 34, {{.+}}, {{.+}}* [[OMP_PF_LB]], {{.+}}* [[OMP_PF_UB]],{{.+}})
+
+ // PrevEUB is only used when 'for' has a chunked schedule, otherwise EUB is used
+ // In this case we use EUB
+ // CHECK-DAG: [[OMP_PF_UB_VAL_1:%.+]] = load{{.+}} [[OMP_PF_UB]],
+ // CHECK: [[PF_NUM_IT_1:%.+]] = load{{.+}},
+ // CHECK-DAG: [[PF_CMP_UB_NUM_IT:%.+]] = icmp{{.+}} [[OMP_PF_UB_VAL_1]], [[PF_NUM_IT_1]]
+ // CHECK: br i1 [[PF_CMP_UB_NUM_IT]], label %[[PF_EUB_TRUE:.+]], label %[[PF_EUB_FALSE:.+]]
+ // CHECK: [[PF_EUB_TRUE]]:
+ // CHECK: [[PF_NUM_IT_2:%.+]] = load{{.+}},
+ // CHECK: br label %[[PF_EUB_END:.+]]
+ // CHECK-DAG: [[PF_EUB_FALSE]]:
+ // CHECK: [[OMP_PF_UB_VAL2:%.+]] = load{{.+}} [[OMP_PF_UB]],
+ // CHECK: br label %[[PF_EUB_END]]
+ // CHECK-DAG: [[PF_EUB_END]]:
+ // CHECK-DAG: [[PF_EUB_RES:%.+]] = phi{{.+}} [ [[PF_NUM_IT_2]], %[[PF_EUB_TRUE]] ], [ [[OMP_PF_UB_VAL2]], %[[PF_EUB_FALSE]] ]
+ // CHECK: store{{.+}} [[PF_EUB_RES]],{{.+}} [[OMP_PF_UB]],
+
+ // initialize omp.iv
+ // CHECK: [[OMP_PF_LB_VAL_1:%.+]] = load{{.+}}, {{.+}} [[OMP_PF_LB]],
+ // CHECK: store {{.+}} [[OMP_PF_LB_VAL_1]], {{.+}}* [[OMP_PF_IV]],
+ // CHECK: br label %[[OMP_PF_JUMP_BACK:.+]]
+
+ // check exit condition
+ // CHECK: [[OMP_PF_JUMP_BACK]]:
+ // CHECK-DAG: [[OMP_PF_IV_VAL_1:%.+]] = load {{.+}} [[OMP_PF_IV]],
+ // CHECK-DAG: [[OMP_PF_UB_VAL_3:%.+]] = load {{.+}} [[OMP_PF_UB]],
+ // CHECK: [[PF_CMP_IV_UB:%.+]] = icmp sle {{.+}} [[OMP_PF_IV_VAL_1]], [[OMP_PF_UB_VAL_3]]
+ // CHECK: br {{.+}} [[PF_CMP_IV_UB]], label %[[PF_BODY:.+]], label %[[PF_END:.+]]
+
+ // check that PrevLB and PrevUB are passed to the 'for'
+ // CHECK: [[PF_BODY]]:
+ // CHECK-DAG: {{.+}} = load{{.+}}, {{.+}}* [[OMP_PF_IV]],
+ // CHECK: br label {{.+}}
+
+ // check stride 1 for 'for' in 'distribute parallel for simd'
+ // CHECK-DAG: [[OMP_PF_IV_VAL_2:%.+]] = load {{.+}}, {{.+}}* [[OMP_PF_IV]],
+ // CHECK: [[OMP_PF_IV_INC:%.+]] = add{{.+}} [[OMP_PF_IV_VAL_2]], 1
+ // CHECK: store{{.+}} [[OMP_PF_IV_INC]], {{.+}}* [[OMP_PF_IV]],
+ // CHECK: br label %[[OMP_PF_JUMP_BACK]]
+
+ // CHECK-DAG: call void @__kmpc_for_static_fini(
+ // CHECK: ret
+ }
+
+ // schedule: static chunk
+ #pragma omp target
+ #pragma omp teams
+ // CHECK: define{{.+}} void [[OFFLOADING_FUN_5]](
+ // CHECK: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, i32 5, {{.+}}* [[OMP_OUTLINED_5:@.+]] to {{.+}})
+
+ #pragma omp distribute parallel for simd schedule(static, ch)
+ for (int i = 0; i < n; ++i) {
+ a[i] = b[i] + c[i];
+ // CHECK: define{{.+}} void [[OMP_OUTLINED_5]](
+ // CHECK: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 92,
+ // CHECK: call{{.+}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}}[[OMP_PARFOR_OUTLINED_5:@.+]] to {{.+}},
+ // skip rest of implementation of 'distribute' as it is tested above for default dist_schedule case
+ // CHECK: ret
+
+ // 'parallel for' implementation using outer and inner loops and PrevEUB
+ // CHECK: define{{.+}} void [[OMP_PARFOR_OUTLINED_5]]({{.+}}, {{.+}}, i{{[0-9]+}} [[OMP_PREV_LB_IN:%.+]], i{{[0-9]+}} [[OMP_PREV_UB_IN:%.+]], {{.+}}, {{.+}}, {{.+}}, {{.+}}, {{.+}})
+ // CHECK-DAG: [[OMP_PF_LB:%.omp.lb]] = alloca{{.+}},
+ // CHECK-DAG: [[OMP_PF_UB:%.omp.ub]] = alloca{{.+}},
+ // CHECK-DAG: [[OMP_PF_IV:%.omp.iv]] = alloca{{.+}},
+ // CHECK-DAG: [[OMP_PF_ST:%.omp.stride]] = alloca{{.+}},
+
+ // initialize lb and ub to PrevLB and PrevUB
+ // CHECK-DAG: store{{.+}} [[OMP_PREV_LB_IN]], {{.+}}* [[PREV_LB_ADDR:%.+]],
+ // CHECK-DAG: store{{.+}} [[OMP_PREV_UB_IN]], {{.+}}* [[PREV_UB_ADDR:%.+]],
+ // CHECK-DAG: [[OMP_PREV_LB_VAL:%.+]] = load{{.+}}, {{.+}}* [[PREV_LB_ADDR]],
+ // CHECK-64-DAG: [[OMP_PREV_LB_TRC:%.+]] = trunc{{.+}} [[OMP_PREV_LB_VAL]] to {{.+}}
+ // CHECK-DAG: [[OMP_PREV_UB_VAL:%.+]] = load{{.+}}, {{.+}}* [[PREV_UB_ADDR]],
+ // CHECK-64-DAG: [[OMP_PREV_UB_TRC:%.+]] = trunc{{.+}} [[OMP_PREV_UB_VAL]] to {{.+}}
+ // CHECK-64-DAG: store{{.+}} [[OMP_PREV_LB_TRC]], {{.+}}* [[OMP_PF_LB]],
+ // CHECK-32-DAG: store{{.+}} [[OMP_PREV_LB_VAL]], {{.+}}* [[OMP_PF_LB]],
+ // CHECK-64-DAG: store{{.+}} [[OMP_PREV_UB_TRC]], {{.+}}* [[OMP_PF_UB]],
+ // CHECK-32-DAG: store{{.+}} [[OMP_PREV_UB_VAL]], {{.+}}* [[OMP_PF_UB]],
+ // CHECK: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, {{.+}} 33, {{.+}}, {{.+}}* [[OMP_PF_LB]], {{.+}}* [[OMP_PF_UB]],{{.+}})
+ // CHECK: br label %[[OMP_PF_OUTER_LOOP_HEADER:.+]]
+
+ // check PrevEUB (using PrevUB instead of NumIt as upper bound)
+ // CHECK: [[OMP_PF_OUTER_LOOP_HEADER]]:
+ // CHECK-DAG: [[OMP_PF_UB_VAL_1:%.+]] = load{{.+}} [[OMP_PF_UB]],
+ // CHECK-64-DAG: [[OMP_PF_UB_VAL_CONV:%.+]] = sext{{.+}} [[OMP_PF_UB_VAL_1]] to
+ // CHECK: [[PF_PREV_UB_VAL_1:%.+]] = load{{.+}}, {{.+}}* [[PREV_UB_ADDR]],
+ // CHECK-64-DAG: [[PF_CMP_UB_NUM_IT:%.+]] = icmp{{.+}} [[OMP_PF_UB_VAL_CONV]], [[PF_PREV_UB_VAL_1]]
+ // CHECK-32-DAG: [[PF_CMP_UB_NUM_IT:%.+]] = icmp{{.+}} [[OMP_PF_UB_VAL_1]], [[PF_PREV_UB_VAL_1]]
+ // CHECK: br i1 [[PF_CMP_UB_NUM_IT]], label %[[PF_EUB_TRUE:.+]], label %[[PF_EUB_FALSE:.+]]
+ // CHECK: [[PF_EUB_TRUE]]:
+ // CHECK: [[PF_PREV_UB_VAL_2:%.+]] = load{{.+}}, {{.+}}* [[PREV_UB_ADDR]],
+ // CHECK: br label %[[PF_EUB_END:.+]]
+ // CHECK-DAG: [[PF_EUB_FALSE]]:
+ // CHECK: [[OMP_PF_UB_VAL_2:%.+]] = load{{.+}} [[OMP_PF_UB]],
+ // CHECK-64: [[OMP_PF_UB_VAL_2_CONV:%.+]] = sext{{.+}} [[OMP_PF_UB_VAL_2]] to
+ // CHECK: br label %[[PF_EUB_END]]
+ // CHECK-DAG: [[PF_EUB_END]]:
+ // CHECK-64-DAG: [[PF_EUB_RES:%.+]] = phi{{.+}} [ [[PF_PREV_UB_VAL_2]], %[[PF_EUB_TRUE]] ], [ [[OMP_PF_UB_VAL_2_CONV]], %[[PF_EUB_FALSE]] ]
+ // CHECK-32-DAG: [[PF_EUB_RES:%.+]] = phi{{.+}} [ [[PF_PREV_UB_VAL_2]], %[[PF_EUB_TRUE]] ], [ [[OMP_PF_UB_VAL_2]], %[[PF_EUB_FALSE]] ]
+ // CHECK-64-DAG: [[PF_EUB_RES_CONV:%.+]] = trunc{{.+}} [[PF_EUB_RES]] to
+ // CHECK-64: store{{.+}} [[PF_EUB_RES_CONV]],{{.+}} [[OMP_PF_UB]],
+ // CHECK-32: store{{.+}} [[PF_EUB_RES]], {{.+}} [[OMP_PF_UB]],
+
+ // initialize omp.iv (IV = LB)
+ // CHECK: [[OMP_PF_LB_VAL_1:%.+]] = load{{.+}}, {{.+}} [[OMP_PF_LB]],
+ // CHECK: store {{.+}} [[OMP_PF_LB_VAL_1]], {{.+}}* [[OMP_PF_IV]],
+
+ // outer loop: while (IV < UB) {
+ // CHECK-DAG: [[OMP_PF_IV_VAL_1:%.+]] = load{{.+}}, {{.+}}* [[OMP_PF_IV]],
+ // CHECK-DAG: [[OMP_PF_UB_VAL_3:%.+]] = load{{.+}}, {{.+}}* [[OMP_PF_UB]],
+ // CHECK: [[PF_CMP_IV_UB_1:%.+]] = icmp{{.+}} [[OMP_PF_IV_VAL_1]], [[OMP_PF_UB_VAL_3]]
+ // CHECK: br{{.+}} [[PF_CMP_IV_UB_1]], label %[[OMP_PF_OUTER_LOOP_BODY:.+]], label %[[OMP_PF_OUTER_LOOP_END:.+]]
+
+ // CHECK: [[OMP_PF_OUTER_LOOP_BODY]]:
+ // CHECK: br label %[[OMP_PF_INNER_FOR_HEADER:.+]]
+
+ // CHECK: [[OMP_PF_INNER_FOR_HEADER]]:
+ // CHECK-DAG: [[OMP_PF_IV_VAL_2:%.+]] = load{{.+}}, {{.+}}* [[OMP_PF_IV]],
+ // CHECK-DAG: [[OMP_PF_UB_VAL_4:%.+]] = load{{.+}}, {{.+}}* [[OMP_PF_UB]],
+ // CHECK: [[PF_CMP_IV_UB_2:%.+]] = icmp{{.+}} [[OMP_PF_IV_VAL_2]], [[OMP_PF_UB_VAL_4]]
+ // CHECK: br{{.+}} [[PF_CMP_IV_UB_2]], label %[[OMP_PF_INNER_LOOP_BODY:.+]], label %[[OMP_PF_INNER_LOOP_END:.+]]
+
+ // CHECK: [[OMP_PF_INNER_LOOP_BODY]]:
+ // CHECK-DAG: {{.+}} = load{{.+}}, {{.+}}* [[OMP_PF_IV]],
+ // skip body branch
+ // CHECK: br{{.+}}
+ // CHECK: br label %[[OMP_PF_INNER_LOOP_INC:.+]]
+
+ // IV = IV + 1 and inner loop latch
+ // CHECK: [[OMP_PF_INNER_LOOP_INC]]:
+ // CHECK-DAG: [[OMP_PF_IV_VAL_3:%.+]] = load{{.+}}, {{.+}}* [[OMP_IV]],
+ // CHECK-DAG: [[OMP_PF_NEXT_IV:%.+]] = add{{.+}} [[OMP_PF_IV_VAL_3]], 1
+ // CHECK-DAG: store{{.+}} [[OMP_PF_NEXT_IV]], {{.+}}* [[OMP_IV]],
+ // CHECK: br label %[[OMP_PF_INNER_FOR_HEADER]]
+
+ // check NextLB and NextUB
+ // CHECK: [[OMP_PF_INNER_LOOP_END]]:
+ // CHECK: br label %[[OMP_PF_OUTER_LOOP_INC:.+]]
+
+ // CHECK: [[OMP_PF_OUTER_LOOP_INC]]:
+ // CHECK-DAG: [[OMP_PF_LB_VAL_2:%.+]] = load{{.+}}, {{.+}} [[OMP_PF_LB]],
+ // CHECK-DAG: [[OMP_PF_ST_VAL_1:%.+]] = load{{.+}}, {{.+}} [[OMP_PF_ST]],
+ // CHECK-DAG: [[OMP_PF_LB_NEXT:%.+]] = add{{.+}} [[OMP_PF_LB_VAL_2]], [[OMP_PF_ST_VAL_1]]
+ // CHECK: store{{.+}} [[OMP_PF_LB_NEXT]], {{.+}}* [[OMP_PF_LB]],
+ // CHECK-DAG: [[OMP_PF_UB_VAL_5:%.+]] = load{{.+}}, {{.+}} [[OMP_PF_UB]],
+ // CHECK-DAG: [[OMP_PF_ST_VAL_2:%.+]] = load{{.+}}, {{.+}} [[OMP_PF_ST]],
+ // CHECK-DAG: [[OMP_PF_UB_NEXT:%.+]] = add{{.+}} [[OMP_PF_UB_VAL_5]], [[OMP_PF_ST_VAL_2]]
+ // CHECK: store{{.+}} [[OMP_PF_UB_NEXT]], {{.+}}* [[OMP_PF_UB]],
+ // CHECK: br label %[[OMP_PF_OUTER_LOOP_HEADER]]
+
+ // CHECK: [[OMP_PF_OUTER_LOOP_END]]:
+ // CHECK-DAG: call void @__kmpc_for_static_fini(
+ // CHECK: ret
+ }
+
+ // schedule: dynamic no chunk
+ #pragma omp target
+ #pragma omp teams
+ // CHECK: define{{.+}} void [[OFFLOADING_FUN_6]](
+ // CHECK: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, i32 4, {{.+}}* [[OMP_OUTLINED_6:@.+]] to {{.+}})
+
+ #pragma omp distribute parallel for simd schedule(dynamic)
+ for (int i = 0; i < n; ++i) {
+ a[i] = b[i] + c[i];
+ // CHECK: define{{.+}} void [[OMP_OUTLINED_6]](
+ // CHECK: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 92,
+ // CHECK: call{{.+}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}}[[OMP_PARFOR_OUTLINED_6:@.+]] to {{.+}},
+ // skip rest of implementation of 'distribute' as it is tested above for default dist_schedule case
+ // CHECK: ret
+
+ // 'parallel for' implementation using outer and inner loops and PrevEUB
+ // CHECK: define{{.+}} void [[OMP_PARFOR_OUTLINED_6]]({{.+}}, {{.+}}, i{{[0-9]+}} [[OMP_PREV_LB_IN:%.+]], i{{[0-9]+}} [[OMP_PREV_UB_IN:%.+]], {{.+}}, {{.+}}, {{.+}}, {{.+}})
+ // CHECK-DAG: [[OMP_PF_LB:%.omp.lb]] = alloca{{.+}},
+ // CHECK-DAG: [[OMP_PF_UB:%.omp.ub]] = alloca{{.+}},
+ // CHECK-DAG: [[OMP_PF_IV:%.omp.iv]] = alloca{{.+}},
+ // CHECK-DAG: [[OMP_PF_ST:%.omp.stride]] = alloca{{.+}},
+
+ // initialize lb and ub to PrevLB and PrevUB
+ // CHECK-DAG: store{{.+}} [[OMP_PREV_LB_IN]], {{.+}}* [[PREV_LB_ADDR:%.+]],
+ // CHECK-DAG: store{{.+}} [[OMP_PREV_UB_IN]], {{.+}}* [[PREV_UB_ADDR:%.+]],
+ // CHECK-DAG: [[OMP_PREV_LB_VAL:%.+]] = load{{.+}}, {{.+}}* [[PREV_LB_ADDR]],
+ // CHECK-64-DAG: [[OMP_PREV_LB_TRC:%.+]] = trunc{{.+}} [[OMP_PREV_LB_VAL]] to {{.+}}
+ // CHECK-DAG: [[OMP_PREV_UB_VAL:%.+]] = load{{.+}}, {{.+}}* [[PREV_UB_ADDR]],
+ // CHECK-64-DAG: [[OMP_PREV_UB_TRC:%.+]] = trunc{{.+}} [[OMP_PREV_UB_VAL]] to {{.+}}
+ // CHECK-64-DAG: store{{.+}} [[OMP_PREV_LB_TRC]], {{.+}}* [[OMP_PF_LB]],
+ // CHECK-64-DAG: store{{.+}} [[OMP_PREV_UB_TRC]], {{.+}}* [[OMP_PF_UB]],
+ // CHECK-32-DAG: store{{.+}} [[OMP_PREV_LB_VAL]], {{.+}}* [[OMP_PF_LB]],
+ // CHECK-32-DAG: store{{.+}} [[OMP_PREV_UB_VAL]], {{.+}}* [[OMP_PF_UB]],
+ // CHECK-DAG: [[OMP_PF_LB_VAL:%.+]] = load{{.+}}, {{.+}} [[OMP_PF_LB]],
+ // CHECK-DAG: [[OMP_PF_UB_VAL:%.+]] = load{{.+}}, {{.+}} [[OMP_PF_UB]],
+ // CHECK: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, {{.+}} 35, {{.+}} [[OMP_PF_LB_VAL]], {{.+}} [[OMP_PF_UB_VAL]], {{.+}}, {{.+}})
+ // CHECK: br label %[[OMP_PF_OUTER_LOOP_HEADER:.+]]
+
+ // CHECK: [[OMP_PF_OUTER_LOOP_HEADER]]:
+ // CHECK: [[IS_FIN:%.+]] = call{{.+}} @__kmpc_dispatch_next_4({{.+}}, {{.+}}, {{.+}}, {{.+}}* [[OMP_PF_LB]], {{.+}}* [[OMP_PF_UB]], {{.+}}* [[OMP_PF_ST]])
+ // CHECK: [[IS_FIN_CMP:%.+]] = icmp{{.+}} [[IS_FIN]], 0
+ // CHECK: br{{.+}} [[IS_FIN_CMP]], label %[[OMP_PF_OUTER_LOOP_BODY:.+]], label %[[OMP_PF_OUTER_LOOP_END:.+]]
+
+ // initialize omp.iv (IV = LB)
+ // CHECK: [[OMP_PF_OUTER_LOOP_BODY]]:
+ // CHECK-DAG: [[OMP_PF_LB_VAL_1:%.+]] = load{{.+}}, {{.+}} [[OMP_PF_LB]],
+ // CHECK-DAG: store {{.+}} [[OMP_PF_LB_VAL_1]], {{.+}}* [[OMP_PF_IV]],
+ // CHECK: br label %[[OMP_PF_INNER_LOOP_HEADER:.+]]
+
+ // CHECK: [[OMP_PF_INNER_LOOP_HEADER]]:
+ // CHECK-DAG: [[OMP_PF_IV_VAL_2:%.+]] = load{{.+}}, {{.+}}* [[OMP_PF_IV]],
+ // CHECK-DAG: [[OMP_PF_UB_VAL_4:%.+]] = load{{.+}}, {{.+}}* [[OMP_PF_UB]],
+ // CHECK: [[PF_CMP_IV_UB_2:%.+]] = icmp{{.+}} [[OMP_PF_IV_VAL_2]], [[OMP_PF_UB_VAL_4]]
+ // CHECK: br{{.+}} [[PF_CMP_IV_UB_2]], label %[[OMP_PF_INNER_LOOP_BODY:.+]], label %[[OMP_PF_INNER_LOOP_END:.+]]
+
+ // CHECK: [[OMP_PF_INNER_LOOP_BODY]]:
+ // CHECK-DAG: {{.+}} = load{{.+}}, {{.+}}* [[OMP_PF_IV]],
+ // skip body branch
+ // CHECK: br{{.+}}
+ // CHECK: br label %[[OMP_PF_INNER_LOOP_INC:.+]]
+
+ // IV = IV + 1 and inner loop latch
+ // CHECK: [[OMP_PF_INNER_LOOP_INC]]:
+ // CHECK-DAG: [[OMP_PF_IV_VAL_3:%.+]] = load{{.+}}, {{.+}}* [[OMP_IV]],
+ // CHECK-DAG: [[OMP_PF_NEXT_IV:%.+]] = add{{.+}} [[OMP_PF_IV_VAL_3]], 1
+ // CHECK-DAG: store{{.+}} [[OMP_PF_NEXT_IV]], {{.+}}* [[OMP_IV]],
+ // CHECK: br label %[[OMP_PF_INNER_LOOP_HEADER]]
+
+ // check NextLB and NextUB
+ // CHECK: [[OMP_PF_INNER_LOOP_END]]:
+ // CHECK: br label %[[OMP_PF_OUTER_LOOP_INC:.+]]
+
+ // CHECK: [[OMP_PF_OUTER_LOOP_INC]]:
+ // CHECK: br label %[[OMP_PF_OUTER_LOOP_HEADER]]
+
+ // CHECK: [[OMP_PF_OUTER_LOOP_END]]:
+ // CHECK: ret
+ }
+
+ // schedule: dynamic chunk
+ #pragma omp target
+ #pragma omp teams
+ // CHECK: define{{.+}} void [[OFFLOADING_FUN_7]](
+ // CHECK: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, i32 5, {{.+}}* [[OMP_OUTLINED_7:@.+]] to {{.+}})
+
+ #pragma omp distribute parallel for simd schedule(dynamic, ch)
+ for (int i = 0; i < n; ++i) {
+ a[i] = b[i] + c[i];
+ // CHECK: define{{.+}} void [[OMP_OUTLINED_7]](
+ // CHECK: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 92,
+ // CHECK: call{{.+}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}}[[OMP_PARFOR_OUTLINED_7:@.+]] to {{.+}},
+ // skip rest of implementation of 'distribute' as it is tested above for default dist_schedule case
+ // CHECK: ret
+
+ // 'parallel for' implementation using outer and inner loops and PrevEUB
+ // CHECK: define{{.+}} void [[OMP_PARFOR_OUTLINED_7]]({{.+}}, {{.+}}, i{{[0-9]+}} [[OMP_PREV_LB_IN:%.+]], i{{[0-9]+}} [[OMP_PREV_UB_IN:%.+]], {{.+}}, {{.+}}, {{.+}}, {{.+}}, {{.+}})
+ // CHECK-DAG: [[OMP_PF_LB:%.omp.lb]] = alloca{{.+}},
+ // CHECK-DAG: [[OMP_PF_UB:%.omp.ub]] = alloca{{.+}},
+ // CHECK-DAG: [[OMP_PF_IV:%.omp.iv]] = alloca{{.+}},
+ // CHECK-DAG: [[OMP_PF_ST:%.omp.stride]] = alloca{{.+}},
+
+ // initialize lb and ub to PrevLB and PrevUB
+ // CHECK-DAG: store{{.+}} [[OMP_PREV_LB_IN]], {{.+}}* [[PREV_LB_ADDR:%.+]],
+ // CHECK-DAG: store{{.+}} [[OMP_PREV_UB_IN]], {{.+}}* [[PREV_UB_ADDR:%.+]],
+ // CHECK-DAG: [[OMP_PREV_LB_VAL:%.+]] = load{{.+}}, {{.+}}* [[PREV_LB_ADDR]],
+ // CHECK-64-DAG: [[OMP_PREV_LB_TRC:%.+]] = trunc{{.+}} [[OMP_PREV_LB_VAL]] to {{.+}}
+ // CHECK-DAG: [[OMP_PREV_UB_VAL:%.+]] = load{{.+}}, {{.+}}* [[PREV_UB_ADDR]],
+ // CHECK-64-DAG: [[OMP_PREV_UB_TRC:%.+]] = trunc{{.+}} [[OMP_PREV_UB_VAL]] to {{.+}}
+ // CHECK-64-DAG: store{{.+}} [[OMP_PREV_LB_TRC]], {{.+}}* [[OMP_PF_LB]],
+ // CHECK-64-DAG: store{{.+}} [[OMP_PREV_UB_TRC]], {{.+}}* [[OMP_PF_UB]],
+ // CHECK-32-DAG: store{{.+}} [[OMP_PREV_LB_VAL]], {{.+}}* [[OMP_PF_LB]],
+ // CHECK-32-DAG: store{{.+}} [[OMP_PREV_UB_VAL]], {{.+}}* [[OMP_PF_UB]],
+ // CHECK-DAG: [[OMP_PF_LB_VAL:%.+]] = load{{.+}}, {{.+}} [[OMP_PF_LB]],
+ // CHECK-DAG: [[OMP_PF_UB_VAL:%.+]] = load{{.+}}, {{.+}} [[OMP_PF_UB]],
+ // CHECK: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, {{.+}} 35, {{.+}} [[OMP_PF_LB_VAL]], {{.+}} [[OMP_PF_UB_VAL]], {{.+}}, {{.+}})
+ // CHECK: br label %[[OMP_PF_OUTER_LOOP_HEADER:.+]]
+
+ // CHECK: [[OMP_PF_OUTER_LOOP_HEADER]]:
+ // CHECK: [[IS_FIN:%.+]] = call{{.+}} @__kmpc_dispatch_next_4({{.+}}, {{.+}}, {{.+}}, {{.+}}* [[OMP_PF_LB]], {{.+}}* [[OMP_PF_UB]], {{.+}}* [[OMP_PF_ST]])
+ // CHECK: [[IS_FIN_CMP:%.+]] = icmp{{.+}} [[IS_FIN]], 0
+ // CHECK: br{{.+}} [[IS_FIN_CMP]], label %[[OMP_PF_OUTER_LOOP_BODY:.+]], label %[[OMP_PF_OUTER_LOOP_END:.+]]
+
+ // initialize omp.iv (IV = LB)
+ // CHECK: [[OMP_PF_OUTER_LOOP_BODY]]:
+ // CHECK-DAG: [[OMP_PF_LB_VAL_1:%.+]] = load{{.+}}, {{.+}} [[OMP_PF_LB]],
+ // CHECK-DAG: store {{.+}} [[OMP_PF_LB_VAL_1]], {{.+}}* [[OMP_PF_IV]],
+ // CHECK: br label %[[OMP_PF_INNER_LOOP_HEADER:.+]]
+
+ // CHECK: [[OMP_PF_INNER_LOOP_HEADER]]:
+ // CHECK-DAG: [[OMP_PF_IV_VAL_2:%.+]] = load{{.+}}, {{.+}}* [[OMP_PF_IV]],
+ // CHECK-DAG: [[OMP_PF_UB_VAL_4:%.+]] = load{{.+}}, {{.+}}* [[OMP_PF_UB]],
+ // CHECK: [[PF_CMP_IV_UB_2:%.+]] = icmp{{.+}} [[OMP_PF_IV_VAL_2]], [[OMP_PF_UB_VAL_4]]
+ // CHECK: br{{.+}} [[PF_CMP_IV_UB_2]], label %[[OMP_PF_INNER_LOOP_BODY:.+]], label %[[OMP_PF_INNER_LOOP_END:.+]]
+
+ // CHECK: [[OMP_PF_INNER_LOOP_BODY]]:
+ // CHECK-DAG: {{.+}} = load{{.+}}, {{.+}}* [[OMP_PF_IV]],
+ // skip body branch
+ // CHECK: br{{.+}}
+ // CHECK: br label %[[OMP_PF_INNER_LOOP_INC:.+]]
+
+ // IV = IV + 1 and inner loop latch
+ // CHECK: [[OMP_PF_INNER_LOOP_INC]]:
+ // CHECK-DAG: [[OMP_PF_IV_VAL_3:%.+]] = load{{.+}}, {{.+}}* [[OMP_IV]],
+ // CHECK-DAG: [[OMP_PF_NEXT_IV:%.+]] = add{{.+}} [[OMP_PF_IV_VAL_3]], 1
+ // CHECK-DAG: store{{.+}} [[OMP_PF_NEXT_IV]], {{.+}}* [[OMP_IV]],
+ // CHECK: br label %[[OMP_PF_INNER_LOOP_HEADER]]
+
+ // check NextLB and NextUB
+ // CHECK: [[OMP_PF_INNER_LOOP_END]]:
+ // CHECK: br label %[[OMP_PF_OUTER_LOOP_INC:.+]]
+
+ // CHECK: [[OMP_PF_OUTER_LOOP_INC]]:
+ // CHECK: br label %[[OMP_PF_OUTER_LOOP_HEADER]]
+
+ // CHECK: [[OMP_PF_OUTER_LOOP_END]]:
+ // CHECK: ret
+ }
+
+ return tmain<int>();
+#endif
+}
+
+// check code
+// CHECK: define{{.+}} [[TMAIN]]()
+
+// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+// CHECK: call void [[OFFLOADING_FUN_1:@.+]](
+
+// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+// CHECK: call void [[OFFLOADING_FUN_2:@.+]](
+
+// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+// CHECK: call void [[OFFLOADING_FUN_3:@.+]](
+
+// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+// CHECK: call void [[OFFLOADING_FUN_4:@.+]](
+
+// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+// CHECK: call void [[OFFLOADING_FUN_5:@.+]](
+
+// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+// CHECK: call void [[OFFLOADING_FUN_6:@.+]](
+
+// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+// CHECK: call void [[OFFLOADING_FUN_7:@.+]](
+
+// CHECK: define{{.+}} void [[OFFLOADING_FUN_1]](
+// CHECK: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, i32 4, {{.+}}* [[OMP_OUTLINED_1:@.+]] to {{.+}})
+
+// CHECK: define{{.+}} void [[OMP_OUTLINED_1]](
+// CHECK-DAG: [[OMP_IV:%.omp.iv]] = alloca
+// CHECK-DAG: [[OMP_LB:%.omp.comb.lb]] = alloca
+// CHECK-DAG: [[OMP_UB:%.omp.comb.ub]] = alloca
+// CHECK-DAG: [[OMP_ST:%.omp.stride]] = alloca
+
+// CHECK: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 92,
+
+// check EUB for distribute
+// CHECK-DAG: [[OMP_UB_VAL_1:%.+]] = load{{.+}} [[OMP_UB]],
+// CHECK: [[NUM_IT_1:%.+]] = load{{.+}},
+// CHECK-DAG: [[CMP_UB_NUM_IT:%.+]] = icmp sgt {{.+}} [[OMP_UB_VAL_1]], [[NUM_IT_1]]
+// CHECK: br {{.+}} [[CMP_UB_NUM_IT]], label %[[EUB_TRUE:.+]], label %[[EUB_FALSE:.+]]
+// CHECK-DAG: [[EUB_TRUE]]:
+// CHECK: [[NUM_IT_2:%.+]] = load{{.+}},
+// CHECK: br label %[[EUB_END:.+]]
+// CHECK-DAG: [[EUB_FALSE]]:
+// CHECK: [[OMP_UB_VAL2:%.+]] = load{{.+}} [[OMP_UB]],
+// CHECK: br label %[[EUB_END]]
+// CHECK-DAG: [[EUB_END]]:
+// CHECK-DAG: [[EUB_RES:%.+]] = phi{{.+}} [ [[NUM_IT_2]], %[[EUB_TRUE]] ], [ [[OMP_UB_VAL2]], %[[EUB_FALSE]] ]
+// CHECK: store{{.+}} [[EUB_RES]], {{.+}}* [[OMP_UB]],
+
+// initialize omp.iv
+// CHECK: [[OMP_LB_VAL_1:%.+]] = load{{.+}}, {{.+}}* [[OMP_LB]],
+// CHECK: store {{.+}} [[OMP_LB_VAL_1]], {{.+}}* [[OMP_IV]],
+// CHECK: br label %[[OMP_JUMP_BACK:.+]]
+
+// check exit condition
+// CHECK: [[OMP_JUMP_BACK]]:
+// CHECK-DAG: [[OMP_IV_VAL_1:%.+]] = load {{.+}} [[OMP_IV]],
+// CHECK-DAG: [[OMP_UB_VAL_3:%.+]] = load {{.+}} [[OMP_UB]],
+// CHECK: [[CMP_IV_UB:%.+]] = icmp sle {{.+}} [[OMP_IV_VAL_1]], [[OMP_UB_VAL_3]]
+// CHECK: br {{.+}} [[CMP_IV_UB]], label %[[DIST_BODY:.+]], label %[[DIST_END:.+]]
+
+// check that PrevLB and PrevUB are passed to the 'for'
+// CHECK: [[DIST_BODY]]:
+// CHECK-DAG: [[OMP_PREV_LB:%.+]] = load {{.+}}, {{.+}} [[OMP_LB]],
+// CHECK-64-DAG: [[OMP_PREV_LB_EXT:%.+]] = zext {{.+}} [[OMP_PREV_LB]] to {{.+}}
+// CHECK-DAG: [[OMP_PREV_UB:%.+]] = load {{.+}}, {{.+}} [[OMP_UB]],
+// CHECK-64-DAG: [[OMP_PREV_UB_EXT:%.+]] = zext {{.+}} [[OMP_PREV_UB]] to {{.+}}
+// check that distlb and distub are properly passed to fork_call
+// CHECK-64: call{{.+}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}}[[OMP_PARFOR_OUTLINED_1:@.+]] to {{.+}}, i{{[0-9]+}} [[OMP_PREV_LB_EXT]], i{{[0-9]+}} [[OMP_PREV_UB_EXT]], {{.+}})
+// CHECK-32: call{{.+}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}}[[OMP_PARFOR_OUTLINED_1:@.+]] to {{.+}}, i{{[0-9]+}} [[OMP_PREV_LB]], i{{[0-9]+}} [[OMP_PREV_UB]], {{.+}})
+// CHECK: br label %[[DIST_INC:.+]]
+
+// increment by stride (distInc - 'parallel for' executes the whole chunk) and latch
+// CHECK: [[DIST_INC]]:
+// CHECK-DAG: [[OMP_IV_VAL_2:%.+]] = load {{.+}}, {{.+}}* [[OMP_IV]],
+// CHECK-DAG: [[OMP_ST_VAL_1:%.+]] = load {{.+}}, {{.+}}* [[OMP_ST]],
+// CHECK: [[OMP_IV_INC:%.+]] = add{{.+}} [[OMP_IV_VAL_2]], [[OMP_ST_VAL_1]]
+// CHECK: store{{.+}} [[OMP_IV_INC]], {{.+}}* [[OMP_IV]],
+// CHECK: br label %[[OMP_JUMP_BACK]]
+
+// CHECK-DAG: call void @__kmpc_for_static_fini(
+// CHECK: ret
+
+// implementation of 'parallel for'
+// CHECK: define{{.+}} void [[OMP_PARFOR_OUTLINED_1]]({{.+}}, {{.+}}, i{{[0-9]+}} [[OMP_PREV_LB_IN:%.+]], i{{[0-9]+}} [[OMP_PREV_UB_IN:%.+]], {{.+}}, {{.+}}, {{.+}}, {{.+}})
+
+// CHECK-DAG: [[OMP_PF_LB:%.omp.lb]] = alloca{{.+}},
+// CHECK-DAG: [[OMP_PF_UB:%.omp.ub]] = alloca{{.+}},
+// CHECK-DAG: [[OMP_PF_IV:%.omp.iv]] = alloca{{.+}},
+
+// initialize lb and ub to PrevLB and PrevUB
+// CHECK-DAG: store{{.+}} [[OMP_PREV_LB_IN]], {{.+}}* [[PREV_LB_ADDR:%.+]],
+// CHECK-DAG: store{{.+}} [[OMP_PREV_UB_IN]], {{.+}}* [[PREV_UB_ADDR:%.+]],
+// CHECK-DAG: [[OMP_PREV_LB_VAL:%.+]] = load{{.+}}, {{.+}}* [[PREV_LB_ADDR]],
+// CHECK-64-DAG: [[OMP_PREV_LB_TRC:%.+]] = trunc{{.+}} [[OMP_PREV_LB_VAL]] to {{.+}}
+// CHECK-DAG: [[OMP_PREV_UB_VAL:%.+]] = load{{.+}}, {{.+}}* [[PREV_UB_ADDR]],
+// CHECK-64-DAG: [[OMP_PREV_UB_TRC:%.+]] = trunc{{.+}} [[OMP_PREV_UB_VAL]] to {{.+}}
+// CHECK-64-DAG: store{{.+}} [[OMP_PREV_LB_TRC]], {{.+}}* [[OMP_PF_LB]],
+// CHECK-32-DAG: store{{.+}} [[OMP_PREV_LB_VAL]], {{.+}}* [[OMP_PF_LB]],
+// CHECK-64-DAG: store{{.+}} [[OMP_PREV_UB_TRC]], {{.+}}* [[OMP_PF_UB]],
+// CHECK-32-DAG: store{{.+}} [[OMP_PREV_UB_VAL]], {{.+}}* [[OMP_PF_UB]],
+// CHECK: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, {{.+}} 34, {{.+}}, {{.+}}* [[OMP_PF_LB]], {{.+}}* [[OMP_PF_UB]],{{.+}})
+
+// PrevEUB is only used when 'for' has a chunked schedule, otherwise EUB is used
+// In this case we use EUB
+// CHECK-DAG: [[OMP_PF_UB_VAL_1:%.+]] = load{{.+}} [[OMP_PF_UB]],
+// CHECK: [[PF_NUM_IT_1:%.+]] = load{{.+}},
+// CHECK-DAG: [[PF_CMP_UB_NUM_IT:%.+]] = icmp{{.+}} [[OMP_PF_UB_VAL_1]], [[PF_NUM_IT_1]]
+// CHECK: br i1 [[PF_CMP_UB_NUM_IT]], label %[[PF_EUB_TRUE:.+]], label %[[PF_EUB_FALSE:.+]]
+// CHECK: [[PF_EUB_TRUE]]:
+// CHECK: [[PF_NUM_IT_2:%.+]] = load{{.+}},
+// CHECK: br label %[[PF_EUB_END:.+]]
+// CHECK-DAG: [[PF_EUB_FALSE]]:
+// CHECK: [[OMP_PF_UB_VAL2:%.+]] = load{{.+}} [[OMP_PF_UB]],
+// CHECK: br label %[[PF_EUB_END]]
+// CHECK-DAG: [[PF_EUB_END]]:
+// CHECK-DAG: [[PF_EUB_RES:%.+]] = phi{{.+}} [ [[PF_NUM_IT_2]], %[[PF_EUB_TRUE]] ], [ [[OMP_PF_UB_VAL2]], %[[PF_EUB_FALSE]] ]
+// CHECK: store{{.+}} [[PF_EUB_RES]],{{.+}} [[OMP_PF_UB]],
+
+// initialize omp.iv
+// CHECK: [[OMP_PF_LB_VAL_1:%.+]] = load{{.+}}, {{.+}} [[OMP_PF_LB]],
+// CHECK: store {{.+}} [[OMP_PF_LB_VAL_1]], {{.+}}* [[OMP_PF_IV]],
+// CHECK: br label %[[OMP_PF_JUMP_BACK:.+]]
+
+// check exit condition
+// CHECK: [[OMP_PF_JUMP_BACK]]:
+// CHECK-DAG: [[OMP_PF_IV_VAL_1:%.+]] = load {{.+}} [[OMP_PF_IV]],
+// CHECK-DAG: [[OMP_PF_UB_VAL_3:%.+]] = load {{.+}} [[OMP_PF_UB]],
+// CHECK: [[PF_CMP_IV_UB:%.+]] = icmp sle {{.+}} [[OMP_PF_IV_VAL_1]], [[OMP_PF_UB_VAL_3]]
+// CHECK: br {{.+}} [[PF_CMP_IV_UB]], label %[[PF_BODY:.+]], label %[[PF_END:.+]]
+
+// check that PrevLB and PrevUB are passed to the 'for'
+// CHECK: [[PF_BODY]]:
+// CHECK-DAG: {{.+}} = load{{.+}}, {{.+}}* [[OMP_PF_IV]],
+// CHECK: br label {{.+}}
+
+// check stride 1 for 'for' in 'distribute parallel for simd'
+// CHECK-DAG: [[OMP_PF_IV_VAL_2:%.+]] = load {{.+}}, {{.+}}* [[OMP_PF_IV]],
+// CHECK: [[OMP_PF_IV_INC:%.+]] = add{{.+}} [[OMP_PF_IV_VAL_2]], 1
+// CHECK: store{{.+}} [[OMP_PF_IV_INC]], {{.+}}* [[OMP_PF_IV]],
+// CHECK: br label %[[OMP_PF_JUMP_BACK]]
+
+// CHECK-DAG: call void @__kmpc_for_static_fini(
+// CHECK: ret
+
+// CHECK: define{{.+}} void [[OFFLOADING_FUN_2]](
+// CHECK: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, i32 4, {{.+}}* [[OMP_OUTLINED_2:@.+]] to {{.+}})
+
+// CHECK: define{{.+}} void [[OMP_OUTLINED_2]](
+// CHECK-DAG: [[OMP_IV:%.omp.iv]] = alloca
+// CHECK-DAG: [[OMP_LB:%.omp.comb.lb]] = alloca
+// CHECK-DAG: [[OMP_UB:%.omp.comb.ub]] = alloca
+// CHECK-DAG: [[OMP_ST:%.omp.stride]] = alloca
+
+// CHECK: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 92,
+
+// check EUB for distribute
+// CHECK-DAG: [[OMP_UB_VAL_1:%.+]] = load{{.+}} [[OMP_UB]],
+// CHECK: [[NUM_IT_1:%.+]] = load{{.+}},
+// CHECK-DAG: [[CMP_UB_NUM_IT:%.+]] = icmp sgt {{.+}} [[OMP_UB_VAL_1]], [[NUM_IT_1]]
+// CHECK: br {{.+}} [[CMP_UB_NUM_IT]], label %[[EUB_TRUE:.+]], label %[[EUB_FALSE:.+]]
+// CHECK-DAG: [[EUB_TRUE]]:
+// CHECK: [[NUM_IT_2:%.+]] = load{{.+}},
+// CHECK: br label %[[EUB_END:.+]]
+// CHECK-DAG: [[EUB_FALSE]]:
+// CHECK: [[OMP_UB_VAL2:%.+]] = load{{.+}} [[OMP_UB]],
+// CHECK: br label %[[EUB_END]]
+// CHECK-DAG: [[EUB_END]]:
+// CHECK-DAG: [[EUB_RES:%.+]] = phi{{.+}} [ [[NUM_IT_2]], %[[EUB_TRUE]] ], [ [[OMP_UB_VAL2]], %[[EUB_FALSE]] ]
+// CHECK: store{{.+}} [[EUB_RES]], {{.+}}* [[OMP_UB]],
+
+// initialize omp.iv
+// CHECK: [[OMP_LB_VAL_1:%.+]] = load{{.+}}, {{.+}}* [[OMP_LB]],
+// CHECK: store {{.+}} [[OMP_LB_VAL_1]], {{.+}}* [[OMP_IV]],
+// CHECK: br label %[[OMP_JUMP_BACK:.+]]
+
+// check exit condition
+// CHECK: [[OMP_JUMP_BACK]]:
+// CHECK-DAG: [[OMP_IV_VAL_1:%.+]] = load {{.+}} [[OMP_IV]],
+// CHECK-DAG: [[OMP_UB_VAL_3:%.+]] = load {{.+}} [[OMP_UB]],
+// CHECK: [[CMP_IV_UB:%.+]] = icmp sle {{.+}} [[OMP_IV_VAL_1]], [[OMP_UB_VAL_3]]
+// CHECK: br {{.+}} [[CMP_IV_UB]], label %[[DIST_BODY:.+]], label %[[DIST_END:.+]]
+
+// check that PrevLB and PrevUB are passed to the 'for'
+// CHECK: [[DIST_BODY]]:
+// CHECK-DAG: [[OMP_PREV_LB:%.+]] = load {{.+}}, {{.+}} [[OMP_LB]],
+// CHECK-64-DAG: [[OMP_PREV_LB_EXT:%.+]] = zext {{.+}} [[OMP_PREV_LB]] to {{.+}}
+// CHECK-DAG: [[OMP_PREV_UB:%.+]] = load {{.+}}, {{.+}} [[OMP_UB]],
+// CHECK-64-DAG: [[OMP_PREV_UB_EXT:%.+]] = zext {{.+}} [[OMP_PREV_UB]] to {{.+}}
+// check that distlb and distub are properly passed to fork_call
+// CHECK-64: call{{.+}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}}[[OMP_PARFOR_OUTLINED_2:@.+]] to {{.+}}, i{{[0-9]+}} [[OMP_PREV_LB_EXT]], i{{[0-9]+}} [[OMP_PREV_UB_EXT]], {{.+}})
+// CHECK-32: call{{.+}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}}[[OMP_PARFOR_OUTLINED_2:@.+]] to {{.+}}, i{{[0-9]+}} [[OMP_PREV_LB]], i{{[0-9]+}} [[OMP_PREV_UB]], {{.+}})
+// CHECK: br label %[[DIST_INC:.+]]
+
+// increment by stride (distInc - 'parallel for' executes the whole chunk) and latch
+// CHECK: [[DIST_INC]]:
+// CHECK-DAG: [[OMP_IV_VAL_2:%.+]] = load {{.+}}, {{.+}}* [[OMP_IV]],
+// CHECK-DAG: [[OMP_ST_VAL_1:%.+]] = load {{.+}}, {{.+}}* [[OMP_ST]],
+// CHECK: [[OMP_IV_INC:%.+]] = add{{.+}} [[OMP_IV_VAL_2]], [[OMP_ST_VAL_1]]
+// CHECK: store{{.+}} [[OMP_IV_INC]], {{.+}}* [[OMP_IV]],
+// CHECK: br label %[[OMP_JUMP_BACK]]
+
+// CHECK-DAG: call void @__kmpc_for_static_fini(
+// CHECK: ret
+
+// implementation of 'parallel for'
+// CHECK: define{{.+}} void [[OMP_PARFOR_OUTLINED_2]]({{.+}}, {{.+}}, i{{[0-9]+}} [[OMP_PREV_LB_IN:%.+]], i{{[0-9]+}} [[OMP_PREV_UB_IN:%.+]], {{.+}}, {{.+}}, {{.+}}, {{.+}})
+
+// CHECK-DAG: [[OMP_PF_LB:%.omp.lb]] = alloca{{.+}},
+// CHECK-DAG: [[OMP_PF_UB:%.omp.ub]] = alloca{{.+}},
+// CHECK-DAG: [[OMP_PF_IV:%.omp.iv]] = alloca{{.+}},
+
+// initialize lb and ub to PrevLB and PrevUB
+// CHECK-DAG: store{{.+}} [[OMP_PREV_LB_IN]], {{.+}}* [[PREV_LB_ADDR:%.+]],
+// CHECK-DAG: store{{.+}} [[OMP_PREV_UB_IN]], {{.+}}* [[PREV_UB_ADDR:%.+]],
+// CHECK-DAG: [[OMP_PREV_LB_VAL:%.+]] = load{{.+}}, {{.+}}* [[PREV_LB_ADDR]],
+// CHECK-64-DAG: [[OMP_PREV_LB_TRC:%.+]] = trunc{{.+}} [[OMP_PREV_LB_VAL]] to {{.+}}
+// CHECK-DAG: [[OMP_PREV_UB_VAL:%.+]] = load{{.+}}, {{.+}}* [[PREV_UB_ADDR]],
+// CHECK-64-DAG: [[OMP_PREV_UB_TRC:%.+]] = trunc{{.+}} [[OMP_PREV_UB_VAL]] to {{.+}}
+// CHECK-64-DAG: store{{.+}} [[OMP_PREV_LB_TRC]], {{.+}}* [[OMP_PF_LB]],
+// CHECK-32-DAG: store{{.+}} [[OMP_PREV_LB_VAL]], {{.+}}* [[OMP_PF_LB]],
+// CHECK-64-DAG: store{{.+}} [[OMP_PREV_UB_TRC]], {{.+}}* [[OMP_PF_UB]],
+// CHECK-32-DAG: store{{.+}} [[OMP_PREV_UB_VAL]], {{.+}}* [[OMP_PF_UB]],
+// CHECK: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, {{.+}} 34, {{.+}}, {{.+}}* [[OMP_PF_LB]], {{.+}}* [[OMP_PF_UB]],{{.+}})
+
+// PrevEUB is only used when 'for' has a chunked schedule, otherwise EUB is used
+// In this case we use EUB
+// CHECK-DAG: [[OMP_PF_UB_VAL_1:%.+]] = load{{.+}} [[OMP_PF_UB]],
+// CHECK: [[PF_NUM_IT_1:%.+]] = load{{.+}},
+// CHECK-DAG: [[PF_CMP_UB_NUM_IT:%.+]] = icmp{{.+}} [[OMP_PF_UB_VAL_1]], [[PF_NUM_IT_1]]
+// CHECK: br i1 [[PF_CMP_UB_NUM_IT]], label %[[PF_EUB_TRUE:.+]], label %[[PF_EUB_FALSE:.+]]
+// CHECK: [[PF_EUB_TRUE]]:
+// CHECK: [[PF_NUM_IT_2:%.+]] = load{{.+}},
+// CHECK: br label %[[PF_EUB_END:.+]]
+// CHECK-DAG: [[PF_EUB_FALSE]]:
+// CHECK: [[OMP_PF_UB_VAL2:%.+]] = load{{.+}} [[OMP_PF_UB]],
+// CHECK: br label %[[PF_EUB_END]]
+// CHECK-DAG: [[PF_EUB_END]]:
+// CHECK-DAG: [[PF_EUB_RES:%.+]] = phi{{.+}} [ [[PF_NUM_IT_2]], %[[PF_EUB_TRUE]] ], [ [[OMP_PF_UB_VAL2]], %[[PF_EUB_FALSE]] ]
+// CHECK: store{{.+}} [[PF_EUB_RES]],{{.+}} [[OMP_PF_UB]],
+
+// initialize omp.iv
+// CHECK: [[OMP_PF_LB_VAL_1:%.+]] = load{{.+}}, {{.+}} [[OMP_PF_LB]],
+// CHECK: store {{.+}} [[OMP_PF_LB_VAL_1]], {{.+}}* [[OMP_PF_IV]],
+// CHECK: br label %[[OMP_PF_JUMP_BACK:.+]]
+
+// check exit condition
+// CHECK: [[OMP_PF_JUMP_BACK]]:
+// CHECK-DAG: [[OMP_PF_IV_VAL_1:%.+]] = load {{.+}} [[OMP_PF_IV]],
+// CHECK-DAG: [[OMP_PF_UB_VAL_3:%.+]] = load {{.+}} [[OMP_PF_UB]],
+// CHECK: [[PF_CMP_IV_UB:%.+]] = icmp sle {{.+}} [[OMP_PF_IV_VAL_1]], [[OMP_PF_UB_VAL_3]]
+// CHECK: br {{.+}} [[PF_CMP_IV_UB]], label %[[PF_BODY:.+]], label %[[PF_END:.+]]
+
+// check that PrevLB and PrevUB are passed to the 'for'
+// CHECK: [[PF_BODY]]:
+// CHECK-DAG: {{.+}} = load{{.+}}, {{.+}}* [[OMP_PF_IV]],
+// CHECK: br label {{.+}}
+
+// check stride 1 for 'for' in 'distribute parallel for simd'
+// CHECK-DAG: [[OMP_PF_IV_VAL_2:%.+]] = load {{.+}}, {{.+}}* [[OMP_PF_IV]],
+// CHECK: [[OMP_PF_IV_INC:%.+]] = add{{.+}} [[OMP_PF_IV_VAL_2]], 1
+// CHECK: store{{.+}} [[OMP_PF_IV_INC]], {{.+}}* [[OMP_PF_IV]],
+// CHECK: br label %[[OMP_PF_JUMP_BACK]]
+
+// CHECK-DAG: call void @__kmpc_for_static_fini(
+// CHECK: ret
+
+// CHECK: define{{.+}} void [[OFFLOADING_FUN_3]](
+// CHECK: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, i32 5, {{.+}}* [[OMP_OUTLINED_3:@.+]] to {{.+}})
+
+// CHECK: define{{.+}} void [[OMP_OUTLINED_3]](
+// CHECK-DAG: [[OMP_IV:%.omp.iv]] = alloca
+// CHECK-DAG: [[OMP_LB:%.omp.comb.lb]] = alloca
+// CHECK-DAG: [[OMP_UB:%.omp.comb.ub]] = alloca
+// CHECK-DAG: [[OMP_ST:%.omp.stride]] = alloca
+
+// unlike the previous tests, in this one we have a outer and inner loop for 'distribute'
+// CHECK: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 91,
+// CHECK: br label %[[DIST_OUTER_LOOP_HEADER:.+]]
+
+// CHECK: [[DIST_OUTER_LOOP_HEADER]]:
+// check EUB for distribute
+// CHECK-DAG: [[OMP_UB_VAL_1:%.+]] = load{{.+}} [[OMP_UB]],
+// CHECK: [[NUM_IT_1:%.+]] = load{{.+}},
+// CHECK-DAG: [[CMP_UB_NUM_IT:%.+]] = icmp sgt {{.+}} [[OMP_UB_VAL_1]], [[NUM_IT_1]]
+// CHECK: br {{.+}} [[CMP_UB_NUM_IT]], label %[[EUB_TRUE:.+]], label %[[EUB_FALSE:.+]]
+// CHECK-DAG: [[EUB_TRUE]]:
+// CHECK: [[NUM_IT_2:%.+]] = load{{.+}},
+// CHECK: br label %[[EUB_END:.+]]
+// CHECK-DAG: [[EUB_FALSE]]:
+// CHECK: [[OMP_UB_VAL2:%.+]] = load{{.+}} [[OMP_UB]],
+// CHECK: br label %[[EUB_END]]
+// CHECK-DAG: [[EUB_END]]:
+// CHECK-DAG: [[EUB_RES:%.+]] = phi{{.+}} [ [[NUM_IT_2]], %[[EUB_TRUE]] ], [ [[OMP_UB_VAL2]], %[[EUB_FALSE]] ]
+// CHECK: store{{.+}} [[EUB_RES]], {{.+}}* [[OMP_UB]],
+
+// initialize omp.iv
+// CHECK: [[OMP_LB_VAL_1:%.+]] = load{{.+}}, {{.+}}* [[OMP_LB]],
+// CHECK: store {{.+}} [[OMP_LB_VAL_1]], {{.+}}* [[OMP_IV]],
+
+// check exit condition
+// CHECK-DAG: [[OMP_IV_VAL_1:%.+]] = load {{.+}} [[OMP_IV]],
+// CHECK-DAG: [[OMP_UB_VAL_3:%.+]] = load {{.+}} [[OMP_UB]],
+// CHECK: [[CMP_IV_UB:%.+]] = icmp sle {{.+}} [[OMP_IV_VAL_1]], [[OMP_UB_VAL_3]]
+// CHECK: br {{.+}} [[CMP_IV_UB]], label %[[DIST_OUTER_LOOP_BODY:.+]], label %[[DIST_OUTER_LOOP_END:.+]]
+
+// CHECK: [[DIST_OUTER_LOOP_BODY]]:
+// CHECK: br label %[[DIST_INNER_LOOP_HEADER:.+]]
+
+// CHECK: [[DIST_INNER_LOOP_HEADER]]:
+// CHECK-DAG: [[OMP_IV_VAL_2:%.+]] = load {{.+}} [[OMP_IV]],
+// CHECK-DAG: [[OMP_UB_VAL_4:%.+]] = load {{.+}} [[OMP_UB]],
+// CHECK: [[CMP_IV_UB_2:%.+]] = icmp sle {{.+}} [[OMP_IV_VAL_2]], [[OMP_UB_VAL_4]]
+// CHECK: br{{.+}} [[CMP_IV_UB_2]], label %[[DIST_INNER_LOOP_BODY:.+]], label %[[DIST_INNER_LOOP_END:.+]]
+
+// check that PrevLB and PrevUB are passed to the 'for'
+// CHECK: [[DIST_INNER_LOOP_BODY]]:
+// CHECK-DAG: [[OMP_PREV_LB:%.+]] = load {{.+}}, {{.+}} [[OMP_LB]],
+// CHECK-64-DAG: [[OMP_PREV_LB_EXT:%.+]] = zext {{.+}} [[OMP_PREV_LB]] to {{.+}}
+// CHECK-DAG: [[OMP_PREV_UB:%.+]] = load {{.+}}, {{.+}} [[OMP_UB]],
+// CHECK-64-DAG: [[OMP_PREV_UB_EXT:%.+]] = zext {{.+}} [[OMP_PREV_UB]] to {{.+}}
+// check that distlb and distub are properly passed to fork_call
+// CHECK-64: call{{.+}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}}[[OMP_PARFOR_OUTLINED_3:@.+]] to {{.+}}, i{{[0-9]+}} [[OMP_PREV_LB_EXT]], i{{[0-9]+}} [[OMP_PREV_UB_EXT]], {{.+}})
+// CHECK-32: call{{.+}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}}[[OMP_PARFOR_OUTLINED_3:@.+]] to {{.+}}, i{{[0-9]+}} [[OMP_PREV_LB]], i{{[0-9]+}} [[OMP_PREV_UB]], {{.+}})
+// CHECK: br label %[[DIST_INNER_LOOP_INC:.+]]
+
+// check DistInc
+// CHECK: [[DIST_INNER_LOOP_INC]]:
+// CHECK-DAG: [[OMP_IV_VAL_3:%.+]] = load {{.+}}, {{.+}}* [[OMP_IV]],
+// CHECK-DAG: [[OMP_ST_VAL_1:%.+]] = load {{.+}}, {{.+}}* [[OMP_ST]],
+// CHECK: [[OMP_IV_INC:%.+]] = add{{.+}} [[OMP_IV_VAL_3]], [[OMP_ST_VAL_1]]
+// CHECK: store{{.+}} [[OMP_IV_INC]], {{.+}}* [[OMP_IV]],
+// CHECK: br label %[[DIST_INNER_LOOP_HEADER]]
+
+// CHECK: [[DIST_INNER_LOOP_END]]:
+// CHECK: br label %[[DIST_OUTER_LOOP_INC:.+]]
+
+// CHECK: [[DIST_OUTER_LOOP_INC]]:
+// check NextLB and NextUB
+// CHECK-DAG: [[OMP_LB_VAL_2:%.+]] = load{{.+}}, {{.+}} [[OMP_LB]],
+// CHECK-DAG: [[OMP_ST_VAL_2:%.+]] = load{{.+}}, {{.+}} [[OMP_ST]],
+// CHECK-DAG: [[OMP_LB_NEXT:%.+]] = add{{.+}} [[OMP_LB_VAL_2]], [[OMP_ST_VAL_2]]
+// CHECK: store{{.+}} [[OMP_LB_NEXT]], {{.+}}* [[OMP_LB]],
+// CHECK-DAG: [[OMP_UB_VAL_5:%.+]] = load{{.+}}, {{.+}} [[OMP_UB]],
+// CHECK-DAG: [[OMP_ST_VAL_3:%.+]] = load{{.+}}, {{.+}} [[OMP_ST]],
+// CHECK-DAG: [[OMP_UB_NEXT:%.+]] = add{{.+}} [[OMP_UB_VAL_5]], [[OMP_ST_VAL_3]]
+// CHECK: store{{.+}} [[OMP_UB_NEXT]], {{.+}}* [[OMP_UB]],
+// CHECK: br label %[[DIST_OUTER_LOOP_HEADER]]
+
+// outer loop exit
+// CHECK: [[DIST_OUTER_LOOP_END]]:
+// CHECK-DAG: call void @__kmpc_for_static_fini(
+// CHECK: ret
+
+// skip implementation of 'parallel for': using default scheduling and was tested above
+
+// CHECK: define{{.+}} void [[OFFLOADING_FUN_4]](
+// CHECK: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, i32 4, {{.+}}* [[OMP_OUTLINED_4:@.+]] to {{.+}})
+
+// CHECK: define{{.+}} void [[OMP_OUTLINED_4]](
+// CHECK-DAG: [[OMP_IV:%.omp.iv]] = alloca
+// CHECK-DAG: [[OMP_LB:%.omp.comb.lb]] = alloca
+// CHECK-DAG: [[OMP_UB:%.omp.comb.ub]] = alloca
+// CHECK-DAG: [[OMP_ST:%.omp.stride]] = alloca
+
+// CHECK: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 92,
+// CHECK: call{{.+}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}}[[OMP_PARFOR_OUTLINED_4:@.+]] to {{.+}},
+// skip rest of implementation of 'distribute' as it is tested above for default dist_schedule case
+// CHECK: ret
+
+// 'parallel for' implementation is the same as the case without schedule clase (static no chunk is the default)
+// CHECK: define{{.+}} void [[OMP_PARFOR_OUTLINED_4]]({{.+}}, {{.+}}, i{{[0-9]+}} [[OMP_PREV_LB_IN:%.+]], i{{[0-9]+}} [[OMP_PREV_UB_IN:%.+]], {{.+}}, {{.+}}, {{.+}}, {{.+}})
+
+// CHECK-DAG: [[OMP_PF_LB:%.omp.lb]] = alloca{{.+}},
+// CHECK-DAG: [[OMP_PF_UB:%.omp.ub]] = alloca{{.+}},
+// CHECK-DAG: [[OMP_PF_IV:%.omp.iv]] = alloca{{.+}},
+
+// initialize lb and ub to PrevLB and PrevUB
+// CHECK-DAG: store{{.+}} [[OMP_PREV_LB_IN]], {{.+}}* [[PREV_LB_ADDR:%.+]],
+// CHECK-DAG: store{{.+}} [[OMP_PREV_UB_IN]], {{.+}}* [[PREV_UB_ADDR:%.+]],
+// CHECK-DAG: [[OMP_PREV_LB_VAL:%.+]] = load{{.+}}, {{.+}}* [[PREV_LB_ADDR]],
+// CHECK-64-DAG: [[OMP_PREV_LB_TRC:%.+]] = trunc{{.+}} [[OMP_PREV_LB_VAL]] to {{.+}}
+// CHECK-DAG: [[OMP_PREV_UB_VAL:%.+]] = load{{.+}}, {{.+}}* [[PREV_UB_ADDR]],
+// CHECK-64-DAG: [[OMP_PREV_UB_TRC:%.+]] = trunc{{.+}} [[OMP_PREV_UB_VAL]] to {{.+}}
+// CHECK-64-DAG: store{{.+}} [[OMP_PREV_LB_TRC]], {{.+}}* [[OMP_PF_LB]],
+// CHECK-32-DAG: store{{.+}} [[OMP_PREV_LB_VAL]], {{.+}}* [[OMP_PF_LB]],
+// CHECK-64-DAG: store{{.+}} [[OMP_PREV_UB_TRC]], {{.+}}* [[OMP_PF_UB]],
+// CHECK-32-DAG: store{{.+}} [[OMP_PREV_UB_VAL]], {{.+}}* [[OMP_PF_UB]],
+// CHECK: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, {{.+}} 34, {{.+}}, {{.+}}* [[OMP_PF_LB]], {{.+}}* [[OMP_PF_UB]],{{.+}})
+
+// PrevEUB is only used when 'for' has a chunked schedule, otherwise EUB is used
+// In this case we use EUB
+// CHECK-DAG: [[OMP_PF_UB_VAL_1:%.+]] = load{{.+}} [[OMP_PF_UB]],
+// CHECK: [[PF_NUM_IT_1:%.+]] = load{{.+}},
+// CHECK-DAG: [[PF_CMP_UB_NUM_IT:%.+]] = icmp{{.+}} [[OMP_PF_UB_VAL_1]], [[PF_NUM_IT_1]]
+// CHECK: br i1 [[PF_CMP_UB_NUM_IT]], label %[[PF_EUB_TRUE:.+]], label %[[PF_EUB_FALSE:.+]]
+// CHECK: [[PF_EUB_TRUE]]:
+// CHECK: [[PF_NUM_IT_2:%.+]] = load{{.+}},
+// CHECK: br label %[[PF_EUB_END:.+]]
+// CHECK-DAG: [[PF_EUB_FALSE]]:
+// CHECK: [[OMP_PF_UB_VAL2:%.+]] = load{{.+}} [[OMP_PF_UB]],
+// CHECK: br label %[[PF_EUB_END]]
+// CHECK-DAG: [[PF_EUB_END]]:
+// CHECK-DAG: [[PF_EUB_RES:%.+]] = phi{{.+}} [ [[PF_NUM_IT_2]], %[[PF_EUB_TRUE]] ], [ [[OMP_PF_UB_VAL2]], %[[PF_EUB_FALSE]] ]
+// CHECK: store{{.+}} [[PF_EUB_RES]],{{.+}} [[OMP_PF_UB]],
+
+// initialize omp.iv
+// CHECK: [[OMP_PF_LB_VAL_1:%.+]] = load{{.+}}, {{.+}} [[OMP_PF_LB]],
+// CHECK: store {{.+}} [[OMP_PF_LB_VAL_1]], {{.+}}* [[OMP_PF_IV]],
+// CHECK: br label %[[OMP_PF_JUMP_BACK:.+]]
+
+// check exit condition
+// CHECK: [[OMP_PF_JUMP_BACK]]:
+// CHECK-DAG: [[OMP_PF_IV_VAL_1:%.+]] = load {{.+}} [[OMP_PF_IV]],
+// CHECK-DAG: [[OMP_PF_UB_VAL_3:%.+]] = load {{.+}} [[OMP_PF_UB]],
+// CHECK: [[PF_CMP_IV_UB:%.+]] = icmp sle {{.+}} [[OMP_PF_IV_VAL_1]], [[OMP_PF_UB_VAL_3]]
+// CHECK: br {{.+}} [[PF_CMP_IV_UB]], label %[[PF_BODY:.+]], label %[[PF_END:.+]]
+
+// check that PrevLB and PrevUB are passed to the 'for'
+// CHECK: [[PF_BODY]]:
+// CHECK-DAG: {{.+}} = load{{.+}}, {{.+}}* [[OMP_PF_IV]],
+// CHECK: br label {{.+}}
+
+// check stride 1 for 'for' in 'distribute parallel for simd'
+// CHECK-DAG: [[OMP_PF_IV_VAL_2:%.+]] = load {{.+}}, {{.+}}* [[OMP_PF_IV]],
+// CHECK: [[OMP_PF_IV_INC:%.+]] = add{{.+}} [[OMP_PF_IV_VAL_2]], 1
+// CHECK: store{{.+}} [[OMP_PF_IV_INC]], {{.+}}* [[OMP_PF_IV]],
+// CHECK: br label %[[OMP_PF_JUMP_BACK]]
+
+// CHECK-DAG: call void @__kmpc_for_static_fini(
+// CHECK: ret
+
+// CHECK: define{{.+}} void [[OFFLOADING_FUN_5]](
+// CHECK: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, i32 5, {{.+}}* [[OMP_OUTLINED_5:@.+]] to {{.+}})
+
+// CHECK: define{{.+}} void [[OMP_OUTLINED_5]](
+// CHECK: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 92,
+// CHECK: call{{.+}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}}[[OMP_PARFOR_OUTLINED_5:@.+]] to {{.+}},
+// skip rest of implementation of 'distribute' as it is tested above for default dist_schedule case
+// CHECK: ret
+
+// 'parallel for' implementation using outer and inner loops and PrevEUB
+// CHECK: define{{.+}} void [[OMP_PARFOR_OUTLINED_5]]({{.+}}, {{.+}}, i{{[0-9]+}} [[OMP_PREV_LB_IN:%.+]], i{{[0-9]+}} [[OMP_PREV_UB_IN:%.+]], {{.+}}, {{.+}}, {{.+}}, {{.+}}, {{.+}})
+// CHECK-DAG: [[OMP_PF_LB:%.omp.lb]] = alloca{{.+}},
+// CHECK-DAG: [[OMP_PF_UB:%.omp.ub]] = alloca{{.+}},
+// CHECK-DAG: [[OMP_PF_IV:%.omp.iv]] = alloca{{.+}},
+// CHECK-DAG: [[OMP_PF_ST:%.omp.stride]] = alloca{{.+}},
+
+// initialize lb and ub to PrevLB and PrevUB
+// CHECK-DAG: store{{.+}} [[OMP_PREV_LB_IN]], {{.+}}* [[PREV_LB_ADDR:%.+]],
+// CHECK-DAG: store{{.+}} [[OMP_PREV_UB_IN]], {{.+}}* [[PREV_UB_ADDR:%.+]],
+// CHECK-DAG: [[OMP_PREV_LB_VAL:%.+]] = load{{.+}}, {{.+}}* [[PREV_LB_ADDR]],
+// CHECK-64-DAG: [[OMP_PREV_LB_TRC:%.+]] = trunc{{.+}} [[OMP_PREV_LB_VAL]] to {{.+}}
+// CHECK-DAG: [[OMP_PREV_UB_VAL:%.+]] = load{{.+}}, {{.+}}* [[PREV_UB_ADDR]],
+// CHECK-64-DAG: [[OMP_PREV_UB_TRC:%.+]] = trunc{{.+}} [[OMP_PREV_UB_VAL]] to {{.+}}
+// CHECK-64-DAG: store{{.+}} [[OMP_PREV_LB_TRC]], {{.+}}* [[OMP_PF_LB]],
+// CHECK-32-DAG: store{{.+}} [[OMP_PREV_LB_VAL]], {{.+}}* [[OMP_PF_LB]],
+// CHECK-64-DAG: store{{.+}} [[OMP_PREV_UB_TRC]], {{.+}}* [[OMP_PF_UB]],
+// CHECK-32-DAG: store{{.+}} [[OMP_PREV_UB_VAL]], {{.+}}* [[OMP_PF_UB]],
+// CHECK: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, {{.+}} 33, {{.+}}, {{.+}}* [[OMP_PF_LB]], {{.+}}* [[OMP_PF_UB]],{{.+}})
+// CHECK: br label %[[OMP_PF_OUTER_LOOP_HEADER:.+]]
+
+// check PrevEUB (using PrevUB instead of NumIt as upper bound)
+// CHECK: [[OMP_PF_OUTER_LOOP_HEADER]]:
+// CHECK-DAG: [[OMP_PF_UB_VAL_1:%.+]] = load{{.+}} [[OMP_PF_UB]],
+// CHECK-64-DAG: [[OMP_PF_UB_VAL_CONV:%.+]] = sext{{.+}} [[OMP_PF_UB_VAL_1]] to
+// CHECK: [[PF_PREV_UB_VAL_1:%.+]] = load{{.+}}, {{.+}}* [[PREV_UB_ADDR]],
+// CHECK-64-DAG: [[PF_CMP_UB_NUM_IT:%.+]] = icmp{{.+}} [[OMP_PF_UB_VAL_CONV]], [[PF_PREV_UB_VAL_1]]
+// CHECK-32-DAG: [[PF_CMP_UB_NUM_IT:%.+]] = icmp{{.+}} [[OMP_PF_UB_VAL_1]], [[PF_PREV_UB_VAL_1]]
+// CHECK: br i1 [[PF_CMP_UB_NUM_IT]], label %[[PF_EUB_TRUE:.+]], label %[[PF_EUB_FALSE:.+]]
+// CHECK: [[PF_EUB_TRUE]]:
+// CHECK: [[PF_PREV_UB_VAL_2:%.+]] = load{{.+}}, {{.+}}* [[PREV_UB_ADDR]],
+// CHECK: br label %[[PF_EUB_END:.+]]
+// CHECK-DAG: [[PF_EUB_FALSE]]:
+// CHECK: [[OMP_PF_UB_VAL_2:%.+]] = load{{.+}} [[OMP_PF_UB]],
+// CHECK-64: [[OMP_PF_UB_VAL_2_CONV:%.+]] = sext{{.+}} [[OMP_PF_UB_VAL_2]] to
+// CHECK: br label %[[PF_EUB_END]]
+// CHECK-DAG: [[PF_EUB_END]]:
+// CHECK-64-DAG: [[PF_EUB_RES:%.+]] = phi{{.+}} [ [[PF_PREV_UB_VAL_2]], %[[PF_EUB_TRUE]] ], [ [[OMP_PF_UB_VAL_2_CONV]], %[[PF_EUB_FALSE]] ]
+// CHECK-32-DAG: [[PF_EUB_RES:%.+]] = phi{{.+}} [ [[PF_PREV_UB_VAL_2]], %[[PF_EUB_TRUE]] ], [ [[OMP_PF_UB_VAL_2]], %[[PF_EUB_FALSE]] ]
+// CHECK-64-DAG: [[PF_EUB_RES_CONV:%.+]] = trunc{{.+}} [[PF_EUB_RES]] to
+// CHECK-64: store{{.+}} [[PF_EUB_RES_CONV]],{{.+}} [[OMP_PF_UB]],
+// CHECK-32: store{{.+}} [[PF_EUB_RES]], {{.+}} [[OMP_PF_UB]],
+
+// initialize omp.iv (IV = LB)
+// CHECK: [[OMP_PF_LB_VAL_1:%.+]] = load{{.+}}, {{.+}} [[OMP_PF_LB]],
+// CHECK: store {{.+}} [[OMP_PF_LB_VAL_1]], {{.+}}* [[OMP_PF_IV]],
+
+// outer loop: while (IV < UB) {
+// CHECK-DAG: [[OMP_PF_IV_VAL_1:%.+]] = load{{.+}}, {{.+}}* [[OMP_PF_IV]],
+// CHECK-DAG: [[OMP_PF_UB_VAL_3:%.+]] = load{{.+}}, {{.+}}* [[OMP_PF_UB]],
+// CHECK: [[PF_CMP_IV_UB_1:%.+]] = icmp{{.+}} [[OMP_PF_IV_VAL_1]], [[OMP_PF_UB_VAL_3]]
+// CHECK: br{{.+}} [[PF_CMP_IV_UB_1]], label %[[OMP_PF_OUTER_LOOP_BODY:.+]], label %[[OMP_PF_OUTER_LOOP_END:.+]]
+
+// CHECK: [[OMP_PF_OUTER_LOOP_BODY]]:
+// CHECK: br label %[[OMP_PF_INNER_FOR_HEADER:.+]]
+
+// CHECK: [[OMP_PF_INNER_FOR_HEADER]]:
+// CHECK-DAG: [[OMP_PF_IV_VAL_2:%.+]] = load{{.+}}, {{.+}}* [[OMP_PF_IV]],
+// CHECK-DAG: [[OMP_PF_UB_VAL_4:%.+]] = load{{.+}}, {{.+}}* [[OMP_PF_UB]],
+// CHECK: [[PF_CMP_IV_UB_2:%.+]] = icmp{{.+}} [[OMP_PF_IV_VAL_2]], [[OMP_PF_UB_VAL_4]]
+// CHECK: br{{.+}} [[PF_CMP_IV_UB_2]], label %[[OMP_PF_INNER_LOOP_BODY:.+]], label %[[OMP_PF_INNER_LOOP_END:.+]]
+
+// CHECK: [[OMP_PF_INNER_LOOP_BODY]]:
+// CHECK-DAG: {{.+}} = load{{.+}}, {{.+}}* [[OMP_PF_IV]],
+// skip body branch
+// CHECK: br{{.+}}
+// CHECK: br label %[[OMP_PF_INNER_LOOP_INC:.+]]
+
+// IV = IV + 1 and inner loop latch
+// CHECK: [[OMP_PF_INNER_LOOP_INC]]:
+// CHECK-DAG: [[OMP_PF_IV_VAL_3:%.+]] = load{{.+}}, {{.+}}* [[OMP_IV]],
+// CHECK-DAG: [[OMP_PF_NEXT_IV:%.+]] = add{{.+}} [[OMP_PF_IV_VAL_3]], 1
+// CHECK-DAG: store{{.+}} [[OMP_PF_NEXT_IV]], {{.+}}* [[OMP_IV]],
+// CHECK: br label %[[OMP_PF_INNER_FOR_HEADER]]
+
+// check NextLB and NextUB
+// CHECK: [[OMP_PF_INNER_LOOP_END]]:
+// CHECK: br label %[[OMP_PF_OUTER_LOOP_INC:.+]]
+
+// CHECK: [[OMP_PF_OUTER_LOOP_INC]]:
+// CHECK-DAG: [[OMP_PF_LB_VAL_2:%.+]] = load{{.+}}, {{.+}} [[OMP_PF_LB]],
+// CHECK-DAG: [[OMP_PF_ST_VAL_1:%.+]] = load{{.+}}, {{.+}} [[OMP_PF_ST]],
+// CHECK-DAG: [[OMP_PF_LB_NEXT:%.+]] = add{{.+}} [[OMP_PF_LB_VAL_2]], [[OMP_PF_ST_VAL_1]]
+// CHECK: store{{.+}} [[OMP_PF_LB_NEXT]], {{.+}}* [[OMP_PF_LB]],
+// CHECK-DAG: [[OMP_PF_UB_VAL_5:%.+]] = load{{.+}}, {{.+}} [[OMP_PF_UB]],
+// CHECK-DAG: [[OMP_PF_ST_VAL_2:%.+]] = load{{.+}}, {{.+}} [[OMP_PF_ST]],
+// CHECK-DAG: [[OMP_PF_UB_NEXT:%.+]] = add{{.+}} [[OMP_PF_UB_VAL_5]], [[OMP_PF_ST_VAL_2]]
+// CHECK: store{{.+}} [[OMP_PF_UB_NEXT]], {{.+}}* [[OMP_PF_UB]],
+// CHECK: br label %[[OMP_PF_OUTER_LOOP_HEADER]]
+
+// CHECK: [[OMP_PF_OUTER_LOOP_END]]:
+// CHECK-DAG: call void @__kmpc_for_static_fini(
+// CHECK: ret
+
+// CHECK: define{{.+}} void [[OFFLOADING_FUN_6]](
+// CHECK: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, i32 4, {{.+}}* [[OMP_OUTLINED_6:@.+]] to {{.+}})
+
+// CHECK: define{{.+}} void [[OMP_OUTLINED_6]](
+// CHECK: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 92,
+// CHECK: call{{.+}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}}[[OMP_PARFOR_OUTLINED_6:@.+]] to {{.+}},
+// skip rest of implementation of 'distribute' as it is tested above for default dist_schedule case
+// CHECK: ret
+
+// 'parallel for' implementation using outer and inner loops and PrevEUB
+// CHECK: define{{.+}} void [[OMP_PARFOR_OUTLINED_6]]({{.+}}, {{.+}}, i{{[0-9]+}} [[OMP_PREV_LB_IN:%.+]], i{{[0-9]+}} [[OMP_PREV_UB_IN:%.+]], {{.+}}, {{.+}}, {{.+}}, {{.+}})
+// CHECK-DAG: [[OMP_PF_LB:%.omp.lb]] = alloca{{.+}},
+// CHECK-DAG: [[OMP_PF_UB:%.omp.ub]] = alloca{{.+}},
+// CHECK-DAG: [[OMP_PF_IV:%.omp.iv]] = alloca{{.+}},
+// CHECK-DAG: [[OMP_PF_ST:%.omp.stride]] = alloca{{.+}},
+
+// initialize lb and ub to PrevLB and PrevUB
+// CHECK-DAG: store{{.+}} [[OMP_PREV_LB_IN]], {{.+}}* [[PREV_LB_ADDR:%.+]],
+// CHECK-DAG: store{{.+}} [[OMP_PREV_UB_IN]], {{.+}}* [[PREV_UB_ADDR:%.+]],
+// CHECK-DAG: [[OMP_PREV_LB_VAL:%.+]] = load{{.+}}, {{.+}}* [[PREV_LB_ADDR]],
+// CHECK-64-DAG: [[OMP_PREV_LB_TRC:%.+]] = trunc{{.+}} [[OMP_PREV_LB_VAL]] to {{.+}}
+// CHECK-DAG: [[OMP_PREV_UB_VAL:%.+]] = load{{.+}}, {{.+}}* [[PREV_UB_ADDR]],
+// CHECK-64-DAG: [[OMP_PREV_UB_TRC:%.+]] = trunc{{.+}} [[OMP_PREV_UB_VAL]] to {{.+}}
+// CHECK-64-DAG: store{{.+}} [[OMP_PREV_LB_TRC]], {{.+}}* [[OMP_PF_LB]],
+// CHECK-64-DAG: store{{.+}} [[OMP_PREV_UB_TRC]], {{.+}}* [[OMP_PF_UB]],
+// CHECK-32-DAG: store{{.+}} [[OMP_PREV_LB_VAL]], {{.+}}* [[OMP_PF_LB]],
+// CHECK-32-DAG: store{{.+}} [[OMP_PREV_UB_VAL]], {{.+}}* [[OMP_PF_UB]],
+// CHECK-DAG: [[OMP_PF_LB_VAL:%.+]] = load{{.+}}, {{.+}} [[OMP_PF_LB]],
+// CHECK-DAG: [[OMP_PF_UB_VAL:%.+]] = load{{.+}}, {{.+}} [[OMP_PF_UB]],
+// CHECK: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, {{.+}} 35, {{.+}} [[OMP_PF_LB_VAL]], {{.+}} [[OMP_PF_UB_VAL]], {{.+}}, {{.+}})
+// CHECK: br label %[[OMP_PF_OUTER_LOOP_HEADER:.+]]
+
+// CHECK: [[OMP_PF_OUTER_LOOP_HEADER]]:
+// CHECK: [[IS_FIN:%.+]] = call{{.+}} @__kmpc_dispatch_next_4({{.+}}, {{.+}}, {{.+}}, {{.+}}* [[OMP_PF_LB]], {{.+}}* [[OMP_PF_UB]], {{.+}}* [[OMP_PF_ST]])
+// CHECK: [[IS_FIN_CMP:%.+]] = icmp{{.+}} [[IS_FIN]], 0
+// CHECK: br{{.+}} [[IS_FIN_CMP]], label %[[OMP_PF_OUTER_LOOP_BODY:.+]], label %[[OMP_PF_OUTER_LOOP_END:.+]]
+
+// initialize omp.iv (IV = LB)
+// CHECK: [[OMP_PF_OUTER_LOOP_BODY]]:
+// CHECK-DAG: [[OMP_PF_LB_VAL_1:%.+]] = load{{.+}}, {{.+}} [[OMP_PF_LB]],
+// CHECK-DAG: store {{.+}} [[OMP_PF_LB_VAL_1]], {{.+}}* [[OMP_PF_IV]],
+// CHECK: br label %[[OMP_PF_INNER_LOOP_HEADER:.+]]
+
+// CHECK: [[OMP_PF_INNER_LOOP_HEADER]]:
+// CHECK-DAG: [[OMP_PF_IV_VAL_2:%.+]] = load{{.+}}, {{.+}}* [[OMP_PF_IV]],
+// CHECK-DAG: [[OMP_PF_UB_VAL_4:%.+]] = load{{.+}}, {{.+}}* [[OMP_PF_UB]],
+// CHECK: [[PF_CMP_IV_UB_2:%.+]] = icmp{{.+}} [[OMP_PF_IV_VAL_2]], [[OMP_PF_UB_VAL_4]]
+// CHECK: br{{.+}} [[PF_CMP_IV_UB_2]], label %[[OMP_PF_INNER_LOOP_BODY:.+]], label %[[OMP_PF_INNER_LOOP_END:.+]]
+
+// CHECK: [[OMP_PF_INNER_LOOP_BODY]]:
+// CHECK-DAG: {{.+}} = load{{.+}}, {{.+}}* [[OMP_PF_IV]],
+// skip body branch
+// CHECK: br{{.+}}
+// CHECK: br label %[[OMP_PF_INNER_LOOP_INC:.+]]
+
+// IV = IV + 1 and inner loop latch
+// CHECK: [[OMP_PF_INNER_LOOP_INC]]:
+// CHECK-DAG: [[OMP_PF_IV_VAL_3:%.+]] = load{{.+}}, {{.+}}* [[OMP_IV]],
+// CHECK-DAG: [[OMP_PF_NEXT_IV:%.+]] = add{{.+}} [[OMP_PF_IV_VAL_3]], 1
+// CHECK-DAG: store{{.+}} [[OMP_PF_NEXT_IV]], {{.+}}* [[OMP_IV]],
+// CHECK: br label %[[OMP_PF_INNER_LOOP_HEADER]]
+
+// check NextLB and NextUB
+// CHECK: [[OMP_PF_INNER_LOOP_END]]:
+// CHECK: br label %[[OMP_PF_OUTER_LOOP_INC:.+]]
+
+// CHECK: [[OMP_PF_OUTER_LOOP_INC]]:
+// CHECK: br label %[[OMP_PF_OUTER_LOOP_HEADER]]
+
+// CHECK: [[OMP_PF_OUTER_LOOP_END]]:
+// CHECK: ret
+
+// CHECK: define{{.+}} void [[OFFLOADING_FUN_7]](
+// CHECK: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, i32 5, {{.+}}* [[OMP_OUTLINED_7:@.+]] to {{.+}})
+
+// CHECK: define{{.+}} void [[OMP_OUTLINED_7]](
+// CHECK: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 92,
+// CHECK: call{{.+}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}}[[OMP_PARFOR_OUTLINED_7:@.+]] to {{.+}},
+// skip rest of implementation of 'distribute' as it is tested above for default dist_schedule case
+// CHECK: ret
+
+// 'parallel for' implementation using outer and inner loops and PrevEUB
+// CHECK: define{{.+}} void [[OMP_PARFOR_OUTLINED_7]]({{.+}}, {{.+}}, i{{[0-9]+}} [[OMP_PREV_LB_IN:%.+]], i{{[0-9]+}} [[OMP_PREV_UB_IN:%.+]], {{.+}}, {{.+}}, {{.+}}, {{.+}}, {{.+}})
+// CHECK-DAG: [[OMP_PF_LB:%.omp.lb]] = alloca{{.+}},
+// CHECK-DAG: [[OMP_PF_UB:%.omp.ub]] = alloca{{.+}},
+// CHECK-DAG: [[OMP_PF_IV:%.omp.iv]] = alloca{{.+}},
+// CHECK-DAG: [[OMP_PF_ST:%.omp.stride]] = alloca{{.+}},
+
+// initialize lb and ub to PrevLB and PrevUB
+// CHECK-DAG: store{{.+}} [[OMP_PREV_LB_IN]], {{.+}}* [[PREV_LB_ADDR:%.+]],
+// CHECK-DAG: store{{.+}} [[OMP_PREV_UB_IN]], {{.+}}* [[PREV_UB_ADDR:%.+]],
+// CHECK-DAG: [[OMP_PREV_LB_VAL:%.+]] = load{{.+}}, {{.+}}* [[PREV_LB_ADDR]],
+// CHECK-64-DAG: [[OMP_PREV_LB_TRC:%.+]] = trunc{{.+}} [[OMP_PREV_LB_VAL]] to {{.+}}
+// CHECK-DAG: [[OMP_PREV_UB_VAL:%.+]] = load{{.+}}, {{.+}}* [[PREV_UB_ADDR]],
+// CHECK-64-DAG: [[OMP_PREV_UB_TRC:%.+]] = trunc{{.+}} [[OMP_PREV_UB_VAL]] to {{.+}}
+// CHECK-64-DAG: store{{.+}} [[OMP_PREV_LB_TRC]], {{.+}}* [[OMP_PF_LB]],
+// CHECK-64-DAG: store{{.+}} [[OMP_PREV_UB_TRC]], {{.+}}* [[OMP_PF_UB]],
+// CHECK-32-DAG: store{{.+}} [[OMP_PREV_LB_VAL]], {{.+}}* [[OMP_PF_LB]],
+// CHECK-32-DAG: store{{.+}} [[OMP_PREV_UB_VAL]], {{.+}}* [[OMP_PF_UB]],
+// CHECK-DAG: [[OMP_PF_LB_VAL:%.+]] = load{{.+}}, {{.+}} [[OMP_PF_LB]],
+// CHECK-DAG: [[OMP_PF_UB_VAL:%.+]] = load{{.+}}, {{.+}} [[OMP_PF_UB]],
+// CHECK: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, {{.+}} 35, {{.+}} [[OMP_PF_LB_VAL]], {{.+}} [[OMP_PF_UB_VAL]], {{.+}}, {{.+}})
+// CHECK: br label %[[OMP_PF_OUTER_LOOP_HEADER:.+]]
+
+// CHECK: [[OMP_PF_OUTER_LOOP_HEADER]]:
+// CHECK: [[IS_FIN:%.+]] = call{{.+}} @__kmpc_dispatch_next_4({{.+}}, {{.+}}, {{.+}}, {{.+}}* [[OMP_PF_LB]], {{.+}}* [[OMP_PF_UB]], {{.+}}* [[OMP_PF_ST]])
+// CHECK: [[IS_FIN_CMP:%.+]] = icmp{{.+}} [[IS_FIN]], 0
+// CHECK: br{{.+}} [[IS_FIN_CMP]], label %[[OMP_PF_OUTER_LOOP_BODY:.+]], label %[[OMP_PF_OUTER_LOOP_END:.+]]
+
+// initialize omp.iv (IV = LB)
+// CHECK: [[OMP_PF_OUTER_LOOP_BODY]]:
+// CHECK-DAG: [[OMP_PF_LB_VAL_1:%.+]] = load{{.+}}, {{.+}} [[OMP_PF_LB]],
+// CHECK-DAG: store {{.+}} [[OMP_PF_LB_VAL_1]], {{.+}}* [[OMP_PF_IV]],
+// CHECK: br label %[[OMP_PF_INNER_LOOP_HEADER:.+]]
+
+// CHECK: [[OMP_PF_INNER_LOOP_HEADER]]:
+// CHECK-DAG: [[OMP_PF_IV_VAL_2:%.+]] = load{{.+}}, {{.+}}* [[OMP_PF_IV]],
+// CHECK-DAG: [[OMP_PF_UB_VAL_4:%.+]] = load{{.+}}, {{.+}}* [[OMP_PF_UB]],
+// CHECK: [[PF_CMP_IV_UB_2:%.+]] = icmp{{.+}} [[OMP_PF_IV_VAL_2]], [[OMP_PF_UB_VAL_4]]
+// CHECK: br{{.+}} [[PF_CMP_IV_UB_2]], label %[[OMP_PF_INNER_LOOP_BODY:.+]], label %[[OMP_PF_INNER_LOOP_END:.+]]
+
+// CHECK: [[OMP_PF_INNER_LOOP_BODY]]:
+// CHECK-DAG: {{.+}} = load{{.+}}, {{.+}}* [[OMP_PF_IV]],
+// skip body branch
+// CHECK: br{{.+}}
+// CHECK: br label %[[OMP_PF_INNER_LOOP_INC:.+]]
+
+// IV = IV + 1 and inner loop latch
+// CHECK: [[OMP_PF_INNER_LOOP_INC]]:
+// CHECK-DAG: [[OMP_PF_IV_VAL_3:%.+]] = load{{.+}}, {{.+}}* [[OMP_IV]],
+// CHECK-DAG: [[OMP_PF_NEXT_IV:%.+]] = add{{.+}} [[OMP_PF_IV_VAL_3]], 1
+// CHECK-DAG: store{{.+}} [[OMP_PF_NEXT_IV]], {{.+}}* [[OMP_IV]],
+// CHECK: br label %[[OMP_PF_INNER_LOOP_HEADER]]
+
+// check NextLB and NextUB
+// CHECK: [[OMP_PF_INNER_LOOP_END]]:
+// CHECK: br label %[[OMP_PF_OUTER_LOOP_INC:.+]]
+
+// CHECK: [[OMP_PF_OUTER_LOOP_INC]]:
+// CHECK: br label %[[OMP_PF_OUTER_LOOP_HEADER]]
+
+// CHECK: [[OMP_PF_OUTER_LOOP_END]]:
+// CHECK: ret
+
+// CHECK: !{!"llvm.loop.vectorize.enable", i1 true}
+#endif
diff --git a/test/OpenMP/distribute_parallel_for_simd_firstprivate_codegen.cpp b/test/OpenMP/distribute_parallel_for_simd_firstprivate_codegen.cpp
new file mode 100644
index 000000000000..b8d0f4ad7540
--- /dev/null
+++ b/test/OpenMP/distribute_parallel_for_simd_firstprivate_codegen.cpp
@@ -0,0 +1,611 @@
+// RxUN: %clang_cc1 -DLAMBDA -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+// RUN: %clang_cc1 -DLAMBDA -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-32
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-32
+
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+template <class T>
+struct S {
+ T f;
+ S(T a) : f(a) {}
+ S() : f() {}
+ operator T() { return T(); }
+ ~S() {}
+};
+
+// CHECK: [[S_FLOAT_TY:%.+]] = type { float }
+// CHECK: [[S_INT_TY:%.+]] = type { i{{[0-9]+}} }
+template <typename T>
+T tmain() {
+ S<T> test;
+ T t_var = T();
+ T vec[] = {1, 2};
+ S<T> s_arr[] = {1, 2};
+ S<T> &var = test;
+ #pragma omp target
+ #pragma omp teams
+ #pragma omp distribute parallel for simd firstprivate(t_var, vec, s_arr, s_arr, var, var)
+ for (int i = 0; i < 2; ++i) {
+ vec[i] = t_var;
+ s_arr[i] = var;
+ }
+ return T();
+}
+
+int main() {
+ static int svar;
+ volatile double g;
+ volatile double &g1 = g;
+
+ #ifdef LAMBDA
+ // LAMBDA-LABEL: @main
+ // LAMBDA: call{{.*}} void [[OUTER_LAMBDA:@.+]](
+ [&]() {
+ static float sfvar;
+ // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
+ // LAMBDA: call i{{[0-9]+}} @__tgt_target_teams(
+ // LAMBDA: call void [[OFFLOADING_FUN:@.+]](
+
+ // LAMBDA: define{{.+}} void [[OFFLOADING_FUN]](
+ // LAMBDA: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, i32 4, {{.+}}* [[OMP_OUTLINED:@.+]] to {{.+}})
+ #pragma omp target
+ #pragma omp teams
+ #pragma omp distribute parallel for simd firstprivate(g, g1, svar, sfvar)
+ for (int i = 0; i < 2; ++i) {
+ // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_OUTLINED]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, double* {{.+}} [[G_IN:%.+]], double*{{.+}} [[G1_IN:%.+]], i{{[0-9]+}}*{{.+}} [[SVAR_IN:%.+]], float*{{.+}} [[SFVAR_IN:%.+]])
+
+ // addr alloca's
+ // LAMBDA: [[G_ADDR:%.+]] = alloca double*,
+ // LAMBDA: [[G1_ADDR:%.+]] = alloca double*,
+ // LAMBDA: [[SVAR_ADDR:%.+]] = alloca i{{[0-9]+}}*,
+ // LAMBDA: [[SFVAR_ADDR:%.+]] = alloca float*,
+ // LAMBDA: [[G1_REF:%.+]] = alloca double*,
+
+ // private alloca's
+ // LAMBDA: [[G_PRIV:%.+]] = alloca double,
+ // LAMBDA: [[G1_PRIV:%.+]] = alloca double,
+ // LAMBDA: [[TMP_PRIV:%.+]] = alloca double*,
+ // LAMBDA: [[SVAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[SFVAR_PRIV:%.+]] = alloca float,
+
+ // transfer input parameters into addr alloca's
+ // LAMBDA-DAG: store {{.+}} [[G_IN]], {{.+}} [[G_ADDR]],
+ // LAMBDA-DAG: store {{.+}} [[G1_IN]], {{.+}} [[G1_ADDR]],
+ // LAMBDA-DAG: store {{.+}} [[SVAR_IN]], {{.+}} [[SVAR_ADDR]],
+ // LAMBDA-DAG: store {{.+}} [[SFVAR_IN]], {{.+}} [[SFVAR_ADDR]],
+
+ // init private alloca's with addr alloca's
+ // g
+ // LAMBDA-DAG: [[G_CONV:%.+]] = load {{.+}}*, {{.+}}** [[G_ADDR]]
+ // LAMBDA-DAG: [[G_ADDR_VAL:%.+]] = load {{.+}}, {{.+}}* [[G_CONV]],
+ // LAMBDA-DAG: store {{.+}} [[G_ADDR_VAL]], {{.+}}* [[G_PRIV]],
+
+ // g1
+ // LAMBDA-DAG: [[TMP_REF:%.+]] = load {{.+}}*, {{.+}}** [[G1_REF]],
+ // LAMBDA-DAG: [[TMP_VAL:%.+]] = load {{.+}}, {{.+}}* [[TMP_REF]],
+ // LAMBDA-DAG: store {{.+}} [[TMP_VAL]], {{.+}}* [[G1_PRIV]]
+ // LAMBDA-DAG: store {{.+}}* [[G1_PRIV]], {{.+}}** [[TMP_PRIV]],
+
+ // svar
+ // LAMBDA-DAG: [[SVAR_REF:%.+]] = load {{.+}}*, {{.+}}** [[SVAR_ADDR]],
+ // LAMBDA-DAG: [[SVAR_VAL:%.+]] = load {{.+}}, {{.+}}* [[SVAR_REF]],
+ // LAMBDA-DAG: store {{.+}} [[SVAR_VAL]], {{.+}}* [[SVAR_PRIV]],
+
+ // sfvar
+ // LAMBDA-DAG: [[SFVAR_REF:%.+]] = load {{.+}}*, {{.+}}** [[SFVAR_ADDR]],
+ // LAMBDA-DAG: [[SFVAR_VAL:%.+]] = load {{.+}}, {{.+}}* [[SFVAR_REF]],
+ // LAMBDA-DAG: store {{.+}} [[SFVAR_VAL]], {{.+}}* [[SFVAR_PRIV]],
+
+ // LAMBDA: call {{.*}}void @__kmpc_for_static_init_4(
+ // pass firstprivate parameters to parallel outlined function
+ // g
+ // LAMBDA-64-DAG: [[G_PRIV_VAL:%.+]] = load {{.+}}, {{.+}}* [[G_PRIV]],
+ // LAMBDA-64: [[G_CAST_CONV:%.+]] = bitcast {{.+}}* [[G_CAST:%.+]] to
+ // LAMBDA-64-DAG: store {{.+}} [[G_PRIV_VAL]], {{.+}}* [[G_CAST_CONV]],
+ // LAMBDA-64-DAG: [[G_PAR:%.+]] = load {{.+}}, {{.+}}* [[G_CAST]],
+
+ // g1
+ // LAMBDA-DAG: [[TMP_PRIV_VAL:%.+]] = load {{.+}}, {{.+}}* [[TMP_PRIV]],
+ // LAMBDA-DAG: [[G1_PRIV_VAL:%.+]] = load {{.+}}, {{.+}}* [[TMP_PRIV_VAL]],
+ // LAMBDA: [[G1_CAST_CONV:%.+]] = bitcast {{.+}}* [[G1_CAST:%.+]] to
+ // LAMBDA-DAG: store {{.+}} [[G1_PRIV_VAL]], {{.+}}* [[G1_CAST_CONV]],
+ // LAMBDA-DAG: [[G1_PAR:%.+]] = load {{.+}}, {{.+}}* [[G1_CAST]],
+
+ // svar
+ // LAMBDA: [[SVAR_VAL:%.+]] = load {{.+}}, {{.+}}* [[SVAR_PRIV]],
+ // LAMBDA-64-DAG: [[SVAR_CAST_CONV:%.+]] = bitcast {{.+}}* [[SVAR_CAST:%.+]] to
+ // LAMBDA-64-DAG: store {{.+}} [[SVAR_VAL]], {{.+}}* [[SVAR_CAST_CONV]],
+ // LAMBDA-32-DAG: store {{.+}} [[SVAR_VAL]], {{.+}}* [[SVAR_CAST:%.+]],
+ // LAMBDA-DAG: [[SVAR_PAR:%.+]] = load {{.+}}, {{.+}}* [[SVAR_CAST]],
+
+ // sfvar
+ // LAMBDA: [[SFVAR_VAL:%.+]] = load {{.+}}, {{.+}}* [[SFVAR_PRIV]],
+ // LAMBDA-DAG: [[SFVAR_CAST_CONV:%.+]] = bitcast {{.+}}* [[SFVAR_CAST:%.+]] to
+ // LAMBDA-DAG: store {{.+}} [[SFVAR_VAL]], {{.+}}* [[SFVAR_CAST_CONV]],
+ // LAMBDA-DAG: [[SFVAR_PAR:%.+]] = load {{.+}}, {{.+}}* [[SFVAR_CAST]],
+
+ // LAMBDA-64: call{{.+}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}}[[OMP_PARFOR_OUTLINED:@.+]] to void ({{.+}})*), {{.+}}, {{.+}}, {{.+}} [[G_PAR]], {{.+}} [[G1_PAR]], {{.+}} [[SVAR_PAR]], {{.+}} [[SFVAR_PAR]])
+ // LAMBDA-32: call{{.+}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}}[[OMP_PARFOR_OUTLINED:@.+]] to void ({{.+}})*), {{.+}}, {{.+}}, {{.+}} [[G_PRIV]], {{.+}} [[G1_PAR]], {{.+}} [[SVAR_PAR]], {{.+}} [[SFVAR_PAR]])
+ // LAMBDA: call {{.*}}void @__kmpc_for_static_fini(
+ // LAMBDA: ret void
+
+
+ // LAMBDA-64: define{{.+}} void [[OMP_PARFOR_OUTLINED]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, {{.+}}, {{.+}}, i{{[0-9]+}} [[G_IN:%.+]], i{{[0-9]+}} [[G1_IN:%.+]], i{{[0-9]+}} [[SVAR_IN:%.+]], i{{[0-9]+}} [[SFVAR_IN:%.+]])
+ // LAMBDA-32: define{{.+}} void [[OMP_PARFOR_OUTLINED]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, {{.+}}, {{.+}}, double* {{.+}} [[G_IN:%.+]], i{{[0-9]+}} [[G1_IN:%.+]], i{{[0-9]+}} [[SVAR_IN:%.+]], i{{[0-9]+}} [[SFVAR_IN:%.+]])
+ // skip initial params
+ // LAMBDA: {{.+}} = alloca{{.+}},
+ // LAMBDA: {{.+}} = alloca{{.+}},
+ // LAMBDA: {{.+}} = alloca{{.+}},
+ // LAMBDA: {{.+}} = alloca{{.+}},
+
+ // addr alloca's
+ // LAMBDA-64: [[G_ADDR:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA-32: [[G_ADDR:%.+]] = alloca double*,
+ // LAMBDA: [[G1_ADDR:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[SVAR_ADDR:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[SFVAR_ADDR:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[G1_REF:%.+]] = alloca double*,
+
+ // private alloca's (only for 32-bit)
+ // LAMBDA-32: [[G_PRIV:%.+]] = alloca double,
+
+ // transfer input parameters into addr alloca's
+ // LAMBDA-DAG: store {{.+}} [[G_IN]], {{.+}} [[G_ADDR]],
+ // LAMBDA-DAG: store {{.+}} [[G1_IN]], {{.+}} [[G1_ADDR]],
+ // LAMBDA-DAG: store {{.+}} [[SVAR_IN]], {{.+}} [[SVAR_ADDR]],
+ // LAMBDA-DAG: store {{.+}} [[SFVAR_IN]], {{.+}} [[SFVAR_ADDR]],
+
+ // prepare parameters for lambda
+ // g
+ // LAMBDA-64-DAG: [[G_CONV:%.+]] = bitcast {{.+}}* [[G_ADDR]] to
+ // LAMBDA-32-DAG: [[G_ADDR_REF:%.+]] = load {{.+}}*, {{.+}}** [[G_ADDR]]
+ // LAMBDA-32-DAG: [[G_ADDR_VAL:%.+]] = load {{.+}}, {{.+}}* [[G_ADDR_REF]],
+ // LAMBDA-32-DAG: store {{.+}} [[G_ADDR_VAL]], {{.+}}* [[G_PRIV]],
+
+ // g1
+ // LAMBDA-DAG: [[G1_CONV:%.+]] = bitcast {{.+}}* [[G1_ADDR]] to
+ // LAMBDA-DAG: store {{.+}}* [[G1_CONV]], {{.+}}* [[G1_REF]],
+
+ // svar
+ // LAMBDA-64-DAG: [[SVAR_CONV:%.+]] = bitcast {{.+}}* [[SVAR_ADDR]] to
+
+ // sfvar
+ // LAMBDA-DAG: [[SFVAR_CONV:%.+]] = bitcast {{.+}}* [[SFVAR_ADDR]] to
+
+ // LAMBDA: call {{.*}}void @__kmpc_for_static_init_4(
+ g = 1;
+ g1 = 1;
+ svar = 3;
+ sfvar = 4.0;
+ // LAMBDA-64: store double 1.0{{.+}}, double* [[G_CONV]],
+ // LAMBDA-32: store double 1.0{{.+}}, double* [[G_PRIV]],
+ // LAMBDA: [[G1_REF_REF:%.+]] = load {{.+}}*, {{.+}}** [[G1_REF]],
+ // LAMBDA: store {{.+}} 1.0{{.+}}, {{.+}}* [[G1_REF_REF]],
+ // LAMBDA-64: store {{.+}} 3, {{.+}}* [[SVAR_CONV]],
+ // LAMBDA-32: store {{.+}} 3, {{.+}}* [[SVAR_ADDR]],
+ // LAMBDA: store {{.+}} 4.0{{.+}}, {{.+}}* [[SFVAR_CONV]],
+
+ // pass params to inner lambda
+ // LAMBDA: [[G_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // LAMBDA-64: store double* [[G_CONV]], double** [[G_PRIVATE_ADDR_REF]],
+ // LAMBDA-32: store double* [[G_PRIV]], double** [[G_PRIVATE_ADDR_REF]],
+ // LAMBDA: [[G1_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // LAMBDA: [[G1_REF_REF:%.+]] = load double*, double** [[G1_REF]],
+ // LAMBDA: store double* [[G1_REF_REF]], double** [[G1_PRIVATE_ADDR_REF]],
+ // LAMBDA: [[SVAR_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+ // LAMBDA-64: store i{{[0-9]+}}* [[SVAR_CONV]], i{{[0-9]+}}** [[SVAR_PRIVATE_ADDR_REF]]
+ // LAMBDA-32: store i{{[0-9]+}}* [[SVAR_ADDR]], i{{[0-9]+}}** [[SVAR_PRIVATE_ADDR_REF]]
+ // LAMBDA: [[SFVAR_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 3
+ // LAMBDA: store float* [[SFVAR_CONV]], float** [[SFVAR_PRIVATE_ADDR_REF]]
+ // LAMBDA: call{{.*}} void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]])
+ // LAMBDA: call {{.*}}void @__kmpc_for_static_fini(
+ // LAMBDA: ret void
+ [&]() {
+ // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]])
+ // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]],
+ g = 2;
+ g1 = 2;
+ svar = 4;
+ sfvar = 8.0;
+ // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]]
+ // LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // LAMBDA: [[G_REF:%.+]] = load double*, double** [[G_PTR_REF]]
+ // LAMBDA: store double 2.0{{.+}}, double* [[G_REF]]
+
+ // LAMBDA: [[TMP_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // LAMBDA: [[G1_REF:%.+]] = load double*, double** [[TMP_PTR_REF]]
+ // LAMBDA: store double 2.0{{.+}}, double* [[G1_REF]],
+ // LAMBDA: [[SVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+ // LAMBDA: [[SVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SVAR_PTR_REF]]
+ // LAMBDA: store i{{[0-9]+}} 4, i{{[0-9]+}}* [[SVAR_REF]]
+ // LAMBDA: [[SFVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 3
+ // LAMBDA: [[SFVAR_REF:%.+]] = load float*, float** [[SFVAR_PTR_REF]]
+ // LAMBDA: store float 8.0{{.+}}, float* [[SFVAR_REF]]
+ }();
+ }
+ }();
+ return 0;
+ #else
+ S<float> test;
+ int t_var = 0;
+ int vec[] = {1, 2};
+ S<float> s_arr[] = {1, 2};
+ S<float> &var = test;
+
+ #pragma omp target
+ #pragma omp teams
+ #pragma omp distribute parallel for simd firstprivate(t_var, vec, s_arr, s_arr, var, var, svar)
+ for (int i = 0; i < 2; ++i) {
+ vec[i] = t_var;
+ s_arr[i] = var;
+ }
+ return tmain<int>();
+ #endif
+}
+
+// CHECK-LABEL: define{{.*}} i{{[0-9]+}} @main()
+// CHECK: [[TEST:%.+]] = alloca [[S_FLOAT_TY]],
+// CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR:@.+]]([[S_FLOAT_TY]]* [[TEST]])
+// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+// CHECK: call void [[OFFLOAD_FUN_0:@.+]](
+// CHECK: call {{.*}} [[S_FLOAT_TY_DEF_DESTR:@.+]]([[S_FLOAT_TY]]* [[TEST]])
+
+// CHECK: define{{.+}} [[OFFLOAD_FUN_0]](i{{[0-9]+}} [[T_VAR_IN:%.+]], [2 x i{{[0-9]+}}]* {{.+}} [[VEC_IN:%.+]], [2 x [[S_FLOAT_TY]]]* {{.+}} [[S_ARR_IN:%.+]], [[S_FLOAT_TY]]* {{.+}} [[VAR_IN:%.+]], i{{[0-9]+}} [[SVAR_IN:%.+]])
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_teams(%{{.+}}* @{{.+}}, i{{[0-9]+}} 5, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, i{{[0-9]+}}*, [2 x i{{[0-9]+}}]*, [2 x [[S_FLOAT_TY]]]*, [[S_FLOAT_TY]]*, i{{[0-9]+}}*)* [[OMP_OUTLINED_0:@.+]] to void
+// CHECK: ret
+
+// CHECK: define internal void [[OMP_OUTLINED_0]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i{{[0-9]+}}*{{.+}} [[T_VAR_IN:%.+]], [2 x i{{[0-9]+}}]* {{.+}} [[VEC_IN:%.+]], [2 x [[S_FLOAT_TY]]]* {{.+}} [[S_ARR_IN:%.+]], [[S_FLOAT_TY]]* {{.+}} [[VAR_IN:%.+]], i{{[0-9]+}}*{{.+}} [[SVAR_IN:%.+]])
+
+// CHECK: alloca i{{[0-9]+}}*,
+// CHECK: alloca i{{[0-9]+}}*,
+// addr alloca's
+// CHECK: [[T_VAR_ADDR:%.+]] = alloca i{{[0-9]+}}*,
+// CHECK: [[VEC_ADDR:%.+]] = alloca [2 x i{{[0-9]+}}]*,
+// CHECK: [[S_ARR_ADDR:%.+]] = alloca [2 x [[S_FLOAT_TY]]]*,
+// CHECK: [[VAR_ADDR:%.+]] = alloca [[S_FLOAT_TY]]*,
+// CHECK: [[SVAR_ADDR:%.+]] = alloca i{{[0-9]+}}*,
+// CHECK: [[TMP:%.+]] = alloca [[S_FLOAT_TY]]*,
+
+// skip loop alloca's
+// CHECK: [[OMP_IV:.omp.iv+]] = alloca i{{[0-9]+}},
+// CHECK: [[OMP_LB:.omp.comb.lb+]] = alloca i{{[0-9]+}},
+// CHECK: [[OMP_UB:.omp.comb.ub+]] = alloca i{{[0-9]+}},
+// CHECK: [[OMP_ST:.omp.stride+]] = alloca i{{[0-9]+}},
+// CHECK: [[OMP_IS_LAST:.omp.is_last+]] = alloca i{{[0-9]+}},
+
+// private alloca's
+// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]],
+// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]],
+// CHECK: [[TMP_PRIV:%.+]] = alloca [[S_FLOAT_TY]]*,
+// CHECK: [[SVAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+
+// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_REF:%.+]]
+
+// init addr alloca's with input values
+// CHECK-DAG: store {{.+}} [[T_VAR_IN]], {{.+}}* [[T_VAR_ADDR]],
+// CHECK-DAG: store {{.+}} [[VEC_IN]], {{.+}} [[VEC_ADDR]],
+// CHECK-DAG: store {{.+}} [[S_ARR_IN]], {{.+}} [[S_ARR_ADDR]],
+// CHECK-DAG: store {{.+}} [[VAR_IN]], {{.+}} [[VAR_ADDR]],
+// CHECK-DAG: store {{.+}} [[SVAR_IN]], {{.+}} [[SVAR_ADDR]],
+
+// init private alloca's with addr alloca's
+// t-var
+// CHECK-DAG: [[T_VAR_ADDR_REF:%.+]] = load {{.+}}*, {{.+}}** [[T_VAR_ADDR]],
+// CHECK-DAG: [[T_VAR:%.+]] = load {{.+}}, {{.+}}* [[T_VAR_ADDR_REF]],
+// CHECK-DAG: store {{.+}} [[T_VAR]], {{.+}} [[T_VAR_PRIV]],
+
+// vec
+// CHECK-DAG: [[VEC_ADDR_VAL:%.+]] = load {{.+}}*, {{.+}}** [[VEC_ADDR]],
+// CHECK-DAG: [[VEC_PRIV_BCAST:%.+]] = bitcast {{.+}} [[VEC_PRIV]] to
+// CHECK-DAG: [[VEC_ADDR_BCAST:%.+]] = bitcast {{.+}} [[VEC_ADDR_VAL]] to
+// CHECK-DAG: call void @llvm.memcpy{{.+}}({{.+}}* [[VEC_PRIV_BCAST]], {{.+}}* [[VEC_ADDR_BCAST]],
+
+// s_arr
+// CHECK-DAG: [[S_ARR_ADDR_VAL:%.+]] = load {{.+}}*, {{.+}}** [[S_ARR_ADDR]],
+// CHECK-DAG: [[S_ARR_BGN:%.+]] = getelementptr {{.+}}, {{.+}}* [[S_ARR_PRIV]],
+// CHECK-DAG: [[S_ARR_ADDR_BCAST:%.+]] = bitcast {{.+}}* [[S_ARR_ADDR_VAL]] to
+// CHECK-DAG: [[S_ARR_BGN_GEP:%.+]] = getelementptr {{.+}}, {{.+}}* [[S_ARR_BGN]],
+// CHECK-DAG: [[S_ARR_EMPTY:%.+]] = icmp {{.+}} [[S_ARR_BGN]], [[S_ARR_BGN_GEP]]
+// CHECK-DAG: br {{.+}} [[S_ARR_EMPTY]], label %[[CPY_DONE:.+]], label %[[CPY_BODY:.+]]
+// CHECK-DAG: [[CPY_BODY]]:
+// CHECK-DAG: call void @llvm.memcpy{{.+}}(
+// CHECK-DAG: [[CPY_DONE]]:
+
+// var
+// CHECK-DAG: [[TMP_REF:%.+]] = load {{.+}}*, {{.+}}* [[TMP]],
+// CHECK-DAG: [[VAR_PRIV_BCAST:%.+]] = bitcast {{.+}}* [[VAR_PRIV]] to
+// CHECK-DAG: [[TMP_REF_BCAST:%.+]] = bitcast {{.+}}* [[TMP_REF]] to
+// CHECK-DAG: call void @llvm.memcpy.{{.+}}({{.+}}* [[VAR_PRIV_BCAST]], {{.+}}* [[TMP_REF_BCAST]],
+// CHECK-DAG: store {{.+}}* [[VAR_PRIV]], {{.+}}** [[TMP_PRIV]],
+
+// svar
+// CHECK-DAG: [[SVAR_CONV_REF:%.+]] = load {{.+}}*, {{.+}}** [[SVAR_ADDR]],
+// CHECK-DAG: [[SVAR_CONV_VAL:%.+]] = load {{.+}}, {{.+}}* [[SVAR_CONV_REF]],
+// CHECK-DAG: store {{.+}} [[SVAR_CONV_VAL]], {{.+}}* [[SVAR_PRIV]],
+
+// CHECK: call void @__kmpc_for_static_init_4(
+// pass private alloca's to fork
+// CHECK-DAG: [[T_VAR_PRIV_VAL:%.+]] = load {{.+}}, {{.+}}* [[T_VAR_PRIV]],
+// not dag to distinguish with S_VAR_CAST
+// CHECK-64: [[T_VAR_CAST_CONV:%.+]] = bitcast {{.+}}* [[T_VAR_CAST:%.+]] to
+// CHECK-64-DAG: store {{.+}} [[T_VAR_PRIV_VAL]], {{.+}} [[T_VAR_CAST_CONV]],
+// CHECK-32: store {{.+}} [[T_VAR_PRIV_VAL]], {{.+}} [[T_VAR_CAST:%.+]],
+// CHECK-DAG: [[T_VAR_CAST_VAL:%.+]] = load {{.+}}, {{.+}}* [[T_VAR_CAST]],
+// CHECK-DAG: [[TMP_PRIV_VAL:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[TMP_PRIV]],
+// CHECK-DAG: [[SVAR_PRIV_VAL:%.+]] = load {{.+}}, {{.+}}* [[SVAR_PRIV]],
+// CHECK-64-DAG: [[SVAR_CAST_CONV:%.+]] = bitcast {{.+}}* [[SVAR_CAST:%.+]] to
+// CHECK-64-DAG: store {{.+}} [[SVAR_PRIV_VAL]], {{.+}}* [[SVAR_CAST_CONV]],
+// CHECK-32-DAG: store {{.+}} [[SVAR_PRIV_VAL]], {{.+}}* [[SVAR_CAST:%.+]],
+// CHECK-DAG: [[SVAR_CAST_VAL:%.+]] = load {{.+}}, {{.+}}* [[SVAR_CAST]],
+// CHECK: call{{.+}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}}[[OMP_PARFOR_OUTLINED_0:@.+]] to void ({{.+}})*), {{.+}}, {{.+}}, [2 x i{{[0-9]+}}]* [[VEC_PRIV]], i{{[0-9]+}} [[T_VAR_CAST_VAL]], [2 x [[S_FLOAT_TY]]]* [[S_ARR_PRIV]], [[S_FLOAT_TY]]* [[TMP_PRIV_VAL]], i{{[0-9]+}} [[SVAR_CAST_VAL]])
+// CHECK: call void @__kmpc_for_static_fini(
+
+// call destructors: var..
+// CHECK-DAG: call {{.+}} [[S_FLOAT_TY_DEF_DESTR]]([[S_FLOAT_TY]]* [[VAR_PRIV]])
+
+// ..and s_arr
+// CHECK: {{.+}}:
+// CHECK: [[S_ARR_EL_PAST:%.+]] = phi [[S_FLOAT_TY]]*
+// CHECK: [[S_ARR_PRIV_ITEM:%.+]] = getelementptr {{.+}}, {{.+}} [[S_ARR_EL_PAST]],
+// CHECK: call {{.*}} [[S_FLOAT_TY_DEF_DESTR]]([[S_FLOAT_TY]]* [[S_ARR_PRIV_ITEM]])
+
+// CHECK: ret void
+
+// By OpenMP specifications, 'firstprivate' applies to both distribute and parallel for.
+// However, the support for 'firstprivate' of 'parallel' is only used when 'parallel'
+// is found alone. Therefore we only have one 'firstprivate' support for 'parallel for'
+// in combination
+// CHECK: define internal void [[OMP_PARFOR_OUTLINED_0]]({{.+}}, {{.+}}, {{.+}}, {{.+}}, [2 x i{{[0-9]+}}]* {{.+}} [[VEC_IN:%.+]], i{{[0-9]+}} [[T_VAR_IN:%.+]], [2 x [[S_FLOAT_TY]]]* {{.+}} [[S_ARR_IN:%.+]], [[S_FLOAT_TY]]* {{.+}} [[VAR_IN:%.+]], i{{[0-9]+}} [[SVAR_IN:%.+]])
+
+// addr alloca's
+// CHECK: [[VEC_ADDR:%.+]] = alloca [2 x i{{[0-9]+}}]*,
+// CHECK: [[T_VAR_ADDR:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[S_ARR_ADDR:%.+]] = alloca [2 x [[S_FLOAT_TY]]]*,
+// CHECK: [[VAR_ADDR:%.+]] = alloca [[S_FLOAT_TY]]*,
+// CHECK: [[SVAR_ADDR:%.+]] = alloca i{{[0-9]+}},
+
+// skip loop alloca's
+// CHECK: [[OMP_IV:.omp.iv+]] = alloca i{{[0-9]+}},
+// CHECK: [[OMP_LB:.omp.lb+]] = alloca i{{[0-9]+}},
+// CHECK: [[OMP_UB:.omp.ub+]] = alloca i{{[0-9]+}},
+// CHECK: [[OMP_ST:.omp.stride+]] = alloca i{{[0-9]+}},
+// CHECK: [[OMP_IS_LAST:.omp.is_last+]] = alloca i{{[0-9]+}},
+
+// private alloca's
+// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]],
+// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]],
+// CHECK: [[TMP_PRIV:%.+]] = alloca [[S_FLOAT_TY]]*,
+
+// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_REF:%.+]]
+
+// init addr alloca's with input values
+// CHECK-DAG: store {{.+}} [[VEC_IN]], {{.+}} [[VEC_ADDR]],
+// CHECK-DAG: store {{.+}} [[T_VAR_IN]], {{.+}}* [[T_VAR_ADDR]],
+// CHECK-DAG: store {{.+}} [[S_ARR_IN]], {{.+}} [[S_ARR_ADDR]],
+// CHECK-DAG: store {{.+}} [[VAR_IN]], {{.+}} [[VAR_ADDR]],
+// CHECK-DAG: store {{.+}} [[SVAR_IN]], {{.+}} [[SVAR_ADDR]],
+
+// init private alloca's with addr alloca's
+// vec
+// CHECK-DAG: [[VEC_ADDR_VAL:%.+]] = load {{.+}}*, {{.+}}** [[VEC_ADDR]],
+// CHECK-DAG: [[VEC_PRIV_BCAST:%.+]] = bitcast {{.+}} [[VEC_PRIV]] to
+// CHECK-DAG: [[VEC_ADDR_BCAST:%.+]] = bitcast {{.+}} [[VEC_ADDR_VAL]] to
+// CHECK-DAG: call void @llvm.memcpy{{.+}}({{.+}}* [[VEC_PRIV_BCAST]], {{.+}}* [[VEC_ADDR_BCAST]],
+
+// s_arr
+// CHECK-DAG: [[S_ARR_ADDR_VAL:%.+]] = load {{.+}}*, {{.+}}** [[S_ARR_ADDR]],
+// CHECK-DAG: [[S_ARR_BGN:%.+]] = getelementptr {{.+}}, {{.+}}* [[S_ARR_PRIV]],
+// CHECK-DAG: [[S_ARR_ADDR_BCAST:%.+]] = bitcast {{.+}}* [[S_ARR_ADDR_VAL]] to
+// CHECK-DAG: [[S_ARR_BGN_GEP:%.+]] = getelementptr {{.+}}, {{.+}}* [[S_ARR_BGN]],
+// CHECK-DAG: [[S_ARR_EMPTY:%.+]] = icmp {{.+}} [[S_ARR_BGN]], [[S_ARR_BGN_GEP]]
+// CHECK-DAG: br {{.+}} [[S_ARR_EMPTY]], label %[[CPY_DONE:.+]], label %[[CPY_BODY:.+]]
+// CHECK-DAG: [[CPY_BODY]]:
+// CHECK-DAG: call void @llvm.memcpy{{.+}}(
+// CHECK-DAG: [[CPY_DONE]]:
+
+// var
+// CHECK-DAG: [[VAR_ADDR_REF:%.+]] = load {{.+}}*, {{.+}}* [[VAR_ADDR]],
+// CHECK-DAG: [[VAR_PRIV_BCAST:%.+]] = bitcast {{.+}}* [[VAR_PRIV]] to
+// CHECK-DAG: [[VAR_ADDR_BCAST:%.+]] = bitcast {{.+}}* [[VAR_ADDR_REF]] to
+// CHECK-DAG: call void @llvm.memcpy.{{.+}}({{.+}}* [[VAR_PRIV_BCAST]], {{.+}}* [[VAR_ADDR_BCAST]],
+// CHECK-DAG: store {{.+}}* [[VAR_PRIV]], {{.+}}** [[TMP_PRIV]],
+
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: call void @__kmpc_for_static_fini(
+
+// call destructors: var..
+// CHECK-DAG: call {{.+}} [[S_FLOAT_TY_DEF_DESTR]]([[S_FLOAT_TY]]* [[VAR_PRIV]])
+
+// ..and s_arr
+// CHECK: {{.+}}:
+// CHECK: [[S_ARR_EL_PAST:%.+]] = phi [[S_FLOAT_TY]]*
+// CHECK: [[S_ARR_PRIV_ITEM:%.+]] = getelementptr {{.+}}, {{.+}} [[S_ARR_EL_PAST]],
+// CHECK: call {{.*}} [[S_FLOAT_TY_DEF_DESTR]]([[S_FLOAT_TY]]* [[S_ARR_PRIV_ITEM]])
+
+// CHECK: ret void
+
+// template tmain with S_INT_TY
+// CHECK-LABEL: define{{.*}} i{{[0-9]+}} @{{.+}}tmain{{.+}}()
+// CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]],
+// CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR:@.+]]([[S_INT_TY]]* [[TEST]])
+// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+// CHECK: call void [[OFFLOAD_FUN_0:@.+]](
+// CHECK: call {{.*}} [[S_INT_TY_DEF_DESTR:@.+]]([[S_INT_TY]]* [[TEST]])
+
+// CHECK: define{{.+}} [[OFFLOAD_FUN_0]](i{{[0-9]+}} [[T_VAR_IN:%.+]], [2 x i{{[0-9]+}}]* {{.+}} [[VEC_IN:%.+]], [2 x [[S_INT_TY]]]* {{.+}} [[S_ARR_IN:%.+]], [[S_INT_TY]]* {{.+}} [[VAR_IN:%.+]])
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_teams(%{{.+}}* @{{.+}}, i{{[0-9]+}} 4, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, i{{[0-9]+}}*, [2 x i{{[0-9]+}}]*, [2 x [[S_INT_TY]]]*, [[S_INT_TY]]*)* [[OMP_OUTLINED_0:@.+]] to void
+// CHECK: ret
+
+// CHECK: define internal void [[OMP_OUTLINED_0]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i{{[0-9]+}}*{{.+}} [[T_VAR_IN:%.+]], [2 x i{{[0-9]+}}]* {{.+}} [[VEC_IN:%.+]], [2 x [[S_INT_TY]]]* {{.+}} [[S_ARR_IN:%.+]], [[S_INT_TY]]* {{.+}} [[VAR_IN:%.+]])
+
+// CHECK: alloca i{{[0-9]+}}*,
+// CHECK: alloca i{{[0-9]+}}*,
+// addr alloca's
+// CHECK: [[T_VAR_ADDR:%.+]] = alloca i{{[0-9]+}}*,
+// CHECK: [[VEC_ADDR:%.+]] = alloca [2 x i{{[0-9]+}}]*,
+// CHECK: [[S_ARR_ADDR:%.+]] = alloca [2 x [[S_INT_TY]]]*,
+// CHECK: [[VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*,
+// CHECK: [[TMP:%.+]] = alloca [[S_INT_TY]]*,
+
+// skip loop alloca's
+// CHECK: [[OMP_IV:.omp.iv+]] = alloca i{{[0-9]+}},
+// CHECK: [[OMP_LB:.omp.comb.lb+]] = alloca i{{[0-9]+}},
+// CHECK: [[OMP_UB:.omp.comb.ub+]] = alloca i{{[0-9]+}},
+// CHECK: [[OMP_ST:.omp.stride+]] = alloca i{{[0-9]+}},
+// CHECK: [[OMP_IS_LAST:.omp.is_last+]] = alloca i{{[0-9]+}},
+
+// private alloca's
+// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_INT_TY]]],
+// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_INT_TY]],
+// CHECK: [[TMP_PRIV:%.+]] = alloca [[S_INT_TY]]*,
+
+// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_REF:%.+]]
+
+// init addr alloca's with input values
+// CHECK-DAG: store {{.+}} [[T_VAR_IN]], {{.+}}* [[T_VAR_ADDR]],
+// CHECK-DAG: store {{.+}} [[VEC_IN]], {{.+}} [[VEC_ADDR]],
+// CHECK-DAG: store {{.+}} [[S_ARR_IN]], {{.+}} [[S_ARR_ADDR]],
+// CHECK-DAG: store {{.+}} [[VAR_IN]], {{.+}} [[VAR_ADDR]],
+
+// init private alloca's with addr alloca's
+// t-var
+// CHECK-DAG: [[T_VAR_ADDR_REF:%.+]] = load {{.+}}*, {{.+}}** [[T_VAR_ADDR]],
+// CHECK-DAG: [[T_VAR_ADDR_VAL:%.+]] = load {{.+}}, {{.+}}* [[T_VAR_ADDR_REF]],
+// CHECK-DAG: store {{.+}} [[T_VAR_ADDR_VAL]], {{.+}} [[T_VAR_PRIV]],
+
+// vec
+// CHECK-DAG: [[VEC_ADDR_VAL:%.+]] = load {{.+}}*, {{.+}}** [[VEC_ADDR]],
+// CHECK-DAG: [[VEC_PRIV_BCAST:%.+]] = bitcast {{.+}} [[VEC_PRIV]] to
+// CHECK-DAG: [[VEC_ADDR_BCAST:%.+]] = bitcast {{.+}} [[VEC_ADDR_VAL]] to
+// CHECK-DAG: call void @llvm.memcpy{{.+}}({{.+}}* [[VEC_PRIV_BCAST]], {{.+}}* [[VEC_ADDR_BCAST]],
+
+// s_arr
+// CHECK-DAG: [[S_ARR_ADDR_VAL:%.+]] = load {{.+}}*, {{.+}}** [[S_ARR_ADDR]],
+// CHECK-DAG: [[S_ARR_BGN:%.+]] = getelementptr {{.+}}, {{.+}}* [[S_ARR_PRIV]],
+// CHECK-DAG: [[S_ARR_ADDR_BCAST:%.+]] = bitcast {{.+}}* [[S_ARR_ADDR_VAL]] to
+// CHECK-DAG: [[S_ARR_BGN_GEP:%.+]] = getelementptr {{.+}}, {{.+}}* [[S_ARR_BGN]],
+// CHECK-DAG: [[S_ARR_EMPTY:%.+]] = icmp {{.+}} [[S_ARR_BGN]], [[S_ARR_BGN_GEP]]
+// CHECK-DAG: br {{.+}} [[S_ARR_EMPTY]], label %[[CPY_DONE:.+]], label %[[CPY_BODY:.+]]
+// CHECK-DAG: [[CPY_BODY]]:
+// CHECK-DAG: call void @llvm.memcpy{{.+}}(
+// CHECK-DAG: [[CPY_DONE]]:
+
+// var
+// CHECK-DAG: [[TMP_REF:%.+]] = load {{.+}}*, {{.+}}* [[TMP]],
+// CHECK-DAG: [[VAR_PRIV_BCAST:%.+]] = bitcast {{.+}}* [[VAR_PRIV]] to
+// CHECK-DAG: [[TMP_REF_BCAST:%.+]] = bitcast {{.+}}* [[TMP_REF]] to
+// CHECK-DAG: call void @llvm.memcpy.{{.+}}({{.+}}* [[VAR_PRIV_BCAST]], {{.+}}* [[TMP_REF_BCAST]],
+// CHECK-DAG: store {{.+}}* [[VAR_PRIV]], {{.+}}** [[TMP_PRIV]],
+
+// CHECK: call void @__kmpc_for_static_init_4(
+// pass private alloca's to fork
+// CHECK-DAG: [[T_VAR_PRIV_VAL:%.+]] = load {{.+}}, {{.+}}* [[T_VAR_PRIV]],
+// not dag to distinguish with S_VAR_CAST
+// CHECK-64: [[T_VAR_CAST_CONV:%.+]] = bitcast {{.+}}* [[T_VAR_CAST:%.+]] to
+// CHECK-64-DAG: store {{.+}} [[T_VAR_PRIV_VAL]], {{.+}} [[T_VAR_CAST_CONV]],
+// CHECK-32: store {{.+}} [[T_VAR_PRIV_VAL]], {{.+}} [[T_VAR_CAST:%.+]],
+// CHECK-DAG: [[T_VAR_CAST_VAL:%.+]] = load {{.+}}, {{.+}}* [[T_VAR_CAST]],
+// CHECK-DAG: [[TMP_PRIV_VAL:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[TMP_PRIV]],
+// CHECK: call{{.+}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}}[[OMP_PARFOR_OUTLINED_0:@.+]] to void ({{.+}})*), {{.+}}, {{.+}}, [2 x i{{[0-9]+}}]* [[VEC_PRIV]], i{{[0-9]+}} [[T_VAR_CAST_VAL]], [2 x [[S_INT_TY]]]* [[S_ARR_PRIV]], [[S_INT_TY]]* [[TMP_PRIV_VAL]])
+// CHECK: call void @__kmpc_for_static_fini(
+
+// call destructors: var..
+// CHECK-DAG: call {{.+}} [[S_INT_TY_DEF_DESTR]]([[S_INT_TY]]* [[VAR_PRIV]])
+
+// ..and s_arr
+// CHECK: {{.+}}:
+// CHECK: [[S_ARR_EL_PAST:%.+]] = phi [[S_INT_TY]]*
+// CHECK: [[S_ARR_PRIV_ITEM:%.+]] = getelementptr {{.+}}, {{.+}} [[S_ARR_EL_PAST]],
+// CHECK: call {{.*}} [[S_INT_TY_DEF_DESTR]]([[S_INT_TY]]* [[S_ARR_PRIV_ITEM]])
+
+// CHECK: ret void
+
+// By OpenMP specifications, 'firstprivate' applies to both distribute and parallel for.
+// However, the support for 'firstprivate' of 'parallel' is only used when 'parallel'
+// is found alone. Therefore we only have one 'firstprivate' support for 'parallel for'
+// in combination
+// CHECK: define internal void [[OMP_PARFOR_OUTLINED_0]]({{.+}}, {{.+}}, {{.+}}, {{.+}}, [2 x i{{[0-9]+}}]* {{.+}} [[VEC_IN:%.+]], i{{[0-9]+}} [[T_VAR_IN:%.+]], [2 x [[S_INT_TY]]]* {{.+}} [[S_ARR_IN:%.+]], [[S_INT_TY]]* {{.+}} [[VAR_IN:%.+]])
+
+// addr alloca's
+// CHECK: [[VEC_ADDR:%.+]] = alloca [2 x i{{[0-9]+}}]*,
+// CHECK: [[T_VAR_ADDR:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[S_ARR_ADDR:%.+]] = alloca [2 x [[S_INT_TY]]]*,
+// CHECK: [[VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*,
+
+// skip loop alloca's
+// CHECK: [[OMP_IV:.omp.iv+]] = alloca i{{[0-9]+}},
+// CHECK: [[OMP_LB:.omp.lb+]] = alloca i{{[0-9]+}},
+// CHECK: [[OMP_UB:.omp.ub+]] = alloca i{{[0-9]+}},
+// CHECK: [[OMP_ST:.omp.stride+]] = alloca i{{[0-9]+}},
+// CHECK: [[OMP_IS_LAST:.omp.is_last+]] = alloca i{{[0-9]+}},
+
+// private alloca's
+// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_INT_TY]]],
+// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_INT_TY]],
+// CHECK: [[TMP_PRIV:%.+]] = alloca [[S_INT_TY]]*,
+
+// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_REF:%.+]]
+
+// init addr alloca's with input values
+// CHECK-DAG: store {{.+}} [[VEC_IN]], {{.+}} [[VEC_ADDR]],
+// CHECK-DAG: store {{.+}} [[T_VAR_IN]], {{.+}}* [[T_VAR_ADDR]],
+// CHECK-DAG: store {{.+}} [[S_ARR_IN]], {{.+}} [[S_ARR_ADDR]],
+// CHECK-DAG: store {{.+}} [[VAR_IN]], {{.+}} [[VAR_ADDR]],
+
+// init private alloca's with addr alloca's
+// vec
+// CHECK-DAG: [[VEC_ADDR_VAL:%.+]] = load {{.+}}*, {{.+}}** [[VEC_ADDR]],
+// CHECK-DAG: [[VEC_PRIV_BCAST:%.+]] = bitcast {{.+}} [[VEC_PRIV]] to
+// CHECK-DAG: [[VEC_ADDR_BCAST:%.+]] = bitcast {{.+}} [[VEC_ADDR_VAL]] to
+// CHECK-DAG: call void @llvm.memcpy{{.+}}({{.+}}* [[VEC_PRIV_BCAST]], {{.+}}* [[VEC_ADDR_BCAST]],
+
+// s_arr
+// CHECK-DAG: [[S_ARR_ADDR_VAL:%.+]] = load {{.+}}*, {{.+}}** [[S_ARR_ADDR]],
+// CHECK-DAG: [[S_ARR_BGN:%.+]] = getelementptr {{.+}}, {{.+}}* [[S_ARR_PRIV]],
+// CHECK-DAG: [[S_ARR_ADDR_BCAST:%.+]] = bitcast {{.+}}* [[S_ARR_ADDR_VAL]] to
+// CHECK-DAG: [[S_ARR_BGN_GEP:%.+]] = getelementptr {{.+}}, {{.+}}* [[S_ARR_BGN]],
+// CHECK-DAG: [[S_ARR_EMPTY:%.+]] = icmp {{.+}} [[S_ARR_BGN]], [[S_ARR_BGN_GEP]]
+// CHECK-DAG: br {{.+}} [[S_ARR_EMPTY]], label %[[CPY_DONE:.+]], label %[[CPY_BODY:.+]]
+// CHECK-DAG: [[CPY_BODY]]:
+// CHECK-DAG: call void @llvm.memcpy{{.+}}(
+// CHECK-DAG: [[CPY_DONE]]:
+
+// var
+// CHECK-DAG: [[VAR_ADDR_REF:%.+]] = load {{.+}}*, {{.+}}* [[VAR_ADDR]],
+// CHECK-DAG: [[VAR_PRIV_BCAST:%.+]] = bitcast {{.+}}* [[VAR_PRIV]] to
+// CHECK-DAG: [[VAR_ADDR_BCAST:%.+]] = bitcast {{.+}}* [[VAR_ADDR_REF]] to
+// CHECK-DAG: call void @llvm.memcpy.{{.+}}({{.+}}* [[VAR_PRIV_BCAST]], {{.+}}* [[VAR_ADDR_BCAST]],
+// CHECK-DAG: store {{.+}}* [[VAR_PRIV]], {{.+}}** [[TMP_PRIV]],
+
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: call void @__kmpc_for_static_fini(
+
+// call destructors: var..
+// CHECK-DAG: call {{.+}} [[S_INT_TY_DEF_DESTR]]([[S_INT_TY]]* [[VAR_PRIV]])
+
+// ..and s_arr
+// CHECK: {{.+}}:
+// CHECK: [[S_ARR_EL_PAST:%.+]] = phi [[S_INT_TY]]*
+// CHECK: [[S_ARR_PRIV_ITEM:%.+]] = getelementptr {{.+}}, {{.+}} [[S_ARR_EL_PAST]],
+// CHECK: call {{.*}} [[S_INT_TY_DEF_DESTR]]([[S_INT_TY]]* [[S_ARR_PRIV_ITEM]])
+
+// CHECK: ret void
+
+#endif
diff --git a/test/OpenMP/distribute_parallel_for_simd_firstprivate_messages.cpp b/test/OpenMP/distribute_parallel_for_simd_firstprivate_messages.cpp
index 07d30e48312b..646407643b25 100644
--- a/test/OpenMP/distribute_parallel_for_simd_firstprivate_messages.cpp
+++ b/test/OpenMP/distribute_parallel_for_simd_firstprivate_messages.cpp
@@ -42,7 +42,7 @@ public:
};
class S5 {
int a;
- S5(const S5 &s5) : a(s5.a) {} // expected-note 4 {{implicitly declared private here}}
+ S5(const S5 &s5) : a(s5.a) {} // expected-note 2 {{implicitly declared private here}}
public:
S5() : a(0) {}
@@ -50,7 +50,7 @@ public:
};
class S6 {
int a;
- S6() : a(0) {}
+ S6() : a(0) {} // expected-note {{implicitly declared private here}}
public:
S6(const S6 &s6) : a(s6.a) {}
@@ -150,9 +150,10 @@ int foomain(int argc, char **argv) {
#pragma omp distribute parallel for simd firstprivate(i)
for (int k = 0; k < argc; ++k)
++k;
+// expected-error@+3 {{lastprivate variable cannot be firstprivate}} expected-note@+3 {{defined as lastprivate}}
#pragma omp target
#pragma omp teams
-#pragma omp distribute parallel for simd lastprivate(g) firstprivate(g) // expected-error {{calling a private constructor of class 'S5'}}
+#pragma omp distribute parallel for simd lastprivate(g) firstprivate(g)
for (i = 0; i < argc; ++i)
foo();
#pragma omp parallel private(i)
@@ -314,14 +315,16 @@ int main(int argc, char **argv) {
#pragma omp distribute parallel for simd firstprivate(j)
for (i = 0; i < argc; ++i)
foo();
+// expected-error@+3 {{lastprivate variable cannot be firstprivate}} expected-note@+3 {{defined as lastprivate}}
#pragma omp target
#pragma omp teams
-#pragma omp distribute parallel for simd lastprivate(g) firstprivate(g) // expected-error {{calling a private constructor of class 'S5'}}
+#pragma omp distribute parallel for simd lastprivate(g) firstprivate(g)
for (i = 0; i < argc; ++i)
foo();
+// expected-error@+3 {{lastprivate variable cannot be firstprivate}} expected-note@+3 {{defined as lastprivate}}
#pragma omp target
#pragma omp teams
-#pragma omp distribute parallel for simd lastprivate(n) firstprivate(n) // OK
+#pragma omp distribute parallel for simd lastprivate(n) firstprivate(n) // expected-error {{calling a private constructor of class 'S6'}}
for (i = 0; i < argc; ++i)
foo();
#pragma omp parallel
diff --git a/test/OpenMP/distribute_parallel_for_simd_if_codegen.cpp b/test/OpenMP/distribute_parallel_for_simd_if_codegen.cpp
new file mode 100644
index 000000000000..b55038720134
--- /dev/null
+++ b/test/OpenMP/distribute_parallel_for_simd_if_codegen.cpp
@@ -0,0 +1,192 @@
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple %itanium_abi_triple -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple %itanium_abi_triple -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+void fn1();
+void fn2();
+void fn3();
+void fn4();
+void fn5();
+void fn6();
+
+int Arg;
+
+// CHECK-LABEL: define {{.*}}void @{{.+}}gtid_test
+void gtid_test() {
+#pragma omp target
+#pragma omp teams
+// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+// CHECK: call void [[OFFLOADING_FUN_0:@.+]](
+// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+// CHECK: call void [[OFFLOADING_FUN_1:@.+]](
+#pragma omp distribute parallel for simd
+ for(int i = 0 ; i < 100; i++) {}
+ // CHECK: define internal void [[OFFLOADING_FUN_0]](
+ // CHECK: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, i32 0, {{.+}}* [[OMP_TEAMS_OUTLINED_0:@.+]] to {{.+}})
+ // CHECK: define{{.+}} void [[OMP_TEAMS_OUTLINED_0]](
+ // CHECK: call void @__kmpc_for_static_init_4(
+ // CHECK: call void {{.+}} @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{.+}} 2, {{.+}}* [[OMP_OUTLINED_0:@.+]] to void
+ // CHECK: call void @__kmpc_for_static_fini(
+
+ // CHECK: define{{.+}} void [[OMP_OUTLINED_0]](
+ // CHECK: call void @__kmpc_for_static_init_4(
+ // CHECK: call void @__kmpc_for_static_fini(
+ // CHECK: ret
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd if (parallel: false)
+ for(int i = 0 ; i < 100; i++) {
+ // CHECK: define internal void [[OFFLOADING_FUN_1]](
+ // CHECK: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, i32 0, {{.+}}* [[OMP_TEAMS_OUTLINED_1:@.+]] to {{.+}})
+ // CHECK: define{{.+}} void [[OMP_TEAMS_OUTLINED_1]](
+ // CHECK: call void @__kmpc_for_static_init_4(
+ // CHECK: call void @__kmpc_serialized_parallel(
+ // CHECK: call void [[OMP_OUTLINED_1:@.+]](
+ // CHECK: call void @__kmpc_end_serialized_parallel(
+ // CHECK: call void @__kmpc_for_static_fini(
+ // CHECK: define{{.+}} void [[OMP_OUTLINED_1]](
+ // CHECK: call void @__kmpc_for_static_init_4(
+ // CHECK: call void @{{.+}}gtid_test
+ // CHECK: call void @__kmpc_for_static_fini(
+ // CHECK: ret
+ gtid_test();
+ }
+}
+
+
+template <typename T>
+int tmain(T Arg) {
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd if (true)
+ for(int i = 0 ; i < 100; i++) {
+ fn1();
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd if (false)
+ for(int i = 0 ; i < 100; i++) {
+ fn2();
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd if (parallel: Arg)
+ for(int i = 0 ; i < 100; i++) {
+ fn3();
+ }
+ return 0;
+}
+
+// CHECK-LABEL: define {{.*}}i{{[0-9]+}} @main()
+int main() {
+// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+// CHECK: call void [[OFFLOADING_FUN_0:@.+]](
+// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+// CHECK: call void [[OFFLOADING_FUN_1:@.+]](
+// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+// CHECK: call void [[OFFLOADING_FUN_2:@.+]](
+// CHECK: = call {{.*}}i{{.+}} @{{.+}}tmain
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd if (true)
+ for(int i = 0 ; i < 100; i++) {
+ // CHECK: define internal void [[OFFLOADING_FUN_0]](
+ // CHECK: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, i32 0, {{.+}}* [[OMP_TEAMS_OUTLINED_0:@.+]] to {{.+}})
+ // CHECK: define{{.+}} void [[OMP_TEAMS_OUTLINED_0]](
+
+ // CHECK: call void @__kmpc_for_static_init_4(
+ // CHECK: call void {{.+}} @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{.+}} 2, {{.+}}* [[OMP_OUTLINED_2:@.+]] to void
+ // CHECK: call void @__kmpc_for_static_fini(
+ // CHECK: define{{.+}} void [[OMP_OUTLINED_2]](
+ // CHECK: call void @__kmpc_for_static_init_4(
+ // CHECK: call {{.*}}void @{{.+}}fn4
+ // CHECK: call void @__kmpc_for_static_fini(
+
+ fn4();
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd if (false)
+ for(int i = 0 ; i < 100; i++) {
+ // CHECK: define internal void [[OFFLOADING_FUN_1]](
+ // CHECK: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, i32 0, {{.+}}* [[OMP_TEAMS_OUTLINED_1:@.+]] to {{.+}})
+ // CHECK: define{{.+}} void [[OMP_TEAMS_OUTLINED_1]](
+
+ // CHECK: call void @__kmpc_for_static_init_4(
+ // CHECK: call void @__kmpc_serialized_parallel(
+ // CHECK: call void [[OMP_OUTLINED_3:@.+]](
+ // CHECK: call void @__kmpc_end_serialized_parallel(
+ // CHECK: call void @__kmpc_for_static_fini(
+
+ // CHECK: define{{.+}} void [[OMP_OUTLINED_3]](
+ // CHECK: call void @__kmpc_for_static_init_4(
+ // CHECK: call {{.*}}void @{{.+}}fn5
+ // CHECK: call void @__kmpc_for_static_fini(
+ fn5();
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd if (Arg)
+ for(int i = 0 ; i < 100; i++) {
+ // CHECK: define internal void [[OFFLOADING_FUN_2]](
+ // CHECK: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}}* [[OMP_TEAMS_OUTLINED_2:@.+]] to {{.+}})
+ // CHECK: define{{.+}} void [[OMP_TEAMS_OUTLINED_2]](
+
+ // CHECK: call void @__kmpc_for_static_init_4(
+ // CHECK: call void {{.+}} @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{.+}} 2, {{.+}}* [[OMP_OUTLINED_4:@.+]] to void
+ // CHECK: call void @__kmpc_serialized_parallel(
+ // CHECK: call void [[OMP_OUTLINED_4:@.+]](
+ // CHECK: call void @__kmpc_end_serialized_parallel(
+ // CHECK: call void @__kmpc_for_static_fini(
+
+ // CHECK: define{{.+}} void [[OMP_OUTLINED_4]](
+ // CHECK: call void @__kmpc_for_static_init_4(
+ // CHECK: call {{.*}}void @{{.+}}fn6
+ // CHECK: call void @__kmpc_for_static_fini(
+ fn6();
+ }
+
+ return tmain(Arg);
+}
+
+// CHECK-LABEL: define {{.+}} @{{.+}}tmain
+
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: call {{.*}}void {{.+}} @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{.+}} 2, void {{.+}}* [[T_OUTLINE_FUN_1:@.+]] to void
+// CHECK: call void @__kmpc_for_static_fini(
+
+// CHECK: define internal {{.*}}void [[T_OUTLINE_FUN_1]]
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: call {{.*}}void @{{.+}}fn1
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: ret void
+
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: call {{.*}}void @__kmpc_serialized_parallel(
+// CHECK: call void [[T_OUTLINE_FUN_2:@.+]](
+// CHECK: call {{.*}}void @__kmpc_end_serialized_parallel(
+// CHECK: call void @__kmpc_for_static_fini(
+
+// CHECK: define internal {{.*}}void [[T_OUTLINE_FUN_2]]
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: call {{.*}}void @{{.+}}fn2
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: ret void
+
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: call {{.*}}void {{.+}} @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{.+}} 2, void {{.+}}* [[T_OUTLINE_FUN_3:@.+]] to void
+// CHECK: call {{.*}}void @__kmpc_serialized_parallel(
+// call void [[T_OUTLINE_FUN_3:@.+]](
+// CHECK: call {{.*}}void @__kmpc_end_serialized_parallel(
+
+// CHECK: define internal {{.*}}void [[T_OUTLINE_FUN_3]]
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: call {{.*}}void @{{.+}}fn3
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: ret void
+#endif
diff --git a/test/OpenMP/distribute_parallel_for_simd_lastprivate_codegen.cpp b/test/OpenMP/distribute_parallel_for_simd_lastprivate_codegen.cpp
new file mode 100644
index 000000000000..89ef33abd64d
--- /dev/null
+++ b/test/OpenMP/distribute_parallel_for_simd_lastprivate_codegen.cpp
@@ -0,0 +1,671 @@
+// RUN: %clang_cc1 -DLAMBDA -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+// RUN: %clang_cc1 -DLAMBDA -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-32
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-32
+
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+template <class T>
+struct S {
+ T f;
+ S(T a) : f(a) {}
+ S() : f() {}
+ operator T() { return T(); }
+ ~S() {}
+};
+
+// CHECK: [[S_FLOAT_TY:%.+]] = type { float }
+// CHECK: [[S_INT_TY:%.+]] = type { i{{[0-9]+}} }
+template <typename T>
+T tmain() {
+ S<T> test;
+ T t_var = T();
+ T vec[] = {1, 2};
+ S<T> s_arr[] = {1, 2};
+ S<T> &var = test;
+ #pragma omp target
+ #pragma omp teams
+#pragma omp distribute parallel for simd lastprivate(t_var, vec, s_arr, s_arr, var, var)
+ for (int i = 0; i < 2; ++i) {
+ vec[i] = t_var;
+ s_arr[i] = var;
+ }
+ return T();
+}
+
+int main() {
+ static int svar;
+ volatile double g;
+ volatile double &g1 = g;
+
+ #ifdef LAMBDA
+ // LAMBDA-LABEL: @main
+ // LAMBDA: call{{.*}} void [[OUTER_LAMBDA:@.+]](
+ [&]() {
+ static float sfvar;
+ // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
+ // LAMBDA: call i{{[0-9]+}} @__tgt_target_teams(
+ // LAMBDA: call void [[OFFLOADING_FUN:@.+]](
+
+ // LAMBDA: define{{.+}} void [[OFFLOADING_FUN]](
+ // LAMBDA: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, i32 4, {{.+}}* [[OMP_OUTLINED:@.+]] to {{.+}})
+ #pragma omp target
+ #pragma omp teams
+#pragma omp distribute parallel for simd lastprivate(g, g1, svar, sfvar)
+ for (int i = 0; i < 2; ++i) {
+ // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_OUTLINED]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, double*{{.+}} [[G_IN:%.+]], double*{{.+}} [[G1_IN:%.+]], i{{[0-9]+}}*{{.+}} [[SVAR_IN:%.+]], float*{{.+}} [[SFVAR_IN:%.+]])
+ // LAMBDA: [[G_PRIVATE_ADDR:%.+]] = alloca double*,
+ // LAMBDA: [[G1_PRIVATE_ADDR:%.+]] = alloca double*,
+ // LAMBDA: [[SVAR_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}*,
+ // LAMBDA: [[SFVAR_PRIVATE_ADDR:%.+]] = alloca float*,
+ // LAMBDA: [[TMP_G1:%.+]] = alloca double*,
+ // loop variables
+ // LAMBDA: {{.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: {{.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: {{.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: {{.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: {{.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: [[OMP_IS_LAST:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[G_PRIVATE:%.+]] = alloca double,
+ // LAMBDA: [[G1_PRIVATE:%.+]] = alloca double,
+ // LAMBDA: [[TMP_G1_PRIVATE:%.+]] = alloca double*,
+ // LAMBDA: [[SVAR_PRIVATE:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[SFVAR_PRIVATE:%.+]] = alloca float,
+
+ // init addr alloca's
+ // LAMBDA: store double* [[G_IN]], double** [[G_PRIVATE_ADDR]],
+ // LAMBDA: store double* [[G1_IN]], double** [[G1_PRIVATE_ADDR]],
+ // LAMBDA: store i{{[0-9]+}}* [[SVAR_IN]], i{{[0-9]+}}** [[SVAR_PRIVATE_ADDR]],
+ // LAMBDA: store float* [[SFVAR_IN]], float** [[SFVAR_PRIVATE_ADDR]],
+
+ // init private variables
+ // LAMBDA: [[G_IN_REF:%.+]] = load double*, double** [[G_PRIVATE_ADDR]],
+ // LAMBDA: [[SVAR_IN_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SVAR_PRIVATE_ADDR]],
+ // LAMBDA: [[SFVAR_IN_REF:%.+]] = load float*, float** [[SFVAR_PRIVATE_ADDR]],
+ // LAMBDA: [[G1_IN_REF:%.+]] = load double*, double** [[G1_PRIVATE_ADDR]],
+ // LAMBDA: store double* [[G1_IN_REF]], double** [[TMP_G1]],
+ // LAMBDA: [[TMP_G1_VAL:%.+]] = load double*, double** [[TMP_G1]],
+ // LAMBDA: store double* [[G1_PRIVATE]], double** [[TMP_G1_PRIVATE]],
+
+ // LAMBDA: call {{.*}}void @__kmpc_for_static_init_4(
+ // LAMBDA: [[G1_PAR:%.+]] = load{{.+}}, {{.+}} [[TMP_G1_PRIVATE]],
+ // LAMBDA-64: call{{.+}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}}[[OMP_PARFOR_OUTLINED:@.+]] to void ({{.+}})*), {{.+}}, {{.+}}, {{.+}} [[G_PRIVATE]], {{.+}} [[G1_PAR]], {{.+}} [[SVAR_PRIVATE]], {{.+}} [[SFVAR_PRIVATE]])
+ // LAMBDA-32: call{{.+}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}}[[OMP_PARFOR_OUTLINED:@.+]] to void ({{.+}})*), {{.+}}, {{.+}}, {{.+}} [[G_PRIVATE]], {{.+}} [[G1_PAR]], {{.+}} [[SVAR_PRIVATE]], {{.+}} [[SFVAR_PRIVATE]])
+ // LAMBDA: call {{.*}}void @__kmpc_for_static_fini(
+
+ // linear counter
+ // LAMBDA: [[OMP_IS_LAST_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[OMP_IS_LAST]],
+ // LAMBDA: [[IS_LAST_IT:%.+]] = icmp ne i{{[0-9]+}} [[OMP_IS_LAST_VAL]], 0
+ // LAMBDA: br i1 [[IS_LAST_IT]], label %[[OMP_COUNTER_BLOCK:.+]], label %[[OMP_COUNTER_DONE:.+]]
+ // LAMBDA: [[OMP_COUNTER_BLOCK]]:
+ // LAMBDA: store i{{[0-9]+}} 2, i{{[0-9]+}}* %
+ // LAMBDA: br label %[[OMP_COUNTER_DONE]]
+ // LAMBDA: [[OMP_COUNTER_DONE]]:
+
+ // lastprivate
+ // LAMBDA: [[OMP_IS_LAST_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[OMP_IS_LAST]],
+ // LAMBDA: [[IS_LAST_IT:%.+]] = icmp ne i{{[0-9]+}} [[OMP_IS_LAST_VAL]], 0
+ // LAMBDA: br i1 [[IS_LAST_IT]], label %[[OMP_LASTPRIV_BLOCK:.+]], label %[[OMP_LASTPRIV_DONE:.+]]
+
+ // LAMBDA: [[OMP_LASTPRIV_BLOCK]]:
+ // LAMBDA: [[G_PRIV_VAL:%.+]] = load double, double* [[G_PRIVATE]],
+ // LAMBDA: store{{.*}} double [[G_PRIV_VAL]], double* [[G_IN_REF]],
+ // LAMBDA: [[TMP_G1_PRIV_REF:%.+]] = load double*, double** [[TMP_G1_PRIVATE]],
+ // LAMBDA: [[TMP_G1_PRIV_VAL:%.+]] = load double, double* [[TMP_G1_PRIV_REF]],
+ // LAMBDA: store{{.*}} double [[TMP_G1_PRIV_VAL]], double* [[TMP_G1_VAL]],
+
+ // LAMBDA: [[SVAR_PRIV_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SVAR_PRIVATE]],
+ // LAMBDA: store i{{[0-9]+}} [[SVAR_PRIV_VAL]], i{{[0-9]+}}* [[SVAR_IN_REF]],
+ // LAMBDA: [[SFVAR_PRIV_VAL:%.+]] = load float, float* [[SFVAR_PRIVATE]],
+ // LAMBDA: store float [[SFVAR_PRIV_VAL]], float* [[SFVAR_IN_REF]],
+ // LAMBDA: br label %[[OMP_LASTPRIV_DONE]]
+ // LAMBDA: [[OMP_LASTPRIV_DONE]]:
+ // LAMBDA: ret
+
+ g = 1;
+ g1 = 1;
+ svar = 3;
+ sfvar = 4.0;
+ // outlined function for 'parallel for'
+ // LAMBDA-64: define{{.+}} void [[OMP_PARFOR_OUTLINED]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, {{.+}}, {{.+}}, {{.+}} [[G_IN:%.+]], {{.+}} [[G1_IN:%.+]], {{.+}} [[SVAR_IN:%.+]], {{.+}} [[SFVAR_IN:%.+]])
+ // LAMBDA-32: define{{.+}} void [[OMP_PARFOR_OUTLINED]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, {{.+}}, {{.+}}, {{.+}} [[G_IN:%.+]], {{.+}} [[G1_IN:%.+]], {{.+}} [[SVAR_IN:%.+]], {{.+}} [[SFVAR_IN:%.+]])
+
+ // addr alloca's
+ // LAMBDA: [[G_PRIVATE_ADDR:%.+]] = alloca double*,
+ // LAMBDA: [[G1_PRIVATE_ADDR:%.+]] = alloca double*,
+ // LAMBDA: [[SVAR_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}*,
+ // LAMBDA: [[SFVAR_PRIVATE_ADDR:%.+]] = alloca float*,
+
+ // loop variables
+ // LAMBDA: {{.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: {{.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: {{.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: {{.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: {{.+}} = alloca i{{[0-9]+}},
+
+ // private alloca's
+ // LAMBDA: [[OMP_IS_LAST:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[G_PRIVATE:%.+]] = alloca double,
+ // LAMBDA: [[G1_PRIVATE:%.+]] = alloca double,
+ // LAMBDA: [[TMP_G1_PRIVATE:%.+]] = alloca double*,
+ // LAMBDA: [[SVAR_PRIVATE:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[SFVAR_PRIVATE:%.+]] = alloca float,
+
+ // init addr alloca's
+ // LAMBDA: store double* [[G_IN]], double** [[G_PRIVATE_ADDR]],
+ // LAMBDA: store double* [[G1_IN]], double** [[G1_PRIVATE_ADDR]],
+ // LAMBDA: store i{{[0-9]+}}* [[SVAR_IN]], i{{[0-9]+}}** [[SVAR_PRIVATE_ADDR]],
+ // LAMBDA: store float* [[SFVAR_IN]], float** [[SFVAR_PRIVATE_ADDR]],
+
+ // init private variables
+ // LAMBDA: [[G_IN_REF:%.+]] = load double*, double** [[G_PRIVATE_ADDR]],
+ // LAMBDA: [[SVAR_IN_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SVAR_PRIVATE_ADDR]],
+ // LAMBDA: [[SFVAR_IN_REF:%.+]] = load float*, float** [[SFVAR_PRIVATE_ADDR]],
+
+ // LAMBDA: [[G1_IN_REF:%.+]] = load double*, double** [[G1_PRIVATE_ADDR]],
+ // LAMBDA: store double* [[G1_PRIVATE]], double** [[TMP_G1_PRIVATE]],
+
+ // LAMBDA: call {{.*}}void @__kmpc_for_static_init_4(
+
+ // loop body
+ // LAMBDA: store double 1.0{{.+}}, double* [[G_PRIVATE]],
+ // LAMBDA: [[TMP_G1_REF:%.+]] = load double*, double** [[TMP_G1_PRIVATE]],
+ // LAMBDA: store{{.+}} double 1.0{{.+}}, double* [[TMP_G1_REF]],
+ // LAMBDA: store i{{[0-9]+}} 3, i{{[0-9]+}}* [[SVAR_PRIVATE]],
+ // LAMBDA: store float 4.0{{.+}}, float* [[SFVAR_PRIVATE]],
+ // LAMBDA: [[G_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // LAMBDA: store double* [[G_PRIVATE]], double** [[G_PRIVATE_ADDR_REF]],
+ // LAMBDA: [[TMP_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // LAMBDA: [[G1_PRIVATE_ADDR_FROM_TMP:%.+]] = load double*, double** [[TMP_G1_PRIVATE]],
+ // LAMBDA: store double* [[G1_PRIVATE_ADDR_FROM_TMP]], double** [[TMP_PRIVATE_ADDR_REF]],
+ // LAMBDA: [[SVAR_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+ // LAMBDA: store i{{[0-9]+}}* [[SVAR_PRIVATE]], i{{[0-9]+}}** [[SVAR_PRIVATE_ADDR_REF]]
+ // LAMBDA: [[SFVAR_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 3
+ // LAMBDA: store float* [[SFVAR_PRIVATE]], float** [[SFVAR_PRIVATE_ADDR_REF]]
+ // LAMBDA: call{{.*}} void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]])
+
+ // LAMBDA: call {{.*}}void @__kmpc_for_static_fini(
+
+ // lastprivate
+ // LAMBDA: [[OMP_IS_LAST_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[OMP_IS_LAST]],
+ // LAMBDA: [[OMP_IS_LAST_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[OMP_IS_LAST]],
+ // LAMBDA: [[IS_LAST_IT:%.+]] = icmp ne i{{[0-9]+}} [[OMP_IS_LAST_VAL]], 0
+ // LAMBDA: br i1 [[IS_LAST_IT]], label %[[OMP_LASTPRIV_BLOCK:.+]], label %[[OMP_LASTPRIV_DONE:.+]]
+ // LAMBDA: [[OMP_LASTPRIV_BLOCK]]:
+ // LAMBDA: [[G_PRIV_VAL:%.+]] = load double, double* [[G_PRIVATE]],
+ // LAMBDA: store{{.*}} double [[G_PRIV_VAL]], double* [[G_IN_REF]],
+ // LAMBDA: [[TMP_G1_PRIV_REF:%.+]] = load double*, double** [[TMP_G1_PRIVATE]],
+ // LAMBDA: [[TMP_G1_PRIV_VAL:%.+]] = load double, double* [[TMP_G1_PRIV_REF]],
+ // LAMBDA: store{{.*}} double [[TMP_G1_PRIV_VAL]], double* [[G1_IN_REF]],
+ // LAMBDA: [[SVAR_PRIV_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SVAR_PRIVATE]],
+ // LAMBDA: store i{{[0-9]+}} [[SVAR_PRIV_VAL]], i{{[0-9]+}}* [[SVAR_IN_REF]],
+ // LAMBDA: [[SFVAR_PRIV_VAL:%.+]] = load float, float* [[SFVAR_PRIVATE]],
+ // LAMBDA: store float [[SFVAR_PRIV_VAL]], float* [[SFVAR_IN_REF]],
+ // LAMBDA: br label %[[OMP_LASTPRIV_DONE]]
+ // LAMBDA: [[OMP_LASTPRIV_DONE]]:
+ // LAMBDA: ret
+
+ [&]() {
+ // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]])
+ // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]],
+ g = 2;
+ g1 = 2;
+ svar = 4;
+ sfvar = 8.0;
+ // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]]
+ // LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // LAMBDA: [[G_REF:%.+]] = load double*, double** [[G_PTR_REF]]
+ // LAMBDA: store double 2.0{{.+}}, double* [[G_REF]]
+
+ // LAMBDA: [[TMP_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // LAMBDA: [[G1_REF:%.+]] = load double*, double** [[TMP_PTR_REF]]
+ // LAMBDA: store double 2.0{{.+}}, double* [[G1_REF]],
+ // LAMBDA: [[SVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+ // LAMBDA: [[SVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SVAR_PTR_REF]]
+ // LAMBDA: store i{{[0-9]+}} 4, i{{[0-9]+}}* [[SVAR_REF]]
+ // LAMBDA: [[SFVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 3
+ // LAMBDA: [[SFVAR_REF:%.+]] = load float*, float** [[SFVAR_PTR_REF]]
+ // LAMBDA: store float 8.0{{.+}}, float* [[SFVAR_REF]]
+ }();
+ }
+ }();
+ return 0;
+ #else
+ S<float> test;
+ int t_var = 0;
+ int vec[] = {1, 2};
+ S<float> s_arr[] = {1, 2};
+ S<float> &var = test;
+
+ #pragma omp target
+ #pragma omp teams
+#pragma omp distribute parallel for simd lastprivate(t_var, vec, s_arr, s_arr, var, var, svar)
+ for (int i = 0; i < 2; ++i) {
+ vec[i] = t_var;
+ s_arr[i] = var;
+ }
+ int i;
+
+ return tmain<int>();
+ #endif
+}
+
+// CHECK: define{{.*}} i{{[0-9]+}} @main()
+// CHECK: [[TEST:%.+]] = alloca [[S_FLOAT_TY]],
+// CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR:@.+]]([[S_FLOAT_TY]]* [[TEST]])
+// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+// CHECK: call void [[OFFLOAD_FUN:@.+]](i{{[0-9]+}} {{.+}}, [2 x i{{[0-9]+}}]* {{.+}}, [2 x [[S_FLOAT_TY]]]* {{.+}}, [[S_FLOAT_TY]]* {{.+}}, i{{[0-9]+}} {{.+}})
+// CHECK: ret
+
+// CHECK: define{{.+}} [[OFFLOAD_FUN]](i{{[0-9]+}} {{.+}}, [2 x i{{[0-9]+}}]*{{.+}} {{.+}}, [2 x [[S_FLOAT_TY]]]*{{.+}} {{.+}}, [[S_FLOAT_TY]]*{{.+}} {{.+}}, i{{[0-9]+}} {{.+}})
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_teams(
+// CHECK: ret
+//
+// CHECK: define internal void [[OMP_OUTLINED:@.+]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i{{[0-9]+}}*{{.+}} [[T_VAR_IN:%.+]], [2 x i{{[0-9]+}}]*{{.+}} [[VEC_IN:%.+]], [2 x [[S_FLOAT_TY]]]*{{.+}} [[S_ARR_IN:%.+]], [[S_FLOAT_TY]]*{{.+}} [[VAR_IN:%.+]], i{{[0-9]+}}*{{.*}} [[S_VAR_IN:%.+]])
+// CHECK: {{.+}} = alloca i{{[0-9]+}}*,
+// CHECK: {{.+}} = alloca i{{[0-9]+}}*,
+// CHECK: [[T_VAR_ADDR:%.+]] = alloca i{{[0-9]+}}*,
+// CHECK: [[VEC_ADDR:%.+]] = alloca [2 x i{{[0-9]+}}]*,
+// CHECK: [[S_ARR_ADDR:%.+]] = alloca [2 x [[S_FLOAT_TY]]]*,
+// CHECK: [[VAR_ADDR:%.+]] = alloca [[S_FLOAT_TY]]*,
+// CHECK: [[SVAR_ADDR:%.+]] = alloca i{{[0-9]+}}*,
+// CHECK: [[TMP:%.*]] = alloca [[S_FLOAT_TY]]*,
+// skip loop variables
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: [[OMP_IS_LAST:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]],
+// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]],
+// CHECK: [[TMP_PRIV:%.+]] = alloca [[S_FLOAT_TY]]*,
+// CHECK: [[S_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+
+// copy from parameters to local address variables
+// CHECK: store i{{[0-9]+}}* [[T_VAR_IN]], i{{[0-9]+}}** [[T_VAR_ADDR]],
+// CHECK: store [2 x i{{[0-9]+}}]* [[VEC_IN]], [2 x i{{[0-9]+}}]** [[VEC_ADDR]],
+// CHECK: store [2 x [[S_FLOAT_TY]]]* [[S_ARR_IN]], [2 x [[S_FLOAT_TY]]]** [[S_ARR_ADDR]],
+// CHECK: store [[S_FLOAT_TY]]* [[VAR_IN]], [[S_FLOAT_TY]]** [[VAR_ADDR]],
+// CHECK: store i{{[0-9]+}}* [[S_VAR_IN]], i{{[0-9]+}}** [[SVAR_ADDR]],
+
+// load content of local address variables
+// CHECK: [[T_VAR_ADDR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[T_VAR_ADDR]],
+// CHECK: [[VEC_ADDR_REF:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** [[VEC_ADDR]],
+// CHECK: [[S_ARR_ADDR_REF:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[S_ARR_ADDR]],
+// CHECK: [[SVAR_ADDR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SVAR_ADDR]],
+// CHECK: [[VAR_ADDR_REF:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[VAR_ADDR]],
+// CHECK: store [[S_FLOAT_TY]]* [[VAR_ADDR_REF]], [[S_FLOAT_TY]]** [[TMP]],
+// CHECK: store i{{[0-9]+}} 0, i{{[0-9]+}}* [[OMP_IS_LAST]],
+
+// call constructor for s_arr
+// CHECK: [[S_ARR_BGN:%.+]] = getelementptr{{.+}} [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[S_ARR_PRIV]],
+// CHECK: [[S_ARR_END:%.+]] = getelementptr {{.+}} [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[S_ARR_BGN]],
+// CHECK: br label %[[S_ARR_CST_LOOP:.+]]
+// CHECK: [[S_ARR_CST_LOOP]]:
+// CHECK: [[S_ARR_CTOR:%.+]] = phi {{.+}}
+// CHECK: call void [[S_FLOAT_TY_DEF_CONSTR]]([[S_FLOAT_TY]]* [[S_ARR_CTOR]])
+// CHECK: [[S_ARR_NEXT:%.+]] = getelementptr {{.+}} [[S_ARR_CTOR]],
+// CHECK: [[S_ARR_DONE:%.+]] = icmp {{.+}} [[S_ARR_NEXT]], [[S_ARR_END]]
+// CHECK: br i1 [[S_ARR_DONE]], label %[[S_ARR_CST_END:.+]], label %[[S_ARR_CST_LOOP]]
+// CHECK: [[S_ARR_CST_END]]:
+// CHECK: [[TMP_REF:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[TMP]],
+// CHECK: call void [[S_FLOAT_TY_DEF_CONSTR]]([[S_FLOAT_TY]]* [[VAR_PRIV]])
+// CHECK: store [[S_FLOAT_TY]]* [[VAR_PRIV]], [[S_FLOAT_TY]]** [[TMP_PRIV]],
+
+// the distribute loop
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: [[TMP_PRIV_VAL:%.+]] = load {{.+}}, {{.+}} [[TMP_PRIV]],
+// CHECK-64: call{{.+}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}}[[OMP_PARFOR_OUTLINED:@.+]] to void ({{.+}})*), {{.+}}, {{.+}}, {{.+}} [[VEC_PRIV]], {{.+}} [[T_VAR_PRIV]], {{.+}} [[S_ARR_PRIV]], {{.+}} [[TMP_PRIV_VAL]], {{.+}} [[S_VAR_PRIV]])
+// CHECK-32: call{{.+}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}}[[OMP_PARFOR_OUTLINED:@.+]] to void ({{.+}})*), {{.+}}, {{.+}}, {{.+}} [[VEC_PRIV]], {{.+}} [[T_VAR_PRIV]], {{.+}} [[S_ARR_PRIV]], {{.+}} [[TMP_PRIV_VAL]], {{.+}} [[S_VAR_PRIV]])
+
+// CHECK: call void @__kmpc_for_static_fini(
+
+// lastprivates
+// CHECK: [[OMP_IS_LAST_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[OMP_IS_LAST]],
+// CHECK: [[IS_LAST_IT:%.+]] = icmp ne i{{[0-9]+}} [[OMP_IS_LAST_VAL]], 0
+// CHECK: br i1 [[IS_LAST_IT]], label %[[OMP_LASTPRIV_BLOCK:.+]], label %[[OMP_LASTPRIV_DONE:.+]]
+
+// CHECK: [[OMP_LASTPRIV_BLOCK]]:
+// CHECK: [[T_VAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_PRIV]],
+// CHECK: store i{{[0-9]+}} [[T_VAR_VAL]], i{{[0-9]+}}* [[T_VAR_ADDR_REF]],
+// CHECK: [[BCAST_VEC_ADDR_REF:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_ADDR_REF]] to i8*
+// CHECK: [[BCAST_VEC_PRIV:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[BCAST_VEC_ADDR_REF]], i8* [[BCAST_VEC_PRIV]],
+// CHECK: [[S_ARR_BEGIN:%.+]] = getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[S_ARR_ADDR_REF]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+// CHECK: [[S_ARR_PRIV_BCAST:%.+]] = bitcast [2 x [[S_FLOAT_TY]]]* [[S_ARR_PRIV]] to [[S_FLOAT_TY]]*
+// CHECK: [[S_ARR_BEGIN_GEP:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[S_ARR_BEGIN]], i{{[0-9]+}} 2
+// CHECK: [[S_ARR_IS_EMPTY:%.+]] = icmp eq [[S_FLOAT_TY]]* [[S_ARR_BEGIN]], [[S_ARR_BEGIN_GEP]]
+// CHECK: br i1 [[S_ARR_IS_EMPTY]], label %[[S_ARR_COPY_DONE:.+]], label %[[S_ARR_COPY_BLOCK:.+]]
+// CHECK: [[S_ARR_COPY_BLOCK]]:
+// CHECK: [[S_ARR_SRC_EL:%.+]] = phi [[S_FLOAT_TY]]*{{.+}}
+// CHECK: [[S_ARR_DST_EL:%.+]] = phi [[S_FLOAT_TY]]*{{.+}}
+// CHECK: [[S_ARR_DST_BCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[S_ARR_DST_EL]] to i8*
+// CHECK: [[S_ARR_SRC_BCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[S_ARR_SRC_EL]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[S_ARR_DST_BCAST]], i8* [[S_ARR_SRC_BCAST]]{{.+}})
+// CHECK: [[S_ARR_DST_NEXT:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[S_ARR_DST_EL]], i{{[0-9]+}} 1
+// CHECK: [[S_ARR_SRC_NEXT:%.+]] = getelementptr{{.+}}
+// CHECK: [[CPY_IS_FINISHED:%.+]] = icmp eq [[S_FLOAT_TY]]* [[S_ARR_DST_NEXT]], [[S_ARR_BEGIN_GEP]]
+// CHECK: br i1 [[CPY_IS_FINISHED]], label %[[S_ARR_COPY_DONE]], label %[[S_ARR_COPY_BLOCK]]
+// CHECK: [[S_ARR_COPY_DONE]]:
+// CHECK: [[TMP_VAL1:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[TMP_PRIV]],
+// CHECK: [[VAR_ADDR_REF_BCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[TMP_REF]] to i8*
+// CHECK: [[TMP_VAL1_BCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[TMP_VAL1]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[VAR_ADDR_REF_BCAST]], i8* [[TMP_VAL1_BCAST]],{{.+}})
+// CHECK: [[SVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[S_VAR_PRIV]],
+// CHECK: store i{{[0-9]+}} [[SVAR_VAL]], i{{[0-9]+}}* [[SVAR_ADDR_REF]],
+// CHECK: ret void
+
+// outlined function for 'parallel for'
+// CHECK-64: define{{.+}} void [[OMP_PARFOR_OUTLINED]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, {{.+}}, {{.+}}, {{.+}} [[VEC_IN:%.+]], {{.+}} [[T_VAR_IN:%.+]], {{.+}} [[S_ARR_IN:%.+]], {{.+}} [[VAR_IN:%.+]], {{.+}} [[SVAR_IN:%.+]])
+// CHECK-32: define{{.+}} void [[OMP_PARFOR_OUTLINED]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, {{.+}}, {{.+}}, {{.+}} [[VEC_IN:%.+]], {{.+}} [[T_VAR_IN:%.+]], {{.+}} [[S_ARR_IN:%.+]], {{.+}} [[VAR_IN:%.+]], {{.+}} [[SVAR_IN:%.+]])
+
+// CHECK: {{.+}} = alloca i{{[0-9]+}}*,
+// CHECK: {{.+}} = alloca i{{[0-9]+}}*,
+// CHECK: [[VEC_ADDR:%.+]] = alloca [2 x i{{[0-9]+}}]*,
+// CHECK: [[T_VAR_ADDR:%.+]] = alloca i{{[0-9]+}}*,
+// CHECK: [[S_ARR_ADDR:%.+]] = alloca [2 x [[S_FLOAT_TY]]]*,
+// CHECK: [[VAR_ADDR:%.+]] = alloca [[S_FLOAT_TY]]*,
+// CHECK: [[SVAR_ADDR:%.+]] = alloca i{{[0-9]+}}*,
+// skip loop variables
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: [[OMP_IS_LAST:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]],
+// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]],
+// CHECK: [[TMP_PRIV:%.+]] = alloca [[S_FLOAT_TY]]*,
+// CHECK: [[S_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+
+// copy from parameters to local address variables
+// CHECK: store [2 x i{{[0-9]+}}]* [[VEC_IN]], [2 x i{{[0-9]+}}]** [[VEC_ADDR]],
+// CHECK: store i{{[0-9]+}}* [[T_VAR_IN]], i{{[0-9]+}}** [[T_VAR_ADDR]],
+// CHECK: store [2 x [[S_FLOAT_TY]]]* [[S_ARR_IN]], [2 x [[S_FLOAT_TY]]]** [[S_ARR_ADDR]],
+// CHECK: store [[S_FLOAT_TY]]* [[VAR_IN]], [[S_FLOAT_TY]]** [[VAR_ADDR]],
+// CHECK: store i{{[0-9]+}}* [[S_VAR_IN]], i{{[0-9]+}}** [[SVAR_ADDR]],
+
+// load content of local address variables
+// CHECK: [[VEC_ADDR_REF:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** [[VEC_ADDR]],
+// CHECK: [[T_VAR_ADDR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[T_VAR_ADDR]],
+// CHECK: [[S_ARR_ADDR_REF:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[S_ARR_ADDR]],
+// CHECK: [[SVAR_ADDR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SVAR_ADDR]],
+// CHECK: store i{{[0-9]+}} 0, i{{[0-9]+}}* [[OMP_IS_LAST]],
+
+// call constructor for s_arr
+// CHECK: [[S_ARR_BGN:%.+]] = getelementptr{{.+}} [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[S_ARR_PRIV]],
+// CHECK: [[S_ARR_END:%.+]] = getelementptr {{.+}} [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[S_ARR_BGN]],
+// CHECK: br label %[[S_ARR_CST_LOOP:.+]]
+// CHECK: [[S_ARR_CST_LOOP]]:
+// CHECK: [[S_ARR_CTOR:%.+]] = phi {{.+}}
+// CHECK: call void [[S_FLOAT_TY_DEF_CONSTR]]([[S_FLOAT_TY]]* [[S_ARR_CTOR]])
+// CHECK: [[S_ARR_NEXT:%.+]] = getelementptr {{.+}} [[S_ARR_CTOR]],
+// CHECK: [[S_ARR_DONE:%.+]] = icmp {{.+}} [[S_ARR_NEXT]], [[S_ARR_END]]
+// CHECK: br i1 [[S_ARR_DONE]], label %[[S_ARR_CST_END:.+]], label %[[S_ARR_CST_LOOP]]
+// CHECK: [[S_ARR_CST_END]]:
+// CHECK: [[VAR_ADDR_REF:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[VAR_ADDR]],
+// CHECK: call void [[S_FLOAT_TY_DEF_CONSTR]]([[S_FLOAT_TY]]* [[VAR_PRIV]])
+// CHECK: store [[S_FLOAT_TY]]* [[VAR_PRIV]], [[S_FLOAT_TY]]** [[TMP_PRIV]],
+
+// CHECK: call void @__kmpc_for_static_init_4(
+
+// loop body
+// assignment: vec[i] = t_var;
+// CHECK: [[T_VAR_PRIV_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_PRIV]],
+// CHECK: [[VEC_PTR:%.+]] = getelementptr inbounds [2 x i{{[0-9]+}}], [2 x i{{[0-9]+}}]* [[VEC_PRIV]], i{{[0-9]+}} 0, i{{[0-9]+}} {{.+}}
+// CHECK: store i{{[0-9]+}} [[T_VAR_PRIV_VAL]], i{{[0-9]+}}* [[VEC_PTR]],
+
+// assignment: s_arr[i] = var;
+// CHECK-DAG: [[S_ARR_PTR:%.+]] = getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[S_ARR_PRIV]],
+// CHECK-DAG: [[TMP_VAL:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[TMP_PRIV]],
+// CHECK-DAG: [[S_ARR_PTR_BCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[S_ARR_PTR]] to i8*
+// CHECK-DAG: [[TMP_VAL_BCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[TMP_VAL]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[S_ARR_PTR_BCAST]], i8* [[TMP_VAL_BCAST]],
+
+// CHECK: call void @__kmpc_for_static_fini(
+
+// lastprivates
+// CHECK: [[OMP_IS_LAST_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[OMP_IS_LAST]],
+// CHECK: [[IS_LAST_IT:%.+]] = icmp ne i{{[0-9]+}} [[OMP_IS_LAST_VAL]], 0
+// CHECK: br i1 [[IS_LAST_IT]], label %[[OMP_LASTPRIV_BLOCK:.+]], label %[[OMP_LASTPRIV_DONE:.+]]
+
+// CHECK: [[OMP_LASTPRIV_BLOCK]]:
+// CHECK: [[T_VAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_PRIV]],
+// CHECK: store i{{[0-9]+}} [[T_VAR_VAL]], i{{[0-9]+}}* [[T_VAR_ADDR_REF]],
+// CHECK: [[BCAST_VEC_ADDR_REF:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_ADDR_REF]] to i8*
+// CHECK: [[BCAST_VEC_PRIV:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[BCAST_VEC_ADDR_REF]], i8* [[BCAST_VEC_PRIV]],
+// CHECK: [[S_ARR_BEGIN:%.+]] = getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[S_ARR_ADDR_REF]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+// CHECK: [[S_ARR_PRIV_BCAST:%.+]] = bitcast [2 x [[S_FLOAT_TY]]]* [[S_ARR_PRIV]] to [[S_FLOAT_TY]]*
+// CHECK: [[S_ARR_BEGIN_GEP:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[S_ARR_BEGIN]], i{{[0-9]+}} 2
+// CHECK: [[S_ARR_IS_EMPTY:%.+]] = icmp eq [[S_FLOAT_TY]]* [[S_ARR_BEGIN]], [[S_ARR_BEGIN_GEP]]
+// CHECK: br i1 [[S_ARR_IS_EMPTY]], label %[[S_ARR_COPY_DONE:.+]], label %[[S_ARR_COPY_BLOCK:.+]]
+// CHECK: [[S_ARR_COPY_BLOCK]]:
+// CHECK: [[S_ARR_SRC_EL:%.+]] = phi [[S_FLOAT_TY]]*{{.+}}
+// CHECK: [[S_ARR_DST_EL:%.+]] = phi [[S_FLOAT_TY]]*{{.+}}
+// CHECK: [[S_ARR_DST_BCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[S_ARR_DST_EL]] to i8*
+// CHECK: [[S_ARR_SRC_BCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[S_ARR_SRC_EL]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[S_ARR_DST_BCAST]], i8* [[S_ARR_SRC_BCAST]]{{.+}})
+// CHECK: [[S_ARR_DST_NEXT:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[S_ARR_DST_EL]], i{{[0-9]+}} 1
+// CHECK: [[S_ARR_SRC_NEXT:%.+]] = getelementptr{{.+}}
+// CHECK: [[CPY_IS_FINISHED:%.+]] = icmp eq [[S_FLOAT_TY]]* [[S_ARR_DST_NEXT]], [[S_ARR_BEGIN_GEP]]
+// CHECK: br i1 [[CPY_IS_FINISHED]], label %[[S_ARR_COPY_DONE]], label %[[S_ARR_COPY_BLOCK]]
+// CHECK: [[S_ARR_COPY_DONE]]:
+// CHECK: [[TMP_VAL1:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[TMP_PRIV]],
+// CHECK: [[VAR_ADDR_REF_BCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[VAR_ADDR_REF]] to i8*
+// CHECK: [[TMP_VAL1_BCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[TMP_VAL1]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[VAR_ADDR_REF_BCAST]], i8* [[TMP_VAL1_BCAST]],{{.+}})
+// CHECK: [[SVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[S_VAR_PRIV]],
+// CHECK: store i{{[0-9]+}} [[SVAR_VAL]], i{{[0-9]+}}* [[SVAR_ADDR_REF]],
+// CHECK: ret void
+
+// template tmain
+// CHECK: define{{.*}} i{{[0-9]+}} [[TMAIN_INT:@.+]]()
+// CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]],
+// CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR:@.+]]([[S_INT_TY]]* [[TEST]])
+// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+// CHECK: call void [[OFFLOAD_FUN_1:@.+]](i{{[0-9]+}} {{.+}}, [2 x i{{[0-9]+}}]* {{.+}}, [2 x [[S_INT_TY]]]* {{.+}}, [[S_INT_TY]]* {{.+}})
+// CHECK: ret
+
+// CHECK: define internal void [[OFFLOAD_FUN_1]](
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_teams(%{{.+}}* @{{.+}}, i{{[0-9]+}} 4,
+// CHECK: ret
+
+// CHECK: define internal void [[OMP_OUTLINED_1:@.+]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i{{[0-9]+}}*{{.+}} [[T_VAR_IN:%.+]], [2 x i{{[0-9]+}}]*{{.+}} [[VEC_IN:%.+]], [2 x [[S_INT_TY]]]*{{.+}} [[S_ARR_IN:%.+]], [[S_INT_TY]]*{{.+}} [[VAR_IN:%.+]])
+// skip alloca of global_tid and bound_tid
+// CHECK: {{.+}} = alloca i{{[0-9]+}}*,
+// CHECK: {{.+}} = alloca i{{[0-9]+}}*,
+// CHECK: [[T_VAR_ADDR:%.+]] = alloca i{{[0-9]+}}*,
+// CHECK: [[VEC_ADDR:%.+]] = alloca [2 x i{{[0-9]+}}]*,
+// CHECK: [[S_ARR_ADDR:%.+]] = alloca [2 x [[S_INT_TY]]]*,
+// CHECK: [[VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*,
+// CHECK: [[TMP:%.+]] = alloca [[S_INT_TY]]*,
+// skip loop variables
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: [[OMP_IS_LAST:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_INT_TY]]],
+// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_INT_TY]],
+// CHECK: [[TMP_PRIV:%.+]] = alloca [[S_INT_TY]]*,
+
+// skip init of bound and global tid
+// CHECK: store i{{[0-9]+}}* {{.*}},
+// CHECK: store i{{[0-9]+}}* {{.*}},
+// copy from parameters to local address variables
+// CHECK: store i{{[0-9]+}}* [[T_VAR_IN]], i{{[0-9]+}}** [[T_VAR_ADDR]],
+// CHECK: store [2 x i{{[0-9]+}}]* [[VEC_IN]], [2 x i{{[0-9]+}}]** [[VEC_ADDR]],
+// CHECK: store [2 x [[S_INT_TY]]]* [[S_ARR_IN]], [2 x [[S_INT_TY]]]** [[S_ARR_ADDR]],
+// CHECK: store [[S_INT_TY]]* [[VAR_IN]], [[S_INT_TY]]** [[VAR_ADDR]],
+
+// load content of local address variables
+// CHECK: [[T_VAR_ADDR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[T_VAR_ADDR]],
+// CHECK: [[VEC_ADDR_REF:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** [[VEC_ADDR]],
+// CHECK: [[S_ARR_ADDR_REF:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** [[S_ARR_ADDR]],
+// CHECK: [[VAR_ADDR_REF:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[VAR_ADDR]],
+// CHECK-DAG: store [[S_INT_TY]]* [[VAR_ADDR_REF]], [[S_INT_TY]]** [[TMP]],
+// CHECK-DAG: store i{{[0-9]+}} 0, i{{[0-9]+}}* [[OMP_IS_LAST]],
+// CHECK-DAG: [[TMP_REF:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[TMP]],
+
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: [[TMP_PRIV_VAL:%.+]] = load {{.+}}, {{.+}} [[TMP_PRIV]],
+// CHECK-64: call{{.+}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}}[[OMP_PARFOR_OUTLINED:@.+]] to void ({{.+}})*), {{.+}}, {{.+}}, {{.+}} [[VEC_PRIV]], {{.+}} [[T_VAR_PRIV]], {{.+}} [[S_ARR_PRIV]], {{.+}} [[TMP_PRIV_VAL]])
+// CHECK-32: call{{.+}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}}[[OMP_PARFOR_OUTLINED:@.+]] to void ({{.+}})*), {{.+}}, {{.+}}, {{.+}} [[VEC_PRIV]], {{.+}} [[T_VAR_PRIV]], {{.+}} [[S_ARR_PRIV]], {{.+}} [[TMP_PRIV_VAL]])
+
+// CHECK: call void @__kmpc_for_static_fini(
+
+// lastprivates
+// CHECK: [[OMP_IS_LAST_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[OMP_IS_LAST]],
+// CHECK: [[IS_LAST_IT:%.+]] = icmp ne i{{[0-9]+}} [[OMP_IS_LAST_VAL]], 0
+// CHECK: br i1 [[IS_LAST_IT]], label %[[OMP_LASTPRIV_BLOCK:.+]], label %[[OMP_LASTPRIV_DONE:.+]]
+
+// CHECK: [[OMP_LASTPRIV_BLOCK]]:
+// CHECK: [[T_VAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_PRIV]],
+// CHECK: store i{{[0-9]+}} [[T_VAR_VAL]], i{{[0-9]+}}* [[T_VAR_ADDR_REF]],
+// CHECK: [[BCAST_VEC_ADDR_REF:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_ADDR_REF]] to i8*
+// CHECK: [[BCAST_VEC_PRIV:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[BCAST_VEC_ADDR_REF]], i8* [[BCAST_VEC_PRIV]],
+// CHECK: [[S_ARR_BEGIN:%.+]] = getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[S_ARR_ADDR_REF]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+// CHECK: [[S_ARR_PRIV_BCAST:%.+]] = bitcast [2 x [[S_INT_TY]]]* [[S_ARR_PRIV]] to [[S_INT_TY]]*
+// CHECK: [[S_ARR_BEGIN_GEP:%.+]] = getelementptr [[S_INT_TY]], [[S_INT_TY]]* [[S_ARR_BEGIN]], i{{[0-9]+}} 2
+// CHECK: [[S_ARR_IS_EMPTY:%.+]] = icmp eq [[S_INT_TY]]* [[S_ARR_BEGIN]], [[S_ARR_BEGIN_GEP]]
+// CHECK: br i1 [[S_ARR_IS_EMPTY]], label %[[S_ARR_COPY_DONE:.+]], label %[[S_ARR_COPY_BLOCK:.+]]
+// CHECK: [[S_ARR_COPY_BLOCK]]:
+// CHECK: [[S_ARR_SRC_EL:%.+]] = phi [[S_INT_TY]]*{{.+}}
+// CHECK: [[S_ARR_DST_EL:%.+]] = phi [[S_INT_TY]]*{{.+}}
+// CHECK: [[S_ARR_DST_BCAST:%.+]] = bitcast [[S_INT_TY]]* [[S_ARR_DST_EL]] to i8*
+// CHECK: [[S_ARR_SRC_BCAST:%.+]] = bitcast [[S_INT_TY]]* [[S_ARR_SRC_EL]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[S_ARR_DST_BCAST]], i8* [[S_ARR_SRC_BCAST]]{{.+}})
+// CHECK: [[S_ARR_DST_NEXT:%.+]] = getelementptr [[S_INT_TY]], [[S_INT_TY]]* [[S_ARR_DST_EL]], i{{[0-9]+}} 1
+// CHECK: [[S_ARR_SRC_NEXT:%.+]] = getelementptr{{.+}}
+// CHECK: [[CPY_IS_FINISHED:%.+]] = icmp eq [[S_INT_TY]]* [[S_ARR_DST_NEXT]], [[S_ARR_BEGIN_GEP]]
+// CHECK: br i1 [[CPY_IS_FINISHED]], label %[[S_ARR_COPY_DONE]], label %[[S_ARR_COPY_BLOCK]]
+// CHECK: [[S_ARR_COPY_DONE]]:
+// CHECK: [[TMP_VAL:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[TMP_PRIV]],
+// CHECK: [[VAR_ADDR_REF_BCAST:%.+]] = bitcast [[S_INT_TY]]* [[TMP_REF]] to i8*
+// CHECK: [[TMP_VAL_BCAST:%.+]] = bitcast [[S_INT_TY]]* [[TMP_VAL]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[VAR_ADDR_REF_BCAST]], i8* [[TMP_VAL_BCAST]],{{.+}})
+// CHECK: ret void
+
+// outlined function for 'parallel for'
+// CHECK-64: define{{.+}} void [[OMP_PARFOR_OUTLINED]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, {{.+}}, {{.+}}, {{.+}} [[VEC_IN:%.+]], {{.+}} [[T_VAR_IN:%.+]], {{.+}} [[S_ARR_IN:%.+]], {{.+}} [[VAR_IN:%.+]])
+// CHECK-32: define{{.+}} void [[OMP_PARFOR_OUTLINED]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, {{.+}}, {{.+}}, {{.+}} [[VEC_IN:%.+]], {{.+}} [[T_VAR_IN:%.+]], {{.+}} [[S_ARR_IN:%.+]], {{.+}} [[VAR_IN:%.+]])
+
+// CHECK: {{.+}} = alloca i{{[0-9]+}}*,
+// CHECK: {{.+}} = alloca i{{[0-9]+}}*,
+// CHECK: [[VEC_ADDR:%.+]] = alloca [2 x i{{[0-9]+}}]*,
+// CHECK: [[T_VAR_ADDR:%.+]] = alloca i{{[0-9]+}}*,
+// CHECK: [[S_ARR_ADDR:%.+]] = alloca [2 x [[S_INT_TY]]]*,
+// CHECK: [[VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*,
+// skip loop variables
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: [[OMP_IS_LAST:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_INT_TY]]],
+// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_INT_TY]],
+// CHECK: [[TMP_PRIV:%.+]] = alloca [[S_INT_TY]]*,
+
+// copy from parameters to local address variables
+// CHECK: store [2 x i{{[0-9]+}}]* [[VEC_IN]], [2 x i{{[0-9]+}}]** [[VEC_ADDR]],
+// CHECK: store i{{[0-9]+}}* [[T_VAR_IN]], i{{[0-9]+}}** [[T_VAR_ADDR]],
+// CHECK: store [2 x [[S_INT_TY]]]* [[S_ARR_IN]], [2 x [[S_INT_TY]]]** [[S_ARR_ADDR]],
+// CHECK: store [[S_INT_TY]]* [[VAR_IN]], [[S_INT_TY]]** [[VAR_ADDR]],
+
+// load content of local address variables
+// CHECK: [[VEC_ADDR_REF:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** [[VEC_ADDR]],
+// CHECK: [[T_VAR_ADDR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[T_VAR_ADDR]],
+// CHECK: [[S_ARR_ADDR_REF:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** [[S_ARR_ADDR]],
+// CHECK: store i{{[0-9]+}} 0, i{{[0-9]+}}* [[OMP_IS_LAST]],
+
+// call constructor for s_arr
+// CHECK: [[S_ARR_BGN:%.+]] = getelementptr{{.+}} [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[S_ARR_PRIV]],
+// CHECK: [[S_ARR_END:%.+]] = getelementptr {{.+}} [[S_INT_TY]], [[S_INT_TY]]* [[S_ARR_BGN]],
+// CHECK: br label %[[S_ARR_CST_LOOP:.+]]
+// CHECK: [[S_ARR_CST_LOOP]]:
+// CHECK: [[S_ARR_CTOR:%.+]] = phi {{.+}}
+// CHECK: call void [[S_INT_TY_DEF_CONSTR]]([[S_INT_TY]]* [[S_ARR_CTOR]])
+// CHECK: [[S_ARR_NEXT:%.+]] = getelementptr {{.+}} [[S_ARR_CTOR]],
+// CHECK: [[S_ARR_DONE:%.+]] = icmp {{.+}} [[S_ARR_NEXT]], [[S_ARR_END]]
+// CHECK: br i1 [[S_ARR_DONE]], label %[[S_ARR_CST_END:.+]], label %[[S_ARR_CST_LOOP]]
+// CHECK: [[S_ARR_CST_END]]:
+// CHECK: [[VAR_ADDR_REF:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[VAR_ADDR]],
+// CHECK: call void [[S_INT_TY_DEF_CONSTR]]([[S_INT_TY]]* [[VAR_PRIV]])
+// CHECK: store [[S_INT_TY]]* [[VAR_PRIV]], [[S_INT_TY]]** [[TMP_PRIV]],
+
+// CHECK: call void @__kmpc_for_static_init_4(
+
+// assignment: vec[i] = t_var;
+// CHECK: [[IV_VAL:%.+]] =
+// CHECK: [[T_VAR_PRIV_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_PRIV]],
+// CHECK: [[VEC_PTR:%.+]] = getelementptr inbounds [2 x i{{[0-9]+}}], [2 x i{{[0-9]+}}]* [[VEC_PRIV]], i{{[0-9]+}} 0, i{{[0-9]+}} {{.+}}
+// CHECK: store i{{[0-9]+}} [[T_VAR_PRIV_VAL]], i{{[0-9]+}}* [[VEC_PTR]],
+
+// assignment: s_arr[i] = var;
+// CHECK-DAG: [[S_ARR_PTR:%.+]] = getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[S_ARR_PRIV]],
+// CHECK-DAG: [[TMP_VAL:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[TMP_PRIV]],
+// CHECK-DAG: [[S_ARR_PTR_BCAST:%.+]] = bitcast [[S_INT_TY]]* [[S_ARR_PTR]] to i8*
+// CHECK-DAG: [[TMP_VAL_BCAST:%.+]] = bitcast [[S_INT_TY]]* [[TMP_VAL]] to i8*
+// CHECK-DAG: call void @llvm.memcpy.{{.+}}(i8* [[S_ARR_PTR_BCAST]], i8* [[TMP_VAL_BCAST]],
+
+// CHECK: call void @__kmpc_for_static_fini(
+
+// lastprivates
+// CHECK: [[OMP_IS_LAST_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[OMP_IS_LAST]],
+// CHECK: [[IS_LAST_IT:%.+]] = icmp ne i{{[0-9]+}} [[OMP_IS_LAST_VAL]], 0
+// CHECK: br i1 [[IS_LAST_IT]], label %[[OMP_LASTPRIV_BLOCK:.+]], label %[[OMP_LASTPRIV_DONE:.+]]
+
+// CHECK: [[OMP_LASTPRIV_BLOCK]]:
+// CHECK: [[T_VAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_PRIV]],
+// CHECK: store i{{[0-9]+}} [[T_VAR_VAL]], i{{[0-9]+}}* [[T_VAR_ADDR_REF]],
+// CHECK: [[BCAST_VEC_ADDR_REF:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_ADDR_REF]] to i8*
+// CHECK: [[BCAST_VEC_PRIV:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[BCAST_VEC_ADDR_REF]], i8* [[BCAST_VEC_PRIV]],
+// CHECK: [[S_ARR_BEGIN:%.+]] = getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[S_ARR_ADDR_REF]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+// CHECK: [[S_ARR_PRIV_BCAST:%.+]] = bitcast [2 x [[S_INT_TY]]]* [[S_ARR_PRIV]] to [[S_INT_TY]]*
+// CHECK: [[S_ARR_BEGIN_GEP:%.+]] = getelementptr [[S_INT_TY]], [[S_INT_TY]]* [[S_ARR_BEGIN]], i{{[0-9]+}} 2
+// CHECK: [[S_ARR_IS_EMPTY:%.+]] = icmp eq [[S_INT_TY]]* [[S_ARR_BEGIN]], [[S_ARR_BEGIN_GEP]]
+// CHECK: br i1 [[S_ARR_IS_EMPTY]], label %[[S_ARR_COPY_DONE:.+]], label %[[S_ARR_COPY_BLOCK:.+]]
+// CHECK: [[S_ARR_COPY_BLOCK]]:
+// CHECK: [[S_ARR_SRC_EL:%.+]] = phi [[S_INT_TY]]*{{.+}}
+// CHECK: [[S_ARR_DST_EL:%.+]] = phi [[S_INT_TY]]*{{.+}}
+// CHECK: [[S_ARR_DST_BCAST:%.+]] = bitcast [[S_INT_TY]]* [[S_ARR_DST_EL]] to i8*
+// CHECK: [[S_ARR_SRC_BCAST:%.+]] = bitcast [[S_INT_TY]]* [[S_ARR_SRC_EL]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[S_ARR_DST_BCAST]], i8* [[S_ARR_SRC_BCAST]]{{.+}})
+// CHECK: [[S_ARR_DST_NEXT:%.+]] = getelementptr [[S_INT_TY]], [[S_INT_TY]]* [[S_ARR_DST_EL]], i{{[0-9]+}} 1
+// CHECK: [[S_ARR_SRC_NEXT:%.+]] = getelementptr{{.+}}
+// CHECK: [[CPY_IS_FINISHED:%.+]] = icmp eq [[S_INT_TY]]* [[S_ARR_DST_NEXT]], [[S_ARR_BEGIN_GEP]]
+// CHECK: br i1 [[CPY_IS_FINISHED]], label %[[S_ARR_COPY_DONE]], label %[[S_ARR_COPY_BLOCK]]
+// CHECK: [[S_ARR_COPY_DONE]]:
+// CHECK: [[TMP_VAL1:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[TMP_PRIV]],
+// CHECK: [[VAR_ADDR_REF_BCAST:%.+]] = bitcast [[S_INT_TY]]* [[VAR_ADDR_REF]] to i8*
+// CHECK: [[TMP_VAL1_BCAST:%.+]] = bitcast [[S_INT_TY]]* [[TMP_VAL1]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[VAR_ADDR_REF_BCAST]], i8* [[TMP_VAL1_BCAST]],{{.+}})
+// CHECK: ret void
+
+// CHECK: !{!"llvm.loop.vectorize.enable", i1 true}
+#endif
+
diff --git a/test/OpenMP/distribute_parallel_for_simd_lastprivate_messages.cpp b/test/OpenMP/distribute_parallel_for_simd_lastprivate_messages.cpp
index 109fde0577c4..73450d4f1181 100644
--- a/test/OpenMP/distribute_parallel_for_simd_lastprivate_messages.cpp
+++ b/test/OpenMP/distribute_parallel_for_simd_lastprivate_messages.cpp
@@ -18,14 +18,14 @@ public:
const S2 &operator =(const S2&) const;
S2 &operator =(const S2&);
static float S2s; // expected-note {{static data member is predetermined as shared}}
- static const float S2sc;
+ static const float S2sc; // expected-note {{static data member is predetermined as shared}}
};
-const float S2::S2sc = 0; // expected-note {{static data member is predetermined as shared}}
+const float S2::S2sc = 0;
const S2 b;
const S2 ba[5];
class S3 {
int a;
- S3 &operator=(const S3 &s3); // expected-note 2 {{implicitly declared private here}}
+ S3 &operator=(const S3 &s3); // expected-note {{implicitly declared private here}}
public:
S3() : a(0) {}
@@ -52,7 +52,7 @@ public:
};
class S6 {
int a;
- S6() : a(0) {}
+ S6() : a(0) {} // expected-note {{implicitly declared private here}}
public:
S6(const S6 &s6) : a(s6.a) {}
@@ -313,14 +313,16 @@ int main(int argc, char **argv) {
#pragma omp distribute parallel for simd lastprivate(j)
for (i = 0; i < argc; ++i)
foo();
+// expected-error@+3 {{firstprivate variable cannot be lastprivate}} expected-note@+3 {{defined as firstprivate}}
#pragma omp target
#pragma omp teams
-#pragma omp distribute parallel for simd firstprivate(m) lastprivate(m) // expected-error {{'operator=' is a private member of 'S3'}}
+#pragma omp distribute parallel for simd firstprivate(m) lastprivate(m)
for (i = 0; i < argc; ++i)
foo();
+// expected-error@+3 {{lastprivate variable cannot be firstprivate}} expected-note@+3 {{defined as lastprivate}}
#pragma omp target
#pragma omp teams
-#pragma omp distribute parallel for simd lastprivate(n) firstprivate(n) // OK
+#pragma omp distribute parallel for simd lastprivate(n) firstprivate(n) // expected-error {{calling a private constructor of class 'S6'}}
for (i = 0; i < argc; ++i)
foo();
static int si;
diff --git a/test/OpenMP/distribute_parallel_for_simd_linear_messages.cpp b/test/OpenMP/distribute_parallel_for_simd_linear_messages.cpp
index 632ef066c0fa..66fd94b9e0f2 100644
--- a/test/OpenMP/distribute_parallel_for_simd_linear_messages.cpp
+++ b/test/OpenMP/distribute_parallel_for_simd_linear_messages.cpp
@@ -18,41 +18,49 @@ void test_linear_colons()
{
int B = 0;
+// expected-error@+3 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
#pragma omp teams
#pragma omp distribute parallel for simd linear(B:bfoo())
for (int i = 0; i < 10; ++i) ;
+// expected-error@+3 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
#pragma omp teams
#pragma omp distribute parallel for simd linear(B::ib:B:bfoo()) // expected-error {{unexpected ':' in nested name specifier; did you mean '::'}}
for (int i = 0; i < 10; ++i) ;
+// expected-error@+3 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
#pragma omp teams
#pragma omp distribute parallel for simd linear(B:ib) // expected-error {{use of undeclared identifier 'ib'; did you mean 'B::ib'}}
for (int i = 0; i < 10; ++i) ;
+// expected-error@+3 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
#pragma omp teams
#pragma omp distribute parallel for simd linear(z:B:ib) // expected-error {{unexpected ':' in nested name specifier; did you mean '::'?}}
for (int i = 0; i < 10; ++i) ;
+// expected-error@+3 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
#pragma omp teams
#pragma omp distribute parallel for simd linear(B:B::bfoo())
for (int i = 0; i < 10; ++i) ;
+// expected-error@+3 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
#pragma omp teams
#pragma omp distribute parallel for simd linear(X::x : ::z)
for (int i = 0; i < 10; ++i) ;
+// expected-error@+3 3 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
#pragma omp teams
#pragma omp distribute parallel for simd linear(B,::z, X::x)
for (int i = 0; i < 10; ++i) ;
+// expected-error@+3 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
#pragma omp teams
#pragma omp distribute parallel for simd linear(::z)
@@ -63,6 +71,7 @@ void test_linear_colons()
#pragma omp distribute parallel for simd linear(B::bfoo()) // expected-error {{expected variable name}}
for (int i = 0; i < 10; ++i) ;
+// expected-error@+3 2 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
#pragma omp teams
#pragma omp distribute parallel for simd linear(B::ib,B:C1+C2)
@@ -148,11 +157,13 @@ template<class I, class C> int foomain(I argc, C **argv) {
#pragma omp distribute parallel for simd linear () // expected-error {{expected expression}}
for (int k = 0; k < argc; ++k) ++k;
+// expected-error@+3 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
#pragma omp teams
#pragma omp distribute parallel for simd linear (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
for (int k = 0; k < argc; ++k) ++k;
+// expected-error@+3 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
#pragma omp teams
#pragma omp distribute parallel for simd linear (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
@@ -163,6 +174,7 @@ template<class I, class C> int foomain(I argc, C **argv) {
#pragma omp distribute parallel for simd linear (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
for (int k = 0; k < argc; ++k) ++k;
+// expected-error@+3 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
#pragma omp teams
#pragma omp distribute parallel for simd linear (argc : 5)
@@ -183,6 +195,7 @@ template<class I, class C> int foomain(I argc, C **argv) {
#pragma omp distribute parallel for simd linear (argv[1]) // expected-error {{expected variable name}}
for (int k = 0; k < argc; ++k) ++k;
+// expected-error@+3 2 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
#pragma omp teams
#pragma omp distribute parallel for simd linear(e, g)
@@ -193,6 +206,7 @@ template<class I, class C> int foomain(I argc, C **argv) {
#pragma omp distribute parallel for simd linear(h) // expected-error {{threadprivate or thread local variable cannot be linear}}
for (int k = 0; k < argc; ++k) ++k;
+// expected-error@+3 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
#pragma omp teams
#pragma omp distribute parallel for simd linear(i)
@@ -202,28 +216,13 @@ template<class I, class C> int foomain(I argc, C **argv) {
{
int v = 0;
int i;
+ int k;
#pragma omp target
#pragma omp teams
- #pragma omp distribute parallel for simd linear(v:i)
- for (int k = 0; k < argc; ++k) { i = k; v += i; }
+ #pragma omp distribute parallel for simd linear(k:i)
+ for (k = 0; k < argc; ++k) { i = k; v += i; }
}
-#pragma omp target
-#pragma omp teams
-#pragma omp parallel for simd linear(j)
- for (int k = 0; k < argc; ++k) ++k;
-
- int v = 0;
-
-#pragma omp target
-#pragma omp teams
-#pragma omp distribute parallel for simd linear(v:j)
- for (int k = 0; k < argc; ++k) { ++k; v += j; }
-
-#pragma omp target
-#pragma omp teams
-#pragma omp distribute parallel for simd linear(i)
- for (int k = 0; k < argc; ++k) ++k;
return 0;
}
@@ -262,11 +261,13 @@ int main(int argc, char **argv) {
#pragma omp distribute parallel for simd linear () // expected-error {{expected expression}}
for (int k = 0; k < argc; ++k) ++k;
+// expected-error@+3 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
#pragma omp teams
#pragma omp distribute parallel for simd linear (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
for (int k = 0; k < argc; ++k) ++k;
+// expected-error@+3 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
#pragma omp teams
#pragma omp distribute parallel for simd linear (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
@@ -277,6 +278,7 @@ int main(int argc, char **argv) {
#pragma omp distribute parallel for simd linear (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
for (int k = 0; k < argc; ++k) ++k;
+// expected-error@+3 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
#pragma omp teams
#pragma omp distribute parallel for simd linear (argc)
@@ -314,24 +316,14 @@ int main(int argc, char **argv) {
#pragma omp target
#pragma omp teams
#pragma omp distribute parallel for simd linear(i)
- for (int k = 0; k < argc; ++k) ++k;
+ for (i = 0; i < argc; ++i) ++i;
#pragma omp target
#pragma omp teams
#pragma omp distribute parallel for simd linear(i : 4)
- for (int k = 0; k < argc; ++k) { ++k; i += 4; }
+ for (i = 0; i < argc; ++i) { ++i; i += 4; }
}
-#pragma omp target
-#pragma omp teams
-#pragma omp distribute parallel for simd linear(j)
- for (int k = 0; k < argc; ++k) ++k;
-
-#pragma omp target
-#pragma omp teams
-#pragma omp distribute parallel for simd linear(i)
- for (int k = 0; k < argc; ++k) ++k;
-
foomain<int,char>(argc,argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}}
return 0;
}
diff --git a/test/OpenMP/distribute_parallel_for_simd_loop_messages.cpp b/test/OpenMP/distribute_parallel_for_simd_loop_messages.cpp
index 1fedb3c02d79..d137d47ca2a4 100644
--- a/test/OpenMP/distribute_parallel_for_simd_loop_messages.cpp
+++ b/test/OpenMP/distribute_parallel_for_simd_loop_messages.cpp
@@ -2,7 +2,7 @@
class S {
int a;
- S() : a(0) {}
+ S() : a(0) {} // expected-note {{implicitly declared private here}}
public:
S(int v) : a(v) {}
@@ -790,9 +790,10 @@ void test_loop_eh() {
void test_loop_firstprivate_lastprivate() {
S s(4);
+// expected-error@+3 {{lastprivate variable cannot be firstprivate}} expected-note@+3 {{defined as lastprivate}}
#pragma omp target
#pragma omp teams
-#pragma omp distribute parallel for simd lastprivate(s) firstprivate(s)
+#pragma omp distribute parallel for simd lastprivate(s) firstprivate(s) // expected-error {{calling a private constructor of class 'S'}}
for (int i = 0; i < 16; ++i)
;
}
diff --git a/test/OpenMP/distribute_parallel_for_simd_misc_messages.c b/test/OpenMP/distribute_parallel_for_simd_misc_messages.c
index 01c079e3dac1..4d071621fcb8 100644
--- a/test/OpenMP/distribute_parallel_for_simd_misc_messages.c
+++ b/test/OpenMP/distribute_parallel_for_simd_misc_messages.c
@@ -68,7 +68,7 @@ void test_non_identifiers() {
#pragma omp target
#pragma omp teams
// expected-warning@+1 {{extra tokens at the end of '#pragma omp distribute parallel for simd' are ignored}}
-#pragma omp distribute parallel for simd linear(x);
+#pragma omp distribute parallel for simd firstprivate(x);
for (i = 0; i < 16; ++i)
;
@@ -548,89 +548,6 @@ void test_linear() {
#pragma omp distribute parallel for simd linear(x, y, z)
for (i = 0; i < 16; ++i)
;
-
- int x, y;
-#pragma omp target
-#pragma omp teams
-// expected-error@+1 {{expected expression}}
-#pragma omp distribute parallel for simd linear(x :)
- for (i = 0; i < 16; ++i)
- ;
-#pragma omp target
-#pragma omp teams
-// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
-#pragma omp distribute parallel for simd linear(x :, )
- for (i = 0; i < 16; ++i)
- ;
-#pragma omp target
-#pragma omp teams
-#pragma omp distribute parallel for simd linear(x : 1)
- for (i = 0; i < 16; ++i)
- ;
-#pragma omp target
-#pragma omp teams
-#pragma omp distribute parallel for simd linear(x : 2 * 2)
- for (i = 0; i < 16; ++i)
- ;
-#pragma omp target
-#pragma omp teams
-// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
-#pragma omp distribute parallel for simd linear(x : 1, y)
- for (i = 0; i < 16; ++i)
- ;
-#pragma omp target
-#pragma omp teams
-// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
-#pragma omp distribute parallel for simd linear(x : 1, y, z : 1)
- for (i = 0; i < 16; ++i)
- ;
-
-#pragma omp target
-#pragma omp teams
-// expected-note@+2 {{defined as linear}}
-// expected-error@+1 {{linear variable cannot be linear}}
-#pragma omp distribute parallel for simd linear(x) linear(x)
- for (i = 0; i < 16; ++i)
- ;
-
-#pragma omp target
-#pragma omp teams
-// expected-note@+2 {{defined as private}}
-// expected-error@+1 {{private variable cannot be linear}}
-#pragma omp distribute parallel for simd private(x) linear(x)
- for (i = 0; i < 16; ++i)
- ;
-
-#pragma omp target
-#pragma omp teams
-// expected-note@+2 {{defined as linear}}
-// expected-error@+1 {{linear variable cannot be private}}
-#pragma omp distribute parallel for simd linear(x) private(x)
- for (i = 0; i < 16; ++i)
- ;
-
-#pragma omp target
-#pragma omp teams
-// expected-warning@+1 {{zero linear step (x and other variables in clause should probably be const)}}
-#pragma omp distribute parallel for simd linear(x, y : 0)
- for (i = 0; i < 16; ++i)
- ;
-
-#pragma omp target
-#pragma omp teams
-// expected-note@+2 {{defined as linear}}
-// expected-error@+1 {{linear variable cannot be lastprivate}}
-#pragma omp distribute parallel for simd linear(x) lastprivate(x)
- for (i = 0; i < 16; ++i)
- ;
-
-#pragma omp target
-#pragma omp teams
-// expected-note@+2 {{defined as lastprivate}}
-// expected-error@+1 {{lastprivate variable cannot be linear}}
-#pragma omp distribute parallel for simd lastprivate(x) linear(x)
- for (i = 0; i < 16; ++i)
- ;
}
void test_aligned() {
@@ -934,16 +851,19 @@ void test_firstprivate() {
;
int x, y, z;
+// expected-error@+3 {{lastprivate variable cannot be firstprivate}} expected-note@+3 {{defined as lastprivate}}
#pragma omp target
#pragma omp teams
#pragma omp distribute parallel for simd lastprivate(x) firstprivate(x)
for (i = 0; i < 16; ++i)
;
+// expected-error@+3 2 {{lastprivate variable cannot be firstprivate}} expected-note@+3 2 {{defined as lastprivate}}
#pragma omp target
#pragma omp teams
#pragma omp distribute parallel for simd lastprivate(x, y) firstprivate(x, y)
for (i = 0; i < 16; ++i)
;
+// expected-error@+3 3 {{lastprivate variable cannot be firstprivate}} expected-note@+3 3 {{defined as lastprivate}}
#pragma omp target
#pragma omp teams
#pragma omp distribute parallel for simd lastprivate(x, y, z) firstprivate(x, y, z)
diff --git a/test/OpenMP/distribute_parallel_for_simd_num_threads_codegen.cpp b/test/OpenMP/distribute_parallel_for_simd_num_threads_codegen.cpp
new file mode 100644
index 000000000000..5804a2a72b71
--- /dev/null
+++ b/test/OpenMP/distribute_parallel_for_simd_num_threads_codegen.cpp
@@ -0,0 +1,121 @@
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple %itanium_abi_triple -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple %itanium_abi_triple -fexceptions -fcxx-exceptions -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple %itanium_abi_triple -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+typedef __INTPTR_TYPE__ intptr_t;
+
+// CHECK-DAG: [[IDENT_T_TY:%.+]] = type { i32, i32, i32, i32, i8* }
+// CHECK-DAG: [[S_TY:%.+]] = type { [[INTPTR_T_TY:i[0-9]+]], [[INTPTR_T_TY]], [[INTPTR_T_TY]] }
+// CHECK-DAG: [[STR:@.+]] = private unnamed_addr constant [23 x i8] c";unknown;unknown;0;0;;\00"
+// CHECK-DAG: [[DEF_LOC_2:@.+]] = private unnamed_addr constant [[IDENT_T_TY]] { i32 0, i32 2, i32 0, i32 0, i8* getelementptr inbounds ([23 x i8], [23 x i8]* [[STR]], i32 0, i32 0) }
+
+void foo();
+
+struct S {
+ intptr_t a, b, c;
+ S(intptr_t a) : a(a) {}
+ operator char() { return a; }
+ ~S() {}
+};
+
+template <typename T, int C>
+int tmain() {
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd num_threads(C)
+ for (int i = 0; i < 100; i++)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd num_threads(T(23))
+ for (int i = 0; i < 100; i++)
+ foo();
+ return 0;
+}
+
+int main() {
+ S s(0);
+ char a = s;
+// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+// CHECK: call void [[OFFLOADING_FUN_0:@.+]](
+// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+// CHECK: call void [[OFFLOADING_FUN_1:@.+]](
+// CHECK: invoke{{.+}} [[TMAIN_5:@.+]]()
+// CHECK: invoke{{.+}} [[TMAIN_1:@.+]]()
+#pragma omp target
+#pragma omp teams
+ // CHECK: define internal void [[OFFLOADING_FUN_0]](
+ // CHECK: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, i32 0, {{.+}}* [[OMP_TEAMS_OUTLINED_0:@.+]] to {{.+}})
+#pragma omp distribute parallel for simd num_threads(2)
+ for (int i = 0; i < 100; i++) {
+ // CHECK: define{{.+}} void [[OMP_TEAMS_OUTLINED_0]](
+ // CHECK: call {{.*}}void @__kmpc_push_num_threads([[IDENT_T_TY]]* [[DEF_LOC_2]], i32 {{.+}}, i32 2)
+ // CHECK: call {{.*}}void {{.*}} @__kmpc_fork_call(
+ foo();
+ }
+#pragma omp target
+#pragma omp teams
+ // CHECK: define internal void [[OFFLOADING_FUN_1]](
+
+ // CHECK: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}}* [[OMP_TEAMS_OUTLINED_1:@.+]] to {{.+}})
+#pragma omp distribute parallel for simd num_threads(a)
+ for (int i = 0; i < 100; i++) {
+ // CHECK: define{{.+}} void [[OMP_TEAMS_OUTLINED_1]](
+ // CHECK-DAG: [[A_ADDR:%.+]] = alloca i8*,
+ // CHECK-DAG: [[A_REF:%.+]] = load i8*, i8** [[A_ADDR]],
+ // CHECK-DAG: [[A_VAL:%.+]] = load i8, i8* [[A_REF]],
+ // CHECK-DAG: [[A_EXT:%.+]] = sext i8 [[A_VAL]] to {{.+}}
+ // CHECK: call {{.*}}void @__kmpc_push_num_threads([[IDENT_T_TY]]* [[DEF_LOC_2]], i32 {{.+}}, i32 [[A_EXT]])
+ // CHECK: call {{.*}}void {{.*}} @__kmpc_fork_call(
+ foo();
+ }
+ return a + tmain<char, 5>() + tmain<S, 1>();
+}
+
+// tmain 5
+// CHECK-DAG: define {{.*}}i{{[0-9]+}} [[TMAIN_5]]()
+// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+// CHECK: call void [[T_OFFLOADING_FUN_0:@.+]](
+// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+// CHECK: call void [[T_OFFLOADING_FUN_1:@.+]](
+
+// tmain 1
+// CHECK-DAG: define {{.*}}i{{[0-9]+}} [[TMAIN_1]]()
+// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+// CHECK: call void [[T_OFFLOADING_FUN_2:@.+]](
+// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+// CHECK: call void [[T_OFFLOADING_FUN_3:@.+]](
+
+// CHECK: define internal void [[T_OFFLOADING_FUN_0]](
+// CHECK: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, i32 0, {{.+}}* [[T_OMP_TEAMS_OUTLINED_0:@.+]] to {{.+}})
+
+// CHECK: define{{.+}} void [[T_OMP_TEAMS_OUTLINED_0]](
+// CHECK: call {{.*}}void @__kmpc_push_num_threads([[IDENT_T_TY]]* [[DEF_LOC_2]], i32 {{.+}}, i32 5)
+// CHECK: call {{.*}}void {{.*}} @__kmpc_fork_call(
+
+// CHECK: define internal void [[T_OFFLOADING_FUN_1]](
+// CHECK: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, i32 0, {{.+}}* [[T_OMP_TEAMS_OUTLINED_1:@.+]] to {{.+}})
+
+// CHECK: define{{.+}} void [[T_OMP_TEAMS_OUTLINED_1]](
+// CHECK: call {{.*}}void @__kmpc_push_num_threads([[IDENT_T_TY]]* [[DEF_LOC_2]], i32 {{.+}}, i32 23)
+// CHECK: call {{.*}}void {{.*}} @__kmpc_fork_call(
+
+// CHECK: define internal void [[T_OFFLOADING_FUN_2]](
+// CHECK: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, i32 0, {{.+}}* [[T_OMP_TEAMS_OUTLINED_2:@.+]] to {{.+}})
+
+// CHECK: define{{.+}} void [[T_OMP_TEAMS_OUTLINED_2]](
+// CHECK: call {{.*}}void @__kmpc_push_num_threads([[IDENT_T_TY]]* [[DEF_LOC_2]], i32 {{.+}}, i32 1)
+// CHECK: call {{.*}}void {{.*}} @__kmpc_fork_call(
+
+// CHECK: define internal void [[T_OFFLOADING_FUN_3]](
+// CHECK: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, i32 0, {{.+}}* [[T_OMP_TEAMS_OUTLINED_3:@.+]] to {{.+}})
+
+// CHECK: define{{.+}} void [[T_OMP_TEAMS_OUTLINED_3]](
+// CHECK-DAG: [[CALL_RES:%.+]] = invoke{{.*}} i8 [[S_TY_CHAR_OP:@.+]]([[S_TY]]* {{.+}})
+// CHECK-DAG: [[CALL_RES_SEXT:%.+]] = sext i8 [[CALL_RES]] to {{.+}}
+// CHECK: call {{.*}}void @__kmpc_push_num_threads([[IDENT_T_TY]]* [[DEF_LOC_2]], i32 {{.+}}, i32 [[CALL_RES_SEXT]])
+// CHECK: call {{.*}}void {{.*}} @__kmpc_fork_call(
+#endif
diff --git a/test/OpenMP/distribute_parallel_for_simd_private_codegen.cpp b/test/OpenMP/distribute_parallel_for_simd_private_codegen.cpp
new file mode 100644
index 000000000000..8ffe521bfcbc
--- /dev/null
+++ b/test/OpenMP/distribute_parallel_for_simd_private_codegen.cpp
@@ -0,0 +1,297 @@
+// RUN: %clang_cc1 -DLAMBDA -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+// RUN: %clang_cc1 -DLAMBDA -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-32
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-32
+
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+template <class T>
+struct S {
+ T f;
+ S(T a) : f(a) {}
+ S() : f() {}
+ operator T() { return T(); }
+ ~S() {}
+};
+
+// CHECK: [[S_FLOAT_TY:%.+]] = type { float }
+// CHECK: [[S_INT_TY:%.+]] = type { i{{[0-9]+}} }
+template <typename T>
+T tmain() {
+ S<T> test;
+ T t_var = T();
+ T vec[] = {1, 2};
+ S<T> s_arr[] = {1, 2};
+ S<T> &var = test;
+ #pragma omp target
+ #pragma omp teams
+ #pragma omp distribute parallel for simd private(t_var, vec, s_arr, s_arr, var, var)
+ for (int i = 0; i < 2; ++i) {
+ vec[i] = t_var;
+ s_arr[i] = var;
+ }
+ return T();
+}
+
+int main() {
+ static int svar;
+ volatile double g;
+ volatile double &g1 = g;
+
+ #ifdef LAMBDA
+ // LAMBDA-LABEL: @main
+ // LAMBDA: call{{.*}} void [[OUTER_LAMBDA:@.+]](
+ [&]() {
+ static float sfvar;
+ // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
+ // LAMBDA: call i{{[0-9]+}} @__tgt_target_teams(
+ // LAMBDA: call void [[OFFLOADING_FUN:@.+]](
+
+ // LAMBDA: define{{.+}} void [[OFFLOADING_FUN]]()
+ // LAMBDA: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, i32 0, {{.+}}* [[OMP_OUTLINED:@.+]] to {{.+}})
+ #pragma omp target
+ #pragma omp teams
+ #pragma omp distribute parallel for simd private(g, g1, svar, sfvar)
+ for (int i = 0; i < 2; ++i) {
+ // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_OUTLINED]](i32* noalias %{{.+}}, i32* noalias %{{.+}})
+ // LAMBDA: [[G_PRIVATE_ADDR:%.+]] = alloca double,
+ // LAMBDA: [[G1_PRIVATE_ADDR:%.+]] = alloca double,
+ // LAMBDA: [[TMP_PRIVATE_ADDR:%.+]] = alloca double*,
+ // LAMBDA: [[SVAR_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[SFVAR_PRIVATE_ADDR:%.+]] = alloca float,
+ // LAMBDA: store double* [[G1_PRIVATE_ADDR]], double** [[TMP_PRIVATE_ADDR]],
+ // LAMBDA: call {{.*}}void @__kmpc_for_static_init_4(
+ // LAMBDA: call{{.+}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}}[[OMP_PARFOR_OUTLINED:@.+]] to {{.+}},
+ // LAMBDA: call {{.*}}void @__kmpc_for_static_fini(
+ // LAMBDA: ret void
+
+ // LAMBDA: define{{.+}} void [[OMP_PARFOR_OUTLINED]](
+ // LAMBDA: [[G_PRIVATE_ADDR:%.+]] = alloca double,
+ // LAMBDA: [[G1_PRIVATE_ADDR:%.+]] = alloca double,
+ // LAMBDA: [[TMP_PRIVATE_ADDR:%.+]] = alloca double*,
+ // LAMBDA: [[SVAR_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[SFVAR_PRIVATE_ADDR:%.+]] = alloca float,
+
+ g = 1;
+ g1 = 1;
+ svar = 3;
+ sfvar = 4.0;
+ // LAMBDA: store double* [[G1_PRIVATE_ADDR]], double** [[TMP_PRIVATE_ADDR]],
+ // LAMBDA: store double 1.0{{.+}}, double* [[G_PRIVATE_ADDR]],
+ // LAMBDA: store i{{[0-9]+}} 3, i{{[0-9]+}}* [[SVAR_PRIVATE_ADDR]],
+ // LAMBDA: store float 4.0{{.+}}, float* [[SFVAR_PRIVATE_ADDR]],
+ // LAMBDA: [[G_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // LAMBDA: store double* [[G_PRIVATE_ADDR]], double** [[G_PRIVATE_ADDR_REF]],
+ // LAMBDA: [[TMP_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // LAMBDA: [[G1_PRIVATE_ADDR_FROM_TMP:%.+]] = load double*, double** [[TMP_PRIVATE_ADDR]],
+ // LAMBDA: store double* [[G1_PRIVATE_ADDR_FROM_TMP]], double** [[TMP_PRIVATE_ADDR_REF]],
+ // LAMBDA: [[SVAR_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+ // LAMBDA: store i{{[0-9]+}}* [[SVAR_PRIVATE_ADDR]], i{{[0-9]+}}** [[SVAR_PRIVATE_ADDR_REF]]
+ // LAMBDA: [[SFVAR_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 3
+ // LAMBDA: store float* [[SFVAR_PRIVATE_ADDR]], float** [[SFVAR_PRIVATE_ADDR_REF]]
+ // LAMBDA: call{{.*}} void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]])
+ // LAMBDA: call {{.*}}void @__kmpc_for_static_fini(
+ // LAMBDA: ret void
+ [&]() {
+ // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]])
+ // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]],
+ g = 2;
+ g1 = 2;
+ svar = 4;
+ sfvar = 8.0;
+ // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]]
+ // LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // LAMBDA: [[G_REF:%.+]] = load double*, double** [[G_PTR_REF]]
+ // LAMBDA: store double 2.0{{.+}}, double* [[G_REF]]
+
+ // LAMBDA: [[TMP_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // LAMBDA: [[G1_REF:%.+]] = load double*, double** [[TMP_PTR_REF]]
+ // LAMBDA: store double 2.0{{.+}}, double* [[G1_REF]],
+ // LAMBDA: [[SVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+ // LAMBDA: [[SVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SVAR_PTR_REF]]
+ // LAMBDA: store i{{[0-9]+}} 4, i{{[0-9]+}}* [[SVAR_REF]]
+ // LAMBDA: [[SFVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 3
+ // LAMBDA: [[SFVAR_REF:%.+]] = load float*, float** [[SFVAR_PTR_REF]]
+ // LAMBDA: store float 8.0{{.+}}, float* [[SFVAR_REF]]
+ }();
+ }
+ }();
+ return 0;
+ #else
+ S<float> test;
+ int t_var = 0;
+ int vec[] = {1, 2};
+ S<float> s_arr[] = {1, 2};
+ S<float> &var = test;
+
+ #pragma omp target
+ #pragma omp teams
+ #pragma omp distribute parallel for simd private(t_var, vec, s_arr, s_arr, var, var, svar)
+ for (int i = 0; i < 2; ++i) {
+ vec[i] = t_var;
+ s_arr[i] = var;
+ }
+ return tmain<int>();
+ #endif
+}
+
+// CHECK: define{{.*}} i{{[0-9]+}} @main()
+// CHECK: [[TEST:%.+]] = alloca [[S_FLOAT_TY]],
+// CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR:@.+]]([[S_FLOAT_TY]]* [[TEST]])
+// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+// CHECK: call void [[OFFLOAD_FUN_0:@.+]](
+
+// CHECK: call {{.*}} [[S_FLOAT_TY_DEF_DESTR:@.+]]([[S_FLOAT_TY]]* [[TEST]])
+// CHECK: ret
+
+// CHECK: define{{.+}} [[OFFLOAD_FUN_0]]()
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_teams(%{{.+}}* @{{.+}}, i{{[0-9]+}} 0, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*)* [[OMP_OUTLINED_0:@.+]] to void
+// CHECK: ret
+//
+// CHECK: define internal void [[OMP_OUTLINED_0]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}})
+// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]],
+// CHECK-NOT: alloca [2 x [[S_FLOAT_TY]]],
+// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]],
+// CHECK-NOT: alloca [[S_FLOAT_TY]],
+// CHECK: [[S_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_REF:%.+]]
+// CHECK-NOT: [[T_VAR_PRIV]]
+// CHECK-NOT: [[VEC_PRIV]]
+// this is the ctor loop
+// CHECK: {{.+}}:
+// CHECK: [[S_ARR_PRIV_ITEM:%.+]] = phi [[S_FLOAT_TY]]*
+// CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR]]([[S_FLOAT_TY]]* [[S_ARR_PRIV_ITEM]])
+// CHECK-NOT: [[T_VAR_PRIV]]
+// CHECK-NOT: [[VEC_PRIV]]
+// CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR]]([[S_FLOAT_TY]]* [[VAR_PRIV]])
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: call{{.+}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}}[[OMP_PARFOR_OUTLINED_0:@.+]] to {{.+}},
+// CHECK: call void @__kmpc_for_static_fini(
+
+// call destructors: var..
+// CHECK-DAG: call {{.+}} [[S_FLOAT_TY_DEF_DESTR]]([[S_FLOAT_TY]]* [[VAR_PRIV]])
+
+// ..and s_arr
+// CHECK: {{.+}}:
+// CHECK: [[S_ARR_EL_PAST:%.+]] = phi [[S_FLOAT_TY]]*
+// CHECK: [[S_ARR_PRIV_ITEM:%.+]] = getelementptr {{.+}}, {{.+}} [[S_ARR_EL_PAST]],
+// CHECK: call {{.*}} [[S_FLOAT_TY_DEF_DESTR]]([[S_FLOAT_TY]]* [[S_ARR_PRIV_ITEM]])
+
+// CHECK: ret void
+
+// By OpenMP specifications, private applies to both distribute and parallel for.
+// However, the support for 'private' of 'parallel' is only used when 'parallel'
+// is found alone. Therefore we only have one 'private' support for 'parallel for'
+// in combination
+// CHECK: define{{.+}} void [[OMP_PARFOR_OUTLINED_0]](
+// CHECK: [[T_VAR_PRIV:%t_var+]] = alloca i{{[0-9]+}},
+// CHECK: [[VEC_PRIV:%vec+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK: [[S_ARR_PRIV:%s_arr+]] = alloca [2 x [[S_FLOAT_TY]]],
+// CHECK-NOT: alloca [2 x [[S_FLOAT_TY]]],
+// CHECK: [[VAR_PRIV:%var+]] = alloca [[S_FLOAT_TY]],
+// CHECK-NOT: alloca [[S_FLOAT_TY]],
+// CHECK: [[S_VAR_PRIV:%svar+]] = alloca i{{[0-9]+}},
+// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_REF:%.+]]
+// CHECK-NOT: [[T_VAR_PRIV]]
+// CHECK-NOT: [[VEC_PRIV]]
+// this is the ctor loop
+// CHECK: {{.+}}:
+// CHECK: [[S_ARR_PRIV_ITEM:%.+]] = phi [[S_FLOAT_TY]]*
+// CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR]]([[S_FLOAT_TY]]* [[S_ARR_PRIV_ITEM]])
+// CHECK-NOT: [[T_VAR_PRIV]]
+// CHECK-NOT: [[VEC_PRIV]]
+// CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR]]([[S_FLOAT_TY]]* [[VAR_PRIV]])
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: call void @__kmpc_for_static_fini(
+
+// call destructors: var..
+// CHECK-DAG: call {{.+}} [[S_FLOAT_TY_DEF_DESTR]]([[S_FLOAT_TY]]* [[VAR_PRIV]])
+
+// ..and s_arr
+// CHECK: {{.+}}:
+// CHECK: [[S_ARR_EL_PAST:%.+]] = phi [[S_FLOAT_TY]]*
+// CHECK: [[S_ARR_PRIV_ITEM:%.+]] = getelementptr {{.+}}, {{.+}} [[S_ARR_EL_PAST]],
+// CHECK: call {{.*}} [[S_FLOAT_TY_DEF_DESTR]]([[S_FLOAT_TY]]* [[S_ARR_PRIV_ITEM]])
+
+// CHECK: ret void
+
+// template tmain with S_INT_TY
+// CHECK: define{{.*}} i{{[0-9]+}} [[TMAIN_INT:@.+]]()
+// CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]],
+// CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR:@.+]]([[S_INT_TY]]* [[TEST]])
+// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+// CHECK: call void [[OFFLOAD_FUN_1:@.+]](
+// CHECK: call {{.*}} [[S_INT_TY_DEF_DESTR:@.+]]([[S_INT_TY]]* [[TEST]])
+// CHECK: ret
+
+// CHECK: ret
+
+// CHECK: define internal void [[OFFLOAD_FUN_1]]()
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_teams(%{{.+}}* @{{.+}}, i{{[0-9]+}} 0, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*)* [[OMP_OUTLINED_1:@.+]] to void
+// CHECK: ret
+//
+// CHECK: define internal void [[OMP_OUTLINED_1]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}})
+// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_INT_TY]]],
+// CHECK-NOT: alloca [2 x [[S_INT_TY]]],
+// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_INT_TY]],
+// CHECK-NOT: alloca [[S_INT_TY]],
+// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_REF:%.+]]
+// CHECK-NOT: [[T_VAR_PRIV]]
+// CHECK-NOT: [[VEC_PRIV]]
+// CHECK: {{.+}}:
+// CHECK: [[S_ARR_PRIV_ITEM:%.+]] = phi [[S_INT_TY]]*
+// CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR]]([[S_INT_TY]]* [[S_ARR_PRIV_ITEM]])
+// CHECK-NOT: [[T_VAR_PRIV]]
+// CHECK-NOT: [[VEC_PRIV]]
+// CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR]]([[S_INT_TY]]* [[VAR_PRIV]])
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: call{{.+}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}}[[OMP_PARFOR_OUTLINED_1:@.+]] to {{.+}},
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: ret void
+
+// CHECK: define{{.+}} void [[OMP_PARFOR_OUTLINED_1]](
+// CHECK: [[T_VAR_PRIV:%t_var+]] = alloca i{{[0-9]+}},
+// CHECK: [[VEC_PRIV:%vec+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK: [[S_ARR_PRIV:%s_arr+]] = alloca [2 x [[S_INT_TY]]],
+// CHECK-NOT: alloca [2 x [[S_INT_TY]]],
+// CHECK: [[VAR_PRIV:%var+]] = alloca [[S_INT_TY]],
+// CHECK-NOT: alloca [[S_INT_TY]],
+// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_REF:%.+]]
+// CHECK-NOT: [[T_VAR_PRIV]]
+// CHECK-NOT: [[VEC_PRIV]]
+// this is the ctor loop
+// CHECK: {{.+}}:
+// CHECK: [[S_ARR_PRIV_ITEM:%.+]] = phi [[S_INT_TY]]*
+// CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR]]([[S_INT_TY]]* [[S_ARR_PRIV_ITEM]])
+// CHECK-NOT: [[T_VAR_PRIV]]
+// CHECK-NOT: [[VEC_PRIV]]
+// CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR]]([[S_INT_TY]]* [[VAR_PRIV]])
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: call void @__kmpc_for_static_fini(
+
+// call destructors: var..
+// CHECK-DAG: call {{.+}} [[S_INT_TY_DEF_DESTR]]([[S_INT_TY]]* [[VAR_PRIV]])
+
+// ..and s_arr
+// CHECK: {{.+}}:
+// CHECK: [[S_ARR_EL_PAST:%.+]] = phi [[S_INT_TY]]*
+// CHECK: [[S_ARR_PRIV_ITEM:%.+]] = getelementptr {{.+}}, {{.+}} [[S_ARR_EL_PAST]],
+// CHECK: call {{.*}} [[S_INT_TY_DEF_DESTR]]([[S_INT_TY]]* [[S_ARR_PRIV_ITEM]])
+
+// CHECK: ret void
+
+#endif
diff --git a/test/OpenMP/distribute_parallel_for_simd_proc_bind_codegen.cpp b/test/OpenMP/distribute_parallel_for_simd_proc_bind_codegen.cpp
new file mode 100644
index 000000000000..7f0b631aee7f
--- /dev/null
+++ b/test/OpenMP/distribute_parallel_for_simd_proc_bind_codegen.cpp
@@ -0,0 +1,93 @@
+// add -fopenmp-targets
+
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+typedef __INTPTR_TYPE__ intptr_t;
+
+// CHECK-DAG: [[IDENT_T_TY:%.+]] = type { i32, i32, i32, i32, i8* }
+// CHECK-DAG: [[STR:@.+]] = private unnamed_addr constant [23 x i8] c";unknown;unknown;0;0;;\00"
+// CHECK-DAG: [[DEF_LOC_2:@.+]] = private unnamed_addr constant [[IDENT_T_TY]] { i32 0, i32 2, i32 0, i32 0, i8* getelementptr inbounds ([23 x i8], [23 x i8]* [[STR]], i32 0, i32 0) }
+
+void foo();
+
+struct S {
+ intptr_t a, b, c;
+ S(intptr_t a) : a(a) {}
+ operator char() { return a; }
+ ~S() {}
+};
+
+template <typename T>
+T tmain() {
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd proc_bind(master)
+ for(int i = 0; i < 1000; i++) {}
+ return T();
+}
+
+int main() {
+ // CHECK-LABEL: @main
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd proc_bind(spread)
+ for(int i = 0; i < 1000; i++) {}
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd proc_bind(close)
+ for(int i = 0; i < 1000; i++) {}
+ return tmain<int>();
+}
+
+// CHECK: call {{.*}}@__tgt_target_teams({{.+}})
+// CHECK: call void [[OFFL1:@.+]]()
+// CHECK: call {{.*}}@__tgt_target_teams({{.+}})
+// CHECK: call void [[OFFL2:@.+]]()
+// CHECK: [[CALL_RET:%.+]] = call{{.+}} i32 [[TMAIN:@.+]]()
+// CHECK: ret i32 [[CALL_RET]]
+
+// CHECK: define{{.+}} void [[OFFL1]](
+// CHECK: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, {{.+}}, {{.+}}* [[OMP_OUTLINED_1:@.+]] to {{.+}})
+
+// CHECK: define{{.+}} [[OMP_OUTLINED_1]](i32* {{.+}} [[GTID_IN:%.+]],
+// CHECK: [[GTID_ADDR:%.+]] = alloca i32*,
+// CHECK: store i32* [[GTID_IN]], i32** [[GTID_ADDR]],
+// CHECK: [[GTID_REF:%.+]] = load i32*, i32** [[GTID_ADDR]],
+// CHECK: [[GTID_VAL:%.+]] = load i32, i32* [[GTID_REF]],
+// CHECK: call {{.*}}void @__kmpc_push_proc_bind([[IDENT_T_TY]]* [[DEF_LOC_2]], i32 [[GTID_VAL]], i32 4)
+// CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(
+// CHECK: ret void
+
+// CHECK: define{{.+}} [[OFFL2]]()
+// CHECK: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, {{.+}}, {{.+}}* [[OMP_OUTLINED_1:@.+]] to {{.+}})
+
+// CHECK: define{{.+}} [[OMP_OUTLINED_1]](i32* {{.+}} [[GTID_IN:%.+]],
+// CHECK: [[GTID_ADDR:%.+]] = alloca i32*,
+// CHECK: store i32* [[GTID_IN]], i32** [[GTID_ADDR]],
+// CHECK: [[GTID_REF:%.+]] = load i32*, i32** [[GTID_ADDR]],
+// CHECK: [[GTID_VAL:%.+]] = load i32, i32* [[GTID_REF]],
+// CHECK: call {{.*}}void @__kmpc_push_proc_bind([[IDENT_T_TY]]* [[DEF_LOC_2]], i32 [[GTID_VAL]], i32 3)
+// CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(
+// CHECK: ret void
+
+// CHECK: define{{.+}} [[TMAIN]]()
+// CHECK: call {{.*}}@__tgt_target_teams({{.+}})
+// CHECK: call void [[OFFL3:@.+]]()
+
+// CHECK: define{{.+}} [[OFFL3]]()
+// CHECK: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, {{.+}}, {{.+}}* [[OMP_OUTLINED_3:@.+]] to {{.+}})
+
+// CHECK: define{{.+}} [[OMP_OUTLINED_3]](i32* {{.+}} [[GTID_IN:%.+]],
+// CHECK: [[GTID_ADDR:%.+]] = alloca i32*,
+// CHECK: store i32* [[GTID_IN]], i32** [[GTID_ADDR]],
+// CHECK: [[GTID_REF:%.+]] = load i32*, i32** [[GTID_ADDR]],
+// CHECK: [[GTID_VAL:%.+]] = load i32, i32* [[GTID_REF]],
+// CHECK: call {{.*}}void @__kmpc_push_proc_bind([[IDENT_T_TY]]* [[DEF_LOC_2]], i32 [[GTID_VAL]], i32 2)
+// CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(
+// CHECK: ret void
+#endif
diff --git a/test/OpenMP/distribute_parallel_for_simd_reduction_messages.cpp b/test/OpenMP/distribute_parallel_for_simd_reduction_messages.cpp
index 6ad41d72bf78..94e4541b901b 100644
--- a/test/OpenMP/distribute_parallel_for_simd_reduction_messages.cpp
+++ b/test/OpenMP/distribute_parallel_for_simd_reduction_messages.cpp
@@ -27,9 +27,9 @@ public:
S2() : a(0) {}
S2(S2 &s2) : a(s2.a) {}
static float S2s; // expected-note 2 {{static data member is predetermined as shared}}
- static const float S2sc;
+ static const float S2sc; // expected-note 2 {{'S2sc' declared here}}
};
-const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}}
+const float S2::S2sc = 0;
S2 b; // expected-note 3 {{'b' defined here}}
const S2 ba[5]; // expected-note 2 {{'ba' defined here}}
class S3 {
diff --git a/test/OpenMP/distribute_private_messages.cpp b/test/OpenMP/distribute_private_messages.cpp
index 518b64d9e9ca..0aa1e4796975 100644
--- a/test/OpenMP/distribute_private_messages.cpp
+++ b/test/OpenMP/distribute_private_messages.cpp
@@ -87,7 +87,7 @@ int main(int argc, char **argv) {
#pragma omp teams
{
int i; // expected-note {{predetermined as private}}
- #pragma omp distribute firstprivate(i), private(i) // expected-error {{private variable in '#pragma omp teams' cannot be firstprivate in '#pragma omp distribute'}}
+ #pragma omp distribute firstprivate(i) // expected-error {{firstprivate variable must be shared}}
for (int k = 0; k < argc; ++k) ++k;
}
#pragma omp target
diff --git a/test/OpenMP/distribute_simd_ast_print.cpp b/test/OpenMP/distribute_simd_ast_print.cpp
index 6d2e916292f5..3246ccb46ae3 100644
--- a/test/OpenMP/distribute_simd_ast_print.cpp
+++ b/test/OpenMP/distribute_simd_ast_print.cpp
@@ -84,14 +84,14 @@ T tmain(T argc) {
#pragma omp target
#pragma omp teams
-#pragma omp distribute simd private(argc, b), firstprivate(c, d), lastprivate(d, f) collapse(N) reduction(+ : h) dist_schedule(static,N)
+#pragma omp distribute simd private(argc, b), firstprivate(c, d), lastprivate(f) collapse(N) reduction(+ : h) dist_schedule(static,N)
for (int i = 0; i < 2; ++i)
for (int j = 0; j < 2; ++j)
for (int k = 0; k < 10; ++k)
for (int m = 0; m < 10; ++m)
for (int n = 0; n < 10; ++n)
a++;
-// CHECK: #pragma omp distribute simd private(argc,b) firstprivate(c,d) lastprivate(d,f) collapse(N) reduction(+: h) dist_schedule(static, N)
+// CHECK: #pragma omp distribute simd private(argc,b) firstprivate(c,d) lastprivate(f) collapse(N) reduction(+: h) dist_schedule(static, N)
// CHECK-NEXT: for (int i = 0; i < 2; ++i)
// CHECK-NEXT: for (int j = 0; j < 2; ++j)
// CHECK-NEXT: for (int k = 0; k < 10; ++k)
@@ -129,14 +129,15 @@ int main(int argc, char **argv) {
// CHECK-NEXT: for (int j = 0; j < 10; ++j)
// CHECK-NEXT: a++;
+ int i;
#pragma omp target
#pragma omp teams
-#pragma omp distribute simd aligned(x:8) linear(h:2) safelen(8) simdlen(8)
- for (int i = 0; i < 100; i++)
+#pragma omp distribute simd aligned(x:8) linear(i:2) safelen(8) simdlen(8)
+ for (i = 0; i < 100; i++)
for (int j = 0; j < 200; j++)
a += h + x[j];
-// CHECK: #pragma omp distribute simd aligned(x: 8) linear(h: 2) safelen(8) simdlen(8)
-// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK: #pragma omp distribute simd aligned(x: 8) linear(i: 2) safelen(8) simdlen(8)
+// CHECK-NEXT: for (i = 0; i < 100; i++)
// CHECK-NEXT: for (int j = 0; j < 200; j++)
// CHECK-NEXT: a += h + x[j];
diff --git a/test/OpenMP/distribute_simd_codegen.cpp b/test/OpenMP/distribute_simd_codegen.cpp
new file mode 100644
index 000000000000..d8f18c3e431b
--- /dev/null
+++ b/test/OpenMP/distribute_simd_codegen.cpp
@@ -0,0 +1,269 @@
+// Test host codegen.
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64 --check-prefix HCHECK
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 --check-prefix HCHECK
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 --check-prefix HCHECK
+
+// Test target codegen - host bc file has to be created first. (no significant differences with host version of target region)
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm-bc %s -o %t-ppc-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm-bc %s -o %t-x86-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+// CHECK-DAG: %ident_t = type { i32, i32, i32, i32, i8* }
+// CHECK-DAG: [[STR:@.+]] = private unnamed_addr constant [23 x i8] c";unknown;unknown;0;0;;\00"
+// CHECK-DAG: [[DEF_LOC_0:@.+]] = private unnamed_addr constant %ident_t { i32 0, i32 2, i32 0, i32 0, i8* getelementptr inbounds ([23 x i8], [23 x i8]* [[STR]], i32 0, i32 0) }
+// CHECK-DAG: [[DEF_LOC_DISTRIBUTE_0:@.+]] = private unnamed_addr constant %ident_t { i32 0, i32 2050, i32 0, i32 0, i8* getelementptr inbounds ([23 x i8], [23 x i8]* [[STR]], i32 0, i32 0) }
+
+// CHECK-LABEL: define {{.*void}} @{{.*}}without_schedule_clause{{.*}}(float* {{.+}}, float* {{.+}}, float* {{.+}}, float* {{.+}})
+void without_schedule_clause(float *a, float *b, float *c, float *d) {
+ #pragma omp target
+ #pragma omp teams
+ #pragma omp distribute simd simdlen(8) aligned(a)
+ for (int i = 33; i < 32000000; i += 7) {
+ a[i] = b[i] * c[i] * d[i];
+ }
+}
+
+// CHECK: define {{.*}}void @{{.+}}(i32* noalias [[GBL_TIDP:%.+]], i32* noalias [[BND_TID:%.+]], float** dereferenceable({{[0-9]+}}) [[APTR:%.+]], float** dereferenceable({{[0-9]+}}) [[BPTR:%.+]], float** dereferenceable({{[0-9]+}}) [[CPTR:%.+]], float** dereferenceable({{[0-9]+}}) [[DPTR:%.+]])
+// CHECK: [[TID_ADDR:%.+]] = alloca i32*
+// CHECK: [[IV:%.+iv]] = alloca i32
+// CHECK: [[LB:%.+lb]] = alloca i32
+// CHECK: [[UB:%.+ub]] = alloca i32
+// CHECK: [[ST:%.+stride]] = alloca i32
+// CHECK: [[LAST:%.+last]] = alloca i32
+// CHECK-DAG: store i32* [[GBL_TIDP]], i32** [[TID_ADDR]]
+// CHECK-DAG: call void @llvm.assume(
+// CHECK-DAG: store i32 0, i32* [[LB]]
+// CHECK-DAG: store i32 4571423, i32* [[UB]]
+// CHECK-DAG: store i32 1, i32* [[ST]]
+// CHECK-DAG: store i32 0, i32* [[LAST]]
+// CHECK-DAG: [[GBL_TID:%.+]] = load i32*, i32** [[TID_ADDR]]
+// CHECK-DAG: [[GBL_TIDV:%.+]] = load i32, i32* [[GBL_TID]]
+// CHECK: call void @__kmpc_for_static_init_{{.+}}(%ident_t* [[DEF_LOC_DISTRIBUTE_0]], i32 [[GBL_TIDV]], i32 92, i32* %.omp.is_last, i32* %.omp.lb, i32* %.omp.ub, i32* %.omp.stride, i32 1, i32 1)
+// CHECK-DAG: [[UBV0:%.+]] = load i32, i32* [[UB]]
+// CHECK-DAG: [[USWITCH:%.+]] = icmp sgt i32 [[UBV0]], 4571423
+// CHECK: br i1 [[USWITCH]], label %[[BBCT:.+]], label %[[BBCF:.+]]
+// CHECK-DAG: [[BBCT]]:
+// CHECK-DAG: br label %[[BBCE:.+]]
+// CHECK-DAG: [[BBCF]]:
+// CHECK-DAG: [[UBV1:%.+]] = load i32, i32* [[UB]]
+// CHECK-DAG: br label %[[BBCE]]
+// CHECK: [[BBCE]]:
+// CHECK: [[SELUB:%.+]] = phi i32 [ 4571423, %[[BBCT]] ], [ [[UBV1]], %[[BBCF]] ]
+// CHECK: store i32 [[SELUB]], i32* [[UB]]
+// CHECK: [[LBV0:%.+]] = load i32, i32* [[LB]]
+// CHECK: store i32 [[LBV0]], i32* [[IV]]
+// CHECK: br label %[[BBINNFOR:.+]]
+// CHECK: [[BBINNFOR]]:
+// CHECK: [[IVVAL0:%.+]] = load i32, i32* [[IV]]
+// CHECK: [[UBV2:%.+]] = load i32, i32* [[UB]]
+// CHECK: [[IVLEUB:%.+]] = icmp sle i32 [[IVVAL0]], [[UBV2]]
+// CHECK: br i1 [[IVLEUB]], label %[[BBINNBODY:.+]], label %[[BBINNEND:.+]]
+// CHECK: [[BBINNBODY]]:
+// CHECK: {{.+}} = load i32, i32* [[IV]]
+// ... loop body ...
+// CHECK: br label %[[BBBODYCONT:.+]]
+// CHECK: [[BBBODYCONT]]:
+// CHECK: br label %[[BBINNINC:.+]]
+// CHECK: [[BBINNINC]]:
+// CHECK: [[IVVAL1:%.+]] = load i32, i32* [[IV]]
+// CHECK: [[IVINC:%.+]] = add nsw i32 [[IVVAL1]], 1
+// CHECK: store i32 [[IVINC]], i32* [[IV]]
+// CHECK: br label %[[BBINNFOR]]
+// CHECK: [[BBINNEND]]:
+// CHECK: br label %[[LPEXIT:.+]]
+// CHECK: [[LPEXIT]]:
+// CHECK: call void @__kmpc_for_static_fini(%ident_t* [[DEF_LOC_DISTRIBUTE_0]], i32 [[GBL_TIDV]])
+// CHECK: ret void
+
+
+// CHECK-LABEL: define {{.*void}} @{{.*}}static_not_chunked{{.*}}(float* {{.+}}, float* {{.+}}, float* {{.+}}, float* {{.+}})
+void static_not_chunked(float *a, float *b, float *c, float *d) {
+ #pragma omp target
+ #pragma omp teams
+ #pragma omp distribute simd dist_schedule(static) safelen(32)
+ for (int i = 32000000; i > 33; i += -7) {
+ a[i] = b[i] * c[i] * d[i];
+ }
+}
+
+// CHECK: define {{.*}}void @.omp_outlined.{{.*}}(i32* noalias [[GBL_TIDP:%.+]], i32* noalias [[BND_TID:%.+]], float** dereferenceable({{[0-9]+}}) [[APTR:%.+]], float** dereferenceable({{[0-9]+}}) [[BPTR:%.+]], float** dereferenceable({{[0-9]+}}) [[CPTR:%.+]], float** dereferenceable({{[0-9]+}}) [[DPTR:%.+]])
+// CHECK: [[TID_ADDR:%.+]] = alloca i32*
+// CHECK: [[IV:%.+iv]] = alloca i32
+// CHECK: [[LB:%.+lb]] = alloca i32
+// CHECK: [[UB:%.+ub]] = alloca i32
+// CHECK: [[ST:%.+stride]] = alloca i32
+// CHECK: [[LAST:%.+last]] = alloca i32
+// CHECK-DAG: store i32* [[GBL_TIDP]], i32** [[TID_ADDR]]
+// CHECK-DAG: store i32 0, i32* [[LB]]
+// CHECK-DAG: store i32 4571423, i32* [[UB]]
+// CHECK-DAG: store i32 1, i32* [[ST]]
+// CHECK-DAG: store i32 0, i32* [[LAST]]
+// CHECK-DAG: [[GBL_TID:%.+]] = load i32*, i32** [[TID_ADDR]]
+// CHECK-DAG: [[GBL_TIDV:%.+]] = load i32, i32* [[GBL_TID]]
+// CHECK: call void @__kmpc_for_static_init_{{.+}}(%ident_t* [[DEF_LOC_DISTRIBUTE_0]], i32 [[GBL_TIDV]], i32 92, i32* %.omp.is_last, i32* %.omp.lb, i32* %.omp.ub, i32* %.omp.stride, i32 1, i32 1)
+// CHECK-DAG: [[UBV0:%.+]] = load i32, i32* [[UB]]
+// CHECK-DAG: [[USWITCH:%.+]] = icmp sgt i32 [[UBV0]], 4571423
+// CHECK: br i1 [[USWITCH]], label %[[BBCT:.+]], label %[[BBCF:.+]]
+// CHECK-DAG: [[BBCT]]:
+// CHECK-DAG: br label %[[BBCE:.+]]
+// CHECK-DAG: [[BBCF]]:
+// CHECK-DAG: [[UBV1:%.+]] = load i32, i32* [[UB]]
+// CHECK-DAG: br label %[[BBCE]]
+// CHECK: [[BBCE]]:
+// CHECK: [[SELUB:%.+]] = phi i32 [ 4571423, %[[BBCT]] ], [ [[UBV1]], %[[BBCF]] ]
+// CHECK: store i32 [[SELUB]], i32* [[UB]]
+// CHECK: [[LBV0:%.+]] = load i32, i32* [[LB]]
+// CHECK: store i32 [[LBV0]], i32* [[IV]]
+// CHECK: br label %[[BBINNFOR:.+]]
+// CHECK: [[BBINNFOR]]:
+// CHECK: [[IVVAL0:%.+]] = load i32, i32* [[IV]]
+// CHECK: [[UBV2:%.+]] = load i32, i32* [[UB]]
+// CHECK: [[IVLEUB:%.+]] = icmp sle i32 [[IVVAL0]], [[UBV2]]
+// CHECK: br i1 [[IVLEUB]], label %[[BBINNBODY:.+]], label %[[BBINNEND:.+]]
+// CHECK: [[BBINNBODY]]:
+// CHECK: {{.+}} = load i32, i32* [[IV]]
+// ... loop body ...
+// CHECK: br label %[[BBBODYCONT:.+]]
+// CHECK: [[BBBODYCONT]]:
+// CHECK: br label %[[BBINNINC:.+]]
+// CHECK: [[BBINNINC]]:
+// CHECK: [[IVVAL1:%.+]] = load i32, i32* [[IV]]
+// CHECK: [[IVINC:%.+]] = add nsw i32 [[IVVAL1]], 1
+// CHECK: store i32 [[IVINC]], i32* [[IV]]
+// CHECK: br label %[[BBINNFOR]]
+// CHECK: [[BBINNEND]]:
+// CHECK: br label %[[LPEXIT:.+]]
+// CHECK: [[LPEXIT]]:
+// CHECK: call void @__kmpc_for_static_fini(%ident_t* [[DEF_LOC_DISTRIBUTE_0]], i32 [[GBL_TIDV]])
+// CHECK: ret void
+
+
+// CHECK-LABEL: define {{.*void}} @{{.*}}static_chunked{{.*}}(float* {{.+}}, float* {{.+}}, float* {{.+}}, float* {{.+}})
+void static_chunked(float *a, float *b, float *c, float *d) {
+ #pragma omp target
+ #pragma omp teams
+#pragma omp distribute simd dist_schedule(static, 5)
+ for (unsigned i = 131071; i <= 2147483647; i += 127) {
+ a[i] = b[i] * c[i] * d[i];
+ }
+}
+
+// CHECK: define {{.*}}void @.omp_outlined.{{.*}}(i32* noalias [[GBL_TIDP:%.+]], i32* noalias [[BND_TID:%.+]], float** dereferenceable({{[0-9]+}}) [[APTR:%.+]], float** dereferenceable({{[0-9]+}}) [[BPTR:%.+]], float** dereferenceable({{[0-9]+}}) [[CPTR:%.+]], float** dereferenceable({{[0-9]+}}) [[DPTR:%.+]])
+// CHECK: [[TID_ADDR:%.+]] = alloca i32*
+// CHECK: [[IV:%.+iv]] = alloca i32
+// CHECK: [[LB:%.+lb]] = alloca i32
+// CHECK: [[UB:%.+ub]] = alloca i32
+// CHECK: [[ST:%.+stride]] = alloca i32
+// CHECK: [[LAST:%.+last]] = alloca i32
+// CHECK-DAG: store i32* [[GBL_TIDP]], i32** [[TID_ADDR]]
+// CHECK-DAG: store i32 0, i32* [[LB]]
+// CHECK-DAG: store i32 16908288, i32* [[UB]]
+// CHECK-DAG: store i32 1, i32* [[ST]]
+// CHECK-DAG: store i32 0, i32* [[LAST]]
+// CHECK-DAG: [[GBL_TID:%.+]] = load i32*, i32** [[TID_ADDR]]
+// CHECK-DAG: [[GBL_TIDV:%.+]] = load i32, i32* [[GBL_TID]]
+// CHECK: call void @__kmpc_for_static_init_{{.+}}(%ident_t* [[DEF_LOC_DISTRIBUTE_0]], i32 [[GBL_TIDV]], i32 91, i32* %.omp.is_last, i32* %.omp.lb, i32* %.omp.ub, i32* %.omp.stride, i32 1, i32 5)
+// CHECK-DAG: [[UBV0:%.+]] = load i32, i32* [[UB]]
+// CHECK-DAG: [[USWITCH:%.+]] = icmp ugt i32 [[UBV0]], 16908288
+// CHECK: br i1 [[USWITCH]], label %[[BBCT:.+]], label %[[BBCF:.+]]
+// CHECK-DAG: [[BBCT]]:
+// CHECK-DAG: br label %[[BBCE:.+]]
+// CHECK-DAG: [[BBCF]]:
+// CHECK-DAG: [[UBV1:%.+]] = load i32, i32* [[UB]]
+// CHECK-DAG: br label %[[BBCE]]
+// CHECK: [[BBCE]]:
+// CHECK: [[SELUB:%.+]] = phi i32 [ 16908288, %[[BBCT]] ], [ [[UBV1]], %[[BBCF]] ]
+// CHECK: store i32 [[SELUB]], i32* [[UB]]
+// CHECK: [[LBV0:%.+]] = load i32, i32* [[LB]]
+// CHECK: store i32 [[LBV0]], i32* [[IV]]
+// CHECK: br label %[[BBINNFOR:.+]]
+// CHECK: [[BBINNFOR]]:
+// CHECK: [[IVVAL0:%.+]] = load i32, i32* [[IV]]
+// CHECK: [[UBV2:%.+]] = load i32, i32* [[UB]]
+// CHECK: [[IVLEUB:%.+]] = icmp ule i32 [[IVVAL0]], [[UBV2]]
+// CHECK: br i1 [[IVLEUB]], label %[[BBINNBODY:.+]], label %[[BBINNEND:.+]]
+// CHECK: [[BBINNBODY]]:
+// CHECK: {{.+}} = load i32, i32* [[IV]]
+// ... loop body ...
+// CHECK: br label %[[BBBODYCONT:.+]]
+// CHECK: [[BBBODYCONT]]:
+// CHECK: br label %[[BBINNINC:.+]]
+// CHECK: [[BBINNINC]]:
+// CHECK: [[IVVAL1:%.+]] = load i32, i32* [[IV]]
+// CHECK: [[IVINC:%.+]] = add i32 [[IVVAL1]], 1
+// CHECK: store i32 [[IVINC]], i32* [[IV]]
+// CHECK: br label %[[BBINNFOR]]
+// CHECK: [[BBINNEND]]:
+// CHECK: br label %[[LPEXIT:.+]]
+// CHECK: [[LPEXIT]]:
+// CHECK: call void @__kmpc_for_static_fini(%ident_t* [[DEF_LOC_DISTRIBUTE_0]], i32 [[GBL_TIDV]])
+// CHECK: ret void
+
+// CHECK-LABEL: test_precond
+void test_precond() {
+ char a = 0; char i;
+ #pragma omp target
+ #pragma omp teams
+ #pragma omp distribute simd linear(i)
+ for(i = a; i < 10; ++i);
+}
+
+// a is passed as a parameter to the outlined functions
+// CHECK: define {{.*}}void @.omp_outlined.{{.*}}(i32* noalias [[GBL_TIDP:%.+]], i32* noalias [[BND_TID:%.+]], i8* dereferenceable({{[0-9]+}}) [[APARM:%.+]])
+// CHECK: store i8* [[APARM]], i8** [[APTRADDR:%.+]]
+// ..many loads of %0..
+// CHECK: [[A2:%.+]] = load i8*, i8** [[APTRADDR]]
+// CHECK: [[AVAL0:%.+]] = load i8, i8* [[A2]]
+// CHECK: store i8 [[AVAL0]], i8* [[CAP_EXPR:%.+]],
+// CHECK: [[AVAL1:%.+]] = load i8, i8* [[CAP_EXPR]]
+// CHECK: load i8, i8* [[CAP_EXPR]]
+// CHECK: [[AVAL2:%.+]] = load i8, i8* [[CAP_EXPR]]
+// CHECK: [[ACONV:%.+]] = sext i8 [[AVAL2]] to i32
+// CHECK: [[ACMP:%.+]] = icmp slt i32 [[ACONV]], 10
+// CHECK: br i1 [[ACMP]], label %[[PRECOND_THEN:.+]], label %[[PRECOND_END:.+]]
+// CHECK: [[PRECOND_THEN]]
+// CHECK: call void @__kmpc_for_static_init_4
+// CHECK: call void @__kmpc_for_static_fini
+// CHECK: [[PRECOND_END]]
+
+// no templates for now, as these require special handling in target regions and/or declare target
+
+// HCHECK-LABEL: fint
+// HCHECK: call {{.*}}i32 {{.+}}ftemplate
+// HCHECK: ret i32
+
+// HCHECK: load i16, i16*
+// HCHECK: store i16 %
+// HCHECK: call i32 @__tgt_target_teams(
+// HCHECK: call void @__kmpc_for_static_init_4(
+template <typename T>
+T ftemplate() {
+ short aa = 0;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd dist_schedule(static, aa)
+ for (int i = 0; i < 100; i++) {
+ }
+ return T();
+}
+
+int fint(void) { return ftemplate<int>(); }
+
+#endif
+
+// CHECK: !{!"llvm.loop.vectorize.width", i32 8}
+// CHECK: !{!"llvm.loop.vectorize.enable", i1 true}
+// CHECK: !{!"llvm.loop.vectorize.width", i32 32}
diff --git a/test/OpenMP/distribute_simd_firstprivate_codegen.cpp b/test/OpenMP/distribute_simd_firstprivate_codegen.cpp
new file mode 100644
index 000000000000..5da9c5dc3b1a
--- /dev/null
+++ b/test/OpenMP/distribute_simd_firstprivate_codegen.cpp
@@ -0,0 +1,380 @@
+// RUN: %clang_cc1 -DLAMBDA -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+// RUN: %clang_cc1 -DLAMBDA -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-32
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-32
+
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+template <class T>
+struct S {
+ T f;
+ S(T a) : f(a) {}
+ S() : f() {}
+ operator T() { return T(); }
+ ~S() {}
+};
+
+// CHECK: [[S_FLOAT_TY:%.+]] = type { float }
+// CHECK: [[S_INT_TY:%.+]] = type { i{{[0-9]+}} }
+template <typename T>
+T tmain() {
+ S<T> test;
+ T t_var = T();
+ T vec[] = {1, 2};
+ S<T> s_arr[] = {1, 2};
+ S<T> &var = test;
+ #pragma omp target
+ #pragma omp teams
+#pragma omp distribute simd firstprivate(t_var, vec, s_arr, s_arr, var, var)
+ for (int i = 0; i < 2; ++i) {
+ vec[i] = t_var;
+ s_arr[i] = var;
+ }
+ return T();
+}
+
+int main() {
+ static int svar;
+ volatile double g;
+ volatile double &g1 = g;
+
+ #ifdef LAMBDA
+ // LAMBDA-LABEL: @main
+ // LAMBDA: call{{.*}} void [[OUTER_LAMBDA:@.+]](
+ [&]() {
+ static float sfvar;
+ // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
+ // LAMBDA: call i{{[0-9]+}} @__tgt_target_teams(
+ // LAMBDA: call void [[OFFLOADING_FUN:@.+]](
+
+ // LAMBDA: define{{.+}} void [[OFFLOADING_FUN]](
+ // LAMBDA: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, {{.+}}, {{.+}}* [[OMP_OUTLINED:@.+]] to {{.+}})
+ #pragma omp target
+ #pragma omp teams
+#pragma omp distribute simd firstprivate(g, g1, svar, sfvar)
+ for (int i = 0; i < 2; ++i) {
+ // LAMBDA: define internal{{.*}} void [[OMP_OUTLINED]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, double*{{.*}} [[G_IN:%.+]], double*{{.+}} [[G1_IN:%.+]], i{{[0-9]+}}*{{.+}} [[SVAR_IN:%.+]], float*{{.+}} [[SFVAR_IN:%.+]])
+ // Private alloca's for conversion
+ // LAMBDA: [[G_ADDR:%.+]] = alloca double*,
+ // LAMBDA: [[G1_ADDR:%.+]] = alloca double*,
+ // LAMBDA: [[SVAR_ADDR:%.+]] = alloca i{{[0-9]+}}*,
+ // LAMBDA: [[SFVAR_ADDR:%.+]] = alloca float*,
+ // LAMBDA: [[G1_REF:%.+]] = alloca double*,
+
+ // Actual private variables to be used in the body (tmp is used for the reference type)
+ // LAMBDA: [[G_PRIVATE:%.+]] = alloca double,
+ // LAMBDA: [[G1_PRIVATE:%.+]] = alloca double,
+ // LAMBDA: [[TMP_PRIVATE:%.+]] = alloca double*,
+ // LAMBDA: [[SVAR_PRIVATE:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[SFVAR_PRIVATE:%.+]] = alloca float,
+
+ // Store input parameter addresses into private alloca's for conversion
+ // LAMBDA: store double* [[G_IN]], double** [[G_ADDR]],
+ // LAMBDA: store double* [[G1_IN]], double** [[G1_ADDR]],
+ // LAMBDA: store i{{[0-9]+}}* [[SVAR_IN]], i{{[0-9]+}}** [[SVAR_ADDR]],
+ // LAMBDA: store float* [[SFVAR_IN]], float** [[SFVAR_ADDR]],
+
+ // LAMBDA-DAG: [[G_ADDR_VAL:%.+]] = load double*, double** [[G_ADDR]],
+ // LAMBDA-DAG: [[G1_ADDR_VAL:%.+]] = load double*, double** [[G1_ADDR]],
+ // LAMBDA-DAG: [[SVAR_ADDR_VAL:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SVAR_ADDR]],
+ // LAMBDA-DAG: [[SFVAR_ADDR_VAL:%.+]] = load float*, float** [[SFVAR_ADDR]],
+ // LAMBDA-DAG: store double* [[G1_ADDR_VAL]], double** [[G1_REF]],
+
+ // LAMBDA-DAG: [[G_VAL:%.+]] = load{{.+}} double, double* [[G_ADDR_VAL]],
+ // LAMBDA-DAG: store double [[G_VAL]], double* [[G_PRIVATE]],
+ // LAMBDA-DAG: [[G1_VAL_REF:%.+]] = load double*, double** [[G1_REF]],
+ // LAMBDA-DAG: [[G1_VAL:%.+]] = load{{.+}} double, double* [[G1_VAL_REF]],
+ // LAMBDA-DAG: store double [[G1_VAL]], double* [[G1_PRIVATE]],
+ // LAMBDA-DAG: store double* [[G1_PRIVATE]], double** [[TMP_PRIVATE]],
+ // LAMBDA-DAG: [[SVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SVAR_ADDR_VAL]],
+ // LAMBDA-DAG: store i{{[0-9]+}} [[SVAR_VAL]], i{{[0-9]+}}* [[SVAR_PRIVATE]],
+ // LAMBDA-DAG: [[SFVAR_VAL:%.+]] = load float, float* [[SFVAR_ADDR_VAL]],
+ // LAMBDA-DAG: store float [[SFVAR_VAL]], float* [[SFVAR_PRIVATE]],
+
+ // LAMBDA: call {{.*}}void @__kmpc_for_static_init_4(
+ g += 1;
+ g1 += 1;
+ svar += 3;
+ sfvar += 4.0;
+ // LAMBDA-DAG: [[G_VAL:%.+]] = load double, double* [[G_PRIVATE]],
+ // LAMBDA-DAG: [[G_NEXT:%.+]] = fadd double [[G_VAL]], 1.{{.+}}
+ // LAMBDA-DAG: store double [[G_NEXT]], double* [[G_PRIVATE]],
+ // LAMBDA-DAG: [[TMP_VAL1:%.+]] = load double*, double** [[TMP_PRIVATE]],
+ // LAMBDA-DAG: [[TMP_VAL_VAL1:%.+]] = load{{.*}} double, double* [[TMP_VAL1]],
+ // LAMBDA-DAG: [[TMP_ADD:%.+]] = fadd double [[TMP_VAL_VAL1]], 1.{{.+}}
+ // LAMBDA-DAG: store{{.*}} double [[TMP_ADD]], double* [[TMP_VAL1]],
+ // LAMBDA-DAG: [[SVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SVAR_PRIVATE]],
+ // LAMBDA-DAG: [[SVAR_ADD:%.+]] = add{{.*}} i{{[0-9]+}} [[SVAR_VAL]], 3
+ // LAMBDA-DAG: store i{{[0-9]+}} [[SVAR_ADD]], i{{[0-9]+}}* [[SVAR_PRIVATE]],
+ // LAMBDA-DAG: [[SFVAR_VAL:%.+]] = load float, float* [[SFVAR_PRIVATE]],
+ // LAMBDA-DAG: [[SFVAR_CONV_VAL1:%.+]] = fpext float [[SFVAR_VAL]] to double
+ // LAMBDA-DAG: [[SFVAR_ADD:%.+]] = fadd double [[SFVAR_CONV_VAL1]], 4.{{.+}}
+ // LAMBDA-DAG: [[SFVAR_CONV_VAL2:%.+]] = fptrunc double [[SFVAR_ADD]] to float
+ // LAMBDA-DAG: store float [[SFVAR_CONV_VAL2:%.+]], float* [[SFVAR_PRIVATE]],
+
+ // call inner lambda (use refs to private alloca's)
+ // LAMBDA: [[GEP_0:%.+]] = getelementptr{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // LAMBDA: store double* [[G_PRIVATE]], double** [[GEP_0]],
+ // LAMBDA: [[GEP_1:%.+]] = getelementptr{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // LAMBDA: [[TMP_PAR:%.+]] = load double*, double** [[TMP_PRIVATE]],
+ // LAMBDA: store double* [[TMP_PAR]], double** [[GEP_1]],
+ // LAMBDA: [[GEP_2:%.+]] = getelementptr{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 2
+ // LAMBDA: store i{{[0-9]+}}* [[SVAR_PRIVATE]], i{{[0-9]+}}** [[GEP_2]],
+ // LAMBDA: [[GEP_3:%.+]] = getelementptr{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 3
+ // LAMBDA: store float* [[SFVAR_PRIVATE]], float** [[GEP_3]],
+ // LAMBDA: call{{.*}} void [[INNER_LAMBDA:@.+]](%{{.+}}* {{.+}})
+ // LAMBDA: call {{.*}}void @__kmpc_for_static_fini(
+ [&]() {
+ // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]])
+ // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]],
+ g += 2;
+ g1 += 2;
+ svar += 4;
+ sfvar += 8.0;
+ // LAMBDA-DAG: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]]
+ // LAMBDA-DAG: [[G_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // LAMBDA-DAG: [[G_REF:%.+]] = load double*, double** [[G_PTR_REF]],
+ // LAMBDA-DAG: [[G_REF_VAL:%.+]] = load double, double* [[G_REF]],
+ // LAMBDA-DAG: [[G_REF_ADD:%.+]] = fadd double [[G_REF_VAL]], 2.{{.+}}
+ // LAMBDA-DAG: store double [[G_REF_ADD]], double* [[G_REF]]
+
+ // LAMBDA-DAG: [[TMP_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // LAMBDA-DAG: [[G1_REF:%.+]] = load double*, double** [[TMP_PTR_REF]]
+ // LAMBDA-DAG: [[G1_REF_VAL:%.+]] = load double, double* [[G1_REF]],
+ // LAMBDA-DAG: [[G1_ADD:%.+]] = fadd double [[G1_REF_VAL]], 2.{{.+}}
+ // LAMBDA-DAG: store double [[G1_ADD]], double* [[G1_REF]],
+
+ // LAMBDA-DAG: [[SVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+ // LAMBDA-DAG: [[SVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SVAR_PTR_REF]]
+ // LAMBDA-DAG: [[SVAR_REF_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SVAR_REF]]
+ // LAMBDA-DAG: [[SVAR_ADD:%.+]] = add{{.*}} i{{[0-9]+}} [[SVAR_REF_VAL]], 4
+ // LAMBDA-DAG: store i{{[0-9]+}} [[SVAR_ADD]], i{{[0-9]+}}* [[SVAR_REF]]
+
+ // LAMBDA-DAG: [[SFVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 3
+ // LAMBDA-DAG: [[SFVAR_REF:%.+]] = load float*, float** [[SFVAR_PTR_REF]]
+ // LAMBDA-DAG: [[SFVAR_REF_VAL:%.+]] = load float, float* [[SFVAR_REF]]
+ // LAMBDA-DAG: [[SFVAR_REF_CONV:%.+]] = fpext float [[SFVAR_REF_VAL]] to double
+ // LAMBDA-DAG: [[SFVAR_ADD:%.+]] = fadd double [[SFVAR_REF_CONV]], 8.{{.+}}
+ // LAMBDA-DAG: [[SFVAR_ADD_CONV:%.+]] = fptrunc double [[SFVAR_ADD]] to float
+ // LAMBDA-DAG: store float [[SFVAR_ADD_CONV]], float* [[SFVAR_REF]],
+ }();
+ }
+ }();
+ return 0;
+ #else
+ S<float> test;
+ int t_var = 0;
+ int vec[] = {1, 2};
+ S<float> s_arr[] = {1, 2};
+ S<float> &var = test;
+
+ #pragma omp target
+ #pragma omp teams
+ #pragma omp distribute simd firstprivate(t_var, vec, s_arr, s_arr, var, var, svar)
+ for (int i = 0; i < 2; ++i) {
+ vec[i] = t_var;
+ s_arr[i] = var;
+ }
+ return tmain<int>();
+ #endif
+}
+
+// CHECK: define{{.*}} i{{[0-9]+}} @main()
+// CHECK: [[TEST:%.+]] = alloca [[S_FLOAT_TY]],
+// CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR:@.+]]([[S_FLOAT_TY]]* [[TEST]])
+// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+// CHECK: call void [[OFFLOAD_FUN:@.+]](
+// CHECK: ret
+
+// CHECK: define{{.+}} [[OFFLOAD_FUN]](
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_teams(%{{.+}}* @{{.+}}, i{{[0-9]+}} 5, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, i{{[0-9]+}}*, [2 x i{{[0-9]+}}]*, [2 x [[S_FLOAT_TY]]]*, [[S_FLOAT_TY]]*, i{{[0-9]+}}*)* [[OMP_OUTLINED:@.+]] to void
+// CHECK: ret
+//
+// CHECK: define internal void [[OMP_OUTLINED]](i{{[0-9]+}}*{{.+}}, i{{[0-9]+}}*{{.+}}, i{{[0-9]+}}*{{.+}} [[T_VAR_IN:%.+]], [2 x i{{[0-9]+}}]*{{.*}} [[VEC_IN:%.+]], [2 x [[S_FLOAT_TY]]]*{{.*}} [[S_ARR_IN:%.+]], [[S_FLOAT_TY]]*{{.*}} [[VAR_IN:%.+]], i{{[0-9]+}}*{{.+}} [[SVAR_IN:%.+]])
+
+// CHECK: alloca i{{[0-9]+}}*,
+// CHECK: alloca i{{[0-9]+}}*,
+// CHECK: [[T_VAR_ADDR:%.+]] = alloca i{{[0-9]+}}*,
+// CHECK: [[VEC_ADDR:%.+]] = alloca [2 x i{{[0-9]+}}]*,
+// CHECK: [[S_ARR_ADDR:%.+]] = alloca [2 x [[S_FLOAT_TY]]]*,
+// CHECK: [[VAR_ADDR:%.+]] = alloca [[S_FLOAT_TY]]*,
+// CHECK: [[SVAR_ADDR:%.+]] = alloca i{{[0-9]+}}*,
+// CHECK: [[TMP:%.+]] = alloca [[S_FLOAT_TY]]*,
+
+// discard omp loop variables
+// CHECK: {{.*}} = alloca i{{[0-9]+}},
+// CHECK: {{.*}} = alloca i{{[0-9]+}},
+// CHECK: {{.*}} = alloca i{{[0-9]+}},
+// CHECK: {{.*}} = alloca i{{[0-9]+}},
+// CHECK: {{.*}} = alloca i{{[0-9]+}},
+// CHECK: {{.*}} = alloca i{{[0-9]+}},
+
+// CHECK-DAG: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK-DAG: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK-DAG: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]],
+// CHECK-DAG: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]],
+// CHECK-DAG: [[TMP_PRIV:%.+]] = alloca [[S_FLOAT_TY]]*,
+// CHECK: [[SVAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+
+// CHECK: store i{{[0-9]+}}* [[T_VAR_IN]], i{{[0-9]+}}** [[T_VAR_ADDR]],
+// CHECK: store [2 x i{{[0-9]+}}]* [[VEC_IN]], [2 x i{{[0-9]+}}]** [[VEC_ADDR]],
+// CHECK: store [2 x [[S_FLOAT_TY]]]* [[S_ARR_IN]], [2 x [[S_FLOAT_TY]]]** [[S_ARR_ADDR]],
+// CHECK: store [[S_FLOAT_TY]]* [[VAR_IN]], [[S_FLOAT_TY]]** [[VAR_ADDR]],
+// CHECK: store i{{[0-9]+}}* [[SVAR_IN]], i{{[0-9]+}}** [[SVAR_ADDR]],
+
+// init t_var
+// CHECK-DAG: [[T_VAR_ADDR_CONV_VAL_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[T_VAR_ADDR]],
+// CHECK-DAG: [[T_VAR_ADDR_CONV_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_ADDR_CONV_VAL_REF]],
+// CHECK-DAG: store i{{[0-9]+}} [[T_VAR_ADDR_CONV_VAL]], i{{[0-9]+}}* [[T_VAR_PRIV]],
+
+// init vec
+// CHECK-DAG: [[VEC_ADDR_VAL:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** [[VEC_ADDR]],
+// CHECK-DAG: [[VEC_ADDR_VAL_BCAST:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_ADDR_VAL]] to i{{[0-9]+}}*
+// CHECK-DAG: [[VEC_PRIV_BCAST:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV]] to i{{[0-9]+}}*
+// CHECK-DAG: call void @llvm.memcpy.{{.*}}(i{{[0-9]+}}* [[VEC_PRIV_BCAST]], i{{[0-9]+}}* [[VEC_ADDR_VAL_BCAST]],{{.+}})
+
+// init s_arr
+// CHECK-DAG: [[S_ARR_ADDR_VAL:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[S_ARR_ADDR]],
+// CHECK-DAG: [[S_ARR_ADDR_BCAST:%.+]] = bitcast [2 x [[S_FLOAT_TY]]]* [[S_ARR_ADDR_VAL]] to [[S_FLOAT_TY]]*
+// CHECK-DAG: [[S_ARR_PRIV_BGN:%.+]] = getelementptr{{.+}} [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[S_ARR_PRIV]]{{.+}}
+// CHECK-DAG: [[S_ARR_PRIV_NEXT:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[S_ARR_PRIV_BGN]]{{.+}}
+// CHECK-DAG: [[S_ARR_IS_EMPTY:%.+]] = icmp eq [[S_FLOAT_TY]]* [[S_ARR_PRIV_BGN]], [[S_ARR_PRIV_NEXT]]
+// CHECK-DAG: br i1 [[S_ARR_IS_EMPTY]], label %[[S_ARR_CPY_DONE:.+]], label %[[S_ARR_CPY_BODY:.+]]
+
+// CHECK-DAG: [[S_ARR_CPY_BODY]]:
+// CHECK-DAG: [[S_ARR_SRC_PAST:%.+]] = phi{{.+}} [ [[S_ARR_ADDR_BCAST]],{{.+}} ], [ [[S_ARR_SRC:%.+]],{{.+}} ]
+// CHECK-DAG: [[S_ARR_DST_PAST:%.+]] = phi{{.+}} [ [[S_ARR_PRIV_BGN]],{{.+}} ], [ [[S_ARR_DST:%.+]],{{.+}} ]
+// CHECK-DAG: [[S_ARR_SRC_BCAST:%.+]] = bitcast{{.+}} [[S_ARR_SRC_PAST]] to{{.+}}
+// CHECK-DAG: [[S_ARR_DST_BCAST:%.+]] = bitcast{{.+}} [[S_ARR_DST_PAST]] to{{.+}}
+// CHECK-DAG: call{{.+}} @llvm.memcpy.{{.+}}({{.+}}* [[S_ARR_DST_BCAST]], {{.+}}* [[S_ARR_SRC_BCAST]]{{.+}})
+// CHECK-DAG: [[S_ARR_SRC]] = getelementptr{{.+}}
+// CHECK-DAG: [[S_ARR_DST]] = getelementptr{{.+}}
+// CHECK-DAG: [[S_ARR_CPY_FIN:%.+]] = icmp{{.+}} [[S_ARR_DST]], [[S_ARR_PRIV_NEXT]]
+// CHECK-DAG: br i1 [[S_ARR_CPY_FIN]], label %[[S_ARR_CPY_DONE]], label %[[S_ARR_CPY_BODY]]
+// CHECK-DAG: [[S_ARR_CPY_DONE]]:
+
+// init var
+// CHECK-DAG: [[VAR_ADDR_VAL:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[VAR_ADDR]],
+// CHECK-DAG: store{{.+}} [[VAR_ADDR_VAL]],{{.+}} [[TMP]],
+// CHECK-DAG: [[TMP_VAL:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[TMP]],
+// CHECK-DAG: [[VAR_PRIV_BCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[VAR_PRIV]] to{{.+}}
+// CHECK-DAG: [[TMP_BCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[TMP_VAL]] to{{.+}}
+// CHECK-DAG: call{{.+}} @llvm.memcpy.{{.+}}({{.+}}* [[VAR_PRIV_BCAST]], {{.+}}* [[TMP_BCAST]],{{.+}})
+// CHECK-DAG: store [[S_FLOAT_TY]]* [[VAR_PRIV]], [[S_FLOAT_TY]]** [[TMP_PRIV]],
+
+// init svar
+// CHECK-DAG: [[SVAR_CONV_VAL_REF:%.+]] = load{{.+}},{{.+}} [[SVAR_ADDR]],
+// CHECK-DAG: [[SVAR_CONV_VAL:%.+]] = load{{.+}},{{.+}} [[SVAR_CONV_VAL_REF]],
+// CHECK-DAG: store{{.+}} [[SVAR_CONV_VAL]],{{.+}} [[SVAR_PRIV]],
+
+// CHECK-DAG: store i{{[0-9]+}} 0, i{{[0-9]+}}* %.omp{{.+}},
+// CHECK-DAG: store i{{[0-9]+}} 1, i{{[0-9]+}}* %.omp{{.+}},
+// CHECK-DAG: store i{{[0-9]+}} 1, i{{[0-9]+}}* %.omp{{.+}},
+// CHECK-DAG: store i{{[0-9]+}} 0, i{{[0-9]+}}* %.omp{{.+}},
+
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: ret void
+
+// Template
+// CHECK: define{{.*}} i{{[0-9]+}} [[TMAIN_INT:@.+]]()
+// CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]],
+// CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR:@.+]]([[S_INT_TY]]* [[TEST]])
+// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+// CHECK: call void [[OFFLOAD_FUN_1:@.+]](
+// CHECK: ret
+
+// CHECK: define{{.+}} [[OFFLOAD_FUN_1]](
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_teams(%{{.+}}* @{{.+}}, i{{[0-9]+}} 4, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, i{{[0-9]+}}*, [2 x i{{[0-9]+}}]*, [2 x [[S_INT_TY]]]*, [[S_INT_TY]]*)* [[OMP_OUTLINED_1:@.+]] to void
+// CHECK: ret
+//
+// CHECK: define internal void [[OMP_OUTLINED_1]](i{{[0-9]+}}*{{.+}}, i{{[0-9]+}}*{{.+}}, i{{[0-9]+}}*{{.+}} [[T_VAR_IN:%.+]], [2 x i{{[0-9]+}}]*{{.*}} [[VEC_IN:%.+]], [2 x [[S_INT_TY]]]*{{.*}} [[S_ARR_IN:%.+]], [[S_INT_TY]]*{{.*}} [[VAR_IN:%.+]])
+
+// CHECK: alloca i{{[0-9]+}}*,
+// CHECK: alloca i{{[0-9]+}}*,
+// CHECK: [[T_VAR_ADDR:%.+]] = alloca i{{[0-9]+}}*,
+// CHECK: [[VEC_ADDR:%.+]] = alloca [2 x i{{[0-9]+}}]*,
+// CHECK: [[S_ARR_ADDR:%.+]] = alloca [2 x [[S_INT_TY]]]*,
+// CHECK: [[VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*,
+// CHECK: [[TMP:%.+]] = alloca [[S_INT_TY]]*,
+
+// discard omp loop variables
+// CHECK: {{.*}} = alloca i{{[0-9]+}},
+// CHECK: {{.*}} = alloca i{{[0-9]+}},
+// CHECK: {{.*}} = alloca i{{[0-9]+}},
+// CHECK: {{.*}} = alloca i{{[0-9]+}},
+// CHECK: {{.*}} = alloca i{{[0-9]+}},
+// CHECK: {{.*}} = alloca i{{[0-9]+}},
+
+// CHECK-DAG: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK-DAG: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK-DAG: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_INT_TY]]],
+// CHECK-DAG: [[VAR_PRIV:%.+]] = alloca [[S_INT_TY]],
+// CHECK-DAG: [[TMP_PRIV:%.+]] = alloca [[S_INT_TY]]*,
+
+// CHECK: store i{{[0-9]+}}* [[T_VAR_IN]], i{{[0-9]+}}** [[T_VAR_ADDR]],
+// CHECK: store [2 x i{{[0-9]+}}]* [[VEC_IN]], [2 x i{{[0-9]+}}]** [[VEC_ADDR]],
+// CHECK: store [2 x [[S_INT_TY]]]* [[S_ARR_IN]], [2 x [[S_INT_TY]]]** [[S_ARR_ADDR]],
+// CHECK: store [[S_INT_TY]]* [[VAR_IN]], [[S_INT_TY]]** [[VAR_ADDR]],
+
+// init t_var
+// CHECK-DAG: [[T_VAR_ADDR_CONV_VAL_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[T_VAR_ADDR]],
+// CHECK-DAG: [[T_VAR_ADDR_CONV_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_ADDR_CONV_VAL_REF]],
+// CHECK-DAG: store i{{[0-9]+}} [[T_VAR_ADDR_CONV_VAL]], i{{[0-9]+}}* [[T_VAR_PRIV]],
+
+// init vec
+// CHECK-DAG: [[VEC_ADDR_VAL:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** [[VEC_ADDR]],
+// CHECK-DAG: [[VEC_ADDR_VAL_BCAST:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_ADDR_VAL]] to i{{[0-9]+}}*
+// CHECK-DAG: [[VEC_PRIV_BCAST:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV]] to i{{[0-9]+}}*
+// CHECK-DAG: call void @llvm.memcpy.{{.*}}(i{{[0-9]+}}* [[VEC_PRIV_BCAST]], i{{[0-9]+}}* [[VEC_ADDR_VAL_BCAST]],{{.+}})
+
+// init s_arr
+// CHECK-DAG: [[S_ARR_ADDR_VAL:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** [[S_ARR_ADDR]],
+// CHECK-DAG: [[S_ARR_ADDR_BCAST:%.+]] = bitcast [2 x [[S_INT_TY]]]* [[S_ARR_ADDR_VAL]] to [[S_INT_TY]]*
+// CHECK-DAG: [[S_ARR_PRIV_BGN:%.+]] = getelementptr{{.+}} [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[S_ARR_PRIV]]{{.+}}
+// CHECK-DAG: [[S_ARR_PRIV_NEXT:%.+]] = getelementptr [[S_INT_TY]], [[S_INT_TY]]* [[S_ARR_PRIV_BGN]]{{.+}}
+// CHECK-DAG: [[S_ARR_IS_EMPTY:%.+]] = icmp eq [[S_INT_TY]]* [[S_ARR_PRIV_BGN]], [[S_ARR_PRIV_NEXT]]
+// CHECK-DAG: br i1 [[S_ARR_IS_EMPTY]], label %[[S_ARR_CPY_DONE:.+]], label %[[S_ARR_CPY_BODY:.+]]
+
+// CHECK-DAG: [[S_ARR_CPY_BODY]]:
+// CHECK-DAG: [[S_ARR_SRC_PAST:%.+]] = phi{{.+}} [ [[S_ARR_ADDR_BCAST]],{{.+}} ], [ [[S_ARR_SRC:%.+]],{{.+}} ]
+// CHECK-DAG: [[S_ARR_DST_PAST:%.+]] = phi{{.+}} [ [[S_ARR_PRIV_BGN]],{{.+}} ], [ [[S_ARR_DST:%.+]],{{.+}} ]
+// CHECK-DAG: [[S_ARR_SRC_BCAST:%.+]] = bitcast{{.+}} [[S_ARR_SRC_PAST]] to{{.+}}
+// CHECK-DAG: [[S_ARR_DST_BCAST:%.+]] = bitcast{{.+}} [[S_ARR_DST_PAST]] to{{.+}}
+// CHECK-DAG: call{{.+}} @llvm.memcpy.{{.+}}({{.+}}* [[S_ARR_DST_BCAST]], {{.+}}* [[S_ARR_SRC_BCAST]]{{.+}})
+// CHECK-DAG: [[S_ARR_SRC]] = getelementptr{{.+}}
+// CHECK-DAG: [[S_ARR_DST]] = getelementptr{{.+}}
+// CHECK-DAG: [[S_ARR_CPY_FIN:%.+]] = icmp{{.+}} [[S_ARR_DST]], [[S_ARR_PRIV_NEXT]]
+// CHECK-DAG: br i1 [[S_ARR_CPY_FIN]], label %[[S_ARR_CPY_DONE]], label %[[S_ARR_CPY_BODY]]
+// CHECK-DAG: [[S_ARR_CPY_DONE]]:
+
+// init var
+// CHECK-DAG: [[VAR_ADDR_VAL:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[VAR_ADDR]],
+// CHECK-DAG: store{{.+}} [[VAR_ADDR_VAL]],{{.+}} [[TMP]],
+// CHECK-DAG: [[TMP_VAL:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[TMP]],
+// CHECK-DAG: [[VAR_PRIV_BCAST:%.+]] = bitcast [[S_INT_TY]]* [[VAR_PRIV]] to{{.+}}
+// CHECK-DAG: [[TMP_BCAST:%.+]] = bitcast [[S_INT_TY]]* [[TMP_VAL]] to{{.+}}
+// CHECK-DAG: call{{.+}} @llvm.memcpy.{{.+}}({{.+}}* [[VAR_PRIV_BCAST]], {{.+}}* [[TMP_BCAST]],{{.+}})
+// CHECK-DAG: store [[S_INT_TY]]* [[VAR_PRIV]], [[S_INT_TY]]** [[TMP_PRIV]],
+
+// CHECK-DAG: store i{{[0-9]+}} 0, i{{[0-9]+}}* %.omp{{.+}},
+// CHECK-DAG: store i{{[0-9]+}} 1, i{{[0-9]+}}* %.omp{{.+}},
+// CHECK-DAG: store i{{[0-9]+}} 1, i{{[0-9]+}}* %.omp{{.+}},
+// CHECK-DAG: store i{{[0-9]+}} 0, i{{[0-9]+}}* %.omp{{.+}},
+
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: ret void
+
+// CHECK: !{!"llvm.loop.vectorize.enable", i1 true}
+#endif
diff --git a/test/OpenMP/distribute_simd_firstprivate_messages.cpp b/test/OpenMP/distribute_simd_firstprivate_messages.cpp
index b9267a3037f0..f0c293b78d80 100644
--- a/test/OpenMP/distribute_simd_firstprivate_messages.cpp
+++ b/test/OpenMP/distribute_simd_firstprivate_messages.cpp
@@ -42,7 +42,7 @@ public:
};
class S5 {
int a;
- S5(const S5 &s5) : a(s5.a) {} // expected-note 4 {{implicitly declared private here}}
+ S5(const S5 &s5) : a(s5.a) {} // expected-note 2 {{implicitly declared private here}}
public:
S5() : a(0) {}
@@ -50,7 +50,7 @@ public:
};
class S6 {
int a;
- S6() : a(0) {}
+ S6() : a(0) {} // expected-note {{implicitly declared private here}}
public:
S6(const S6 &s6) : a(s6.a) {}
@@ -150,9 +150,10 @@ int foomain(int argc, char **argv) {
#pragma omp distribute simd firstprivate(i)
for (int k = 0; k < argc; ++k)
++k;
+// expected-error@+3 {{lastprivate variable cannot be firstprivate}} expected-note@+3 {{defined as lastprivate}}
#pragma omp target
#pragma omp teams
-#pragma omp distribute simd lastprivate(g) firstprivate(g) // expected-error {{calling a private constructor of class 'S5'}}
+#pragma omp distribute simd lastprivate(g) firstprivate(g)
for (i = 0; i < argc; ++i)
foo();
#pragma omp parallel private(i)
@@ -314,14 +315,16 @@ int main(int argc, char **argv) {
#pragma omp distribute simd firstprivate(j)
for (i = 0; i < argc; ++i)
foo();
+// expected-error@+3 {{lastprivate variable cannot be firstprivate}} expected-note@+3 {{defined as lastprivate}}
#pragma omp target
#pragma omp teams
-#pragma omp distribute simd lastprivate(g) firstprivate(g) // expected-error {{calling a private constructor of class 'S5'}}
+#pragma omp distribute simd lastprivate(g) firstprivate(g)
for (i = 0; i < argc; ++i)
foo();
+// expected-error@+3 {{lastprivate variable cannot be firstprivate}} expected-note@+3 {{defined as lastprivate}}
#pragma omp target
#pragma omp teams
-#pragma omp distribute simd lastprivate(n) firstprivate(n) // OK
+#pragma omp distribute simd lastprivate(n) firstprivate(n) // expected-error {{calling a private constructor of class 'S6'}}
for (i = 0; i < argc; ++i)
foo();
#pragma omp parallel
diff --git a/test/OpenMP/distribute_simd_lastprivate_codegen.cpp b/test/OpenMP/distribute_simd_lastprivate_codegen.cpp
new file mode 100644
index 000000000000..df842a009879
--- /dev/null
+++ b/test/OpenMP/distribute_simd_lastprivate_codegen.cpp
@@ -0,0 +1,393 @@
+// RUN: %clang_cc1 -DLAMBDA -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+// RUN: %clang_cc1 -DLAMBDA -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-32
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-32
+
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+template <class T>
+struct S {
+ T f;
+ S(T a) : f(a) {}
+ S() : f() {}
+ operator T() { return T(); }
+ ~S() {}
+};
+
+// CHECK: [[S_FLOAT_TY:%.+]] = type { float }
+// CHECK: [[S_INT_TY:%.+]] = type { i{{[0-9]+}} }
+template <typename T>
+T tmain() {
+ S<T> test;
+ T t_var = T();
+ T vec[] = {1, 2};
+ S<T> s_arr[] = {1, 2};
+ S<T> &var = test;
+ #pragma omp target
+ #pragma omp teams
+#pragma omp distribute simd lastprivate(t_var, vec, s_arr, s_arr, var, var)
+ for (int i = 0; i < 2; ++i) {
+ vec[i] = t_var;
+ s_arr[i] = var;
+ }
+ return T();
+}
+
+int main() {
+ static int svar;
+ volatile double g;
+ volatile double &g1 = g;
+
+ #ifdef LAMBDA
+ // LAMBDA-LABEL: @main
+ // LAMBDA: call{{.*}} void [[OUTER_LAMBDA:@.+]](
+ [&]() {
+ static float sfvar;
+ // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
+ // LAMBDA: call i{{[0-9]+}} @__tgt_target_teams(
+ // LAMBDA: call void [[OFFLOADING_FUN:@.+]](
+
+ // LAMBDA: define{{.+}} void [[OFFLOADING_FUN]](
+ // LAMBDA: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, i32 4, {{.+}}* [[OMP_OUTLINED:@.+]] to {{.+}})
+ #pragma omp target
+ #pragma omp teams
+#pragma omp distribute simd lastprivate(g, g1, svar, sfvar)
+ for (int i = 0; i < 2; ++i) {
+ // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_OUTLINED]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, double*{{.+}} [[G_IN:%.+]], double*{{.+}} [[G1_IN:%.+]], i{{[0-9]+}}*{{.+}} [[SVAR_IN:%.+]], float*{{.+}} [[SFVAR_IN:%.+]])
+ // LAMBDA: [[G_PRIVATE_ADDR:%.+]] = alloca double*,
+ // LAMBDA: [[G1_PRIVATE_ADDR:%.+]] = alloca double*,
+ // LAMBDA: [[SVAR_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}*,
+ // LAMBDA: [[SFVAR_PRIVATE_ADDR:%.+]] = alloca float*,
+ // LAMBDA: [[TMP_G1:%.+]] = alloca double*,
+ // loop variables
+ // LAMBDA: {{.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: {{.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: {{.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: {{.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: {{.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: [[OMP_IS_LAST:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[G_PRIVATE:%.+]] = alloca double,
+ // LAMBDA: [[G1_PRIVATE:%.+]] = alloca double,
+ // LAMBDA: [[TMP_G1_PRIVATE:%.+]] = alloca double*,
+ // LAMBDA: [[SVAR_PRIVATE:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[SFVAR_PRIVATE:%.+]] = alloca float,
+ // LAMBDA: store double* [[G_IN]], double** [[G_PRIVATE_ADDR]],
+ // LAMBDA: store double* [[G1_IN]], double** [[G1_PRIVATE_ADDR]],
+ // LAMBDA: store i{{[0-9]+}}* [[SVAR_IN]], i{{[0-9]+}}** [[SVAR_PRIVATE_ADDR]],
+ // LAMBDA: store float* [[SFVAR_IN]], float** [[SFVAR_PRIVATE_ADDR]],
+
+ // init private variables
+ // LAMBDA: [[G_IN_REF:%.+]] = load double*, double** [[G_PRIVATE_ADDR]],
+ // LAMBDA: [[SVAR_IN_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SVAR_PRIVATE_ADDR]],
+ // LAMBDA: [[SFVAR_IN_REF:%.+]] = load float*, float** [[SFVAR_PRIVATE_ADDR]],
+ // LAMBDA: [[G1_IN_REF:%.+]] = load double*, double** [[G1_PRIVATE_ADDR]],
+ // LAMBDA: store double* [[G1_IN_REF]], double** [[TMP_G1]],
+ // LAMBDA: [[TMP_G1_VAL:%.+]] = load double*, double** [[TMP_G1]],
+ // LAMBDA: store double* [[G1_PRIVATE]], double** [[TMP_G1_PRIVATE]],
+ g = 1;
+ g1 = 1;
+ svar = 3;
+ sfvar = 4.0;
+ // LAMBDA: call {{.*}}void @__kmpc_for_static_init_4(
+ // LAMBDA: store double 1.0{{.+}}, double* [[G_PRIVATE]],
+ // LAMBDA: [[TMP_G1_REF:%.+]] = load double*, double** [[TMP_G1_PRIVATE]],
+ // LAMBDA: store{{.+}} double 1.0{{.+}}, double* [[TMP_G1_REF]],
+ // LAMBDA: store i{{[0-9]+}} 3, i{{[0-9]+}}* [[SVAR_PRIVATE]],
+ // LAMBDA: store float 4.0{{.+}}, float* [[SFVAR_PRIVATE]],
+ // LAMBDA: [[G_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // LAMBDA: store double* [[G_PRIVATE]], double** [[G_PRIVATE_ADDR_REF]],
+ // LAMBDA: [[TMP_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // LAMBDA: [[G1_PRIVATE_ADDR_FROM_TMP:%.+]] = load double*, double** [[TMP_G1_PRIVATE]],
+ // LAMBDA: store double* [[G1_PRIVATE_ADDR_FROM_TMP]], double** [[TMP_PRIVATE_ADDR_REF]],
+ // LAMBDA: [[SVAR_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+ // LAMBDA: store i{{[0-9]+}}* [[SVAR_PRIVATE]], i{{[0-9]+}}** [[SVAR_PRIVATE_ADDR_REF]]
+ // LAMBDA: [[SFVAR_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 3
+ // LAMBDA: store float* [[SFVAR_PRIVATE]], float** [[SFVAR_PRIVATE_ADDR_REF]]
+ // LAMBDA: call{{.*}} void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]])
+ // LAMBDA: call {{.*}}void @__kmpc_for_static_fini(
+
+ // linear counter
+ // LAMBDA: [[OMP_IS_LAST_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[OMP_IS_LAST]],
+ // LAMBDA: [[IS_LAST_IT:%.+]] = icmp ne i{{[0-9]+}} [[OMP_IS_LAST_VAL]], 0
+ // LAMBDA: br i1 [[IS_LAST_IT]], label %[[OMP_COUNTER_BLOCK:.+]], label %[[OMP_COUNTER_DONE:.+]]
+ // LAMBDA: [[OMP_COUNTER_BLOCK]]:
+ // LAMBDA: store i{{[0-9]+}} 2, i{{[0-9]+}}* %
+ // LAMBDA: br label %[[OMP_COUNTER_DONE]]
+ // LAMBDA: [[OMP_COUNTER_DONE]]:
+
+
+ // LAMBDA: [[OMP_IS_LAST_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[OMP_IS_LAST]],
+ // LAMBDA: [[IS_LAST_IT:%.+]] = icmp ne i{{[0-9]+}} [[OMP_IS_LAST_VAL]], 0
+ // LAMBDA: br i1 [[IS_LAST_IT]], label %[[OMP_LASTPRIV_BLOCK:.+]], label %[[OMP_LASTPRIV_DONE:.+]]
+
+ // LAMBDA: [[OMP_LASTPRIV_BLOCK]]:
+ // LAMBDA: [[G_PRIV_VAL:%.+]] = load double, double* [[G_PRIVATE]],
+ // LAMBDA: store{{.*}} double [[G_PRIV_VAL]], double* [[G_IN_REF]],
+ // LAMBDA: [[TMP_G1_PRIV_REF:%.+]] = load double*, double** [[TMP_G1_PRIVATE]],
+ // LAMBDA: [[TMP_G1_PRIV_VAL:%.+]] = load double, double* [[TMP_G1_PRIV_REF]],
+ // LAMBDA: store{{.*}} double [[TMP_G1_PRIV_VAL]], double* [[TMP_G1_VAL]],
+
+ // LAMBDA: [[SVAR_PRIV_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SVAR_PRIVATE]],
+ // LAMBDA: store i{{[0-9]+}} [[SVAR_PRIV_VAL]], i{{[0-9]+}}* [[SVAR_IN_REF]],
+ // LAMBDA: [[SFVAR_PRIV_VAL:%.+]] = load float, float* [[SFVAR_PRIVATE]],
+ // LAMBDA: store float [[SFVAR_PRIV_VAL]], float* [[SFVAR_IN_REF]],
+ // LAMBDA: br label %[[OMP_LASTPRIV_DONE]]
+ // LAMBDA: [[OMP_LASTPRIV_DONE]]:
+ // LAMBDA: ret
+ [&]() {
+ // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]])
+ // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]],
+ g = 2;
+ g1 = 2;
+ svar = 4;
+ sfvar = 8.0;
+ // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]]
+ // LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // LAMBDA: [[G_REF:%.+]] = load double*, double** [[G_PTR_REF]]
+ // LAMBDA: store double 2.0{{.+}}, double* [[G_REF]]
+
+ // LAMBDA: [[TMP_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // LAMBDA: [[G1_REF:%.+]] = load double*, double** [[TMP_PTR_REF]]
+ // LAMBDA: store double 2.0{{.+}}, double* [[G1_REF]],
+ // LAMBDA: [[SVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+ // LAMBDA: [[SVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SVAR_PTR_REF]]
+ // LAMBDA: store i{{[0-9]+}} 4, i{{[0-9]+}}* [[SVAR_REF]]
+ // LAMBDA: [[SFVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 3
+ // LAMBDA: [[SFVAR_REF:%.+]] = load float*, float** [[SFVAR_PTR_REF]]
+ // LAMBDA: store float 8.0{{.+}}, float* [[SFVAR_REF]]
+ }();
+ }
+ }();
+ return 0;
+ #else
+ S<float> test;
+ int t_var = 0;
+ int vec[] = {1, 2};
+ S<float> s_arr[] = {1, 2};
+ S<float> &var = test;
+
+ #pragma omp target
+ #pragma omp teams
+#pragma omp distribute simd lastprivate(t_var, vec, s_arr, s_arr, var, var, svar)
+ for (int i = 0; i < 2; ++i) {
+ vec[i] = t_var;
+ s_arr[i] = var;
+ }
+ int i;
+
+ return tmain<int>();
+ #endif
+}
+
+// CHECK: define{{.*}} i{{[0-9]+}} @main()
+// CHECK: [[TEST:%.+]] = alloca [[S_FLOAT_TY]],
+// CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR:@.+]]([[S_FLOAT_TY]]* [[TEST]])
+// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+// CHECK: call void [[OFFLOAD_FUN:@.+]](i{{[0-9]+}} {{.+}}, [2 x i{{[0-9]+}}]* {{.+}}, [2 x [[S_FLOAT_TY]]]* {{.+}}, [[S_FLOAT_TY]]* {{.+}}, i{{[0-9]+}} {{.+}})
+// CHECK: ret
+
+// CHECK: define{{.+}} [[OFFLOAD_FUN]](i{{[0-9]+}} {{.+}}, [2 x i{{[0-9]+}}]*{{.+}} {{.+}}, [2 x [[S_FLOAT_TY]]]*{{.+}} {{.+}}, [[S_FLOAT_TY]]*{{.+}} {{.+}}, i{{[0-9]+}} {{.+}})
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_teams(
+// CHECK: ret
+//
+// CHECK: define internal void [[OMP_OUTLINED:@.+]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i{{[0-9]+}}*{{.+}} [[T_VAR_IN:%.+]], [2 x i{{[0-9]+}}]*{{.+}} [[VEC_IN:%.+]], [2 x [[S_FLOAT_TY]]]*{{.+}} [[S_ARR_IN:%.+]], [[S_FLOAT_TY]]*{{.+}} [[VAR_IN:%.+]], i{{[0-9]+}}*{{.*}} [[S_VAR_IN:%.+]])
+// CHECK: {{.+}} = alloca i{{[0-9]+}}*,
+// CHECK: {{.+}} = alloca i{{[0-9]+}}*,
+// CHECK: [[T_VAR_ADDR:%.+]] = alloca i{{[0-9]+}}*,
+// CHECK: [[VEC_ADDR:%.+]] = alloca [2 x i{{[0-9]+}}]*,
+// CHECK: [[S_ARR_ADDR:%.+]] = alloca [2 x [[S_FLOAT_TY]]]*,
+// CHECK: [[VAR_ADDR:%.+]] = alloca [[S_FLOAT_TY]]*,
+// CHECK: [[SVAR_ADDR:%.+]] = alloca i{{[0-9]+}}*,
+// CHECK: [[TMP:%.*]] = alloca [[S_FLOAT_TY]]*,
+// skip loop variables
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: [[OMP_IS_LAST:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]],
+// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]],
+// CHECK: [[TMP_PRIV:%.+]] = alloca [[S_FLOAT_TY]]*,
+// CHECK: [[S_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+
+// copy from parameters to local address variables
+// CHECK: store i{{[0-9]+}}* [[T_VAR_IN]], i{{[0-9]+}}** [[T_VAR_ADDR]],
+// CHECK: store [2 x i{{[0-9]+}}]* [[VEC_IN]], [2 x i{{[0-9]+}}]** [[VEC_ADDR]],
+// CHECK: store [2 x [[S_FLOAT_TY]]]* [[S_ARR_IN]], [2 x [[S_FLOAT_TY]]]** [[S_ARR_ADDR]],
+// CHECK: store [[S_FLOAT_TY]]* [[VAR_IN]], [[S_FLOAT_TY]]** [[VAR_ADDR]],
+// CHECK: store i{{[0-9]+}}* [[S_VAR_IN]], i{{[0-9]+}}** [[SVAR_ADDR]],
+
+// load content of local address variables
+// CHECK: [[T_VAR_ADDR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[T_VAR_ADDR]],
+// CHECK: [[VEC_ADDR_REF:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** [[VEC_ADDR]],
+// CHECK: [[S_ARR_ADDR_REF:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[S_ARR_ADDR]],
+// CHECK: [[SVAR_ADDR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SVAR_ADDR]],
+// CHECK: [[VAR_ADDR_REF:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[VAR_ADDR]],
+// CHECK: store [[S_FLOAT_TY]]* [[VAR_ADDR_REF]], [[S_FLOAT_TY]]** [[TMP]],
+// CHECK: store i{{[0-9]+}} 0, i{{[0-9]+}}* [[OMP_IS_LAST]],
+// CHECK: [[TMP_REF:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[TMP]],
+// the distribute loop
+// CHECK: call void @__kmpc_for_static_init_4(
+// assignment: vec[i] = t_var;
+// CHECK: [[T_VAR_PRIV_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_PRIV]],
+// CHECK: [[VEC_PTR:%.+]] = getelementptr inbounds [2 x i{{[0-9]+}}], [2 x i{{[0-9]+}}]* [[VEC_PRIV]], i{{[0-9]+}} 0, i{{[0-9]+}} {{.+}}
+// CHECK: store i{{[0-9]+}} [[T_VAR_PRIV_VAL]], i{{[0-9]+}}* [[VEC_PTR]],
+
+// assignment: s_arr[i] = var;
+// CHECK-DAG: [[S_ARR_PTR:%.+]] = getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[S_ARR_PRIV]],
+// CHECK-DAG: [[TMP_VAL:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[TMP_PRIV]],
+// CHECK-DAG: [[S_ARR_PTR_BCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[S_ARR_PTR]] to i8*
+// CHECK-DAG: [[TMP_VAL_BCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[TMP_VAL]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[S_ARR_PTR_BCAST]], i8* [[TMP_VAL_BCAST]],
+// CHECK: call void @__kmpc_for_static_fini(
+
+// lastprivates
+// CHECK: [[OMP_IS_LAST_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[OMP_IS_LAST]],
+// CHECK: [[IS_LAST_IT:%.+]] = icmp ne i{{[0-9]+}} [[OMP_IS_LAST_VAL]], 0
+// CHECK: br i1 [[IS_LAST_IT]], label %[[OMP_LASTPRIV_BLOCK:.+]], label %[[OMP_LASTPRIV_DONE:.+]]
+
+// CHECK: [[OMP_LASTPRIV_BLOCK]]:
+// CHECK: [[T_VAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_PRIV]],
+// CHECK: store i{{[0-9]+}} [[T_VAR_VAL]], i{{[0-9]+}}* [[T_VAR_ADDR_REF]],
+// CHECK: [[BCAST_VEC_ADDR_REF:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_ADDR_REF]] to i8*
+// CHECK: [[BCAST_VEC_PRIV:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[BCAST_VEC_ADDR_REF]], i8* [[BCAST_VEC_PRIV]],
+// CHECK: [[S_ARR_BEGIN:%.+]] = getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[S_ARR_ADDR_REF]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+// CHECK: [[S_ARR_PRIV_BCAST:%.+]] = bitcast [2 x [[S_FLOAT_TY]]]* [[S_ARR_PRIV]] to [[S_FLOAT_TY]]*
+// CHECK: [[S_ARR_BEGIN_GEP:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[S_ARR_BEGIN]], i{{[0-9]+}} 2
+// CHECK: [[S_ARR_IS_EMPTY:%.+]] = icmp eq [[S_FLOAT_TY]]* [[S_ARR_BEGIN]], [[S_ARR_BEGIN_GEP]]
+// CHECK: br i1 [[S_ARR_IS_EMPTY]], label %[[S_ARR_COPY_DONE:.+]], label %[[S_ARR_COPY_BLOCK:.+]]
+// CHECK: [[S_ARR_COPY_BLOCK]]:
+// CHECK: [[S_ARR_SRC_EL:%.+]] = phi [[S_FLOAT_TY]]*{{.+}}
+// CHECK: [[S_ARR_DST_EL:%.+]] = phi [[S_FLOAT_TY]]*{{.+}}
+// CHECK: [[S_ARR_DST_BCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[S_ARR_DST_EL]] to i8*
+// CHECK: [[S_ARR_SRC_BCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[S_ARR_SRC_EL]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[S_ARR_DST_BCAST]], i8* [[S_ARR_SRC_BCAST]]{{.+}})
+// CHECK: [[S_ARR_DST_NEXT:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[S_ARR_DST_EL]], i{{[0-9]+}} 1
+// CHECK: [[S_ARR_SRC_NEXT:%.+]] = getelementptr{{.+}}
+// CHECK: [[CPY_IS_FINISHED:%.+]] = icmp eq [[S_FLOAT_TY]]* [[S_ARR_DST_NEXT]], [[S_ARR_BEGIN_GEP]]
+// CHECK: br i1 [[CPY_IS_FINISHED]], label %[[S_ARR_COPY_DONE]], label %[[S_ARR_COPY_BLOCK]]
+// CHECK: [[S_ARR_COPY_DONE]]:
+// CHECK: [[TMP_VAL1:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[TMP_PRIV]],
+// CHECK: [[VAR_ADDR_REF_BCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[TMP_REF]] to i8*
+// CHECK: [[TMP_VAL1_BCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[TMP_VAL1]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[VAR_ADDR_REF_BCAST]], i8* [[TMP_VAL1_BCAST]],{{.+}})
+// CHECK: [[SVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[S_VAR_PRIV]],
+// CHECK: store i{{[0-9]+}} [[SVAR_VAL]], i{{[0-9]+}}* [[SVAR_ADDR_REF]],
+// CHECK: ret void
+
+// template tmain
+// CHECK: define{{.*}} i{{[0-9]+}} [[TMAIN_INT:@.+]]()
+// CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]],
+// CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR:@.+]]([[S_INT_TY]]* [[TEST]])
+// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+// CHECK: call void [[OFFLOAD_FUN_1:@.+]](i{{[0-9]+}} {{.+}}, [2 x i{{[0-9]+}}]* {{.+}}, [2 x [[S_INT_TY]]]* {{.+}}, [[S_INT_TY]]* {{.+}})
+// CHECK: ret
+
+
+// CHECK: define internal void [[OFFLOAD_FUN_1]](
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_teams(%{{.+}}* @{{.+}}, i{{[0-9]+}} 4,
+// CHECK: ret
+
+// CHECK: define internal void [[OMP_OUTLINED_1:@.+]](i{{[0-9]+}}* noalias [[GTID_ADDR1:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i{{[0-9]+}}*{{.+}} [[T_VAR_IN1:%.+]], [2 x i{{[0-9]+}}]*{{.+}} [[VEC_IN1:%.+]], [2 x [[S_INT_TY]]]*{{.+}} [[S_ARR_IN1:%.+]], [[S_INT_TY]]*{{.+}} [[VAR_IN1:%.+]])
+// skip alloca of global_tid and bound_tid
+// CHECK: {{.+}} = alloca i{{[0-9]+}}*,
+// CHECK: {{.+}} = alloca i{{[0-9]+}}*,
+// CHECK: [[T_VAR_ADDR1:%.+]] = alloca i{{[0-9]+}}*,
+// CHECK: [[VEC_ADDR1:%.+]] = alloca [2 x i{{[0-9]+}}]*,
+// CHECK: [[S_ARR_ADDR1:%.+]] = alloca [2 x [[S_INT_TY]]]*,
+// CHECK: [[VAR_ADDR1:%.+]] = alloca [[S_INT_TY]]*,
+// CHECK: [[TMP:%.+]] = alloca [[S_INT_TY]]*,
+// skip loop variables
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: [[OMP_IS_LAST1:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[T_VAR_PRIV1:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[VEC_PRIV1:%.+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK: [[S_ARR_PRIV1:%.+]] = alloca [2 x [[S_INT_TY]]],
+// CHECK: [[VAR_PRIV1:%.+]] = alloca [[S_INT_TY]],
+// CHECK: [[TMP_PRIV1:%.+]] = alloca [[S_INT_TY]]*,
+
+// skip init of bound and global tid
+// CHECK: store i{{[0-9]+}}* {{.*}},
+// CHECK: store i{{[0-9]+}}* {{.*}},
+// copy from parameters to local address variables
+// CHECK: store i{{[0-9]+}}* [[T_VAR_IN1]], i{{[0-9]+}}** [[T_VAR_ADDR1]],
+// CHECK: store [2 x i{{[0-9]+}}]* [[VEC_IN1]], [2 x i{{[0-9]+}}]** [[VEC_ADDR1]],
+// CHECK: store [2 x [[S_INT_TY]]]* [[S_ARR_IN1]], [2 x [[S_INT_TY]]]** [[S_ARR_ADDR1]],
+// CHECK: store [[S_INT_TY]]* [[VAR_IN1]], [[S_INT_TY]]** [[VAR_ADDR1]],
+
+// load content of local address variables
+// CHECK: [[T_VAR_ADDR_REF1:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[T_VAR_ADDR1]],
+// CHECK: [[VEC_ADDR_REF1:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** [[VEC_ADDR1]],
+// CHECK: [[S_ARR_ADDR_REF1:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** [[S_ARR_ADDR1]],
+// CHECK: [[VAR_ADDR1_REF:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[VAR_ADDR1]],
+// CHECK-DAG: store [[S_INT_TY]]* [[VAR_ADDR1_REF]], [[S_INT_TY]]** [[TMP]],
+// CHECK-DAG: store i{{[0-9]+}} 0, i{{[0-9]+}}* [[OMP_IS_LAST1]],
+// CHECK-DAG: [[TMP_REF:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[TMP]],
+// CHECK: call void @__kmpc_for_static_init_4(
+// assignment: vec[i] = t_var;
+// CHECK: [[IV_VAL1:%.+]] =
+// CHECK: [[T_VAR_PRIV_VAL1:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_PRIV1]],
+// CHECK: [[VEC_PTR1:%.+]] = getelementptr inbounds [2 x i{{[0-9]+}}], [2 x i{{[0-9]+}}]* [[VEC_PRIV1]], i{{[0-9]+}} 0, i{{[0-9]+}} {{.+}}
+// CHECK: store i{{[0-9]+}} [[T_VAR_PRIV_VAL1]], i{{[0-9]+}}* [[VEC_PTR1]],
+
+// assignment: s_arr[i] = var;
+// CHECK-DAG: [[S_ARR_PTR1:%.+]] = getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[S_ARR_PRIV1]],
+// CHECK-DAG: [[TMP_VAL1:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[TMP_PRIV1]],
+// CHECK-DAG: [[S_ARR_PTR_BCAST1:%.+]] = bitcast [[S_INT_TY]]* [[S_ARR_PTR1]] to i8*
+// CHECK-DAG: [[TMP_VAL_BCAST1:%.+]] = bitcast [[S_INT_TY]]* [[TMP_VAL1]] to i8*
+// CHECK-DAG: call void @llvm.memcpy.{{.+}}(i8* [[S_ARR_PTR_BCAST1]], i8* [[TMP_VAL_BCAST1]],
+// CHECK: call void @__kmpc_for_static_fini(
+
+// lastprivates
+// CHECK: [[OMP_IS_LAST_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[OMP_IS_LAST1]],
+// CHECK: [[IS_LAST_IT:%.+]] = icmp ne i{{[0-9]+}} [[OMP_IS_LAST_VAL]], 0
+// CHECK: br i1 [[IS_LAST_IT]], label %[[OMP_LASTPRIV_BLOCK:.+]], label %[[OMP_LASTPRIV_DONE:.+]]
+
+// CHECK: [[OMP_LASTPRIV_BLOCK]]:
+// CHECK: [[T_VAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_PRIV1]],
+// CHECK: store i{{[0-9]+}} [[T_VAR_VAL]], i{{[0-9]+}}* [[T_VAR_ADDR_REF1]],
+// CHECK: [[BCAST_VEC_ADDR_REF:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_ADDR_REF1]] to i8*
+// CHECK: [[BCAST_VEC_PRIV:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV1]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[BCAST_VEC_ADDR_REF]], i8* [[BCAST_VEC_PRIV]],
+// CHECK: [[S_ARR_BEGIN:%.+]] = getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[S_ARR_ADDR_REF]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+// CHECK: [[S_ARR_PRIV_BCAST:%.+]] = bitcast [2 x [[S_INT_TY]]]* [[S_ARR_PRIV1]] to [[S_INT_TY]]*
+// CHECK: [[S_ARR_BEGIN_GEP:%.+]] = getelementptr [[S_INT_TY]], [[S_INT_TY]]* [[S_ARR_BEGIN]], i{{[0-9]+}} 2
+// CHECK: [[S_ARR_IS_EMPTY:%.+]] = icmp eq [[S_INT_TY]]* [[S_ARR_BEGIN]], [[S_ARR_BEGIN_GEP]]
+// CHECK: br i1 [[S_ARR_IS_EMPTY]], label %[[S_ARR_COPY_DONE:.+]], label %[[S_ARR_COPY_BLOCK:.+]]
+// CHECK: [[S_ARR_COPY_BLOCK]]:
+// CHECK: [[S_ARR_SRC_EL:%.+]] = phi [[S_INT_TY]]*{{.+}}
+// CHECK: [[S_ARR_DST_EL:%.+]] = phi [[S_INT_TY]]*{{.+}}
+// CHECK: [[S_ARR_DST_BCAST:%.+]] = bitcast [[S_INT_TY]]* [[S_ARR_DST_EL]] to i8*
+// CHECK: [[S_ARR_SRC_BCAST:%.+]] = bitcast [[S_INT_TY]]* [[S_ARR_SRC_EL]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[S_ARR_DST_BCAST]], i8* [[S_ARR_SRC_BCAST]]{{.+}})
+// CHECK: [[S_ARR_DST_NEXT:%.+]] = getelementptr [[S_INT_TY]], [[S_INT_TY]]* [[S_ARR_DST_EL]], i{{[0-9]+}} 1
+// CHECK: [[S_ARR_SRC_NEXT:%.+]] = getelementptr{{.+}}
+// CHECK: [[CPY_IS_FINISHED:%.+]] = icmp eq [[S_INT_TY]]* [[S_ARR_DST_NEXT]], [[S_ARR_BEGIN_GEP]]
+// CHECK: br i1 [[CPY_IS_FINISHED]], label %[[S_ARR_COPY_DONE]], label %[[S_ARR_COPY_BLOCK]]
+// CHECK: [[S_ARR_COPY_DONE]]:
+// CHECK: [[TMP_VAL1:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[TMP_PRIV1]],
+// CHECK: [[VAR_ADDR_REF_BCAST:%.+]] = bitcast [[S_INT_TY]]* [[TMP_REF]] to i8*
+// CHECK: [[TMP_VAL1_BCAST:%.+]] = bitcast [[S_INT_TY]]* [[TMP_VAL1]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[VAR_ADDR_REF_BCAST]], i8* [[TMP_VAL1_BCAST]],{{.+}})
+// CHECK: ret void
+
+// CHECK: !{!"llvm.loop.vectorize.enable", i1 true}
+#endif
diff --git a/test/OpenMP/distribute_simd_lastprivate_messages.cpp b/test/OpenMP/distribute_simd_lastprivate_messages.cpp
index 0f96cb4c3ec8..82ce15e55048 100644
--- a/test/OpenMP/distribute_simd_lastprivate_messages.cpp
+++ b/test/OpenMP/distribute_simd_lastprivate_messages.cpp
@@ -18,14 +18,14 @@ public:
const S2 &operator =(const S2&) const;
S2 &operator =(const S2&);
static float S2s; // expected-note {{static data member is predetermined as shared}}
- static const float S2sc;
+ static const float S2sc; // expected-note {{static data member is predetermined as shared}}
};
-const float S2::S2sc = 0; // expected-note {{static data member is predetermined as shared}}
+const float S2::S2sc = 0;
const S2 b;
const S2 ba[5];
class S3 {
int a;
- S3 &operator=(const S3 &s3); // expected-note 2 {{implicitly declared private here}}
+ S3 &operator=(const S3 &s3); // expected-note {{implicitly declared private here}}
public:
S3() : a(0) {}
@@ -52,7 +52,7 @@ public:
};
class S6 {
int a;
- S6() : a(0) {}
+ S6() : a(0) {} // expected-note {{implicitly declared private here}}
public:
S6(const S6 &s6) : a(s6.a) {}
@@ -313,14 +313,16 @@ int main(int argc, char **argv) {
#pragma omp distribute simd lastprivate(j)
for (i = 0; i < argc; ++i)
foo();
+// expected-error@+3 {{firstprivate variable cannot be lastprivate}} expected-note@+3 {{defined as firstprivate}}
#pragma omp target
#pragma omp teams
-#pragma omp distribute simd firstprivate(m) lastprivate(m) // expected-error {{'operator=' is a private member of 'S3'}}
+#pragma omp distribute simd firstprivate(m) lastprivate(m)
for (i = 0; i < argc; ++i)
foo();
+// expected-error@+3 {{lastprivate variable cannot be firstprivate}} expected-note@+3 {{defined as lastprivate}}
#pragma omp target
#pragma omp teams
-#pragma omp distribute simd lastprivate(n) firstprivate(n) // OK
+#pragma omp distribute simd lastprivate(n) firstprivate(n) // expected-error {{calling a private constructor of class 'S6'}}
for (i = 0; i < argc; ++i)
foo();
static int si;
diff --git a/test/OpenMP/distribute_simd_linear_messages.cpp b/test/OpenMP/distribute_simd_linear_messages.cpp
index c60e0a247071..e4d71fee8250 100644
--- a/test/OpenMP/distribute_simd_linear_messages.cpp
+++ b/test/OpenMP/distribute_simd_linear_messages.cpp
@@ -18,41 +18,49 @@ void test_linear_colons()
{
int B = 0;
+// expected-error@+3 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
#pragma omp teams
#pragma omp distribute simd linear(B:bfoo())
for (int i = 0; i < 10; ++i) ;
+// expected-error@+3 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
#pragma omp teams
#pragma omp distribute simd linear(B::ib:B:bfoo()) // expected-error {{unexpected ':' in nested name specifier; did you mean '::'}}
for (int i = 0; i < 10; ++i) ;
+// expected-error@+3 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
#pragma omp teams
#pragma omp distribute simd linear(B:ib) // expected-error {{use of undeclared identifier 'ib'; did you mean 'B::ib'}}
for (int i = 0; i < 10; ++i) ;
+// expected-error@+3 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
#pragma omp teams
#pragma omp distribute simd linear(z:B:ib) // expected-error {{unexpected ':' in nested name specifier; did you mean '::'?}}
for (int i = 0; i < 10; ++i) ;
+// expected-error@+3 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
#pragma omp teams
#pragma omp distribute simd linear(B:B::bfoo())
for (int i = 0; i < 10; ++i) ;
+// expected-error@+3 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
#pragma omp teams
#pragma omp distribute simd linear(X::x : ::z)
for (int i = 0; i < 10; ++i) ;
+// expected-error@+3 3 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
#pragma omp teams
#pragma omp distribute simd linear(B,::z, X::x)
for (int i = 0; i < 10; ++i) ;
+// expected-error@+3 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
#pragma omp teams
#pragma omp distribute simd linear(::z)
@@ -63,6 +71,7 @@ void test_linear_colons()
#pragma omp distribute simd linear(B::bfoo()) // expected-error {{expected variable name}}
for (int i = 0; i < 10; ++i) ;
+// expected-error@+3 2 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
#pragma omp teams
#pragma omp distribute simd linear(B::ib,B:C1+C2)
@@ -148,11 +157,13 @@ template<class I, class C> int foomain(I argc, C **argv) {
#pragma omp distribute simd linear () // expected-error {{expected expression}}
for (int k = 0; k < argc; ++k) ++k;
+// expected-error@+3 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
#pragma omp teams
#pragma omp distribute simd linear (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
for (int k = 0; k < argc; ++k) ++k;
+// expected-error@+3 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
#pragma omp teams
#pragma omp distribute simd linear (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
@@ -163,6 +174,7 @@ template<class I, class C> int foomain(I argc, C **argv) {
#pragma omp distribute simd linear (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
for (int k = 0; k < argc; ++k) ++k;
+// expected-error@+3 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
#pragma omp teams
#pragma omp distribute simd linear (argc : 5)
@@ -183,6 +195,7 @@ template<class I, class C> int foomain(I argc, C **argv) {
#pragma omp distribute simd linear (argv[1]) // expected-error {{expected variable name}}
for (int k = 0; k < argc; ++k) ++k;
+// expected-error@+3 2 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
#pragma omp teams
#pragma omp distribute simd linear(e, g)
@@ -193,37 +206,12 @@ template<class I, class C> int foomain(I argc, C **argv) {
#pragma omp distribute simd linear(h) // expected-error {{threadprivate or thread local variable cannot be linear}}
for (int k = 0; k < argc; ++k) ++k;
+// expected-error@+3 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
#pragma omp teams
#pragma omp distribute simd linear(i)
for (int k = 0; k < argc; ++k) ++k;
- #pragma omp parallel
- {
- int v = 0;
- int i;
- #pragma omp target
- #pragma omp teams
- #pragma omp distribute simd linear(v:i)
- for (int k = 0; k < argc; ++k) { i = k; v += i; }
- }
-
-#pragma omp target
-#pragma omp teams
-#pragma omp parallel for simd linear(j)
- for (int k = 0; k < argc; ++k) ++k;
-
- int v = 0;
-
-#pragma omp target
-#pragma omp teams
-#pragma omp distribute simd linear(v:j)
- for (int k = 0; k < argc; ++k) { ++k; v += j; }
-
-#pragma omp target
-#pragma omp teams
-#pragma omp distribute simd linear(i)
- for (int k = 0; k < argc; ++k) ++k;
return 0;
}
@@ -262,11 +250,13 @@ int main(int argc, char **argv) {
#pragma omp distribute simd linear () // expected-error {{expected expression}}
for (int k = 0; k < argc; ++k) ++k;
+// expected-error@+3 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
#pragma omp teams
#pragma omp distribute simd linear (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
for (int k = 0; k < argc; ++k) ++k;
+// expected-error@+3 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
#pragma omp teams
#pragma omp distribute simd linear (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
@@ -277,6 +267,7 @@ int main(int argc, char **argv) {
#pragma omp distribute simd linear (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
for (int k = 0; k < argc; ++k) ++k;
+// expected-error@+3 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
#pragma omp teams
#pragma omp distribute simd linear (argc)
@@ -310,28 +301,18 @@ int main(int argc, char **argv) {
#pragma omp parallel
{
- int i;
+ int k;
#pragma omp target
#pragma omp teams
- #pragma omp distribute simd linear(i)
- for (int k = 0; k < argc; ++k) ++k;
+ #pragma omp distribute simd linear(k)
+ for (k = 0; k < argc; ++k) ++k;
#pragma omp target
#pragma omp teams
- #pragma omp distribute simd linear(i : 4)
- for (int k = 0; k < argc; ++k) { ++k; i += 4; }
+ #pragma omp distribute simd linear(k : 4)
+ for (k = 0; k < argc; k+=4) { }
}
-#pragma omp target
-#pragma omp teams
-#pragma omp distribute simd linear(j)
- for (int k = 0; k < argc; ++k) ++k;
-
-#pragma omp target
-#pragma omp teams
-#pragma omp distribute simd linear(i)
- for (int k = 0; k < argc; ++k) ++k;
-
foomain<int,char>(argc,argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}}
return 0;
}
diff --git a/test/OpenMP/distribute_simd_misc_messages.c b/test/OpenMP/distribute_simd_misc_messages.c
index 5fc2cb64cc62..f643ed1d5b8e 100644
--- a/test/OpenMP/distribute_simd_misc_messages.c
+++ b/test/OpenMP/distribute_simd_misc_messages.c
@@ -561,89 +561,6 @@ void test_linear() {
#pragma omp distribute simd linear(x, y, z)
for (i = 0; i < 16; ++i)
;
-
- int x, y;
-#pragma omp target
-#pragma omp teams
-// expected-error@+1 {{expected expression}}
-#pragma omp distribute simd linear(x :)
- for (i = 0; i < 16; ++i)
- ;
-#pragma omp target
-#pragma omp teams
-// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
-#pragma omp distribute simd linear(x :, )
- for (i = 0; i < 16; ++i)
- ;
-#pragma omp target
-#pragma omp teams
-#pragma omp distribute simd linear(x : 1)
- for (i = 0; i < 16; ++i)
- ;
-#pragma omp target
-#pragma omp teams
-#pragma omp distribute simd linear(x : 2 * 2)
- for (i = 0; i < 16; ++i)
- ;
-#pragma omp target
-#pragma omp teams
-// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
-#pragma omp distribute simd linear(x : 1, y)
- for (i = 0; i < 16; ++i)
- ;
-#pragma omp target
-#pragma omp teams
-// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
-#pragma omp distribute simd linear(x : 1, y, z : 1)
- for (i = 0; i < 16; ++i)
- ;
-
-#pragma omp target
-#pragma omp teams
-// expected-note@+2 {{defined as linear}}
-// expected-error@+1 {{linear variable cannot be linear}}
-#pragma omp distribute simd linear(x) linear(x)
- for (i = 0; i < 16; ++i)
- ;
-
-#pragma omp target
-#pragma omp teams
-// expected-note@+2 {{defined as private}}
-// expected-error@+1 {{private variable cannot be linear}}
-#pragma omp distribute simd private(x) linear(x)
- for (i = 0; i < 16; ++i)
- ;
-
-#pragma omp target
-#pragma omp teams
-// expected-note@+2 {{defined as linear}}
-// expected-error@+1 {{linear variable cannot be private}}
-#pragma omp distribute simd linear(x) private(x)
- for (i = 0; i < 16; ++i)
- ;
-
-#pragma omp target
-#pragma omp teams
-// expected-warning@+1 {{zero linear step (x and other variables in clause should probably be const)}}
-#pragma omp distribute simd linear(x, y : 0)
- for (i = 0; i < 16; ++i)
- ;
-
-#pragma omp target
-#pragma omp teams
-// expected-note@+2 {{defined as linear}}
-// expected-error@+1 {{linear variable cannot be lastprivate}}
-#pragma omp distribute simd linear(x) lastprivate(x)
- for (i = 0; i < 16; ++i)
- ;
-
-#pragma omp target
-#pragma omp teams
-// expected-note@+2 {{defined as lastprivate}}
-// expected-error@+1 {{lastprivate variable cannot be linear}}
-#pragma omp distribute simd lastprivate(x) linear(x)
- for (i = 0; i < 16; ++i)
- ;
}
void test_aligned() {
@@ -1083,26 +1000,26 @@ void test_loop_messages() {
}
void linear_modifiers(int argc) {
- int f;
+ int k;
#pragma omp target
#pragma omp teams
-#pragma omp distribute simd linear(f)
- for (int k = 0; k < argc; ++k) ++k;
+#pragma omp distribute simd linear(k)
+ for (k = 0; k < argc; ++k) ++k;
#pragma omp target
#pragma omp teams
-#pragma omp distribute simd linear(val(f))
- for (int k = 0; k < argc; ++k) ++k;
+#pragma omp distribute simd linear(val(k))
+ for (k = 0; k < argc; ++k) ++k;
#pragma omp target
#pragma omp teams
-#pragma omp distribute simd linear(uval(f)) // expected-error {{expected 'val' modifier}}
- for (int k = 0; k < argc; ++k) ++k;
+#pragma omp distribute simd linear(uval(k)) // expected-error {{expected 'val' modifier}}
+ for (k = 0; k < argc; ++k) ++k;
#pragma omp target
#pragma omp teams
-#pragma omp distribute simd linear(ref(f)) // expected-error {{expected 'val' modifier}}
- for (int k = 0; k < argc; ++k) ++k;
+#pragma omp distribute simd linear(ref(k)) // expected-error {{expected 'val' modifier}}
+ for (k = 0; k < argc; ++k) ++k;
#pragma omp target
#pragma omp teams
-#pragma omp distribute simd linear(foo(f)) // expected-error {{expected 'val' modifier}}
- for (int k = 0; k < argc; ++k) ++k;
+#pragma omp distribute simd linear(foo(k)) // expected-error {{expected 'val' modifier}}
+ for (k = 0; k < argc; ++k) ++k;
}
diff --git a/test/OpenMP/distribute_simd_private_codegen.cpp b/test/OpenMP/distribute_simd_private_codegen.cpp
new file mode 100644
index 000000000000..ede807a0fb63
--- /dev/null
+++ b/test/OpenMP/distribute_simd_private_codegen.cpp
@@ -0,0 +1,208 @@
+// RUN: %clang_cc1 -DLAMBDA -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+// RUN: %clang_cc1 -DLAMBDA -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-32
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-32
+
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+template <class T>
+struct S {
+ T f;
+ S(T a) : f(a) {}
+ S() : f() {}
+ operator T() { return T(); }
+ ~S() {}
+};
+
+// CHECK: [[S_FLOAT_TY:%.+]] = type { float }
+// CHECK: [[S_INT_TY:%.+]] = type { i{{[0-9]+}} }
+template <typename T>
+T tmain() {
+ S<T> test;
+ T t_var = T();
+ T vec[] = {1, 2};
+ S<T> s_arr[] = {1, 2};
+ S<T> &var = test;
+ #pragma omp target
+ #pragma omp teams
+#pragma omp distribute simd private(t_var, vec, s_arr, s_arr, var, var)
+ for (int i = 0; i < 2; ++i) {
+ vec[i] = t_var;
+ s_arr[i] = var;
+ }
+ return T();
+}
+
+int main() {
+ static int svar;
+ volatile double g;
+ volatile double &g1 = g;
+
+ #ifdef LAMBDA
+ // LAMBDA-LABEL: @main
+ // LAMBDA: call{{.*}} void [[OUTER_LAMBDA:@.+]](
+ [&]() {
+ static float sfvar;
+ // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
+ // LAMBDA: call i{{[0-9]+}} @__tgt_target_teams(
+ // LAMBDA: call void [[OFFLOADING_FUN:@.+]](
+
+ // LAMBDA: define{{.+}} void [[OFFLOADING_FUN]]()
+ // LAMBDA: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, i32 0, {{.+}}* [[OMP_OUTLINED:@.+]] to {{.+}})
+ #pragma omp target
+ #pragma omp teams
+#pragma omp distribute simd private(g, g1, svar, sfvar)
+ for (int i = 0; i < 2; ++i) {
+ // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_OUTLINED]](i32* noalias %{{.+}}, i32* noalias %{{.+}})
+ // LAMBDA: [[G_PRIVATE_ADDR:%.+]] = alloca double,
+ // LAMBDA: [[G1_PRIVATE_ADDR:%.+]] = alloca double,
+ // LAMBDA: [[TMP_PRIVATE_ADDR:%.+]] = alloca double*,
+ // LAMBDA: [[SVAR_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[SFVAR_PRIVATE_ADDR:%.+]] = alloca float,
+ // LAMBDA: store double* [[G1_PRIVATE_ADDR]], double** [[TMP_PRIVATE_ADDR]],
+ g = 1;
+ g1 = 1;
+ svar = 3;
+ sfvar = 4.0;
+ // LAMBDA: call {{.*}}void @__kmpc_for_static_init_4(
+ // LAMBDA: store double 1.0{{.+}}, double* [[G_PRIVATE_ADDR]],
+ // LAMBDA: store i{{[0-9]+}} 3, i{{[0-9]+}}* [[SVAR_PRIVATE_ADDR]],
+ // LAMBDA: store float 4.0{{.+}}, float* [[SFVAR_PRIVATE_ADDR]],
+ // LAMBDA: [[G_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // LAMBDA: store double* [[G_PRIVATE_ADDR]], double** [[G_PRIVATE_ADDR_REF]],
+ // LAMBDA: [[TMP_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // LAMBDA: [[G1_PRIVATE_ADDR_FROM_TMP:%.+]] = load double*, double** [[TMP_PRIVATE_ADDR]],
+ // LAMBDA: store double* [[G1_PRIVATE_ADDR_FROM_TMP]], double** [[TMP_PRIVATE_ADDR_REF]],
+ // LAMBDA: [[SVAR_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+ // LAMBDA: store i{{[0-9]+}}* [[SVAR_PRIVATE_ADDR]], i{{[0-9]+}}** [[SVAR_PRIVATE_ADDR_REF]]
+ // LAMBDA: [[SFVAR_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 3
+ // LAMBDA: store float* [[SFVAR_PRIVATE_ADDR]], float** [[SFVAR_PRIVATE_ADDR_REF]]
+ // LAMBDA: call{{.*}} void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]])
+ // LAMBDA: call {{.*}}void @__kmpc_for_static_fini(
+ [&]() {
+ // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]])
+ // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]],
+ g = 2;
+ g1 = 2;
+ svar = 4;
+ sfvar = 8.0;
+ // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]]
+ // LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // LAMBDA: [[G_REF:%.+]] = load double*, double** [[G_PTR_REF]]
+ // LAMBDA: store double 2.0{{.+}}, double* [[G_REF]]
+
+ // LAMBDA: [[TMP_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // LAMBDA: [[G1_REF:%.+]] = load double*, double** [[TMP_PTR_REF]]
+ // LAMBDA: store double 2.0{{.+}}, double* [[G1_REF]],
+ // LAMBDA: [[SVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+ // LAMBDA: [[SVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SVAR_PTR_REF]]
+ // LAMBDA: store i{{[0-9]+}} 4, i{{[0-9]+}}* [[SVAR_REF]]
+ // LAMBDA: [[SFVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 3
+ // LAMBDA: [[SFVAR_REF:%.+]] = load float*, float** [[SFVAR_PTR_REF]]
+ // LAMBDA: store float 8.0{{.+}}, float* [[SFVAR_REF]]
+ }();
+ }
+ }();
+ return 0;
+ #else
+ S<float> test;
+ int t_var = 0;
+ int vec[] = {1, 2};
+ S<float> s_arr[] = {1, 2};
+ S<float> &var = test;
+
+ #pragma omp target
+ #pragma omp teams
+#pragma omp distribute simd private(t_var, vec, s_arr, s_arr, var, var, svar)
+ for (int i = 0; i < 2; ++i) {
+ vec[i] = t_var;
+ s_arr[i] = var;
+ }
+ int i;
+
+ #pragma omp target
+ #pragma omp teams
+#pragma omp distribute simd
+ for (i = 0; i < 2; ++i) {
+ ;
+ }
+ return tmain<int>();
+ #endif
+}
+
+// CHECK: define{{.*}} i{{[0-9]+}} @main()
+// CHECK: [[TEST:%.+]] = alloca [[S_FLOAT_TY]],
+// CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR:@.+]]([[S_FLOAT_TY]]* [[TEST]])
+// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+// CHECK: call void [[OFFLOAD_FUN:@.+]](
+// CHECK: ret
+
+// CHECK: define{{.+}} [[OFFLOAD_FUN]]()
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_teams(%{{.+}}* @{{.+}}, i{{[0-9]+}} 0, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*)* [[OMP_OUTLINED:@.+]] to void
+// CHECK: ret
+//
+// CHECK: define internal void [[OMP_OUTLINED]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}})
+// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]],
+// CHECK-NOT: alloca [2 x [[S_FLOAT_TY]]],
+// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]],
+// CHECK-NOT: alloca [[S_FLOAT_TY]],
+// CHECK: [[S_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_REF:%.+]]
+// CHECK-NOT: [[T_VAR_PRIV]]
+// CHECK-NOT: [[VEC_PRIV]]
+// CHECK: {{.+}}:
+// CHECK: [[S_ARR_PRIV_ITEM:%.+]] = phi [[S_FLOAT_TY]]*
+// CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR]]([[S_FLOAT_TY]]* [[S_ARR_PRIV_ITEM]])
+// CHECK-NOT: [[T_VAR_PRIV]]
+// CHECK-NOT: [[VEC_PRIV]]
+// CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR]]([[S_FLOAT_TY]]* [[VAR_PRIV]])
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: ret void
+
+// CHECK: define{{.*}} i{{[0-9]+}} [[TMAIN_INT:@.+]]()
+// CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]],
+// CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR:@.+]]([[S_INT_TY]]* [[TEST]])
+// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+// CHECK: call void [[OFFLOAD_FUN_1:@.+]](
+// CHECK: ret
+
+
+// CHECK: define internal void [[OFFLOAD_FUN_1]]()
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_teams(%{{.+}}* @{{.+}}, i{{[0-9]+}} 0, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*)* [[OMP_OUTLINED_1:@.+]] to void
+// CHECK: ret
+//
+// CHECK: define internal void [[OMP_OUTLINED_1]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}})
+// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_INT_TY]]],
+// CHECK-NOT: alloca [2 x [[S_INT_TY]]],
+// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_INT_TY]],
+// CHECK-NOT: alloca [[S_INT_TY]],
+// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_REF:%.+]]
+// CHECK-NOT: [[T_VAR_PRIV]]
+// CHECK-NOT: [[VEC_PRIV]]
+// CHECK: {{.+}}:
+// CHECK: [[S_ARR_PRIV_ITEM:%.+]] = phi [[S_INT_TY]]*
+// CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR]]([[S_INT_TY]]* [[S_ARR_PRIV_ITEM]])
+// CHECK-NOT: [[T_VAR_PRIV]]
+// CHECK-NOT: [[VEC_PRIV]]
+// CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR]]([[S_INT_TY]]* [[VAR_PRIV]])
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: ret void
+
+// CHECK: !{!"llvm.loop.vectorize.enable", i1 true}
+#endif
diff --git a/test/OpenMP/distribute_simd_reduction_codegen.cpp b/test/OpenMP/distribute_simd_reduction_codegen.cpp
new file mode 100644
index 000000000000..8485d8d27d52
--- /dev/null
+++ b/test/OpenMP/distribute_simd_reduction_codegen.cpp
@@ -0,0 +1,204 @@
+// RUN: %clang_cc1 -DCHECK -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -DCHECK -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+
+// RUN: %clang_cc1 -DLAMBDA -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+template <typename T>
+T tmain() {
+ T t_var = T();
+ T vec[] = {1, 2};
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction(+: t_var)
+ for (int i = 0; i < 2; ++i) {
+ t_var += (T) i;
+ }
+ return T();
+}
+
+int main() {
+ static int sivar;
+#ifdef LAMBDA
+ // LAMBDA-LABEL: @main
+ // LAMBDA: call void [[OUTER_LAMBDA:@.+]](
+ [&]() {
+ // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
+ // LAMBDA: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 1, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 0)
+ // LAMBDA: call void @[[LOFFL1:.+]](
+ // LAMBDA: ret
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction(+: sivar)
+ for (int i = 0; i < 2; ++i) {
+ // LAMBDA: define{{.*}} internal{{.*}} void @[[LOFFL1]](i{{64|32}} [[SIVAR_ARG:%.+]])
+ // LAMBDA: [[SIVAR_ADDR:%.+]] = alloca i{{.+}},
+ // LAMBDA: store{{.+}} [[SIVAR_ARG]], {{.+}} [[SIVAR_ADDR]],
+ // LAMBDA: [[SIVAR_CONV:%.+]] = bitcast{{.+}} [[SIVAR_ADDR]] to
+ // LAMBDA: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[LOUTL1:.+]] to {{.+}}, {{.+}} [[SIVAR_CONV]])
+ // LAMBDA: ret void
+
+ // LAMBDA: define internal void @[[LOUTL1]]({{.+}}, {{.+}}, {{.+}} [[SIVAR_ARG:%.+]])
+ // Skip global and bound tid vars
+ // LAMBDA: {{.+}} = alloca i32*,
+ // LAMBDA: {{.+}} = alloca i32*,
+ // LAMBDA: [[SIVAR_ADDR:%.+]] = alloca i{{.+}}*,
+ // LAMBDA: alloca i{{.+}},
+ // LAMBDA: alloca i{{.+}},
+ // LAMBDA: alloca i{{.+}},
+ // LAMBDA: alloca i{{.+}},
+ // LAMBDA: alloca i{{.+}},
+ // LAMBDA: alloca i{{.+}},
+ // LAMBDA: [[SIVAR_PRIV:%.+]] = alloca i{{.+}},
+ // LAMBDA: store{{.+}} [[SIVAR_ARG]], {{.+}} [[SIVAR_ADDR]],
+ // LAMBDA: [[SIVAR_REF:%.+]] = load{{.+}}, {{.+}} [[SIVAR_ADDR]]
+ // LAMBDA: store{{.+}} 0, {{.+}} [[SIVAR_PRIV]],
+
+ // LAMBDA: call void @__kmpc_for_static_init_4(
+ // LAMBDA: store{{.+}}, {{.+}} [[SIVAR_PRIV]],
+ // LAMBDA: call void [[INNER_LAMBDA:@.+]](
+ // LAMBDA: call void @__kmpc_for_static_fini(
+ // LAMBDA: [[LAST_ITER:%.+]] = load i32, i32* %
+ // LAMBDA: [[IS_LAST:%.+]] = icmp ne i32 [[LAST_ITER]], 0
+ // LAMBDA: br i1 [[IS_LAST]], label %[[THEN:.+]], label %[[DONE:.+]]
+ // LAMBDA: [[THEN]]
+ // LAMBDA: store i32 2, i32* %
+ // LAMBDA: br label %[[DONE]]
+ // LAMBDA: [[DONE]]
+ // LAMBDA: [[SIVAR_ORIG_VAL:%.+]] = load i32, i32* [[SIVAR_REF]],
+ // LAMBDA: [[SIVAR_PRIV_VAL:%.+]] = load i32, i32* [[SIVAR_PRIV]],
+ // LAMBDA: [[ADD:%.+]] = add nsw i32 [[SIVAR_ORIG_VAL]], [[SIVAR_PRIV_VAL]]
+ // LAMBDA: store i32 [[ADD]], i32* [[SIVAR_REF]],
+ // LAMBDA: ret void
+
+ sivar += i;
+
+ [&]() {
+ // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]])
+ // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]],
+
+ sivar += 4;
+ // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]]
+
+ // LAMBDA: [[SIVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // LAMBDA: [[SIVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SIVAR_PTR_REF]]
+ // LAMBDA: [[SIVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR_REF]]
+ // LAMBDA: [[SIVAR_INC:%.+]] = add{{.+}} [[SIVAR_VAL]], 4
+ // LAMBDA: store i{{[0-9]+}} [[SIVAR_INC]], i{{[0-9]+}}* [[SIVAR_REF]]
+ }();
+ }
+ }();
+ return 0;
+#else
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction(+: sivar)
+ for (int i = 0; i < 2; ++i) {
+ sivar += i;
+ }
+ return tmain<int>();
+#endif
+}
+
+// CHECK: define {{.*}}i{{[0-9]+}} @main()
+// CHECK: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 1, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 0)
+// CHECK: call void @[[OFFL1:.+]](i{{64|32}} %{{.+}})
+// CHECK: {{%.+}} = call{{.*}} i32 @[[TMAIN_INT:.+]]()
+// CHECK: ret
+
+// CHECK: define{{.*}} void @[[OFFL1]](i{{64|32}} [[SIVAR_ARG:%.+]])
+// CHECK: [[SIVAR_ADDR:%.+]] = alloca i{{.+}},
+// CHECK: store{{.+}} [[SIVAR_ARG]], {{.+}} [[SIVAR_ADDR]],
+// CHECK-64: [[SIVAR_CONV:%.+]] = bitcast{{.+}} [[SIVAR_ADDR]] to
+// CHECK-64: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTL1:.+]] to {{.+}}, {{.+}} [[SIVAR_CONV]])
+// CHECK-32: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTL1:.+]] to {{.+}}, {{.+}} [[SIVAR_ADDR]])
+// CHECK: ret void
+
+// CHECK: define internal void @[[OUTL1]]({{.+}}, {{.+}}, {{.+}} [[SIVAR_ARG:%.+]])
+// Skip global and bound tid vars
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: [[SIVAR_ADDR:%.+]] = alloca i{{.+}}*,
+// CHECK: alloca i{{.+}},
+// CHECK: alloca i{{.+}},
+// CHECK: alloca i{{.+}},
+// CHECK: alloca i{{.+}},
+// CHECK: alloca i{{.+}},
+// CHECK: alloca i{{.+}},
+// CHECK: [[SIVAR_PRIV:%.+]] = alloca i{{.+}},
+// CHECK: store{{.+}} [[SIVAR_ARG]], {{.+}} [[SIVAR_ADDR]],
+// CHECK: [[SIVAR_REF:%.+]] = load{{.+}}, {{.+}} [[SIVAR_ADDR]]
+// CHECK: store{{.+}} 0, {{.+}} [[SIVAR_PRIV]],
+
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: store{{.+}}, {{.+}} [[SIVAR_PRIV]],
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: [[LAST_ITER:%.+]] = load i32, i32* %
+// CHECK: [[IS_LAST:%.+]] = icmp ne i32 [[LAST_ITER]], 0
+// CHECK: br i1 [[IS_LAST]], label %[[THEN:.+]], label %[[DONE:.+]]
+// CHECK: [[THEN]]
+// CHECK: store i32 2, i32* %
+// CHECK: br label %[[DONE]]
+// CHECK: [[DONE]]
+// CHECK: [[SIVAR_ORIG_VAL:%.+]] = load i32, i32* [[SIVAR_REF]],
+// CHECK: [[SIVAR_PRIV_VAL:%.+]] = load i32, i32* [[SIVAR_PRIV]],
+// CHECK: [[ADD:%.+]] = add nsw i32 [[SIVAR_ORIG_VAL]], [[SIVAR_PRIV_VAL]]
+// CHECK: store i32 [[ADD]], i32* [[SIVAR_REF]],
+// CHECK: ret void
+
+// CHECK: define{{.*}} i{{[0-9]+}} @[[TMAIN_INT]]()
+// CHECK: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 1,
+// CHECK: call void @[[TOFFL1:.+]]({{.+}})
+// CHECK: ret
+
+// CHECK: define{{.*}} void @[[TOFFL1]](i{{64|32}} [[TVAR_ARG:%.+]])
+// CHECK: [[TVAR_ADDR:%.+]] = alloca i{{.+}},
+// CHECK: store{{.+}} [[TVAR_ARG]], {{.+}} [[TVAR_ADDR]],
+// CHECK-64: [[TVAR_CONV:%.+]] = bitcast{{.+}} [[TVAR_ADDR]] to
+// CHECK-64: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[TOUTL1:.+]] to {{.+}}, {{.+}} [[TVAR_CONV]])
+// CHECK-32: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[TOUTL1:.+]] to {{.+}}, {{.+}} [[TVAR_ADDR]])
+// CHECK: ret void
+
+// CHECK: define internal void @[[TOUTL1]]({{.+}}, {{.+}}, {{.+}} [[TVAR_ARG:%.+]])
+// Skip global and bound tid vars
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: [[TVAR_ADDR:%.+]] = alloca i{{.+}}*,
+// CHECK: alloca i{{.+}},
+// CHECK: alloca i{{.+}},
+// CHECK: alloca i{{.+}},
+// CHECK: alloca i{{.+}},
+// CHECK: alloca i{{.+}},
+// CHECK: alloca i{{.+}},
+// CHECK: [[TVAR_PRIV:%.+]] = alloca i{{.+}},
+// CHECK: store{{.+}} [[TVAR_ARG]], {{.+}} [[TVAR_ADDR]],
+// CHECK: [[TVAR_REF:%.+]] = load{{.+}}, {{.+}} [[TVAR_ADDR]]
+// CHECK: store{{.+}} 0, {{.+}} [[TVAR_PRIV]],
+
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: store{{.+}}, {{.+}} [[TVAR_PRIV]],
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: [[LAST_ITER:%.+]] = load i32, i32* %
+// CHECK: [[IS_LAST:%.+]] = icmp ne i32 [[LAST_ITER]], 0
+// CHECK: br i1 [[IS_LAST]], label %[[THEN:.+]], label %[[DONE:.+]]
+// CHECK: [[THEN]]
+// CHECK: store i32 2, i32* %
+// CHECK: br label %[[DONE]]
+// CHECK: [[DONE]]
+// CHECK: [[TVAR_ORIG_VAL:%.+]] = load i32, i32* [[TVAR_REF]],
+// CHECK: [[TVAR_PRIV_VAL:%.+]] = load i32, i32* [[TVAR_PRIV]],
+// CHECK: [[ADD:%.+]] = add nsw i32 [[TVAR_ORIG_VAL]], [[TVAR_PRIV_VAL]]
+// CHECK: store i32 [[ADD]], i32* [[TVAR_REF]],
+// CHECK: ret void
+
+// CHECK: !{!"llvm.loop.vectorize.enable", i1 true}
+#endif
diff --git a/test/OpenMP/distribute_simd_reduction_messages.cpp b/test/OpenMP/distribute_simd_reduction_messages.cpp
index fca3e85a7104..ddedcb0892ba 100644
--- a/test/OpenMP/distribute_simd_reduction_messages.cpp
+++ b/test/OpenMP/distribute_simd_reduction_messages.cpp
@@ -27,9 +27,9 @@ public:
S2() : a(0) {}
S2(S2 &s2) : a(s2.a) {}
static float S2s; // expected-note 2 {{static data member is predetermined as shared}}
- static const float S2sc;
+ static const float S2sc; // expected-note 2 {{'S2sc' declared here}}
};
-const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}}
+const float S2::S2sc = 0;
S2 b; // expected-note 3 {{'b' defined here}}
const S2 ba[5]; // expected-note 2 {{'ba' defined here}}
class S3 {
diff --git a/test/OpenMP/dump.cpp b/test/OpenMP/dump.cpp
index 378b53ce5bf1..5ec202cc3040 100644
--- a/test/OpenMP/dump.cpp
+++ b/test/OpenMP/dump.cpp
@@ -52,11 +52,11 @@ struct S {
// CHECK-NEXT: | |-OMPScheduleClause {{.+}} <col:61, col:79>
// CHECK-NEXT: | | `-ImplicitCastExpr {{.+}} <col:78> 'int' <LValueToRValue>
// CHECK-NEXT: | | `-DeclRefExpr {{.+}} <col:78> 'int' lvalue OMPCapturedExpr {{.+}} '.capture_expr.' 'int'
-// CHECK-NEXT: | |-CapturedStmt {{.+}} <line:40:5, <invalid sloc>>
+// CHECK-NEXT: | |-CapturedStmt {{.+}} <line:40:5, line:41:9>
// CHECK-NEXT: | | |-CapturedDecl {{.+}} <<invalid sloc>> <invalid sloc>
-// CHECK-NEXT: | | | |-ForStmt {{.+}} <col:5, <invalid sloc>>
-// CHECK: | | | | `-UnaryOperator {{.+}} <line:41:7, <invalid sloc>> 'int' lvalue prefix '++'
-// CHECK-NEXT: | | | | `-DeclRefExpr {{.+}} <<invalid sloc>> 'int' lvalue OMPCapturedExpr {{.+}} 'a' 'int &'
+// CHECK-NEXT: | | | |-ForStmt {{.+}} <line:40:5, line:41:9>
+// CHECK: | | | | `-UnaryOperator {{.+}} <line:41:7, col:9> 'int' lvalue prefix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.+}} <col:9> 'int' lvalue OMPCapturedExpr {{.+}} 'a' 'int &'
#pragma omp declare simd
#pragma omp declare simd inbranch
diff --git a/test/OpenMP/for_codegen.cpp b/test/OpenMP/for_codegen.cpp
index 466139cfb2fc..1f5dd7ddd0dd 100644
--- a/test/OpenMP/for_codegen.cpp
+++ b/test/OpenMP/for_codegen.cpp
@@ -11,15 +11,26 @@
// CHECK: [[IDENT_T_TY:%.+]] = type { i32, i32, i32, i32, i8* }
// CHECK-DAG: [[IMPLICIT_BARRIER_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 66, i32 0, i32 0, i8*
+// CHECK-DAG: [[LOOP_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 514, i32 0, i32 0, i8*
// CHECK-DAG: [[I:@.+]] = global i8 1,
// CHECK-DAG: [[J:@.+]] = global i8 2,
// CHECK-DAG: [[K:@.+]] = global i8 3,
+// CHECK-LABEL: loop_with_counter_collapse
+void loop_with_counter_collapse() {
+ // CHECK: call void @__kmpc_for_static_init_8(%ident_t* @
+ // CHECK: call void @__kmpc_for_static_fini(%ident_t* @
+ #pragma omp for collapse(2)
+ for (int i = 0; i < 4; i++) {
+ for (int j = i; j < 4; j++) {
+ }
+ }
+}
// CHECK-LABEL: define {{.*void}} @{{.*}}without_schedule_clause{{.*}}(float* {{.+}}, float* {{.+}}, float* {{.+}}, float* {{.+}})
void without_schedule_clause(float *a, float *b, float *c, float *d) {
// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[IDENT_T_TY]]* [[DEFAULT_LOC:[@%].+]])
#pragma omp for nowait
-// CHECK: call void @__kmpc_for_static_init_4([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], i32 34, i32* [[IS_LAST:%[^,]+]], i32* [[OMP_LB:%[^,]+]], i32* [[OMP_UB:%[^,]+]], i32* [[OMP_ST:%[^,]+]], i32 1, i32 1)
+// CHECK: call void @__kmpc_for_static_init_4([[IDENT_T_TY]]* [[LOOP_LOC]], i32 [[GTID]], i32 34, i32* [[IS_LAST:%[^,]+]], i32* [[OMP_LB:%[^,]+]], i32* [[OMP_UB:%[^,]+]], i32* [[OMP_ST:%[^,]+]], i32 1, i32 1)
// UB = min(UB, GlobalUB)
// CHECK-NEXT: [[UB:%.+]] = load i32, i32* [[OMP_UB]]
// CHECK-NEXT: [[UBCMP:%.+]] = icmp sgt i32 [[UB]], 4571423
@@ -51,7 +62,7 @@ void without_schedule_clause(float *a, float *b, float *c, float *d) {
// CHECK-NEXT: br label %{{.+}}
}
// CHECK: [[LOOP1_END]]
-// CHECK: call void @__kmpc_for_static_fini([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]])
+// CHECK: call void @__kmpc_for_static_fini([[IDENT_T_TY]]* [[LOOP_LOC]], i32 [[GTID]])
// CHECK-NOT: __kmpc_barrier
// CHECK: ret void
}
@@ -60,7 +71,7 @@ void without_schedule_clause(float *a, float *b, float *c, float *d) {
void static_not_chunked(float *a, float *b, float *c, float *d) {
// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[IDENT_T_TY]]* [[DEFAULT_LOC:[@%].+]])
#pragma omp for schedule(static)
-// CHECK: call void @__kmpc_for_static_init_4([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], i32 34, i32* [[IS_LAST:%[^,]+]], i32* [[OMP_LB:%[^,]+]], i32* [[OMP_UB:%[^,]+]], i32* [[OMP_ST:%[^,]+]], i32 1, i32 1)
+// CHECK: call void @__kmpc_for_static_init_4([[IDENT_T_TY]]* [[LOOP_LOC]], i32 [[GTID]], i32 34, i32* [[IS_LAST:%[^,]+]], i32* [[OMP_LB:%[^,]+]], i32* [[OMP_UB:%[^,]+]], i32* [[OMP_ST:%[^,]+]], i32 1, i32 1)
// UB = min(UB, GlobalUB)
// CHECK-NEXT: [[UB:%.+]] = load i32, i32* [[OMP_UB]]
// CHECK-NEXT: [[UBCMP:%.+]] = icmp sgt i32 [[UB]], 4571423
@@ -92,7 +103,7 @@ void static_not_chunked(float *a, float *b, float *c, float *d) {
// CHECK-NEXT: br label %{{.+}}
}
// CHECK: [[LOOP1_END]]
-// CHECK: call void @__kmpc_for_static_fini([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]])
+// CHECK: call void @__kmpc_for_static_fini([[IDENT_T_TY]]* [[LOOP_LOC]], i32 [[GTID]])
// CHECK: call {{.+}} @__kmpc_barrier([[IDENT_T_TY]]* [[IMPLICIT_BARRIER_LOC]], i32 [[GTID]])
// CHECK: ret void
}
@@ -101,7 +112,7 @@ void static_not_chunked(float *a, float *b, float *c, float *d) {
void static_chunked(float *a, float *b, float *c, float *d) {
// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[IDENT_T_TY]]* [[DEFAULT_LOC:[@%].+]])
#pragma omp for schedule(monotonic: static, 5)
-// CHECK: call void @__kmpc_for_static_init_4u([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], i32 536870945, i32* [[IS_LAST:%[^,]+]], i32* [[OMP_LB:%[^,]+]], i32* [[OMP_UB:%[^,]+]], i32* [[OMP_ST:%[^,]+]], i32 1, i32 5)
+// CHECK: call void @__kmpc_for_static_init_4u([[IDENT_T_TY]]* [[LOOP_LOC]], i32 [[GTID]], i32 536870945, i32* [[IS_LAST:%[^,]+]], i32* [[OMP_LB:%[^,]+]], i32* [[OMP_UB:%[^,]+]], i32* [[OMP_ST:%[^,]+]], i32 1, i32 5)
// UB = min(UB, GlobalUB)
// CHECK: [[UB:%.+]] = load i32, i32* [[OMP_UB]]
// CHECK-NEXT: [[UBCMP:%.+]] = icmp ugt i32 [[UB]], 16908288
@@ -152,7 +163,7 @@ void static_chunked(float *a, float *b, float *c, float *d) {
// CHECK-NEXT: store i32 [[ADD_UB]], i32* [[OMP_UB]]
// CHECK: [[O_LOOP1_END]]
-// CHECK: call void @__kmpc_for_static_fini([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]])
+// CHECK: call void @__kmpc_for_static_fini([[IDENT_T_TY]]* [[LOOP_LOC]], i32 [[GTID]])
// CHECK: call {{.+}} @__kmpc_barrier([[IDENT_T_TY]]* [[IMPLICIT_BARRIER_LOC]], i32 [[GTID]])
// CHECK: ret void
}
@@ -329,8 +340,8 @@ void runtime(float *a, float *b, float *c, float *d) {
// CHECK-LABEL: test_precond
void test_precond() {
// CHECK: [[A_ADDR:%.+]] = alloca i8,
- // CHECK: [[CAP:%.+]] = alloca i8,
// CHECK: [[I_ADDR:%.+]] = alloca i8,
+ // CHECK: [[CAP:%.+]] = alloca i8,
char a = 0;
// CHECK: store i8 0,
// CHECK: store i32
@@ -375,7 +386,9 @@ void parallel_for(float *a) {
char i = 1, j = 2, k = 3;
// CHECK-LABEL: for_with_global_lcv
void for_with_global_lcv() {
+// CHECK: alloca i8,
// CHECK: [[I_ADDR:%.+]] = alloca i8,
+// CHECK: alloca i8,
// CHECK: [[J_ADDR:%.+]] = alloca i8,
// CHECK: call void @__kmpc_for_static_init_4(
diff --git a/test/OpenMP/for_firstprivate_codegen.cpp b/test/OpenMP/for_firstprivate_codegen.cpp
index 1e1d404b48db..88f54103ad69 100644
--- a/test/OpenMP/for_firstprivate_codegen.cpp
+++ b/test/OpenMP/for_firstprivate_codegen.cpp
@@ -81,8 +81,10 @@ int main() {
// LAMBDA: alloca i{{[0-9]+}},
// LAMBDA: alloca i{{[0-9]+}},
// LAMBDA: alloca i{{[0-9]+}},
+ // LAMBDA: alloca i{{[0-9]+}},
// LAMBDA: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}},
// LAMBDA: [[G1_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[G1_PRIVATE_REF:%.+]] = alloca i{{[0-9]+}}*,
// LAMBDA: [[SIVAR2_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}},
// LAMBDA: store i{{[0-9]+}}* [[SIVAR_REF]], i{{[0-9]+}}** %{{.+}},
@@ -91,20 +93,26 @@ int main() {
// LAMBDA: [[G_VAL:%.+]] = load volatile i{{[0-9]+}}, i{{[0-9]+}}* [[G]]
// LAMBDA: store i{{[0-9]+}} [[G_VAL]], i{{[0-9]+}}* [[G_PRIVATE_ADDR]]
+ // LAMBDA: store i{{[0-9]+}}* [[G1_PRIVATE_ADDR]], i{{[0-9]+}}** [[G1_PRIVATE_REF]],
// LAMBDA: [[SIVAR2_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR2_PRIVATE_ADDR_REF]]
// LAMBDA: store i{{[0-9]+}} [[SIVAR2_VAL]], i{{[0-9]+}}* [[SIVAR2_PRIVATE_ADDR]]
// LAMBDA-NOT: call void @__kmpc_barrier(
g = 1;
- g1 = 1;
- sivar = 2;
+ g1 = 2;
+ sivar = 3;
// LAMBDA: call void @__kmpc_for_static_init_4(
// LAMBDA: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_PRIVATE_ADDR]],
- // LAMBDA: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[SIVAR2_PRIVATE_ADDR]],
+ // LAMBDA: [[G1_PRIVATE_ADDR:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G1_PRIVATE_REF]],
+ // LAMBDA: store volatile i{{[0-9]+}} 2, i{{[0-9]+}}* [[G1_PRIVATE_ADDR]],
+ // LAMBDA: store i{{[0-9]+}} 3, i{{[0-9]+}}* [[SIVAR2_PRIVATE_ADDR]],
// LAMBDA: [[G_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
// LAMBDA: store i{{[0-9]+}}* [[G_PRIVATE_ADDR]], i{{[0-9]+}}** [[G_PRIVATE_ADDR_REF]]
- // LAMBDA: [[SIVAR_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // LAMBDA: [[G1_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // LAMBDA: [[G1_PRIVATE_ADDR:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G1_PRIVATE_REF]],
+ // LAMBDA: store i{{[0-9]+}}* [[G1_PRIVATE_ADDR]], i{{[0-9]+}}** [[G1_PRIVATE_ADDR_REF]]
+ // LAMBDA: [[SIVAR_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
// LAMBDA: store i{{[0-9]+}}* [[SIVAR2_PRIVATE_ADDR]], i{{[0-9]+}}** [[SIVAR_PRIVATE_ADDR_REF]]
// LAMBDA: call void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]])
// LAMBDA: call void @__kmpc_for_static_fini(
@@ -112,17 +120,20 @@ int main() {
[&]() {
// LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]])
// LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]],
- g = 2;
- g1 = 2;
- sivar = 4;
+ g = 4;
+ g1 = 5;
+ sivar = 6;
// LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]]
// LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
// LAMBDA: [[G_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G_PTR_REF]]
- // LAMBDA: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[G_REF]]
- // LAMBDA: [[SIVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // LAMBDA: store i{{[0-9]+}} 4, i{{[0-9]+}}* [[G_REF]]
+ // LAMBDA: [[G1_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // LAMBDA: [[G1_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G1_PTR_REF]]
+ // LAMBDA: store i{{[0-9]+}} 5, i{{[0-9]+}}* [[G1_REF]]
+ // LAMBDA: [[SIVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
// LAMBDA: [[SIVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SIVAR_PTR_REF]]
- // LAMBDA: store i{{[0-9]+}} 4, i{{[0-9]+}}* [[SIVAR_REF]]
+ // LAMBDA: store i{{[0-9]+}} 6, i{{[0-9]+}}* [[SIVAR_REF]]
}();
}
}();
@@ -144,6 +155,7 @@ int main() {
// BLOCKS: alloca i{{[0-9]+}},
// BLOCKS: alloca i{{[0-9]+}},
// BLOCKS: alloca i{{[0-9]+}},
+ // BLOCKS: alloca i{{[0-9]+}},
// BLOCKS: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}},
// BLOCKS: [[G1_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}},
// BLOCKS: [[SIVAR2_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}},
@@ -208,6 +220,7 @@ int main() {
// CHECK: alloca i{{[0-9]+}},
// CHECK: alloca i{{[0-9]+}},
// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]],
@@ -262,38 +275,30 @@ int main() {
// CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT]]()
// CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]],
// CHECK: [[TVAR:%.+]] = alloca i32,
-// CHECK: [[TVAR_CAST:%.+]] = alloca i64,
// CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR:@.+]]([[S_INT_TY]]* [[TEST]])
-// CHECK: [[TVAR_VAL:%.+]] = load i32, i32* [[TVAR]],
-// CHECK: [[TVAR_CONV:%.+]] = bitcast i64* [[TVAR_CAST]] to i32*
-// CHECK: store i32 [[TVAR_VAL]], i32* [[TVAR_CONV]],
-// CHECK: [[PVT_CASTVAL:%[^,]+]] = load i64, i64* [[TVAR_CAST]],
-// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 4, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, i64, [2 x i32]*, [2 x [[S_INT_TY]]]*, [[S_INT_TY]]*)* [[TMAIN_MICROTASK:@.+]] to void (i32*, i32*, ...)*), i64 [[PVT_CASTVAL]],
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 4, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, i32*, [2 x i32]*, [2 x [[S_INT_TY]]]*, [[S_INT_TY]]*)* [[TMAIN_MICROTASK:@.+]] to void (i32*, i32*, ...)*), i32* [[TVAR]],
// CHECK: call {{.*}} [[S_INT_TY_DESTR:@.+]]([[S_INT_TY]]*
// CHECK: ret
//
-// CHECK: define internal void [[TMAIN_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i64 {{.*}}%{{.+}}, [2 x i32]* dereferenceable(8) %{{.+}}, [2 x [[S_INT_TY]]]* dereferenceable(8) %{{.+}}, [[S_INT_TY]]* dereferenceable(4) %{{.+}})
+// CHECK: define internal void [[TMAIN_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i32* dereferenceable(4) %{{.+}}, [2 x i32]* dereferenceable(8) %{{.+}}, [2 x [[S_INT_TY]]]* dereferenceable(8) %{{.+}}, [[S_INT_TY]]* dereferenceable(4) %{{.+}})
// Skip temp vars for loop
-// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
// CHECK: alloca i{{[0-9]+}},
// CHECK: alloca i{{[0-9]+}},
// CHECK: alloca i{{[0-9]+}},
// CHECK: alloca i{{[0-9]+}},
// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_INT_TY]]],
// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_INT_TY]],
// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]],
-// CHECK: %{{.+}} = bitcast i64* [[T_VAR_PRIV]] to i32*
-// CHECK-NOT: load i{{[0-9]+}}*, i{{[0-9]+}}** %
+// CHECK: [[T_VAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** %
// CHECK: [[VEC_REF:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** %
// CHECK: [[S_ARR:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** %
// CHECK: [[VAR:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** %
-// firstprivate t_var(t_var)
-// CHECK-NOT: load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_REF]],
-
// firstprivate vec(vec)
// CHECK: [[VEC_DEST:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV]] to i8*
// CHECK: [[VEC_SRC:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_REF]] to i8*
diff --git a/test/OpenMP/for_lastprivate_codegen.cpp b/test/OpenMP/for_lastprivate_codegen.cpp
index f0fba042c58a..30a17eaf581a 100644
--- a/test/OpenMP/for_lastprivate_codegen.cpp
+++ b/test/OpenMP/for_lastprivate_codegen.cpp
@@ -213,6 +213,7 @@ int main() {
// LAMBDA: alloca i{{[0-9]+}},
// LAMBDA: alloca i{{[0-9]+}},
// LAMBDA: alloca i{{[0-9]+}},
+ // LAMBDA: alloca i{{[0-9]+}},
// LAMBDA: [[A_PRIV:%.+]] = alloca i{{[0-9]+}},
// LAMBDA: [[B_PRIV:%.+]] = alloca i{{[0-9]+}},
// LAMBDA: [[C_PRIV:%.+]] = alloca i{{[0-9]+}},
@@ -246,6 +247,7 @@ int main() {
// LAMBDA: alloca i{{[0-9]+}},
// LAMBDA: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, align 128
// LAMBDA: [[G1_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[G1_PRIVATE_REF:%.+]] = alloca i{{[0-9]+}}*,
// LAMBDA: [[SIVAR_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}},
// LAMBDA: [[SIVAR_PRIVATE_ADDR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** %{{.+}},
@@ -254,10 +256,15 @@ int main() {
// LAMBDA: call {{.+}} @__kmpc_for_static_init_4(%{{.+}}* @{{.+}}, i32 [[GTID]], i32 34, i32* [[IS_LAST_ADDR:%.+]], i32* %{{.+}}, i32* %{{.+}}, i32* %{{.+}}, i32 1, i32 1)
// LAMBDA: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_PRIVATE_ADDR]],
+ // LAMBDA: [[G1_PRIVATE_ADDR:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G1_PRIVATE_REF]],
+ // LAMBDA: store volatile i{{[0-9]+}} 1, i{{[0-9]+}}* [[G1_PRIVATE_ADDR]],
// LAMBDA: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]],
// LAMBDA: [[G_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
// LAMBDA: store i{{[0-9]+}}* [[G_PRIVATE_ADDR]], i{{[0-9]+}}** [[G_PRIVATE_ADDR_REF]]
- // LAMBDA: [[SIVAR_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // LAMBDA: [[G1_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // LAMBDA: [[G1_PRIVATE_ADDR:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G1_PRIVATE_REF]],
+ // LAMBDA: store i{{[0-9]+}}* [[G1_PRIVATE_ADDR]], i{{[0-9]+}}** [[G1_PRIVATE_ADDR_REF]]
+ // LAMBDA: [[SIVAR_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
// LAMBDA: store i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]], i{{[0-9]+}}** [[SIVAR_PRIVATE_ADDR_REF]]
// LAMBDA: call void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]])
// LAMBDA: call void @__kmpc_for_static_fini(%{{.+}}* @{{.+}}, i32 [[GTID]])
@@ -291,7 +298,10 @@ int main() {
// LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
// LAMBDA: [[G_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G_PTR_REF]]
// LAMBDA: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[G_REF]]
- // LAMBDA: [[SIVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // LAMBDA: [[G1_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // LAMBDA: [[G1_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G1_PTR_REF]]
+ // LAMBDA: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[G1_REF]]
+ // LAMBDA: [[SIVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
// LAMBDA: [[SIVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SIVAR_PTR_REF]]
// LAMBDA: store i{{[0-9]+}} 4, i{{[0-9]+}}* [[SIVAR_REF]]
}();
@@ -398,6 +408,7 @@ int main() {
// BLOCKS: alloca i{{[0-9]+}},
// BLOCKS: alloca i{{[0-9]+}},
// BLOCKS: alloca i{{[0-9]+}},
+// BLOCKS: alloca i{{[0-9]+}},
// BLOCKS: [[A_PRIV:%.+]] = alloca i{{[0-9]+}},
// BLOCKS: [[B_PRIV:%.+]] = alloca i{{[0-9]+}},
// BLOCKS: [[C_PRIV:%.+]] = alloca i{{[0-9]+}},
@@ -468,6 +479,7 @@ int main() {
// CHECK: alloca i{{[0-9]+}},
// CHECK: alloca i{{[0-9]+}},
// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]],
@@ -602,6 +614,7 @@ int main() {
// CHECK: ret void
// CHECK: define internal void [[MAIN_MICROTASK3]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}})
+// CHECK: alloca i8,
// CHECK: [[CNT_PRIV:%.+]] = alloca i8,
// CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_REF]]
@@ -664,6 +677,7 @@ int main() {
// CHECK: alloca i{{[0-9]+}},
// CHECK: alloca i{{[0-9]+}},
// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
// CHECK: [[A_PRIV:%.+]] = alloca i{{[0-9]+}},
// CHECK: [[B_PRIV:%.+]] = alloca i{{[0-9]+}},
// CHECK: [[C_PRIV:%.+]] = alloca i{{[0-9]+}},
diff --git a/test/OpenMP/for_lastprivate_messages.cpp b/test/OpenMP/for_lastprivate_messages.cpp
index 79912b6efbca..13ef35e925a7 100644
--- a/test/OpenMP/for_lastprivate_messages.cpp
+++ b/test/OpenMP/for_lastprivate_messages.cpp
@@ -18,9 +18,9 @@ public:
const S2 &operator =(const S2&) const;
S2 &operator =(const S2&);
static float S2s; // expected-note {{static data member is predetermined as shared}}
- static const float S2sc;
+ static const float S2sc; // expected-note {{static data member is predetermined as shared}}
};
-const float S2::S2sc = 0; // expected-note {{static data member is predetermined as shared}}
+const float S2::S2sc = 0;
const S2 b;
const S2 ba[5];
class S3 {
diff --git a/test/OpenMP/for_linear_codegen.cpp b/test/OpenMP/for_linear_codegen.cpp
index 16a67c0b91d2..54cdf8a4cb33 100644
--- a/test/OpenMP/for_linear_codegen.cpp
+++ b/test/OpenMP/for_linear_codegen.cpp
@@ -157,6 +157,7 @@ int main() {
// LAMBDA: alloca i{{[0-9]+}},
// LAMBDA: alloca i{{[0-9]+}},
// LAMBDA: alloca i{{[0-9]+}},
+ // LAMBDA: alloca i{{[0-9]+}},
// LAMBDA: [[A_PRIV:%.+]] = alloca i{{[0-9]+}},
// LAMBDA: [[B_PRIV:%.+]] = alloca i{{[0-9]+}},
// LAMBDA: [[C_PRIV:%.+]] = alloca i{{[0-9]+}},
@@ -181,6 +182,7 @@ int main() {
// LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}})
// LAMBDA: alloca i{{[0-9]+}},
+ // LAMBDA: alloca i{{[0-9]+}},
// LAMBDA: [[G_START_ADDR:%.+]] = alloca i{{[0-9]+}},
// LAMBDA: alloca i{{[0-9]+}},
// LAMBDA: alloca i{{[0-9]+}},
@@ -233,6 +235,7 @@ int main() {
for (int i = 0; i < 2; ++i) {
// BLOCKS: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}})
// BLOCKS: alloca i{{[0-9]+}},
+ // BLOCKS: alloca i{{[0-9]+}},
// BLOCKS: [[G_START_ADDR:%.+]] = alloca i{{[0-9]+}},
// BLOCKS: alloca i{{[0-9]+}},
// BLOCKS: alloca i{{[0-9]+}},
@@ -307,6 +310,7 @@ int main() {
// BLOCKS: alloca i{{[0-9]+}},
// BLOCKS: alloca i{{[0-9]+}},
// BLOCKS: alloca i{{[0-9]+}},
+// BLOCKS: alloca i{{[0-9]+}},
// BLOCKS: [[A_PRIV:%.+]] = alloca i{{[0-9]+}},
// BLOCKS: [[B_PRIV:%.+]] = alloca i{{[0-9]+}},
// BLOCKS: [[C_PRIV:%.+]] = alloca i{{[0-9]+}},
@@ -351,13 +355,13 @@ int main() {
// CHECK: define internal void [[MAIN_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, float** dereferenceable(8) %{{.+}}, i64* dereferenceable(8) %{{.+}})
// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
// CHECK: [[PVAR_START:%.+]] = alloca float*,
// CHECK: [[LVAR_START:%.+]] = alloca i64,
// CHECK: alloca i{{[0-9]+}},
// CHECK: alloca i{{[0-9]+}},
// CHECK: alloca i{{[0-9]+}},
// CHECK: alloca i{{[0-9]+}},
-// CHECK: alloca i{{[0-9]+}},
// CHECK: [[PVAR_PRIV:%.+]] = alloca float*,
// CHECK: [[LVAR_PRIV:%.+]] = alloca i64,
// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_REF:%.+]]
@@ -419,6 +423,7 @@ int main() {
// CHECK: alloca i{{[0-9]+}},
// CHECK: alloca i{{[0-9]+}},
// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
// CHECK: [[A_PRIV:%.+]] = alloca i{{[0-9]+}},
// CHECK: [[B_PRIV:%.+]] = alloca i{{[0-9]+}},
// CHECK: [[C_PRIV:%.+]] = alloca i{{[0-9]+}},
@@ -446,13 +451,13 @@ int main() {
// CHECK: define internal void [[TMAIN_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i32** dereferenceable(8) %{{.+}}, i32* dereferenceable(4) %{{.+}})
// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
// CHECK: [[PVAR_START:%.+]] = alloca i32*,
// CHECK: [[LVAR_START:%.+]] = alloca i32,
// CHECK: alloca i{{[0-9]+}},
// CHECK: alloca i{{[0-9]+}},
// CHECK: alloca i{{[0-9]+}},
// CHECK: alloca i{{[0-9]+}},
-// CHECK: alloca i{{[0-9]+}},
// CHECK: [[PVAR_PRIV:%.+]] = alloca i32*,
// CHECK: [[LVAR_PRIV:%.+]] = alloca i32,
// CHECK: [[LVAR_PRIV_REF:%.+]] = alloca i32*,
diff --git a/test/OpenMP/for_private_codegen.cpp b/test/OpenMP/for_private_codegen.cpp
index 5bad8d00688d..f1416d75b64b 100644
--- a/test/OpenMP/for_private_codegen.cpp
+++ b/test/OpenMP/for_private_codegen.cpp
@@ -52,6 +52,8 @@ int main() {
for (int i = 0; i < 2; ++i) {
// LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}})
// LAMBDA: [[G_PRIVATE_ADDR:%.+]] = alloca double,
+ // LAMBDA: [[G1_PRIVATE_ADDR:%.+]] = alloca double,
+ // LAMBDA: [[G1_PRIVATE_REF:%.+]] = alloca double*,
// LAMBDA: [[SVAR_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}},
// LAMBDA: [[SFVAR_PRIVATE_ADDR:%.+]] = alloca float,
g = 1;
@@ -60,13 +62,18 @@ int main() {
sfvar = 4.0;
// LAMBDA: call {{.*}}void @__kmpc_for_static_init_4(
// LAMBDA: store double 1.0{{.+}}, double* [[G_PRIVATE_ADDR]],
+ // LAMBDA: [[G1_PRIVATE_ADDR:%.+]] = load double*, double** [[G1_PRIVATE_REF]],
+ // LAMBDA: store volatile double 1.0{{.+}}, double* [[G1_PRIVATE_ADDR]],
// LAMBDA: store i{{[0-9]+}} 3, i{{[0-9]+}}* [[SVAR_PRIVATE_ADDR]],
// LAMBDA: store float 4.0{{.+}}, float* [[SFVAR_PRIVATE_ADDR]],
// LAMBDA: [[G_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
// LAMBDA: store double* [[G_PRIVATE_ADDR]], double** [[G_PRIVATE_ADDR_REF]]
- // LAMBDA: [[SVAR_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // LAMBDA: [[G1_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // LAMBDA: [[G1_PRIVATE_ADDR:%.+]] = load double*, double** [[G1_PRIVATE_REF]],
+ // LAMBDA: store double* [[G1_PRIVATE_ADDR]], double** [[G1_PRIVATE_ADDR_REF]]
+ // LAMBDA: [[SVAR_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
// LAMBDA: store i{{[0-9]+}}* [[SVAR_PRIVATE_ADDR]], i{{[0-9]+}}** [[SVAR_PRIVATE_ADDR_REF]]
- // LAMBDA: [[SFVAR_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+ // LAMBDA: [[SFVAR_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 3
// LAMBDA: store float* [[SFVAR_PRIVATE_ADDR]], float** [[SFVAR_PRIVATE_ADDR_REF]]
// LAMBDA: call{{.*}} void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]])
// LAMBDA: call {{.*}}void @__kmpc_for_static_fini(
@@ -81,10 +88,13 @@ int main() {
// LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
// LAMBDA: [[G_REF:%.+]] = load double*, double** [[G_PTR_REF]]
// LAMBDA: store double 2.0{{.+}}, double* [[G_REF]]
- // LAMBDA: [[SVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // LAMBDA: [[G1_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // LAMBDA: [[G1_REF:%.+]] = load double*, double** [[G1_PTR_REF]]
+ // LAMBDA: store double 2.0{{.+}}, double* [[G1_REF]]
+ // LAMBDA: [[SVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
// LAMBDA: [[SVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SVAR_PTR_REF]]
// LAMBDA: store i{{[0-9]+}} 4, i{{[0-9]+}}* [[SVAR_REF]]
- // LAMBDA: [[SFVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+ // LAMBDA: [[SFVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 3
// LAMBDA: [[SFVAR_REF:%.+]] = load float*, float** [[SFVAR_PTR_REF]]
// LAMBDA: store float 8.0{{.+}}, float* [[SFVAR_REF]]
}();
diff --git a/test/OpenMP/for_reduction_codegen.cpp b/test/OpenMP/for_reduction_codegen.cpp
index d5afae990bf4..cef457333062 100644
--- a/test/OpenMP/for_reduction_codegen.cpp
+++ b/test/OpenMP/for_reduction_codegen.cpp
@@ -27,7 +27,7 @@ struct S {
// CHECK-DAG: [[REDUCTION_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 18, i32 0, i32 0, i8*
// CHECK-DAG: [[REDUCTION_LOCK:@.+]] = common global [8 x i32] zeroinitializer
-template <typename T>
+template <typename T, int length>
T tmain() {
T t;
S<T> test;
@@ -36,6 +36,7 @@ T tmain() {
S<T> s_arr[] = {1, 2};
S<T> &var = test;
S<T> var1;
+ S<T> arr[length];
#pragma omp parallel
#pragma omp for reduction(+:t_var) reduction(&:var) reduction(&& : var1) reduction(min: t_var1) nowait
for (int i = 0; i < 2; ++i) {
@@ -48,6 +49,12 @@ T tmain() {
vec[i] = t_var;
s_arr[i] = var;
}
+#pragma omp parallel
+#pragma omp for reduction(+ : arr[1:length-2])
+ for (int i = 0; i < 2; ++i) {
+ vec[i] = t_var;
+ s_arr[i] = var;
+ }
return T();
}
@@ -180,12 +187,12 @@ int main() {
S<float> test;
float t_var = 0, t_var1;
int vec[] = {1, 2};
- S<float> s_arr[] = {1, 2};
+ S<float> s_arr[] = {1, 2, 3, 4};
S<float> &var = test;
S<float> var1, arrs[10][4];
S<float> **var2 = foo();
- S<float> vvar2[2];
- S<float> (&var3)[2] = s_arr;
+ S<float> vvar2[5];
+ S<float> (&var3)[4] = s_arr;
#pragma omp parallel
#pragma omp for reduction(+:t_var) reduction(&:var) reduction(&& : var1) reduction(min: t_var1)
for (int i = 0; i < 2; ++i) {
@@ -200,11 +207,28 @@ int main() {
#pragma omp for reduction(+:arr) reduction(&:arrs)
for (int i = 0; i < 10; ++i)
++arr[1][i];
+ // arr is a VLA, but the array section has constant length so we can generate a constant sized array!
+#pragma omp parallel
+#pragma omp for reduction(+:arr[1][0:2])
+ for (int i = 0; i < 10; ++i)
+ ++arr[1][i];
#pragma omp parallel
#pragma omp for reduction(& : var2[0 : 5][1 : 6])
for (int i = 0; i < 10; ++i)
;
#pragma omp parallel
+#pragma omp for reduction(& : var2[1][1 : 6])
+ for (int i = 0; i < 10; ++i)
+ ;
+#pragma omp parallel
+#pragma omp for reduction(& : var2[1 : 1][1 : 6])
+ for (int i = 0; i < 10; ++i)
+ ;
+#pragma omp parallel
+#pragma omp for reduction(& : var2[1 : 1][1])
+ for (int i = 0; i < 10; ++i)
+ ;
+#pragma omp parallel
#pragma omp for reduction(& : vvar2[0 : 5])
for (int i = 0; i < 10; ++i)
;
@@ -213,28 +237,43 @@ int main() {
for (int i = 0; i < 10; ++i)
;
#pragma omp parallel
+#pragma omp for reduction(& : var3[ : 2])
+ for (int i = 0; i < 10; ++i)
+ ;
+ // TODO: The compiler should also be able to generate a constant sized array in this case!
+#pragma omp parallel
+#pragma omp for reduction(& : var3[2 : ])
+ for (int i = 0; i < 10; ++i)
+ ;
+#pragma omp parallel
#pragma omp for reduction(& : var3)
for (int i = 0; i < 10; ++i)
;
- return tmain<int>();
+ return tmain<int, 42>();
#endif
}
// CHECK: define {{.*}}i{{[0-9]+}} @main()
// CHECK: [[TEST:%.+]] = alloca [[S_FLOAT_TY]],
// CHECK: call {{.*}} [[S_FLOAT_TY_CONSTR:@.+]]([[S_FLOAT_TY]]* [[TEST]])
-// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 6, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, float*, [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]*, float*, [2 x i32]*, [2 x [[S_FLOAT_TY]]]*)* [[MAIN_MICROTASK:@.+]] to void
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 6, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, float*, [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]*, float*, [2 x i32]*, [4 x [[S_FLOAT_TY]]]*)* [[MAIN_MICROTASK:@.+]] to void
// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 5, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, i64, i64, i32*, [2 x i32]*, [10 x [4 x [[S_FLOAT_TY]]]]*)* [[MAIN_MICROTASK1:@.+]] to void
// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 4, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, i64, i64, i32*, [10 x [4 x [[S_FLOAT_TY]]]]*)* [[MAIN_MICROTASK2:@.+]] to void
-// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[S_FLOAT_TY]]***)* [[MAIN_MICROTASK3:@.+]] to void
-// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [2 x [[S_FLOAT_TY]]]*)* [[MAIN_MICROTASK4:@.+]] to void
-// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [2 x [[S_FLOAT_TY]]]*)* [[MAIN_MICROTASK5:@.+]] to void
-// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [2 x [[S_FLOAT_TY]]]*)* [[MAIN_MICROTASK6:@.+]] to void
-// CHECK: = call {{.*}}i{{.+}} [[TMAIN_INT:@.+]]()
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 3, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, i64, i64, i32*)* [[MAIN_MICROTASK3:@.+]] to void
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[S_FLOAT_TY]]***)* [[MAIN_MICROTASK4:@.+]] to void
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[S_FLOAT_TY]]***)* [[MAIN_MICROTASK5:@.+]] to void
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[S_FLOAT_TY]]***)* [[MAIN_MICROTASK6:@.+]] to void
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[S_FLOAT_TY]]***)* [[MAIN_MICROTASK7:@.+]] to void
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [5 x [[S_FLOAT_TY]]]*)* [[MAIN_MICROTASK8:@.+]] to void
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [4 x [[S_FLOAT_TY]]]*)* [[MAIN_MICROTASK9:@.+]] to void
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [4 x [[S_FLOAT_TY]]]*)* [[MAIN_MICROTASK10:@.+]] to void
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [4 x [[S_FLOAT_TY]]]*)* [[MAIN_MICROTASK11:@.+]] to void
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [4 x [[S_FLOAT_TY]]]*)* [[MAIN_MICROTASK12:@.+]] to void
+// CHECK: = call {{.*}}i{{.+}} [[TMAIN_INT_42:@.+]]()
// CHECK: call {{.*}} [[S_FLOAT_TY_DESTR:@.+]]([[S_FLOAT_TY]]*
// CHECK: ret
//
-// CHECK: define internal void [[MAIN_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, float* dereferenceable(4) %{{.+}}, [[S_FLOAT_TY]]* dereferenceable(4) %{{.+}}, [[S_FLOAT_TY]]* dereferenceable(4) %{{.+}}, float* dereferenceable(4) %{{.+}}, [2 x i32]* dereferenceable(8) %vec, [2 x [[S_FLOAT_TY]]]* dereferenceable(8) %{{.+}})
+// CHECK: define internal void [[MAIN_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, float* dereferenceable(4) %{{.+}}, [[S_FLOAT_TY]]* dereferenceable(4) %{{.+}}, [[S_FLOAT_TY]]* dereferenceable(4) %{{.+}}, float* dereferenceable(4) %{{.+}}, [2 x i32]* dereferenceable(8) %vec, [4 x [[S_FLOAT_TY]]]* dereferenceable(16) %{{.+}})
// CHECK: [[T_VAR_PRIV:%.+]] = alloca float,
// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]],
// CHECK: [[VAR1_PRIV:%.+]] = alloca [[S_FLOAT_TY]],
@@ -491,7 +530,7 @@ int main() {
// CHECK: store float [[UP]], float* [[T_VAR1_LHS]],
// CHECK: ret void
-// CHECK: define internal void [[MAIN_MICROTASK1]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i64 %{{.+}}, i64 %{{.+}}, i32* %{{.+}}, [2 x i32]* dereferenceable(8) %{{.+}}, [10 x [4 x [[S_FLOAT_TY]]]]* dereferenceable(160) %{{.+}})
+// CHECK: define internal void [[MAIN_MICROTASK1]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i64 %{{.+}}, i64 %{{.+}}, i32* {{.+}} %{{.+}}, [2 x i32]* dereferenceable(8) %{{.+}}, [10 x [4 x [[S_FLOAT_TY]]]]* dereferenceable(160) %{{.+}})
// Reduction list for runtime.
// CHECK: [[RED_LIST:%.+]] = alloca [4 x i8*],
@@ -692,7 +731,7 @@ int main() {
// CHECK: ret void
-// CHECK: define internal void [[MAIN_MICROTASK2]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i64 %{{.+}}, i64 %{{.+}}, i32* %{{.+}}, [10 x [4 x [[S_FLOAT_TY]]]]* dereferenceable(160) %{{.+}})
+// CHECK: define internal void [[MAIN_MICROTASK2]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i64 %{{.+}}, i64 %{{.+}}, i32* {{.+}} %{{.+}}, [10 x [4 x [[S_FLOAT_TY]]]]* dereferenceable(160) %{{.+}})
// CHECK: [[ARRS_PRIV:%.+]] = alloca [10 x [4 x [[S_FLOAT_TY]]]],
@@ -882,7 +921,35 @@ int main() {
// CHECK: ret void
-// CHECK: define internal void [[MAIN_MICROTASK3]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[S_FLOAT_TY]]*** dereferenceable(8) %{{.+}})
+// CHECK: define internal void [[MAIN_MICROTASK3]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i32* {{.*}} %{{.+}})
+
+// CHECK: [[VLA1_ORIG_ADDR:%.+]] = alloca i64
+// CHECK: [[VLA2_ORIG_ADDR:%.+]] = alloca i64
+// CHECK: [[ARR_ORIG_ADDR:%.+]] = alloca i32*,
+// CHECK: [[ARR_PRIV:%.+]] = alloca [1 x [2 x i32]],
+
+// Reduction list for runtime.
+// CHECK: [[RED_LIST:%.+]] = alloca [1 x i8*],
+
+// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]],
+// CHECK: [[VLA1:%.+]] = load i64, i64* [[VLA1_ORIG_ADDR]]
+// CHECK: [[VLA2:%.+]] = load i64, i64* [[VLA2_ORIG_ADDR]]
+// CHECK: [[ARR_ORIG:%.+]] = load i32*, i32** [[ARR_ORIG_ADDR]],
+
+// CHECK: [[LOW_OFFSET:%.+]] = mul nsw i64 1, [[VLA2]]
+// CHECK: [[ARRIDX:%.+]] = getelementptr inbounds i32, i32* [[ARR_ORIG]], i64 [[LOW_OFFSET]]
+// CHECK: [[LOW:%.+]] = getelementptr inbounds i32, i32* [[ARRIDX]], i64 0
+
+// CHECK: [[START:%.+]] = ptrtoint i32* [[ARR_ORIG]] to i64
+// CHECK: [[LOW_BOUND:%.+]] = ptrtoint i32* [[LOW]] to i64
+// CHECK: [[OFFSET_BYTES:%.+]] = sub i64 [[START]], [[LOW_BOUND]]
+// CHECK: [[OFFSET:%.+]] = sdiv exact i64 [[OFFSET_BYTES]], ptrtoint (i32* getelementptr (i32, i32* null, i32 1) to i64)
+// CHECK: [[ARR_PRIV_PTR:%.+]] = bitcast [1 x [2 x i32]]* [[ARR_PRIV]] to i32*
+// CHECK: [[ARR_PRIV:%.+]] = getelementptr i32, i32* [[ARR_PRIV_PTR]], i64 [[OFFSET]]
+
+// CHECK: ret void
+
+// CHECK: define internal void [[MAIN_MICROTASK4]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[S_FLOAT_TY]]*** dereferenceable(8) %{{.+}})
// CHECK: [[VAR2_ORIG_ADDR:%.+]] = alloca [[S_FLOAT_TY]]***,
@@ -910,44 +977,186 @@ int main() {
// CHECK: store [[S_FLOAT_TY]]* [[PSEUDO_VAR2_PRIV]], [[S_FLOAT_TY]]** [[REF]]
// CHECK: ret void
-// CHECK: define internal void [[MAIN_MICROTASK4]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [2 x [[S_FLOAT_TY]]]* dereferenceable(8) %{{.+}})
+// CHECK: define internal void [[MAIN_MICROTASK5]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[S_FLOAT_TY]]*** dereferenceable(8) %{{.+}})
-// CHECK: [[VVAR2_ORIG_ADDR:%.+]] = alloca [2 x [[S_FLOAT_TY]]]*,
+// CHECK: [[VAR2_ORIG_ADDR:%.+]] = alloca [[S_FLOAT_TY]]***,
+// CHECK: [[VAR2_PRIV:%.+]] = alloca [1 x [6 x [[S_FLOAT_TY]]]],
// Reduction list for runtime.
-// CHECK: [[RED_LIST:%.+]] = alloca [2 x i8*],
+// CHECK: [[RED_LIST:%.+]] = alloca [1 x i8*],
// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]],
-// CHECK: [[VVAR2_ORIG:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[VVAR2_ORIG_ADDR]],
+// CHECK: [[VAR2_ORIG:%.+]] = load [[S_FLOAT_TY]]***, [[S_FLOAT_TY]]**** [[VAR2_ORIG_ADDR]],
-// CHECK: [[LOW:%.+]] = getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[VVAR2_ORIG]], i64 0, i64 0
-// CHECK: [[LAST:%.+]] = ptrtoint [[S_FLOAT_TY]]* %{{.+}} to i64
-// CHECK: [[FIRST:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[LOW]] to i64
-// CHECK: [[BYTE_DIF:%.+]] = sub i64 [[LAST]], [[FIRST]]
-// CHECK: [[DIF:%.+]] = sdiv exact i64 [[BYTE_DIF]], ptrtoint (float* getelementptr (float, float* null, i32 1) to i64)
-// CHECK: [[SIZE:%.+]] = add nuw i64 [[DIF]], 1
-// CHECK: call i8* @llvm.stacksave()
-// CHECK: [[VVAR2_PRIV:%.+]] = alloca [[S_FLOAT_TY]], i64 [[SIZE]],
-// CHECK: [[ORIG_START:%.+]] = bitcast [2 x [[S_FLOAT_TY]]]* [[VVAR2_ORIG]] to [[S_FLOAT_TY]]*
+// CHECK: [[LD:%.+]] = load [[S_FLOAT_TY]]**, [[S_FLOAT_TY]]*** [[VAR2_ORIG]],
+// CHECK: [[ARRIDX:%.+]] = getelementptr inbounds [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[LD]], i64 1
+// CHECK: [[LD:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[ARRIDX]],
+// CHECK: [[LOW:%.+]] = getelementptr inbounds [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[LD]], i64 1
+// CHECK: [[LD:%.+]] = load [[S_FLOAT_TY]]**, [[S_FLOAT_TY]]*** [[VAR2_ORIG]],
+
+// CHECK: [[LD:%.+]] = load [[S_FLOAT_TY]]**, [[S_FLOAT_TY]]*** [[VAR2_ORIG]],
+// CHECK: [[ORIG_START:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[LD]],
// CHECK: [[START:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[ORIG_START]] to i64
// CHECK: [[LOW_BOUND:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[LOW]] to i64
// CHECK: [[OFFSET_BYTES:%.+]] = sub i64 [[START]], [[LOW_BOUND]]
// CHECK: [[OFFSET:%.+]] = sdiv exact i64 [[OFFSET_BYTES]], ptrtoint (float* getelementptr (float, float* null, i32 1) to i64)
-// CHECK: [[PSEUDO_VVAR2_PRIV:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[VVAR2_PRIV]], i64 [[OFFSET]]
-// CHECK: [[VVAR2_PRIV:%.+]] = bitcast [[S_FLOAT_TY]]* [[PSEUDO_VVAR2_PRIV]] to [2 x [[S_FLOAT_TY]]]*
+// CHECK: [[VAR2_PRIV_PTR:%.+]] = bitcast [1 x [6 x [[S_FLOAT_TY]]]]* [[VAR2_PRIV]] to [[S_FLOAT_TY]]*
+// CHECK: [[VAR2_PRIV:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[VAR2_PRIV_PTR]], i64 [[OFFSET]]
+// CHECK: store [[S_FLOAT_TY]]** [[REF:.+]], [[S_FLOAT_TY]]*** %
+// CHECK: store [[S_FLOAT_TY]]* [[VAR2_PRIV]], [[S_FLOAT_TY]]** [[REF]]
// CHECK: ret void
-// CHECK: define internal void [[MAIN_MICROTASK5]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [2 x [[S_FLOAT_TY]]]* dereferenceable(8) %{{.+}})
+// CHECK: define internal void [[MAIN_MICROTASK6]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[S_FLOAT_TY]]*** dereferenceable(8) %{{.+}})
-// CHECK: [[VAR3_ORIG_ADDR:%.+]] = alloca [2 x [[S_FLOAT_TY]]]*,
+// CHECK: [[VAR2_ORIG_ADDR:%.+]] = alloca [[S_FLOAT_TY]]***,
+// CHECK: [[VAR2_PRIV:%.+]] = alloca [1 x [6 x [[S_FLOAT_TY]]]],
// Reduction list for runtime.
-// CHECK: [[RED_LIST:%.+]] = alloca [2 x i8*],
+// CHECK: [[RED_LIST:%.+]] = alloca [1 x i8*],
// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]],
+// CHECK: [[VAR2_ORIG:%.+]] = load [[S_FLOAT_TY]]***, [[S_FLOAT_TY]]**** [[VAR2_ORIG_ADDR]],
+
+// CHECK: [[LD:%.+]] = load [[S_FLOAT_TY]]**, [[S_FLOAT_TY]]*** [[VAR2_ORIG]],
+// CHECK: [[ARRIDX:%.+]] = getelementptr inbounds [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[LD]], i64 1
+// CHECK: [[LD:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[ARRIDX]],
+// CHECK: [[LOW:%.+]] = getelementptr inbounds [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[LD]], i64 1
+// CHECK: [[LD:%.+]] = load [[S_FLOAT_TY]]**, [[S_FLOAT_TY]]*** [[VAR2_ORIG]],
+
+// CHECK: [[LD:%.+]] = load [[S_FLOAT_TY]]**, [[S_FLOAT_TY]]*** [[VAR2_ORIG]],
+// CHECK: [[ORIG_START:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[LD]],
+// CHECK: [[START:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[ORIG_START]] to i64
+// CHECK: [[LOW_BOUND:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[LOW]] to i64
+// CHECK: [[OFFSET_BYTES:%.+]] = sub i64 [[START]], [[LOW_BOUND]]
+// CHECK: [[OFFSET:%.+]] = sdiv exact i64 [[OFFSET_BYTES]], ptrtoint (float* getelementptr (float, float* null, i32 1) to i64)
+// CHECK: [[VAR2_PRIV_PTR:%.+]] = bitcast [1 x [6 x [[S_FLOAT_TY]]]]* [[VAR2_PRIV]] to [[S_FLOAT_TY]]*
+// CHECK: [[VAR2_PRIV:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[VAR2_PRIV_PTR]], i64 [[OFFSET]]
+// CHECK: store [[S_FLOAT_TY]]** [[REF:.+]], [[S_FLOAT_TY]]*** %
+// CHECK: store [[S_FLOAT_TY]]* [[VAR2_PRIV]], [[S_FLOAT_TY]]** [[REF]]
+// CHECK: ret void
+
+// CHECK: define internal void [[MAIN_MICROTASK7]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[S_FLOAT_TY]]*** dereferenceable(8) %{{.+}})
+
+// CHECK: [[VAR2_ORIG_ADDR:%.+]] = alloca [[S_FLOAT_TY]]***,
+// CHECK: [[VAR2_PRIV:%.+]] = alloca [[S_FLOAT_TY]],
+
+// Reduction list for runtime.
+// CHECK: [[RED_LIST:%.+]] = alloca [1 x i8*],
+
+// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]],
+// CHECK: [[VAR2_ORIG:%.+]] = load [[S_FLOAT_TY]]***, [[S_FLOAT_TY]]**** [[VAR2_ORIG_ADDR]],
+
+// CHECK: [[LD:%.+]] = load [[S_FLOAT_TY]]**, [[S_FLOAT_TY]]*** [[VAR2_ORIG]],
+// CHECK: [[ARRIDX:%.+]] = getelementptr inbounds [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[LD]], i64 1
+// CHECK: [[LD:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[ARRIDX]],
+// CHECK: [[LOW:%.+]] = getelementptr inbounds [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[LD]], i64 1
+// CHECK: [[LD:%.+]] = load [[S_FLOAT_TY]]**, [[S_FLOAT_TY]]*** [[VAR2_ORIG]],
+
+// CHECK: [[LD:%.+]] = load [[S_FLOAT_TY]]**, [[S_FLOAT_TY]]*** [[VAR2_ORIG]],
+// CHECK: [[ORIG_START:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[LD]],
+// CHECK: [[START:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[ORIG_START]] to i64
+// CHECK: [[LOW_BOUND:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[LOW]] to i64
+// CHECK: [[OFFSET_BYTES:%.+]] = sub i64 [[START]], [[LOW_BOUND]]
+// CHECK: [[OFFSET:%.+]] = sdiv exact i64 [[OFFSET_BYTES]], ptrtoint (float* getelementptr (float, float* null, i32 1) to i64)
+// CHECK: [[PSEUDO_VAR2_PRIV:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[VAR2_PRIV]], i64 [[OFFSET]]
+// CHECK: store [[S_FLOAT_TY]]** [[REF:.+]], [[S_FLOAT_TY]]*** %
+// CHECK: store [[S_FLOAT_TY]]* [[PSEUDO_VAR2_PRIV]], [[S_FLOAT_TY]]** [[REF]]
+// CHECK: ret void
+
+// CHECK: define internal void [[MAIN_MICROTASK8]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [5 x [[S_FLOAT_TY]]]* dereferenceable(20) %{{.+}})
+
+// CHECK: [[VVAR2_ORIG_ADDR:%.+]] = alloca [5 x [[S_FLOAT_TY]]]*,
+// CHECK: [[VVAR2_PRIV:%.+]] = alloca [5 x [[S_FLOAT_TY]]],
+
+// Reduction list for runtime.
+// CHECK: [[RED_LIST:%.+]] = alloca [1 x i8*],
+
+// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]],
+// CHECK: [[VVAR2_ORIG:%.+]] = load [5 x [[S_FLOAT_TY]]]*, [5 x [[S_FLOAT_TY]]]** [[VVAR2_ORIG_ADDR]],
+
+// CHECK: [[LOW:%.+]] = getelementptr inbounds [5 x [[S_FLOAT_TY]]], [5 x [[S_FLOAT_TY]]]* [[VVAR2_ORIG]], i64 0, i64 0
+// CHECK: [[ORIG_START:%.+]] = bitcast [5 x [[S_FLOAT_TY]]]* [[VVAR2_ORIG]] to [[S_FLOAT_TY]]*
+// CHECK: [[START:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[ORIG_START]] to i64
+// CHECK: [[LOW_BOUND:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[LOW]] to i64
+// CHECK: [[OFFSET_BYTES:%.+]] = sub i64 [[START]], [[LOW_BOUND]]
+// CHECK: [[OFFSET:%.+]] = sdiv exact i64 [[OFFSET_BYTES]], ptrtoint (float* getelementptr (float, float* null, i32 1) to i64)
+// CHECK: [[VVAR2_PRIV_PTR:%.+]] = bitcast [5 x [[S_FLOAT_TY]]]* [[VVAR2_PRIV]] to [[S_FLOAT_TY]]*
+// CHECK: [[VVAR2_PRIV:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[VVAR2_PRIV_PTR]], i64 [[OFFSET]]
+// CHECK: ret void
+
+// CHECK: define internal void [[MAIN_MICROTASK9]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [4 x [[S_FLOAT_TY]]]* dereferenceable(16) %{{.+}})
+
+// CHECK: [[VAR3_ORIG_ADDR:%.+]] = alloca [4 x [[S_FLOAT_TY]]]*,
+// CHECK: [[VAR3_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]],
+
+// Reduction list for runtime.
+// CHECK: [[RED_LIST:%.+]] = alloca [1 x i8*],
+
+// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]],
+
+// CHECK: [[VAR3_ORIG:%.+]] = load [4 x [[S_FLOAT_TY]]]*, [4 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]],
+// CHECK: store [4 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]], [4 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR:%.+]],
+// CHECK: [[VAR3_ORIG:%.+]] = load [4 x [[S_FLOAT_TY]]]*, [4 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]],
+
+// CHECK: [[LOW:%.+]] = getelementptr inbounds [4 x [[S_FLOAT_TY]]], [4 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]], i64 0, i64 1
+// CHECK: [[VAR3_ORIG:%.+]] = load [4 x [[S_FLOAT_TY]]]*, [4 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]],
+
+// CHECK: [[VAR3_ORIG:%.+]] = load [4 x [[S_FLOAT_TY]]]*, [4 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]],
+// CHECK: [[ORIG_START:%.+]] = bitcast [4 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]] to [[S_FLOAT_TY]]*
+// CHECK: [[START:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[ORIG_START]] to i64
+// CHECK: [[LOW_BOUND:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[LOW]] to i64
+// CHECK: [[OFFSET_BYTES:%.+]] = sub i64 [[START]], [[LOW_BOUND]]
+// CHECK: [[OFFSET:%.+]] = sdiv exact i64 [[OFFSET_BYTES]], ptrtoint (float* getelementptr (float, float* null, i32 1) to i64)
+// CHECK: [[VAR3_PRIV_PTR:%.+]] = bitcast [2 x [[S_FLOAT_TY]]]* [[VAR3_PRIV]] to [[S_FLOAT_TY]]*
+// CHECK: [[PSEUDO_VAR3_PRIV:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[VAR3_PRIV_PTR]], i64 [[OFFSET]]
+// CHECK: [[VAR3_PRIV:%.+]] = bitcast [[S_FLOAT_TY]]* [[PSEUDO_VAR3_PRIV]] to [4 x [[S_FLOAT_TY]]]*
+
+// CHECK: store [4 x [[S_FLOAT_TY]]]* [[VAR3_PRIV]], [4 x [[S_FLOAT_TY]]]** %
+
+// CHECK: ret void
+
+// CHECK: define internal void [[MAIN_MICROTASK10]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [4 x [[S_FLOAT_TY]]]* dereferenceable(16) %{{.+}})
+
+// CHECK: [[VAR3_ORIG_ADDR:%.+]] = alloca [4 x [[S_FLOAT_TY]]]*,
+// CHECK: [[VAR3_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]],
+
+// Reduction list for runtime.
+// CHECK: [[RED_LIST:%.+]] = alloca [1 x i8*],
+
+// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]],
+
+// CHECK: [[VAR3_ORIG:%.+]] = load [4 x [[S_FLOAT_TY]]]*, [4 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]],
+// CHECK: store [4 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]], [4 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR:%.+]],
+// CHECK: [[VAR3_ORIG:%.+]] = load [4 x [[S_FLOAT_TY]]]*, [4 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]],
+
+// CHECK: [[LOW:%.+]] = getelementptr inbounds [4 x [[S_FLOAT_TY]]], [4 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]], i64 0, i64 0
+// CHECK: [[VAR3_ORIG:%.+]] = load [4 x [[S_FLOAT_TY]]]*, [4 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]],
+
+// CHECK: [[VAR3_ORIG:%.+]] = load [4 x [[S_FLOAT_TY]]]*, [4 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]],
+// CHECK: [[ORIG_START:%.+]] = bitcast [4 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]] to [[S_FLOAT_TY]]*
+// CHECK: [[START:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[ORIG_START]] to i64
+// CHECK: [[LOW_BOUND:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[LOW]] to i64
+// CHECK: [[OFFSET_BYTES:%.+]] = sub i64 [[START]], [[LOW_BOUND]]
+// CHECK: [[OFFSET:%.+]] = sdiv exact i64 [[OFFSET_BYTES]], ptrtoint (float* getelementptr (float, float* null, i32 1) to i64)
+// CHECK: [[VAR3_PRIV_PTR:%.+]] = bitcast [2 x [[S_FLOAT_TY]]]* [[VAR3_PRIV]] to [[S_FLOAT_TY]]*
+// CHECK: [[PSEUDO_VAR3_PRIV:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[VAR3_PRIV_PTR]], i64 [[OFFSET]]
+// CHECK: [[VAR3_PRIV:%.+]] = bitcast [[S_FLOAT_TY]]* [[PSEUDO_VAR3_PRIV]] to [4 x [[S_FLOAT_TY]]]*
+
+// CHECK: store [4 x [[S_FLOAT_TY]]]* [[VAR3_PRIV]], [4 x [[S_FLOAT_TY]]]** %
+
+// CHECK: ret void
+
+// CHECK: define internal void [[MAIN_MICROTASK11]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [4 x [[S_FLOAT_TY]]]* dereferenceable(16) %{{.+}})
+
+// CHECK: [[VAR3_ORIG_ADDR:%.+]] = alloca [4 x [[S_FLOAT_TY]]]*,
+
+// Reduction list for runtime.
+// CHECK: [[RED_LIST:%.+]] = alloca [2 x i8*],
+
+// CHECK: [[VAR3_ORIG:%.+]] = load [4 x [[S_FLOAT_TY]]]*, [4 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]],
+// CHECK: store [4 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]], [4 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR:%.+]],
+// CHECK: [[VAR3_ORIG:%.+]] = load [4 x [[S_FLOAT_TY]]]*, [4 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]],
-// CHECK: [[VAR3_ORIG:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]],
-// CHECK: store [2 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]], [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR:%.+]],
// CHECK: [[LAST:%.+]] = ptrtoint [[S_FLOAT_TY]]* %{{.+}} to i64
// CHECK: [[FIRST:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[LOW:%.+]] to i64
// CHECK: [[BYTE_DIF:%.+]] = sub i64 [[LAST]], [[FIRST]]
@@ -955,44 +1164,47 @@ int main() {
// CHECK: [[SIZE:%.+]] = add nuw i64 [[DIF]], 1
// CHECK: call i8* @llvm.stacksave()
// CHECK: [[VAR3_PRIV:%.+]] = alloca [[S_FLOAT_TY]], i64 [[SIZE]],
-// CHECK: [[VAR3_ORIG:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]],
-// CHECK: [[ORIG_START:%.+]] = bitcast [2 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]] to [[S_FLOAT_TY]]*
+// CHECK: [[VAR3_ORIG:%.+]] = load [4 x [[S_FLOAT_TY]]]*, [4 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]],
+// CHECK: [[ORIG_START:%.+]] = bitcast [4 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]] to [[S_FLOAT_TY]]*
// CHECK: [[START:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[ORIG_START]] to i64
// CHECK: [[LOW_BOUND:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[LOW]] to i64
// CHECK: [[OFFSET_BYTES:%.+]] = sub i64 [[START]], [[LOW_BOUND]]
// CHECK: [[OFFSET:%.+]] = sdiv exact i64 [[OFFSET_BYTES]], ptrtoint (float* getelementptr (float, float* null, i32 1) to i64)
// CHECK: [[PSEUDO_VAR3_PRIV:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[VAR3_PRIV]], i64 [[OFFSET]]
-// CHECK: [[VAR3_PRIV:%.+]] = bitcast [[S_FLOAT_TY]]* [[PSEUDO_VAR3_PRIV]] to [2 x [[S_FLOAT_TY]]]*
+// CHECK: [[VAR3_PRIV:%.+]] = bitcast [[S_FLOAT_TY]]* [[PSEUDO_VAR3_PRIV]] to [4 x [[S_FLOAT_TY]]]*
-// CHECK: store [2 x [[S_FLOAT_TY]]]* [[VAR3_PRIV]], [2 x [[S_FLOAT_TY]]]** %
+// CHECK: store [4 x [[S_FLOAT_TY]]]* [[VAR3_PRIV]], [4 x [[S_FLOAT_TY]]]** %
// CHECK: ret void
-// CHECK: define internal void [[MAIN_MICROTASK6]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [2 x [[S_FLOAT_TY]]]* dereferenceable(8) %{{.+}})
+// CHECK: define internal void [[MAIN_MICROTASK12]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [4 x [[S_FLOAT_TY]]]* dereferenceable(16) %{{.+}})
-// CHECK: [[VAR3_ORIG_ADDR:%.+]] = alloca [2 x [[S_FLOAT_TY]]]*,
-// CHECK: [[VAR3_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]],
+// CHECK: [[VAR3_ORIG_ADDR:%.+]] = alloca [4 x [[S_FLOAT_TY]]]*,
+// CHECK: [[VAR3_PRIV:%.+]] = alloca [4 x [[S_FLOAT_TY]]],
// Reduction list for runtime.
// CHECK: [[RED_LIST:%.+]] = alloca [1 x i8*],
// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]],
-// CHECK: [[VAR3_ORIG:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]],
-// CHECK: store [2 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]], [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR:%.+]],
-// CHECK: [[VAR3_ORIG:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]],
-// CHECK: getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[VAR3_PRIV]], i32 0, i32 0
-// CHECK: getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* %{{.+}}, i64 2
+// CHECK: [[VAR3_ORIG:%.+]] = load [4 x [[S_FLOAT_TY]]]*, [4 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]],
+// CHECK: store [4 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]], [4 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR:%.+]],
+// CHECK: [[VAR3_ORIG:%.+]] = load [4 x [[S_FLOAT_TY]]]*, [4 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]],
+// CHECK: getelementptr inbounds [4 x [[S_FLOAT_TY]]], [4 x [[S_FLOAT_TY]]]* [[VAR3_PRIV]], i32 0, i32 0
+// CHECK: getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* %{{.+}}, i64 4
-// CHECK: store [2 x [[S_FLOAT_TY]]]* [[VAR3_PRIV]], [2 x [[S_FLOAT_TY]]]** %
-// CHECK: bitcast [2 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]] to [[S_FLOAT_TY]]*
+// CHECK: store [4 x [[S_FLOAT_TY]]]* [[VAR3_PRIV]], [4 x [[S_FLOAT_TY]]]** %
+// CHECK: bitcast [4 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]] to [[S_FLOAT_TY]]*
// CHECK: ret void
-// CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT]]()
+// CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT_42]]()
// CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]],
// CHECK: call {{.*}} [[S_INT_TY_CONSTR:@.+]]([[S_INT_TY]]* [[TEST]])
// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 6, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, i32*, [[S_INT_TY]]*, [[S_INT_TY]]*, i32*, [2 x i32]*, [2 x [[S_INT_TY]]]*)* [[TMAIN_MICROTASK:@.+]] to void
+// Not interested in this one:
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 4,
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 5, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [42 x [[S_INT_TY]]]*, [2 x i32]*, i32*, [2 x [[S_INT_TY]]]*, [[S_INT_TY]]*)* [[TMAIN_MICROTASK2:@.+]] to void
// CHECK: call {{.*}} [[S_INT_TY_DESTR:@.+]]([[S_INT_TY]]*
// CHECK: ret
//
@@ -1002,6 +1214,7 @@ int main() {
// CHECK: alloca i{{[0-9]+}},
// CHECK: alloca i{{[0-9]+}},
// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_INT_TY]],
// CHECK: [[VAR1_PRIV:%.+]] = alloca [[S_INT_TY]],
@@ -1226,5 +1439,28 @@ int main() {
// CHECK: store i{{[0-9]+}} [[UP]], i{{[0-9]+}}* [[T_VAR1_LHS]],
// CHECK: ret void
+// CHECK: define internal void [[TMAIN_MICROTASK2]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [42 x [[S_INT_TY]]]* dereferenceable(168) %{{.*}}, [2 x i32]* dereferenceable(8) %{{.*}}, i32* dereferenceable(4) %{{.*}}, [2 x [[S_INT_TY]]]* dereferenceable(8) %{{.*}}, [[S_INT_TY]]* dereferenceable(4) %{{.*}})
+
+// CHECK: [[ARR_ORIG_ADDR:%.+]] = alloca [42 x [[S_INT_TY]]]*,
+// CHECK: [[ARR_PRIV:%.+]] = alloca [40 x [[S_INT_TY]]],
+
+// Reduction list for runtime.
+// CHECK: [[RED_LIST:%.+]] = alloca [1 x i8*],
+
+// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]],
+
+// CHECK: [[ARR_ORIG:%.+]] = load [42 x [[S_INT_TY]]]*, [42 x [[S_INT_TY]]]** [[ARR_ORIG_ADDR]],
+// CHECK: [[LOW:%.+]] = getelementptr inbounds [42 x [[S_INT_TY]]], [42 x [[S_INT_TY]]]* [[ARR_ORIG]], i64 0, i64 1
+// CHECK: [[ORIG_START:%.+]] = bitcast [42 x [[S_INT_TY]]]* [[ARR_ORIG]] to [[S_INT_TY]]*
+// CHECK: [[START:%.+]] = ptrtoint [[S_INT_TY]]* [[ORIG_START]] to i64
+// CHECK: [[LOW_BOUND:%.+]] = ptrtoint [[S_INT_TY]]* [[LOW]] to i64
+// CHECK: [[OFFSET_BYTES:%.+]] = sub i64 [[START]], [[LOW_BOUND]]
+// CHECK: [[OFFSET:%.+]] = sdiv exact i64 [[OFFSET_BYTES]], ptrtoint (i32* getelementptr (i32, i32* null, i32 1) to i64)
+// CHECK: [[ARR_PRIV_PTR:%.+]] = bitcast [40 x [[S_INT_TY]]]* [[ARR_PRIV]] to [[S_INT_TY]]*
+// CHECK: [[PSEUDO_ARR_PRIV:%.+]] = getelementptr [[S_INT_TY]], [[S_INT_TY]]* [[ARR_PRIV_PTR]], i64 [[OFFSET]]
+// CHECK: [[ARR_PRIV:%.+]] = bitcast [[S_INT_TY]]* [[PSEUDO_ARR_PRIV]] to [42 x [[S_INT_TY]]]*
+
+// CHECK: ret void
+
#endif
diff --git a/test/OpenMP/for_reduction_codegen_UDR.cpp b/test/OpenMP/for_reduction_codegen_UDR.cpp
index 95b04f44d468..05a46a6eb7ff 100644
--- a/test/OpenMP/for_reduction_codegen_UDR.cpp
+++ b/test/OpenMP/for_reduction_codegen_UDR.cpp
@@ -40,7 +40,7 @@ void init_plus(BaseS1&, const BaseS1&);
// CHECK-DAG: [[REDUCTION_LOCK:@.+]] = common global [8 x i32] zeroinitializer
#pragma omp declare reduction(operator&& : int : omp_out = 111 & omp_in)
-template <typename T>
+template <typename T, int length>
T tmain() {
T t;
S<T> test;
@@ -49,6 +49,7 @@ T tmain() {
S<T> s_arr[] = {1, 2};
S<T> &var = test;
S<T> var1;
+ S<T> arr[length];
#pragma omp declare reduction(operator& : T : omp_out = 15 + omp_in)
#pragma omp declare reduction(operator+ : T : omp_out = 1513 + omp_in) initializer(omp_priv = 321)
#pragma omp declare reduction(min : T : omp_out = 47 - omp_in) initializer(omp_priv = 432 / omp_orig)
@@ -66,6 +67,12 @@ T tmain() {
vec[i] = t_var;
s_arr[i] = var;
}
+#pragma omp parallel
+#pragma omp for reduction(+ : arr[1:length-2])
+ for (int i = 0; i < 2; ++i) {
+ vec[i] = t_var;
+ s_arr[i] = var;
+ }
return T();
}
@@ -78,12 +85,12 @@ int main() {
S<float> test;
float t_var = 0, t_var1;
int vec[] = {1, 2};
- S<float> s_arr[] = {1, 2};
+ S<float> s_arr[] = {1, 2, 3, 4};
S<float> &var = test;
S<float> var1, arrs[10][4];
S<float> **var2 = foo();
- S<float> vvar2[2];
- S<float>(&var3)[2] = s_arr;
+ S<float> vvar2[5];
+ S<float>(&var3)[4] = s_arr;
#pragma omp declare reduction(operator+ : int : omp_out = 555 * omp_in) initializer(omp_priv = 888)
#pragma omp parallel
#pragma omp for reduction(+ : t_var) reduction(& : var) reduction(&& : var1) reduction(min : t_var1)
@@ -115,24 +122,24 @@ int main() {
#pragma omp for reduction(& : var3)
for (int i = 0; i < 10; ++i)
;
- return tmain<int>();
+ return tmain<int, 42>();
}
// CHECK: define {{.*}}i{{[0-9]+}} @main()
// CHECK: [[TEST:%.+]] = alloca [[S_FLOAT_TY]],
// CHECK: call {{.*}} [[S_FLOAT_TY_CONSTR:@.+]]([[S_FLOAT_TY]]* [[TEST]])
-// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 6, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, float*, [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]*, float*, [2 x i32]*, [2 x [[S_FLOAT_TY]]]*)* [[MAIN_MICROTASK:@.+]] to void
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 6, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, float*, [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]*, float*, [2 x i32]*, [4 x [[S_FLOAT_TY]]]*)* [[MAIN_MICROTASK:@.+]] to void
// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 5, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, i64, i64, i32*, [2 x i32]*, [10 x [4 x [[S_FLOAT_TY]]]]*)* [[MAIN_MICROTASK1:@.+]] to void
// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 4, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, i64, i64, i32*, [10 x [4 x [[S_FLOAT_TY]]]]*)* [[MAIN_MICROTASK2:@.+]] to void
// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[S_FLOAT_TY]]***)* [[MAIN_MICROTASK3:@.+]] to void
-// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [2 x [[S_FLOAT_TY]]]*)* [[MAIN_MICROTASK4:@.+]] to void
-// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [2 x [[S_FLOAT_TY]]]*)* [[MAIN_MICROTASK5:@.+]] to void
-// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [2 x [[S_FLOAT_TY]]]*)* [[MAIN_MICROTASK6:@.+]] to void
-// CHECK: = call {{.*}}i{{.+}} [[TMAIN_INT:@.+]]()
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [5 x [[S_FLOAT_TY]]]*)* [[MAIN_MICROTASK4:@.+]] to void
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [4 x [[S_FLOAT_TY]]]*)* [[MAIN_MICROTASK5:@.+]] to void
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [4 x [[S_FLOAT_TY]]]*)* [[MAIN_MICROTASK6:@.+]] to void
+// CHECK: = call {{.*}}i{{.+}} [[TMAIN_INT_42:@.+]]()
// CHECK: call {{.*}} [[S_FLOAT_TY_DESTR:@.+]]([[S_FLOAT_TY]]*
// CHECK: ret
//
-// CHECK: define internal void [[MAIN_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, float* dereferenceable(4) %{{.+}}, [[S_FLOAT_TY]]* dereferenceable(12) %{{.+}}, [[S_FLOAT_TY]]* dereferenceable(12) %{{.+}}, float* dereferenceable(4) %{{.+}}, [2 x i32]* dereferenceable(8) %vec, [2 x [[S_FLOAT_TY]]]* dereferenceable(24) %{{.+}})
+// CHECK: define internal void [[MAIN_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, float* dereferenceable(4) %{{.+}}, [[S_FLOAT_TY]]* dereferenceable(12) %{{.+}}, [[S_FLOAT_TY]]* dereferenceable(12) %{{.+}}, float* dereferenceable(4) %{{.+}}, [2 x i32]* dereferenceable(8) %vec, [4 x [[S_FLOAT_TY]]]* dereferenceable(48) %{{.+}})
// CHECK: [[T_VAR_PRIV:%.+]] = alloca float,
// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]],
// CHECK: [[VAR1_PRIV:%.+]] = alloca [[S_FLOAT_TY]],
@@ -300,7 +307,7 @@ int main() {
// CHECK: fadd float 5.550000e+02, %
// CHECK: ret void
-// CHECK: define internal void [[MAIN_MICROTASK1]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i64 %{{.+}}, i64 %{{.+}}, i32* %{{.+}}, [2 x i32]* dereferenceable(8) %{{.+}}, [10 x [4 x [[S_FLOAT_TY]]]]* dereferenceable(480) %{{.+}})
+// CHECK: define internal void [[MAIN_MICROTASK1]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i64 %{{.+}}, i64 %{{.+}}, i32* {{.+}} %{{.+}}, [2 x i32]* dereferenceable(8) %{{.+}}, [10 x [4 x [[S_FLOAT_TY]]]]* dereferenceable(480) %{{.+}})
// Reduction list for runtime.
// CHECK: [[RED_LIST:%.+]] = alloca [4 x i8*],
@@ -496,7 +503,7 @@ int main() {
// CHECK: ret void
-// CHECK: define internal void [[MAIN_MICROTASK2]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i64 %{{.+}}, i64 %{{.+}}, i32* %{{.+}}, [10 x [4 x [[S_FLOAT_TY]]]]* dereferenceable(480) %{{.+}})
+// CHECK: define internal void [[MAIN_MICROTASK2]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i64 %{{.+}}, i64 %{{.+}}, i32* {{.+}} %{{.+}}, [10 x [4 x [[S_FLOAT_TY]]]]* dereferenceable(480) %{{.+}})
// CHECK: [[ARRS_PRIV:%.+]] = alloca [10 x [4 x [[S_FLOAT_TY]]]],
@@ -711,89 +718,87 @@ int main() {
// CHECK: store [[S_FLOAT_TY]]* [[PSEUDO_VAR2_PRIV]], [[S_FLOAT_TY]]** [[REF]]
// CHECK: ret void
-// CHECK: define internal void [[MAIN_MICROTASK4]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [2 x [[S_FLOAT_TY]]]* dereferenceable(24) %{{.+}})
+// CHECK: define internal void [[MAIN_MICROTASK4]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [5 x [[S_FLOAT_TY]]]* dereferenceable(60) %{{.+}})
-// CHECK: [[VVAR2_ORIG_ADDR:%.+]] = alloca [2 x [[S_FLOAT_TY]]]*,
+// CHECK: [[VVAR2_ORIG_ADDR:%.+]] = alloca [5 x [[S_FLOAT_TY]]]*,
+// CHECK: [[VVAR2_PRIV:%.+]] = alloca [5 x [[S_FLOAT_TY]]],
// Reduction list for runtime.
-// CHECK: [[RED_LIST:%.+]] = alloca [2 x i8*],
+// CHECK: [[RED_LIST:%.+]] = alloca [1 x i8*],
// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]],
-// CHECK: [[VVAR2_ORIG:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[VVAR2_ORIG_ADDR]],
+// CHECK: [[VVAR2_ORIG:%.+]] = load [5 x [[S_FLOAT_TY]]]*, [5 x [[S_FLOAT_TY]]]** [[VVAR2_ORIG_ADDR]],
-// CHECK: [[LOW:%.+]] = getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[VVAR2_ORIG]], i64 0, i64 0
-// CHECK: [[LAST:%.+]] = ptrtoint [[S_FLOAT_TY]]* %{{.+}} to i64
-// CHECK: [[FIRST:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[LOW]] to i64
-// CHECK: [[BYTE_DIF:%.+]] = sub i64 [[LAST]], [[FIRST]]
-// CHECK: [[DIF:%.+]] = sdiv exact i64 [[BYTE_DIF]], ptrtoint ([[S_FLOAT_TY]]* getelementptr ([[S_FLOAT_TY]], [[S_FLOAT_TY]]* null, i32 1) to i64)
-// CHECK: [[SIZE:%.+]] = add nuw i64 [[DIF]], 1
-// CHECK: call i8* @llvm.stacksave()
-// CHECK: [[VVAR2_PRIV:%.+]] = alloca [[S_FLOAT_TY]], i64 [[SIZE]],
-// CHECK: [[ORIG_START:%.+]] = bitcast [2 x [[S_FLOAT_TY]]]* [[VVAR2_ORIG]] to [[S_FLOAT_TY]]*
+// CHECK: [[LOW:%.+]] = getelementptr inbounds [5 x [[S_FLOAT_TY]]], [5 x [[S_FLOAT_TY]]]* [[VVAR2_ORIG]], i64 0, i64 0
+// CHECK: [[ORIG_START:%.+]] = bitcast [5 x [[S_FLOAT_TY]]]* [[VVAR2_ORIG]] to [[S_FLOAT_TY]]*
// CHECK: [[START:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[ORIG_START]] to i64
// CHECK: [[LOW_BOUND:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[LOW]] to i64
// CHECK: [[OFFSET_BYTES:%.+]] = sub i64 [[START]], [[LOW_BOUND]]
// CHECK: [[OFFSET:%.+]] = sdiv exact i64 [[OFFSET_BYTES]], ptrtoint ([[S_FLOAT_TY]]* getelementptr ([[S_FLOAT_TY]], [[S_FLOAT_TY]]* null, i32 1) to i64)
-// CHECK: [[PSEUDO_VVAR2_PRIV:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[VVAR2_PRIV]], i64 [[OFFSET]]
-// CHECK: [[VVAR2_PRIV:%.+]] = bitcast [[S_FLOAT_TY]]* [[PSEUDO_VVAR2_PRIV]] to [2 x [[S_FLOAT_TY]]]*
+// CHECK: [[VVAR2_PRIV_PTR:%.+]] = bitcast [5 x [[S_FLOAT_TY]]]* [[VVAR2_PRIV]] to [[S_FLOAT_TY]]*
+// CHECK: [[VVAR2_PRIV:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[VVAR2_PRIV_PTR]], i64 [[OFFSET]]
// CHECK: ret void
-// CHECK: define internal void [[MAIN_MICROTASK5]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [2 x [[S_FLOAT_TY]]]* dereferenceable(24) %{{.+}})
+// CHECK: define internal void [[MAIN_MICROTASK5]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [4 x [[S_FLOAT_TY]]]* dereferenceable(48) %{{.+}})
-// CHECK: [[VAR3_ORIG_ADDR:%.+]] = alloca [2 x [[S_FLOAT_TY]]]*,
+// CHECK: [[VAR3_ORIG_ADDR:%.+]] = alloca [4 x [[S_FLOAT_TY]]]*,
+// CHECK: [[VAR3_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]],
// Reduction list for runtime.
-// CHECK: [[RED_LIST:%.+]] = alloca [2 x i8*],
+// CHECK: [[RED_LIST:%.+]] = alloca [1 x i8*],
// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]],
-// CHECK: [[VAR3_ORIG:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]],
-// CHECK: store [2 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]], [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR:%.+]],
-// CHECK: [[LAST:%.+]] = ptrtoint [[S_FLOAT_TY]]* %{{.+}} to i64
-// CHECK: [[FIRST:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[LOW:%.+]] to i64
-// CHECK: [[BYTE_DIF:%.+]] = sub i64 [[LAST]], [[FIRST]]
-// CHECK: [[DIF:%.+]] = sdiv exact i64 [[BYTE_DIF]], ptrtoint ([[S_FLOAT_TY]]* getelementptr ([[S_FLOAT_TY]], [[S_FLOAT_TY]]* null, i32 1) to i64)
-// CHECK: [[SIZE:%.+]] = add nuw i64 [[DIF]], 1
-// CHECK: call i8* @llvm.stacksave()
-// CHECK: [[VAR3_PRIV:%.+]] = alloca [[S_FLOAT_TY]], i64 [[SIZE]],
-// CHECK: [[VAR3_ORIG:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]],
-// CHECK: [[ORIG_START:%.+]] = bitcast [2 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]] to [[S_FLOAT_TY]]*
+// CHECK: [[VAR3_ORIG:%.+]] = load [4 x [[S_FLOAT_TY]]]*, [4 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]],
+// CHECK: store [4 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]], [4 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR:%.+]],
+// CHECK: [[VAR3_ORIG:%.+]] = load [4 x [[S_FLOAT_TY]]]*, [4 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]],
+
+// CHECK: [[LOW:%.+]] = getelementptr inbounds [4 x [[S_FLOAT_TY]]], [4 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]], i64 0, i64 1
+// CHECK: [[VAR3_ORIG:%.+]] = load [4 x [[S_FLOAT_TY]]]*, [4 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]],
+
+// CHECK: [[VAR3_ORIG:%.+]] = load [4 x [[S_FLOAT_TY]]]*, [4 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]],
+// CHECK: [[ORIG_START:%.+]] = bitcast [4 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]] to [[S_FLOAT_TY]]*
// CHECK: [[START:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[ORIG_START]] to i64
// CHECK: [[LOW_BOUND:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[LOW]] to i64
// CHECK: [[OFFSET_BYTES:%.+]] = sub i64 [[START]], [[LOW_BOUND]]
// CHECK: [[OFFSET:%.+]] = sdiv exact i64 [[OFFSET_BYTES]], ptrtoint ([[S_FLOAT_TY]]* getelementptr ([[S_FLOAT_TY]], [[S_FLOAT_TY]]* null, i32 1) to i64)
-// CHECK: [[PSEUDO_VAR3_PRIV:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[VAR3_PRIV]], i64 [[OFFSET]]
-// CHECK: [[VAR3_PRIV:%.+]] = bitcast [[S_FLOAT_TY]]* [[PSEUDO_VAR3_PRIV]] to [2 x [[S_FLOAT_TY]]]*
+// CHECK: [[VAR3_PRIV_PTR:%.+]] = bitcast [2 x [[S_FLOAT_TY]]]* [[VAR3_PRIV]] to [[S_FLOAT_TY]]*
+// CHECK: [[PSEUDO_VAR3_PRIV:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[VAR3_PRIV_PTR]], i64 [[OFFSET]]
+// CHECK: [[VAR3_PRIV:%.+]] = bitcast [[S_FLOAT_TY]]* [[PSEUDO_VAR3_PRIV]] to [4 x [[S_FLOAT_TY]]]*
-// CHECK: store [2 x [[S_FLOAT_TY]]]* [[VAR3_PRIV]], [2 x [[S_FLOAT_TY]]]** %
+// CHECK: store [4 x [[S_FLOAT_TY]]]* [[VAR3_PRIV]], [4 x [[S_FLOAT_TY]]]** %
// CHECK: ret void
-// CHECK: define internal void [[MAIN_MICROTASK6]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [2 x [[S_FLOAT_TY]]]* dereferenceable(24) %{{.+}})
+// CHECK: define internal void [[MAIN_MICROTASK6]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [4 x [[S_FLOAT_TY]]]* dereferenceable(48) %{{.+}})
-// CHECK: [[VAR3_ORIG_ADDR:%.+]] = alloca [2 x [[S_FLOAT_TY]]]*,
-// CHECK: [[VAR3_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]],
+// CHECK: [[VAR3_ORIG_ADDR:%.+]] = alloca [4 x [[S_FLOAT_TY]]]*,
+// CHECK: [[VAR3_PRIV:%.+]] = alloca [4 x [[S_FLOAT_TY]]],
// Reduction list for runtime.
// CHECK: [[RED_LIST:%.+]] = alloca [1 x i8*],
// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]],
-// CHECK: [[VAR3_ORIG:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]],
-// CHECK: store [2 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]], [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR:%.+]],
-// CHECK: [[VAR3_ORIG:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]],
-// CHECK: getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[VAR3_PRIV]], i32 0, i32 0
-// CHECK: bitcast [2 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]] to [[S_FLOAT_TY]]*
-// CHECK: getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* %{{.+}}, i64 2
+// CHECK: [[VAR3_ORIG:%.+]] = load [4 x [[S_FLOAT_TY]]]*, [4 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]],
+// CHECK: store [4 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]], [4 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR:%.+]],
+// CHECK: [[VAR3_ORIG:%.+]] = load [4 x [[S_FLOAT_TY]]]*, [4 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]],
+// CHECK: getelementptr inbounds [4 x [[S_FLOAT_TY]]], [4 x [[S_FLOAT_TY]]]* [[VAR3_PRIV]], i32 0, i32 0
+// CHECK: bitcast [4 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]] to [[S_FLOAT_TY]]*
+// CHECK: getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* %{{.+}}, i64 4
-// CHECK: store [2 x [[S_FLOAT_TY]]]* [[VAR3_PRIV]], [2 x [[S_FLOAT_TY]]]** %
+// CHECK: store [4 x [[S_FLOAT_TY]]]* [[VAR3_PRIV]], [4 x [[S_FLOAT_TY]]]** %
// CHECK: ret void
-// CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT]]()
+// CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT_42]]()
// CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]],
// CHECK: call {{.*}} [[S_INT_TY_CONSTR:@.+]]([[S_INT_TY]]* [[TEST]])
// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 6, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, i32*, [[S_INT_TY]]*, [[S_INT_TY]]*, i32*, [2 x i32]*, [2 x [[S_INT_TY]]]*)* [[TMAIN_MICROTASK:@.+]] to void
+// Not interested in this one:
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 4,
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 5, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [42 x [[S_INT_TY]]]*, [2 x i32]*, i32*, [2 x [[S_INT_TY]]]*, [[S_INT_TY]]*)* [[TMAIN_MICROTASK2:@.+]] to void
+// CHECK: call {{.*}} [[S_INT_TY_DESTR:@.+]]([[S_INT_TY]]*
// CHECK: call {{.*}} [[S_INT_TY_DESTR:@.+]]([[S_INT_TY]]*
// CHECK: ret
//
@@ -803,6 +808,7 @@ int main() {
// CHECK: alloca i{{[0-9]+}},
// CHECK: alloca i{{[0-9]+}},
// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_INT_TY]],
// CHECK: [[VAR1_PRIV:%.+]] = alloca [[S_INT_TY]],
@@ -964,5 +970,28 @@ int main() {
// CHECK: sub nsw i32 47, %
// CHECK: ret void
+// CHECK: define internal void [[TMAIN_MICROTASK2]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [42 x [[S_INT_TY]]]* dereferenceable(504) %{{.*}}, [2 x i32]* dereferenceable(8) %{{.*}}, i32* dereferenceable(4) %{{.*}}, [2 x [[S_INT_TY]]]* dereferenceable(24) %{{.*}}, [[S_INT_TY]]* dereferenceable(12) %{{.*}})
+
+// CHECK: [[ARR_ORIG_ADDR:%.+]] = alloca [42 x [[S_INT_TY]]]*,
+// CHECK: [[ARR_PRIV:%.+]] = alloca [40 x [[S_INT_TY]]],
+
+// Reduction list for runtime.
+// CHECK: [[RED_LIST:%.+]] = alloca [1 x i8*],
+
+// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]],
+
+// CHECK: [[ARR_ORIG:%.+]] = load [42 x [[S_INT_TY]]]*, [42 x [[S_INT_TY]]]** [[ARR_ORIG_ADDR]],
+// CHECK: [[LOW:%.+]] = getelementptr inbounds [42 x [[S_INT_TY]]], [42 x [[S_INT_TY]]]* [[ARR_ORIG]], i64 0, i64 1
+// CHECK: [[ORIG_START:%.+]] = bitcast [42 x [[S_INT_TY]]]* [[ARR_ORIG]] to [[S_INT_TY]]*
+// CHECK: [[START:%.+]] = ptrtoint [[S_INT_TY]]* [[ORIG_START]] to i64
+// CHECK: [[LOW_BOUND:%.+]] = ptrtoint [[S_INT_TY]]* [[LOW]] to i64
+// CHECK: [[OFFSET_BYTES:%.+]] = sub i64 [[START]], [[LOW_BOUND]]
+// CHECK: [[OFFSET:%.+]] = sdiv exact i64 [[OFFSET_BYTES]], ptrtoint ([[S_INT_TY]]* getelementptr ([[S_INT_TY]], [[S_INT_TY]]* null, i32 1) to i64)
+// CHECK: [[ARR_PRIV_PTR:%.+]] = bitcast [40 x [[S_INT_TY]]]* [[ARR_PRIV]] to [[S_INT_TY]]*
+// CHECK: [[PSEUDO_ARR_PRIV:%.+]] = getelementptr [[S_INT_TY]], [[S_INT_TY]]* [[ARR_PRIV_PTR]], i64 [[OFFSET]]
+// CHECK: [[ARR_PRIV:%.+]] = bitcast [[S_INT_TY]]* [[PSEUDO_ARR_PRIV]] to [42 x [[S_INT_TY]]]*
+
+// CHECK: ret void
+
#endif
diff --git a/test/OpenMP/for_reduction_messages.cpp b/test/OpenMP/for_reduction_messages.cpp
index bb70ecc2b23e..d4f4a795fe2c 100644
--- a/test/OpenMP/for_reduction_messages.cpp
+++ b/test/OpenMP/for_reduction_messages.cpp
@@ -26,9 +26,9 @@ public:
S2() : a(0) {}
S2(S2 &s2) : a(s2.a) {}
static float S2s; // expected-note 2 {{static data member is predetermined as shared}}
- static const float S2sc;
+ static const float S2sc; // expected-note 2 {{'S2sc' declared here}}
};
-const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}}
+const float S2::S2sc = 0;
S2 b; // expected-note 3 {{'b' defined here}}
const S2 ba[5]; // expected-note 2 {{'ba' defined here}}
class S3 {
diff --git a/test/OpenMP/for_simd_lastprivate_messages.cpp b/test/OpenMP/for_simd_lastprivate_messages.cpp
index d48c07d92b39..a176a2d70eb9 100644
--- a/test/OpenMP/for_simd_lastprivate_messages.cpp
+++ b/test/OpenMP/for_simd_lastprivate_messages.cpp
@@ -18,9 +18,9 @@ public:
S2 &operator =(const S2&);
const S2 &operator =(const S2&) const;
static float S2s; // expected-note {{static data member is predetermined as shared}}
- static const float S2sc;
+ static const float S2sc; // expected-note {{static data member is predetermined as shared}}
};
-const float S2::S2sc = 0; // expected-note {{static data member is predetermined as shared}}
+const float S2::S2sc = 0;
const S2 b;
const S2 ba[5];
class S3 {
diff --git a/test/OpenMP/for_simd_reduction_messages.cpp b/test/OpenMP/for_simd_reduction_messages.cpp
index 485070e758ae..a77ab754eff9 100644
--- a/test/OpenMP/for_simd_reduction_messages.cpp
+++ b/test/OpenMP/for_simd_reduction_messages.cpp
@@ -26,9 +26,9 @@ public:
S2() : a(0) {}
S2(S2 &s2) : a(s2.a) {}
static float S2s; // expected-note 2 {{static data member is predetermined as shared}}
- static const float S2sc;
+ static const float S2sc; // expected-note 2 {{'S2sc' declared here}}
};
-const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}}
+const float S2::S2sc = 0;
S2 b; // expected-note 3 {{'b' defined here}}
const S2 ba[5]; // expected-note 2 {{'ba' defined here}}
class S3 {
diff --git a/test/OpenMP/is_initial_device.c b/test/OpenMP/is_initial_device.c
new file mode 100644
index 000000000000..0521f0bd5393
--- /dev/null
+++ b/test/OpenMP/is_initial_device.c
@@ -0,0 +1,36 @@
+// REQUIRES: powerpc-registered-target
+
+// RUN: %clang_cc1 -verify -fopenmp -x c -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-unknown-unknown \
+// RUN: -emit-llvm-bc %s -o %t-ppc-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -x ir -triple powerpc64le-unknown-unknown -emit-llvm \
+// RUN: %t-ppc-host.bc -o - | FileCheck %s -check-prefixes HOST,OUTLINED
+// RUN: %clang_cc1 -verify -fopenmp -x c -triple powerpc64le-unknown-unknown -emit-llvm -fopenmp-is-device \
+// RUN: %s -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s -check-prefixes DEVICE,OUTLINED
+
+// expected-no-diagnostics
+int check() {
+ int host = omp_is_initial_device();
+ int device;
+#pragma omp target map(tofrom: device)
+ {
+ device = omp_is_initial_device();
+ }
+
+ return host + device;
+}
+
+// The host should get a value of 1:
+// HOST: define{{.*}} @check()
+// HOST: [[HOST:%.*]] = alloca i32
+// HOST: store i32 1, i32* [[HOST]]
+
+// OUTLINED: define{{.*}} @{{.*}}omp_offloading{{.*}}(i32*{{.*}} [[DEVICE_ARGUMENT:%.*]])
+// OUTLINED: [[DEVICE_ADDR_STORAGE:%.*]] = alloca i32*
+// OUTLINED: store i32* [[DEVICE_ARGUMENT]], i32** [[DEVICE_ADDR_STORAGE]]
+// OUTLINED: [[DEVICE_ADDR:%.*]] = load i32*, i32** [[DEVICE_ADDR_STORAGE]]
+
+// The outlined function that is called as fallback also runs on the host:
+// HOST: store i32 1, i32* [[DEVICE_ADDR]]
+
+// The device should get a value of 0:
+// DEVICE: store i32 0, i32* [[DEVICE_ADDR]]
diff --git a/test/OpenMP/nvptx_data_sharing.cpp b/test/OpenMP/nvptx_data_sharing.cpp
new file mode 100644
index 000000000000..65215cd2c4f9
--- /dev/null
+++ b/test/OpenMP/nvptx_data_sharing.cpp
@@ -0,0 +1,57 @@
+// Test device data sharing codegen.
+///==========================================================================///
+
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix CK1
+
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+
+void test_ds(){
+ #pragma omp target
+ {
+ int a = 10;
+ #pragma omp parallel
+ {
+ a = 1000;
+ }
+ }
+}
+
+/// ========= In the worker function ========= ///
+
+// CK1: define internal void @__omp_offloading_{{.*}}test_ds{{.*}}worker() [[ATTR1:#.*]] {
+// CK1: [[SHAREDARGS:%.+]] = alloca i8**
+// CK1: call i1 @__kmpc_kernel_parallel(i8** %work_fn, i8*** [[SHAREDARGS]])
+// CK1: [[SHARGSTMP:%.+]] = load i8**, i8*** [[SHAREDARGS]]
+// CK1: call void @__omp_outlined___wrapper{{.*}}({{.*}}, i8** [[SHARGSTMP]])
+
+/// ========= In the kernel function ========= ///
+
+// CK1: {{.*}}define void @__omp_offloading{{.*}}test_ds{{.*}}() [[ATTR2:#.*]] {
+// CK1: [[SHAREDARGS1:%.+]] = alloca i8**
+// CK1: call void @__kmpc_kernel_prepare_parallel({{.*}}, i8*** [[SHAREDARGS1]], i32 1)
+// CK1: [[SHARGSTMP1:%.+]] = load i8**, i8*** [[SHAREDARGS1]]
+// CK1: [[SHARGSTMP2:%.+]] = getelementptr inbounds i8*, i8** [[SHARGSTMP1]]
+// CK1: [[SHAREDVAR:%.+]] = bitcast i32* {{.*}} to i8*
+// CK1: store i8* [[SHAREDVAR]], i8** [[SHARGSTMP2]]
+
+/// ========= In the data sharing wrapper function ========= ///
+
+// CK1: {{.*}}define internal void @__omp_outlined___wrapper({{.*}}i8**) [[ATTR1]] {
+// CK1: [[SHAREDARGS2:%.+]] = alloca i8**
+// CK1: store i8** %2, i8*** [[SHAREDARGS2]]
+// CK1: [[SHARGSTMP3:%.+]] = load i8**, i8*** [[SHAREDARGS2]]
+// CK1: [[SHARGSTMP4:%.+]] = getelementptr inbounds i8*, i8** [[SHARGSTMP3]]
+// CK1: [[SHARGSTMP5:%.+]] = bitcast i8** [[SHARGSTMP4]] to i32**
+// CK1: [[SHARGSTMP6:%.+]] = load i32*, i32** [[SHARGSTMP5]]
+// CK1: call void @__omp_outlined__({{.*}}, i32* [[SHARGSTMP6]])
+
+/// ========= Attributes ========= ///
+
+// CK1-NOT: attributes [[ATTR1]] = { {{.*}}"has-nvptx-shared-depot"{{.*}} }
+// CK1: attributes [[ATTR2]] = { {{.*}}"has-nvptx-shared-depot"{{.*}} }
+
+#endif
diff --git a/test/OpenMP/nvptx_parallel_codegen.cpp b/test/OpenMP/nvptx_parallel_codegen.cpp
index 224f24569669..ba889bf4975f 100644
--- a/test/OpenMP/nvptx_parallel_codegen.cpp
+++ b/test/OpenMP/nvptx_parallel_codegen.cpp
@@ -78,7 +78,7 @@ int bar(int n){
//
// CHECK: [[AWAIT_WORK]]
// CHECK: call void @llvm.nvvm.barrier0()
- // CHECK: [[KPR:%.+]] = call i1 @__kmpc_kernel_parallel(i8** [[OMP_WORK_FN]])
+ // CHECK: [[KPR:%.+]] = call i1 @__kmpc_kernel_parallel(i8** [[OMP_WORK_FN]],
// CHECK: [[KPRB:%.+]] = zext i1 [[KPR]] to i8
// store i8 [[KPRB]], i8* [[OMP_EXEC_STATUS]], align 1
// CHECK: [[WORK:%.+]] = load i8*, i8** [[OMP_WORK_FN]],
@@ -92,20 +92,20 @@ int bar(int n){
//
// CHECK: [[EXEC_PARALLEL]]
// CHECK: [[WF1:%.+]] = load i8*, i8** [[OMP_WORK_FN]],
- // CHECK: [[WM1:%.+]] = icmp eq i8* [[WF1]], bitcast (void (i32*, i32*)* [[PARALLEL_FN1:@.+]] to i8*)
+ // CHECK: [[WM1:%.+]] = icmp eq i8* [[WF1]], bitcast (void (i16, i32, i8**)* [[PARALLEL_FN1:@.+]]_wrapper to i8*)
// CHECK: br i1 [[WM1]], label {{%?}}[[EXEC_PFN1:.+]], label {{%?}}[[CHECK_NEXT1:.+]]
//
// CHECK: [[EXEC_PFN1]]
- // CHECK: call void [[PARALLEL_FN1]](
+ // CHECK: call void [[PARALLEL_FN1]]_wrapper(
// CHECK: br label {{%?}}[[TERM_PARALLEL:.+]]
//
// CHECK: [[CHECK_NEXT1]]
// CHECK: [[WF2:%.+]] = load i8*, i8** [[OMP_WORK_FN]],
- // CHECK: [[WM2:%.+]] = icmp eq i8* [[WF2]], bitcast (void (i32*, i32*)* [[PARALLEL_FN2:@.+]] to i8*)
+ // CHECK: [[WM2:%.+]] = icmp eq i8* [[WF2]], bitcast (void (i16, i32, i8**)* [[PARALLEL_FN2:@.+]]_wrapper to i8*)
// CHECK: br i1 [[WM2]], label {{%?}}[[EXEC_PFN2:.+]], label {{%?}}[[CHECK_NEXT2:.+]]
//
// CHECK: [[EXEC_PFN2]]
- // CHECK: call void [[PARALLEL_FN2]](
+ // CHECK: call void [[PARALLEL_FN2]]_wrapper(
// CHECK: br label {{%?}}[[TERM_PARALLEL:.+]]
//
// CHECK: [[CHECK_NEXT2]]
@@ -152,13 +152,13 @@ int bar(int n){
// CHECK-DAG: [[MWS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
// CHECK: [[MTMP1:%.+]] = sub i32 [[MNTH]], [[MWS]]
// CHECK: call void @__kmpc_kernel_init(i32 [[MTMP1]]
- // CHECK: call void @__kmpc_kernel_prepare_parallel(i8* bitcast (void (i32*, i32*)* [[PARALLEL_FN1]] to i8*))
+ // CHECK: call void @__kmpc_kernel_prepare_parallel(i8* bitcast (void (i16, i32, i8**)* [[PARALLEL_FN1]]_wrapper to i8*),
// CHECK: call void @llvm.nvvm.barrier0()
// CHECK: call void @llvm.nvvm.barrier0()
// CHECK: call void @__kmpc_serialized_parallel(
// CHECK: {{call|invoke}} void [[PARALLEL_FN3:@.+]](
// CHECK: call void @__kmpc_end_serialized_parallel(
- // CHECK: call void @__kmpc_kernel_prepare_parallel(i8* bitcast (void (i32*, i32*)* [[PARALLEL_FN2]] to i8*))
+ // CHECK: call void @__kmpc_kernel_prepare_parallel(i8* bitcast (void (i16, i32, i8**)* [[PARALLEL_FN2]]_wrapper to i8*),
// CHECK: call void @llvm.nvvm.barrier0()
// CHECK: call void @llvm.nvvm.barrier0()
// CHECK-64-DAG: load i32, i32* [[REF_A]]
@@ -166,7 +166,7 @@ int bar(int n){
// CHECK: br label {{%?}}[[TERMINATE:.+]]
//
// CHECK: [[TERMINATE]]
- // CHECK: call void @__kmpc_kernel_deinit()
+ // CHECK: call void @__kmpc_kernel_deinit(
// CHECK: call void @llvm.nvvm.barrier0()
// CHECK: br label {{%?}}[[EXIT]]
//
@@ -203,7 +203,7 @@ int bar(int n){
//
// CHECK: [[AWAIT_WORK]]
// CHECK: call void @llvm.nvvm.barrier0()
- // CHECK: [[KPR:%.+]] = call i1 @__kmpc_kernel_parallel(i8** [[OMP_WORK_FN]])
+ // CHECK: [[KPR:%.+]] = call i1 @__kmpc_kernel_parallel(i8** [[OMP_WORK_FN]],
// CHECK: [[KPRB:%.+]] = zext i1 [[KPR]] to i8
// store i8 [[KPRB]], i8* [[OMP_EXEC_STATUS]], align 1
// CHECK: [[WORK:%.+]] = load i8*, i8** [[OMP_WORK_FN]],
@@ -217,11 +217,11 @@ int bar(int n){
//
// CHECK: [[EXEC_PARALLEL]]
// CHECK: [[WF:%.+]] = load i8*, i8** [[OMP_WORK_FN]],
- // CHECK: [[WM:%.+]] = icmp eq i8* [[WF]], bitcast (void (i32*, i32*)* [[PARALLEL_FN4:@.+]] to i8*)
+ // CHECK: [[WM:%.+]] = icmp eq i8* [[WF]], bitcast (void (i16, i32, i8**)* [[PARALLEL_FN4:@.+]]_wrapper to i8*)
// CHECK: br i1 [[WM]], label {{%?}}[[EXEC_PFN:.+]], label {{%?}}[[CHECK_NEXT:.+]]
//
// CHECK: [[EXEC_PFN]]
- // CHECK: call void [[PARALLEL_FN4]](
+ // CHECK: call void [[PARALLEL_FN4]]_wrapper(
// CHECK: br label {{%?}}[[TERM_PARALLEL:.+]]
//
// CHECK: [[CHECK_NEXT]]
@@ -283,7 +283,7 @@ int bar(int n){
// CHECK: br i1 [[CMP]], label {{%?}}[[IF_THEN:.+]], label {{%?}}[[IF_ELSE:.+]]
//
// CHECK: [[IF_THEN]]
- // CHECK: call void @__kmpc_kernel_prepare_parallel(i8* bitcast (void (i32*, i32*)* [[PARALLEL_FN4]] to i8*))
+ // CHECK: call void @__kmpc_kernel_prepare_parallel(i8* bitcast (void (i16, i32, i8**)* [[PARALLEL_FN4]]_wrapper to i8*),
// CHECK: call void @llvm.nvvm.barrier0()
// CHECK: call void @llvm.nvvm.barrier0()
// CHECK: br label {{%?}}[[IF_END:.+]]
@@ -303,7 +303,7 @@ int bar(int n){
// CHECK: br label {{%?}}[[TERMINATE:.+]]
//
// CHECK: [[TERMINATE]]
- // CHECK: call void @__kmpc_kernel_deinit()
+ // CHECK: call void @__kmpc_kernel_deinit(
// CHECK: call void @llvm.nvvm.barrier0()
// CHECK: br label {{%?}}[[EXIT]]
//
diff --git a/test/OpenMP/nvptx_param_translate.c b/test/OpenMP/nvptx_param_translate.c
new file mode 100644
index 000000000000..ec123ce3811b
--- /dev/null
+++ b/test/OpenMP/nvptx_param_translate.c
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s
+// expected-no-diagnostics
+
+// CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** %
+// CHECK: call void (i8*, ...) [[MAP_FN]](i8* %
+int main() {
+ double a, b;
+
+#pragma omp target map(tofrom \
+ : a) map(to \
+ : b)
+ {
+#pragma omp taskgroup
+#pragma omp task shared(a)
+ a = b;
+ }
+ return 0;
+}
diff --git a/test/OpenMP/nvptx_target_codegen.cpp b/test/OpenMP/nvptx_target_codegen.cpp
index d7ce7dc7d106..23b40e10c4c8 100644
--- a/test/OpenMP/nvptx_target_codegen.cpp
+++ b/test/OpenMP/nvptx_target_codegen.cpp
@@ -91,7 +91,7 @@ int foo(int n) {
// CHECK: br label {{%?}}[[TERMINATE:.+]]
//
// CHECK: [[TERMINATE]]
- // CHECK: call void @__kmpc_kernel_deinit()
+ // CHECK: call void @__kmpc_kernel_deinit(
// CHECK: call void @llvm.nvvm.barrier0()
// CHECK: br label {{%?}}[[EXIT]]
//
@@ -168,7 +168,7 @@ int foo(int n) {
// CHECK: br label {{%?}}[[TERMINATE:.+]]
//
// CHECK: [[TERMINATE]]
- // CHECK: call void @__kmpc_kernel_deinit()
+ // CHECK: call void @__kmpc_kernel_deinit(
// CHECK: call void @llvm.nvvm.barrier0()
// CHECK: br label {{%?}}[[EXIT]]
//
@@ -278,7 +278,7 @@ int foo(int n) {
// CHECK: br label {{%?}}[[TERMINATE:.+]]
//
// CHECK: [[TERMINATE]]
- // CHECK: call void @__kmpc_kernel_deinit()
+ // CHECK: call void @__kmpc_kernel_deinit(
// CHECK: call void @llvm.nvvm.barrier0()
// CHECK: br label {{%?}}[[EXIT]]
//
@@ -441,7 +441,7 @@ int bar(int n){
// CHECK: br label {{%?}}[[TERMINATE:.+]]
//
// CHECK: [[TERMINATE]]
- // CHECK: call void @__kmpc_kernel_deinit()
+ // CHECK: call void @__kmpc_kernel_deinit(
// CHECK: call void @llvm.nvvm.barrier0()
// CHECK: br label {{%?}}[[EXIT]]
//
@@ -531,7 +531,7 @@ int bar(int n){
// CHECK: br label {{%?}}[[TERMINATE:.+]]
//
// CHECK: [[TERMINATE]]
- // CHECK: call void @__kmpc_kernel_deinit()
+ // CHECK: call void @__kmpc_kernel_deinit(
// CHECK: call void @llvm.nvvm.barrier0()
// CHECK: br label {{%?}}[[EXIT]]
//
@@ -616,7 +616,7 @@ int bar(int n){
// CHECK: br label {{%?}}[[TERMINATE:.+]]
//
// CHECK: [[TERMINATE]]
- // CHECK: call void @__kmpc_kernel_deinit()
+ // CHECK: call void @__kmpc_kernel_deinit(
// CHECK: call void @llvm.nvvm.barrier0()
// CHECK: br label {{%?}}[[EXIT]]
//
diff --git a/test/OpenMP/nvptx_target_firstprivate_codegen.cpp b/test/OpenMP/nvptx_target_firstprivate_codegen.cpp
index 5dcff8e54842..f750be03e052 100644
--- a/test/OpenMP/nvptx_target_firstprivate_codegen.cpp
+++ b/test/OpenMP/nvptx_target_firstprivate_codegen.cpp
@@ -1,15 +1,14 @@
-
// Test target codegen - host bc file has to be created first.
// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc
-// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-64
+// RUN: %clang_cc1 -debug-info-kind=limited -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-64
// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm-bc %s -o %t-x86-host.bc
-// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-32
+// RUN: %clang_cc1 -debug-info-kind=limited -verify -fopenmp -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-32
// expected-no-diagnostics
#ifndef HEADER
#define HEADER
-template<typename tx, typename ty>
-struct TT{
+template <typename tx, typename ty>
+struct TT {
tx X;
ty Y;
};
@@ -23,29 +22,32 @@ int foo(int n, double *ptr) {
float b[10];
double c[5][10];
TT<long long, char> d;
-
- #pragma omp target firstprivate(a)
+
+#pragma omp target firstprivate(a) map(tofrom \
+ : b)
{
+ b[a] = a;
}
-
- // TCHECK: define void @__omp_offloading_{{.+}}(i{{[0-9]+}} [[A_IN:%.+]])
+
+ // TCHECK: define {{.*}}void @__omp_offloading_{{.+}}([10 x float] addrspace(1)* noalias [[B_IN:%.+]], i{{[0-9]+}} [[A_IN:%.+]])
// TCHECK: [[A_ADDR:%.+]] = alloca i{{[0-9]+}},
// TCHECK-NOT: alloca i{{[0-9]+}},
+ // TCHECK-64: call void @llvm.dbg.declare(metadata [10 x float] addrspace(1)** %{{.+}}, metadata !{{[0-9]+}}, metadata !DIExpression())
// TCHECK: store i{{[0-9]+}} [[A_IN]], i{{[0-9]+}}* [[A_ADDR]],
- // TCHECK: ret void
+ // TCHECK: ret void
-#pragma omp target firstprivate(aa,b,c,d)
+#pragma omp target firstprivate(aa, b, c, d)
{
aa += 1;
b[2] = 1.0;
c[1][2] = 1.0;
d.X = 1;
- d.Y = 1;
+ d.Y = 1;
}
-
+
// make sure that firstprivate variables are generated in all cases and that we use those instances for operations inside the
// target region
- // TCHECK: define void @__omp_offloading_{{.+}}(i{{[0-9]+}} [[A2_IN:%.+]], [10 x float]* {{.+}} [[B_IN:%.+]], [5 x [10 x double]]* {{.+}} [[C_IN:%.+]], [[TT]]* {{.+}} [[D_IN:%.+]])
+ // TCHECK: define {{.*}}void @__omp_offloading_{{.+}}(i{{[0-9]+}}{{.*}} [[A2_IN:%.+]], [10 x float]*{{.*}} [[B_IN:%.+]], [5 x [10 x double]]*{{.*}} [[C_IN:%.+]], [[TT]]*{{.*}} [[D_IN:%.+]])
// TCHECK: [[A2_ADDR:%.+]] = alloca i{{[0-9]+}},
// TCHECK: [[B_ADDR:%.+]] = alloca [10 x float]*,
// TCHECK: [[C_ADDR:%.+]] = alloca [5 x [10 x double]]*,
@@ -58,10 +60,12 @@ int foo(int n, double *ptr) {
// TCHECK: store [10 x float]* [[B_IN]], [10 x float]** [[B_ADDR]],
// TCHECK: store [5 x [10 x double]]* [[C_IN]], [5 x [10 x double]]** [[C_ADDR]],
// TCHECK: store [[TT]]* [[D_IN]], [[TT]]** [[D_ADDR]],
- // TCHECK: [[CONV_A2ADDR:%.+]] = bitcast i{{[0-9]+}}* [[A2_ADDR]] to i{{[0-9]+}}*
// TCHECK: [[B_ADDR_REF:%.+]] = load [10 x float]*, [10 x float]** [[B_ADDR]],
+ // TCHECK: [[B_ADDR_REF:%.+]] = load [10 x float]*, [10 x float]** %
// TCHECK: [[C_ADDR_REF:%.+]] = load [5 x [10 x double]]*, [5 x [10 x double]]** [[C_ADDR]],
+ // TCHECK: [[C_ADDR_REF:%.+]] = load [5 x [10 x double]]*, [5 x [10 x double]]** %
// TCHECK: [[D_ADDR_REF:%.+]] = load [[TT]]*, [[TT]]** [[D_ADDR]],
+ // TCHECK: [[D_ADDR_REF:%.+]] = load [[TT]]*, [[TT]]** %
// firstprivate(aa): a_priv = a_in
@@ -74,16 +78,15 @@ int foo(int n, double *ptr) {
// TCHECK: [[C_PRIV_BCAST:%.+]] = bitcast [5 x [10 x double]]* [[C_PRIV]] to i8*
// TCHECK: [[C_IN_BCAST:%.+]] = bitcast [5 x [10 x double]]* [[C_ADDR_REF]] to i8*
// TCHECK: call void @llvm.memcpy.{{.+}}(i8* [[C_PRIV_BCAST]], i8* [[C_IN_BCAST]],{{.+}})
-
+
// firstprivate(d)
// TCHECK: [[D_PRIV_BCAST:%.+]] = bitcast [[TT]]* [[D_PRIV]] to i8*
// TCHECK: [[D_IN_BCAST:%.+]] = bitcast [[TT]]* [[D_ADDR_REF]] to i8*
// TCHECK: call void @llvm.memcpy.{{.+}}(i8* [[D_PRIV_BCAST]], i8* [[D_IN_BCAST]],{{.+}})
- // TCHECK: load i16, i16* [[CONV_A2ADDR]],
+ // TCHECK: load i16, i16* [[A2_ADDR]],
-
- #pragma omp target firstprivate(ptr)
+#pragma omp target firstprivate(ptr)
{
ptr[0]++;
}
@@ -98,13 +101,12 @@ int foo(int n, double *ptr) {
return a;
}
-
-template<typename tx>
+template <typename tx>
tx ftemplate(int n) {
tx a = 0;
tx b[10];
-#pragma omp target firstprivate(a,b)
+#pragma omp target firstprivate(a, b)
{
a += 1;
b[2] += 1;
@@ -113,13 +115,12 @@ tx ftemplate(int n) {
return a;
}
-static
-int fstatic(int n) {
+static int fstatic(int n) {
int a = 0;
char aaa = 0;
int b[10];
-#pragma omp target firstprivate(a,aaa,b)
+#pragma omp target firstprivate(a, aaa, b)
{
a += 1;
aaa += 1;
@@ -129,7 +130,7 @@ int fstatic(int n) {
return a;
}
-// TCHECK: define void @__omp_offloading_{{.+}}(i{{[0-9]+}} [[A_IN:%.+]], i{{[0-9]+}} [[A3_IN:%.+]], [10 x i{{[0-9]+}}]*{{.+}} [[B_IN:%.+]])
+// TCHECK: define {{.*}}void @__omp_offloading_{{.+}}(i{{[0-9]+}}{{.*}} [[A_IN:%.+]], i{{[0-9]+}}{{.*}} [[A3_IN:%.+]], [10 x i{{[0-9]+}}]*{{.+}} [[B_IN:%.+]])
// TCHECK: [[A_ADDR:%.+]] = alloca i{{[0-9]+}},
// TCHECK: [[A3_ADDR:%.+]] = alloca i{{[0-9]+}},
// TCHECK: [[B_ADDR:%.+]] = alloca [10 x i{{[0-9]+}}]*,
@@ -138,9 +139,8 @@ int fstatic(int n) {
// TCHECK: store i{{[0-9]+}} [[A_IN]], i{{[0-9]+}}* [[A_ADDR]],
// TCHECK: store i{{[0-9]+}} [[A3_IN]], i{{[0-9]+}}* [[A3_ADDR]],
// TCHECK: store [10 x i{{[0-9]+}}]* [[B_IN]], [10 x i{{[0-9]+}}]** [[B_ADDR]],
-// TCHECK-64: [[A_CONV:%.+]] = bitcast i{{[0-9]+}}* [[A_ADDR]] to i{{[0-9]+}}*
-// TCHECK: [[A3_CONV:%.+]] = bitcast i{{[0-9]+}}* [[A3_ADDR]] to i8*
// TCHECK: [[B_ADDR_REF:%.+]] = load [10 x i{{[0-9]+}}]*, [10 x i{{[0-9]+}}]** [[B_ADDR]],
+// TCHECK: [[B_ADDR_REF:%.+]] = load [10 x i{{[0-9]+}}]*, [10 x i{{[0-9]+}}]** %
// firstprivate(a): a_priv = a_in
@@ -158,8 +158,8 @@ int fstatic(int n) {
struct S1 {
double a;
- int r1(int n){
- int b = n+1;
+ int r1(int n) {
+ int b = n + 1;
#pragma omp target firstprivate(b)
{
@@ -169,7 +169,7 @@ struct S1 {
return (int)b;
}
- // TCHECK: define void @__omp_offloading_{{.+}}([[S1]]* [[TH:%.+]], i{{[0-9]+}} [[B_IN:%.+]])
+ // TCHECK: define internal void @__omp_offloading_{{.+}}([[S1]]* [[TH:%.+]], i{{[0-9]+}} [[B_IN:%.+]])
// TCHECK: [[TH_ADDR:%.+]] = alloca [[S1]]*,
// TCHECK: [[B_ADDR:%.+]] = alloca i{{[0-9]+}},
// TCHECK-NOT: alloca i{{[0-9]+}},
@@ -185,9 +185,7 @@ struct S1 {
// TCHECK: ret void
};
-
-
-int bar(int n, double *ptr){
+int bar(int n, double *ptr) {
int a = 0;
a += foo(n, ptr);
S1 S;
@@ -200,15 +198,15 @@ int bar(int n, double *ptr){
// template
-// TCHECK: define void @__omp_offloading_{{.+}}(i{{[0-9]+}} [[A_IN:%.+]], [10 x i{{[0-9]+}}]*{{.+}} [[B_IN:%.+]])
+// TCHECK: define internal void @__omp_offloading_{{.+}}(i{{[0-9]+}} [[A_IN:%.+]], [10 x i{{[0-9]+}}]*{{.+}} [[B_IN:%.+]])
// TCHECK: [[A_ADDR:%.+]] = alloca i{{[0-9]+}},
// TCHECK: [[B_ADDR:%.+]] = alloca [10 x i{{[0-9]+}}]*,
// TCHECK-NOT: alloca i{{[0-9]+}},
// TCHECK: [[B_PRIV:%.+]] = alloca [10 x i{{[0-9]+}}],
// TCHECK: store i{{[0-9]+}} [[A_IN]], i{{[0-9]+}}* [[A_ADDR]],
// TCHECK: store [10 x i{{[0-9]+}}]* [[B_IN]], [10 x i{{[0-9]+}}]** [[B_ADDR]],
-// TCHECK-64: [[A_ADDR_CONV:%.+]] = bitcast i{{[0-9]+}}* [[A_ADDR]] to i{{[0-9]+}}*
// TCHECK: [[B_ADDR_REF:%.+]] = load [10 x i{{[0-9]+}}]*, [10 x i{{[0-9]+}}]** [[B_ADDR]],
+// TCHECK: [[B_ADDR_REF:%.+]] = load [10 x i{{[0-9]+}}]*, [10 x i{{[0-9]+}}]** %
// firstprivate(a)
// TCHECK-NOT: store i{{[0-9]+}} %{{.+}}, i{{[0-9]+}}*
diff --git a/test/OpenMP/nvptx_target_teams_codegen.cpp b/test/OpenMP/nvptx_target_teams_codegen.cpp
index e823eabbb10f..b79fd185d77a 100644
--- a/test/OpenMP/nvptx_target_teams_codegen.cpp
+++ b/test/OpenMP/nvptx_target_teams_codegen.cpp
@@ -60,7 +60,7 @@ int bar(int n){
//
// CHECK: [[AWAIT_WORK]]
// CHECK: call void @llvm.nvvm.barrier0()
- // CHECK: [[KPR:%.+]] = call i1 @__kmpc_kernel_parallel(i8** [[OMP_WORK_FN]])
+ // CHECK: [[KPR:%.+]] = call i1 @__kmpc_kernel_parallel(i8** [[OMP_WORK_FN]], i8*** %shared_args)
// CHECK: [[KPRB:%.+]] = zext i1 [[KPR]] to i8
// store i8 [[KPRB]], i8* [[OMP_EXEC_STATUS]], align 1
// CHECK: [[WORK:%.+]] = load i8*, i8** [[OMP_WORK_FN]],
@@ -121,11 +121,13 @@ int bar(int n){
// CHECK: [[ACV:%.+]] = load i[[SZ]], i[[SZ]]* [[AC]], align
// CHECK: store i[[SZ]] [[ACV]], i[[SZ]]* [[A_ADDR_T:%.+]], align
// CHECK: [[CONV2:%.+]] = bitcast i[[SZ]]* [[A_ADDR_T]] to i8*
- // CHECK: store i8 49, i8* [[CONV2]], align
+ // CHECK: [[LD_CONV2:%.+]] = load i8, i8* [[CONV2]],
+ // CHECK: store i8 [[LD_CONV2]], i8* [[A_PRIV:%[^,]+]],
+ // CHECK: store i8 49, i8* [[A_PRIV]], align
// CHECK: br label {{%?}}[[TERMINATE:.+]]
//
// CHECK: [[TERMINATE]]
- // CHECK: call void @__kmpc_kernel_deinit()
+ // CHECK: call void @__kmpc_kernel_deinit(
// CHECK: call void @llvm.nvvm.barrier0()
// CHECK: br label {{%?}}[[EXIT]]
//
@@ -146,7 +148,7 @@ int bar(int n){
//
// CHECK: [[AWAIT_WORK]]
// CHECK: call void @llvm.nvvm.barrier0()
- // CHECK: [[KPR:%.+]] = call i1 @__kmpc_kernel_parallel(i8** [[OMP_WORK_FN]])
+ // CHECK: [[KPR:%.+]] = call i1 @__kmpc_kernel_parallel(i8** [[OMP_WORK_FN]], i8*** %shared_args)
// CHECK: [[KPRB:%.+]] = zext i1 [[KPR]] to i8
// store i8 [[KPRB]], i8* [[OMP_EXEC_STATUS]], align 1
// CHECK: [[WORK:%.+]] = load i8*, i8** [[OMP_WORK_FN]],
@@ -207,11 +209,13 @@ int bar(int n){
// CHECK: [[ACV:%.+]] = load i[[SZ]], i[[SZ]]* [[AC]], align
// CHECK: store i[[SZ]] [[ACV]], i[[SZ]]* [[AA_ADDR_T:%.+]], align
// CHECK: [[CONV2:%.+]] = bitcast i[[SZ]]* [[AA_ADDR_T]] to i16*
- // CHECK: store i16 1, i16* [[CONV2]], align
+ // CHECK: [[LD_CONV2:%.+]] = load i16, i16* [[CONV2]],
+ // CHECK: store i16 [[LD_CONV2]], i16* [[A_PRIV:%[^,]+]],
+ // CHECK: store i16 1, i16* [[A_PRIV]], align
// CHECK: br label {{%?}}[[TERMINATE:.+]]
//
// CHECK: [[TERMINATE]]
- // CHECK: call void @__kmpc_kernel_deinit()
+ // CHECK: call void @__kmpc_kernel_deinit(
// CHECK: call void @llvm.nvvm.barrier0()
// CHECK: br label {{%?}}[[EXIT]]
//
diff --git a/test/OpenMP/nvptx_teams_reduction_codegen.cpp b/test/OpenMP/nvptx_teams_reduction_codegen.cpp
index ae129ebfae4d..d77231807fb4 100644
--- a/test/OpenMP/nvptx_teams_reduction_codegen.cpp
+++ b/test/OpenMP/nvptx_teams_reduction_codegen.cpp
@@ -84,7 +84,7 @@ int bar(int n){
// CHECK: br label %[[EXIT]]
//
// CHECK: [[EXIT]]
- // CHECK: call void @__kmpc_kernel_deinit()
+ // CHECK: call void @__kmpc_kernel_deinit(
//
// Reduction function
@@ -360,7 +360,7 @@ int bar(int n){
// CHECK: br label %[[EXIT]]
//
// CHECK: [[EXIT]]
- // CHECK: call void @__kmpc_kernel_deinit()
+ // CHECK: call void @__kmpc_kernel_deinit(
//
// Reduction function
@@ -776,7 +776,7 @@ int bar(int n){
// CHECK: br label %[[EXIT]]
//
// CHECK: [[EXIT]]
- // CHECK: call void @__kmpc_kernel_deinit()
+ // CHECK: call void @__kmpc_kernel_deinit(
//
// Reduction function
diff --git a/test/OpenMP/openmp_offload_codegen.cpp b/test/OpenMP/openmp_offload_codegen.cpp
new file mode 100644
index 000000000000..f89bccf3b552
--- /dev/null
+++ b/test/OpenMP/openmp_offload_codegen.cpp
@@ -0,0 +1,36 @@
+// Test device for mapping codegen.
+///==========================================================================///
+
+// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -S -emit-llvm %s -o - 2>&1 \
+// RUN: | FileCheck -check-prefix=CK1 %s
+
+// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc
+// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix CK1-DEVICE
+
+// expected-no-diagnostics
+
+#ifdef CK1
+
+void target_maps_parallel_integer(int a){
+ int ParamToKernel = a;
+#pragma omp target map(tofrom: ParamToKernel)
+ {
+ ParamToKernel += 1;
+ }
+}
+
+// CK1-DEVICE: {{.*}}void @__omp_offloading_{{.*}}(i32* dereferenceable(4){{.*}}
+
+// CK1: {{.*}}void {{.*}}target_maps_parallel_integer{{.*}} {
+
+// CK1: [[GEPOBP:%.+]] = getelementptr inbounds {{.*}}
+// CK1: [[GEPOBPBIT:%.+]] = bitcast i8** [[GEPOBP]]
+// CK1: store i32* %ParamToKernel, i32** [[GEPOBPBIT]]
+// CK1: [[GEPOP:%.+]] = getelementptr inbounds {{.*}}
+// CK1: [[GEPOPBIT:%.+]] = bitcast i8** [[GEPOP]]
+// CK1: store i32* %ParamToKernel, i32** [[GEPOPBIT]]
+// CK1: [[GEPOBPARG:%.+]] = getelementptr inbounds {{.*}}
+// CK1: [[GEPOPARG:%.+]] = getelementptr inbounds {{.*}}
+// CK1: call {{.*}}tgt_target({{.*}}i8** [[GEPOBPARG]], i8** [[GEPOPARG]]
+
+#endif \ No newline at end of file
diff --git a/test/OpenMP/openmp_win_codegen.cpp b/test/OpenMP/openmp_win_codegen.cpp
new file mode 100644
index 000000000000..45b2c185cb8f
--- /dev/null
+++ b/test/OpenMP/openmp_win_codegen.cpp
@@ -0,0 +1,61 @@
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple x86_64-pc-windows-msvc18.0.0 -std=c++11 -fms-compatibility-version=18 -fms-extensions -emit-llvm %s -fexceptions -fcxx-exceptions -o - -O1 | FileCheck %s
+// REQUIRES: x86-registered-target
+// expected-no-diagnostics
+
+void foo();
+void bar();
+
+struct Test {
+ static void main() {
+ int failed = 0;
+ int j = 2;
+
+#pragma omp parallel
+ {
+ int local_j = 3;
+#pragma omp single copyprivate(local_j)
+ {
+ local_j = 4;
+ }
+
+ // Assure reports a data race, but value written to "j"
+ // should always be the same.
+ j = local_j;
+ }
+
+ }
+};
+
+// CHECK-LABEL: @main
+int main() {
+ // CHECK: call void @{{.+}}main
+ Test::main();
+ // CHECK: call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* {{.*}}@0, i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* [[OUTLINED:@.+]] to void (i32*, i32*, ...)*))
+#pragma omp parallel
+ {
+ try {
+ foo();
+ } catch (int t) {
+#pragma omp critical
+ {
+ bar();
+ };
+ }
+ };
+ // CHECK: ret i32 0
+ return 0;
+}
+
+// CHECK: define internal void [[OUTLINED]](
+// CHECK: [[GID:%.+]] = {{.*}}call i32 @__kmpc_global_thread_num(%ident_t* {{.*}}@0)
+// CHECK: invoke void @{{.+}}foo
+// CHECK: catchswitch within
+// CHECK: catchpad within
+// CHECK: call void @__kmpc_critical(%ident_t* {{.*}}@0, i32 [[GID]],
+// CHECK: invoke void @{{.+}}bar
+// CHECK: call void @__kmpc_end_critical(%ident_t* {{.*}}@0, i32 [[GID]],
+// CHECK: catchret from
+// CHECK: cleanuppad within
+// CHECK: call void @__kmpc_end_critical(%ident_t* {{.*}}@0, i32 [[GID]],
+// CHECK: cleanupret from
+
diff --git a/test/OpenMP/ordered_codegen.cpp b/test/OpenMP/ordered_codegen.cpp
index bd7c07051b04..af6a8722438d 100644
--- a/test/OpenMP/ordered_codegen.cpp
+++ b/test/OpenMP/ordered_codegen.cpp
@@ -216,7 +216,7 @@ float f[10];
// CHECK-LABEL: foo_simd
void foo_simd(int low, int up) {
// CHECK: store float 0.000000e+00, float* %{{.+}}, align {{[0-9]+}}, !llvm.mem.parallel_loop_access !
- // CHECK-NEXT: call void [[CAP_FUNC:@.+]](i32* %{{.+}}) #{{[0-9]+}}, !llvm.mem.parallel_loop_access !
+ // CHECK-NEXT: call void [[CAP_FUNC:@.+]](i32* %{{.+}}), !llvm.mem.parallel_loop_access !
#pragma omp simd
for (int i = low; i < up; ++i) {
f[i] = 0.0;
@@ -224,7 +224,7 @@ void foo_simd(int low, int up) {
f[i] = 1.0;
}
// CHECK: store float 0.000000e+00, float* %{{.+}}, align {{[0-9]+}}
- // CHECK-NEXT: call void [[CAP_FUNC:@.+]](i32* %{{.+}}) #{{[0-9]+}}
+ // CHECK-NEXT: call void [[CAP_FUNC:@.+]](i32* %{{.+}})
#pragma omp for simd ordered
for (int i = low; i < up; ++i) {
f[i] = 0.0;
diff --git a/test/OpenMP/parallel_ast_print.cpp b/test/OpenMP/parallel_ast_print.cpp
index 1e24c6e059bd..09141db5841f 100644
--- a/test/OpenMP/parallel_ast_print.cpp
+++ b/test/OpenMP/parallel_ast_print.cpp
@@ -135,6 +135,9 @@ struct S {
// CHECK-NEXT: #pragma omp threadprivate(S<long>::TS)
// CHECK-NEXT: }
+int thrp;
+#pragma omp threadprivate(thrp)
+
template <typename T, int C>
T tmain(T argc, T *argv) {
T b = argc, c, d, e, f, g;
@@ -143,7 +146,7 @@ T tmain(T argc, T *argv) {
T arr[C][10], arr1[C];
#pragma omp parallel
a=2;
-#pragma omp parallel default(none), private(argc,b) firstprivate(argv) shared (d) if (parallel:argc > 0) num_threads(C) copyin(S<T>::TS) proc_bind(master) reduction(+:c, arr1[argc]) reduction(max:e, arr[:C][0:10])
+#pragma omp parallel default(none), private(argc,b) firstprivate(argv) shared (d) if (parallel:argc > 0) num_threads(C) copyin(S<T>::TS, thrp) proc_bind(master) reduction(+:c, arr1[argc]) reduction(max:e, arr[:C][0:10])
foo();
#pragma omp parallel if (C) num_threads(s) proc_bind(close) reduction(^:e, f, arr[0:C][:argc]) reduction(&& : g)
foo();
@@ -157,7 +160,7 @@ T tmain(T argc, T *argv) {
// CHECK-NEXT: T arr[C][10], arr1[C];
// CHECK-NEXT: #pragma omp parallel
// CHECK-NEXT: a = 2;
-// CHECK-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) shared(d) if(parallel: argc > 0) num_threads(C) copyin(S<T>::TS) proc_bind(master) reduction(+: c,arr1[argc]) reduction(max: e,arr[:C][0:10])
+// CHECK-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) shared(d) if(parallel: argc > 0) num_threads(C) copyin(S<T>::TS,thrp) proc_bind(master) reduction(+: c,arr1[argc]) reduction(max: e,arr[:C][0:10])
// CHECK-NEXT: foo()
// CHECK-NEXT: #pragma omp parallel if(C) num_threads(s) proc_bind(close) reduction(^: e,f,arr[0:C][:argc]) reduction(&&: g)
// CHECK-NEXT: foo()
@@ -168,7 +171,7 @@ T tmain(T argc, T *argv) {
// CHECK-NEXT: int arr[5][10], arr1[5];
// CHECK-NEXT: #pragma omp parallel
// CHECK-NEXT: a = 2;
-// CHECK-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) shared(d) if(parallel: argc > 0) num_threads(5) copyin(S<int>::TS) proc_bind(master) reduction(+: c,arr1[argc]) reduction(max: e,arr[:5][0:10])
+// CHECK-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) shared(d) if(parallel: argc > 0) num_threads(5) copyin(S<int>::TS,thrp) proc_bind(master) reduction(+: c,arr1[argc]) reduction(max: e,arr[:5][0:10])
// CHECK-NEXT: foo()
// CHECK-NEXT: #pragma omp parallel if(5) num_threads(s) proc_bind(close) reduction(^: e,f,arr[0:5][:argc]) reduction(&&: g)
// CHECK-NEXT: foo()
@@ -179,7 +182,7 @@ T tmain(T argc, T *argv) {
// CHECK-NEXT: long arr[1][10], arr1[1];
// CHECK-NEXT: #pragma omp parallel
// CHECK-NEXT: a = 2;
-// CHECK-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) shared(d) if(parallel: argc > 0) num_threads(1) copyin(S<long>::TS) proc_bind(master) reduction(+: c,arr1[argc]) reduction(max: e,arr[:1][0:10])
+// CHECK-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) shared(d) if(parallel: argc > 0) num_threads(1) copyin(S<long>::TS,thrp) proc_bind(master) reduction(+: c,arr1[argc]) reduction(max: e,arr[:1][0:10])
// CHECK-NEXT: foo()
// CHECK-NEXT: #pragma omp parallel if(1) num_threads(s) proc_bind(close) reduction(^: e,f,arr[0:1][:argc]) reduction(&&: g)
// CHECK-NEXT: foo()
diff --git a/test/OpenMP/parallel_codegen.cpp b/test/OpenMP/parallel_codegen.cpp
index 23b323778b47..77e8efded68b 100644
--- a/test/OpenMP/parallel_codegen.cpp
+++ b/test/OpenMP/parallel_codegen.cpp
@@ -53,7 +53,7 @@ int main (int argc, char **argv) {
// CHECK-DEBUG: ret i32
// CHECK-DEBUG-NEXT: }
-// CHECK: define internal {{.*}}void [[OMP_OUTLINED]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i{{[0-9]+}}{{.*}} [[VLA_SIZE:%.+]], i32* [[VLA_ADDR:%[^)]+]])
+// CHECK: define internal {{.*}}void [[OMP_OUTLINED]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i{{[0-9]+}}{{.*}} [[VLA_SIZE:%.+]], i32* {{.+}} [[VLA_ADDR:%[^)]+]])
// CHECK-SAME: #[[FN_ATTRS:[0-9]+]]
// CHECK: store i32* [[VLA_ADDR]], i32** [[VLA_PTR_ADDR:%.+]],
// CHECK: [[VLA_REF:%.+]] = load i32*, i32** [[VLA_PTR_ADDR]]
@@ -64,7 +64,7 @@ int main (int argc, char **argv) {
// CHECK: call {{.*}}void @{{.+terminate.*|abort}}(
// CHECK-NEXT: unreachable
// CHECK-NEXT: }
-// CHECK-DEBUG: define internal void [[OMP_OUTLINED_DEBUG:@.+]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i64 [[VLA_SIZE:%.+]], i32* [[VLA_ADDR:%[^)]+]])
+// CHECK-DEBUG: define internal void [[OMP_OUTLINED_DEBUG:@.+]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i64 [[VLA_SIZE:%.+]], i32* {{.+}} [[VLA_ADDR:%[^)]+]])
// CHECK-DEBUG-SAME: #[[FN_ATTRS:[0-9]+]]
// CHECK-DEBUG: store i32* [[VLA_ADDR]], i32** [[VLA_PTR_ADDR:%.+]],
// CHECK-DEBUG: [[VLA_REF:%.+]] = load i32*, i32** [[VLA_PTR_ADDR]]
@@ -80,7 +80,7 @@ int main (int argc, char **argv) {
// CHECK-DAG: declare {{.*}}void @__kmpc_fork_call(%ident_t*, i32, void (i32*, i32*, ...)*, ...)
// CHECK-DEBUG-DAG: define linkonce_odr void [[FOO]](i32 %argc)
// CHECK-DEBUG-DAG: declare void @__kmpc_fork_call(%ident_t*, i32, void (i32*, i32*, ...)*, ...)
-// CHECK-DEBUG-DAG: define internal void [[OMP_OUTLINED]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i64 [[VLA_SIZE:%.+]], i32* [[VLA_ADDR:%[^)]+]])
+// CHECK-DEBUG-DAG: define internal void [[OMP_OUTLINED]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i64 [[VLA_SIZE:%.+]], i32* {{.+}} [[VLA_ADDR:%[^)]+]])
// CHECK-DEBUG-DAG: call void [[OMP_OUTLINED_DEBUG]]
// CHECK: define linkonce_odr {{[a-z\_\b]*[ ]?i32}} [[TMAIN]](i8** %argc)
@@ -109,7 +109,7 @@ int main (int argc, char **argv) {
// CHECK: call {{.*}}void @{{.+terminate.*|abort}}(
// CHECK-NEXT: unreachable
// CHECK-NEXT: }
-// CHECK-DEBUG: define internal void [[OMP_OUTLINED]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i8*** dereferenceable({{4|8}}) %argc)
+// CHECK-DEBUG: define internal void [[OMP_OUTLINED_DEBUG:@.+]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i8*** dereferenceable({{4|8}}) %argc)
// CHECK-DEBUG: store i8*** %argc, i8**** [[ARGC_PTR_ADDR:%.+]],
// CHECK-DEBUG: [[ARGC_REF:%.+]] = load i8***, i8**** [[ARGC_PTR_ADDR]]
// CHECK-DEBUG-NEXT: [[ARGC:%.+]] = load i8**, i8*** [[ARGC_REF]]
@@ -120,7 +120,9 @@ int main (int argc, char **argv) {
// CHECK-DEBUG-NEXT: }
// CHECK: define linkonce_odr {{.*}}void [[FOO1]](i8** %argc)
-// CHECK-DEBUG: define linkonce_odr void [[FOO1]](i8** %argc)
+// CHECK-DEBUG-DAG: define linkonce_odr void [[FOO1]](i8** %argc)
+// CHECK-DEBUG-DAG: define internal void [[OMP_OUTLINED]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i8*** dereferenceable({{4|8}}) %argc)
+// CHECK-DEBUG-DAG: call void [[OMP_OUTLINED_DEBUG]]({{[^)]+}}){{[^,]*}}, !dbg
// CHECK: attributes #[[FN_ATTRS]] = {{.+}} nounwind
// CHECK-DEBUG: attributes #[[FN_ATTRS]] = {{.+}} nounwind
diff --git a/test/OpenMP/parallel_firstprivate_messages.cpp b/test/OpenMP/parallel_firstprivate_messages.cpp
index fc0eb4c7d358..b2cb4ff131ef 100644
--- a/test/OpenMP/parallel_firstprivate_messages.cpp
+++ b/test/OpenMP/parallel_firstprivate_messages.cpp
@@ -56,7 +56,7 @@ using A::x;
}
int main(int argc, char **argv) {
- const int d = 5;
+ const int d = 5; // expected-note {{variable 'd' declared const here}}
const int da[5] = { 0 };
S4 e(4);
S5 g(5);
@@ -72,6 +72,8 @@ int main(int argc, char **argv) {
#pragma omp parallel firstprivate (argc)
#pragma omp parallel firstprivate (S1) // expected-error {{'S1' does not refer to a value}}
#pragma omp parallel firstprivate (a, b, c, d, f) // expected-error {{firstprivate variable with incomplete type 'S1'}}
+ #pragma omp parallel firstprivate (d)
+ d = 5; // expected-error {{cannot assign to variable 'd' with const-qualified type}}
#pragma omp parallel firstprivate (argv[1]) // expected-error {{expected variable name}}
#pragma omp parallel firstprivate(ba)
#pragma omp parallel firstprivate(ca)
diff --git a/test/OpenMP/parallel_for_codegen.cpp b/test/OpenMP/parallel_for_codegen.cpp
index 1324ee67b615..1773619bce20 100644
--- a/test/OpenMP/parallel_for_codegen.cpp
+++ b/test/OpenMP/parallel_for_codegen.cpp
@@ -8,6 +8,7 @@
#define HEADER
// CHECK-DAG: [[IDENT_T_TY:%.+]] = type { i32, i32, i32, i32, i8* }
+// CHECK-DAG: [[LOOP_LOC:@.+]] = private unnamed_addr constant [[IDENT_T_TY]] { i32 0, i32 514, i32 0, i32 0, i8*
// CHECK-LABEL: with_var_schedule
void with_var_schedule() {
@@ -19,8 +20,8 @@ void with_var_schedule() {
// CHECK: [[CHUNK:%.+]] = load i8*, i8** %
// CHECK: [[CHUNK_VAL:%.+]] = load i8, i8* [[CHUNK]],
// CHECK: [[CHUNK_SIZE:%.+]] = sext i8 [[CHUNK_VAL]] to i64
-// CHECK: call void @__kmpc_for_static_init_8u([[IDENT_T_TY]]* [[DEFAULT_LOC:@[^,]+]], i32 [[GTID:%[^,]+]], i32 33, i32* [[IS_LAST:%[^,]+]], i64* [[OMP_LB:%[^,]+]], i64* [[OMP_UB:%[^,]+]], i64* [[OMP_ST:%[^,]+]], i64 1, i64 [[CHUNK_SIZE]])
-// CHECK: call void @__kmpc_for_static_fini([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]])
+// CHECK: call void @__kmpc_for_static_init_8u([[IDENT_T_TY]]* [[LOOP_LOC]], i32 [[GTID:%[^,]+]], i32 33, i32* [[IS_LAST:%[^,]+]], i64* [[OMP_LB:%[^,]+]], i64* [[OMP_UB:%[^,]+]], i64* [[OMP_ST:%[^,]+]], i64 1, i64 [[CHUNK_SIZE]])
+// CHECK: call void @__kmpc_for_static_fini([[IDENT_T_TY]]* [[LOOP_LOC]], i32 [[GTID]])
#pragma omp parallel for schedule(static, char(a))
for (unsigned long long i = 1; i < 2; ++i) {
}
@@ -32,9 +33,7 @@ void without_schedule_clause(float *a, float *b, float *c, float *d) {
// CHECK: call void ([[IDENT_T_TY]]*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call([[IDENT_T_TY]]* [[DEFAULT_LOC:[@%].+]], i32 4, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, float**, float**, float**, float**)* [[OMP_PARALLEL_FUNC:@.+]] to void (i32*, i32*, ...)*),
// CHECK: define internal void [[OMP_PARALLEL_FUNC]](i32* noalias [[GTID_PARAM_ADDR:%.+]], i32* noalias %{{.+}}, float** dereferenceable(8) %{{.+}}, float** dereferenceable(8) %{{.+}}, float** dereferenceable(8) %{{.+}}, float** dereferenceable(8) %{{.+}})
// CHECK: store i32* [[GTID_PARAM_ADDR]], i32** [[GTID_REF_ADDR:%.+]],
-// CHECK: [[GTID_REF:%.+]] = load i32*, i32** [[GTID_REF_ADDR]],
-// CHECK: [[GTID:%.+]] = load i32, i32* [[GTID_REF]],
-// CHECK: call void @__kmpc_for_static_init_4([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], i32 34, i32* [[IS_LAST:%[^,]+]], i32* [[OMP_LB:%[^,]+]], i32* [[OMP_UB:%[^,]+]], i32* [[OMP_ST:%[^,]+]], i32 1, i32 1)
+// CHECK: call void @__kmpc_for_static_init_4([[IDENT_T_TY]]* [[LOOP_LOC]], i32 [[GTID:%.+]], i32 34, i32* [[IS_LAST:%[^,]+]], i32* [[OMP_LB:%[^,]+]], i32* [[OMP_UB:%[^,]+]], i32* [[OMP_ST:%[^,]+]], i32 1, i32 1)
// UB = min(UB, GlobalUB)
// CHECK-NEXT: [[UB:%.+]] = load i32, i32* [[OMP_UB]]
// CHECK-NEXT: [[UBCMP:%.+]] = icmp sgt i32 [[UB]], 4571423
@@ -65,7 +64,7 @@ void without_schedule_clause(float *a, float *b, float *c, float *d) {
// CHECK-NEXT: br label %{{.+}}
}
// CHECK: [[LOOP1_END]]
-// CHECK: call void @__kmpc_for_static_fini([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]])
+// CHECK: call void @__kmpc_for_static_fini([[IDENT_T_TY]]* [[LOOP_LOC]], i32 [[GTID]])
// CHECK: ret void
}
@@ -75,9 +74,7 @@ void static_not_chunked(float *a, float *b, float *c, float *d) {
// CHECK: call void ([[IDENT_T_TY]]*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call([[IDENT_T_TY]]* [[DEFAULT_LOC:[@%].+]], i32 4, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, float**, float**, float**, float**)* [[OMP_PARALLEL_FUNC:@.+]] to void (i32*, i32*, ...)*),
// CHECK: define internal void [[OMP_PARALLEL_FUNC]](i32* noalias [[GTID_PARAM_ADDR:%.+]], i32* noalias %{{.+}}, float** dereferenceable(8) %{{.+}}, float** dereferenceable(8) %{{.+}}, float** dereferenceable(8) %{{.+}}, float** dereferenceable(8) %{{.+}})
// CHECK: store i32* [[GTID_PARAM_ADDR]], i32** [[GTID_REF_ADDR:%.+]],
-// CHECK: [[GTID_REF:%.+]] = load i32*, i32** [[GTID_REF_ADDR]],
-// CHECK: [[GTID:%.+]] = load i32, i32* [[GTID_REF]],
-// CHECK: call void @__kmpc_for_static_init_4([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], i32 34, i32* [[IS_LAST:%[^,]+]], i32* [[OMP_LB:%[^,]+]], i32* [[OMP_UB:%[^,]+]], i32* [[OMP_ST:%[^,]+]], i32 1, i32 1)
+// CHECK: call void @__kmpc_for_static_init_4([[IDENT_T_TY]]* [[LOOP_LOC]], i32 [[GTID:%.+]], i32 34, i32* [[IS_LAST:%[^,]+]], i32* [[OMP_LB:%[^,]+]], i32* [[OMP_UB:%[^,]+]], i32* [[OMP_ST:%[^,]+]], i32 1, i32 1)
// UB = min(UB, GlobalUB)
// CHECK-NEXT: [[UB:%.+]] = load i32, i32* [[OMP_UB]]
// CHECK-NEXT: [[UBCMP:%.+]] = icmp sgt i32 [[UB]], 4571423
@@ -108,7 +105,7 @@ void static_not_chunked(float *a, float *b, float *c, float *d) {
// CHECK-NEXT: br label %{{.+}}
}
// CHECK: [[LOOP1_END]]
-// CHECK: call void @__kmpc_for_static_fini([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]])
+// CHECK: call void @__kmpc_for_static_fini([[IDENT_T_TY]]* [[LOOP_LOC]], i32 [[GTID]])
// CHECK: ret void
}
@@ -118,9 +115,7 @@ void static_chunked(float *a, float *b, float *c, float *d) {
// CHECK: call void ([[IDENT_T_TY]]*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call([[IDENT_T_TY]]* [[DEFAULT_LOC:[@%].+]], i32 4, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, float**, float**, float**, float**)* [[OMP_PARALLEL_FUNC:@.+]] to void (i32*, i32*, ...)*),
// CHECK: define internal void [[OMP_PARALLEL_FUNC]](i32* noalias [[GTID_PARAM_ADDR:%.+]], i32* noalias %{{.+}}, float** dereferenceable(8) %{{.+}}, float** dereferenceable(8) %{{.+}}, float** dereferenceable(8) %{{.+}}, float** dereferenceable(8) %{{.+}})
// CHECK: store i32* [[GTID_PARAM_ADDR]], i32** [[GTID_REF_ADDR:%.+]],
-// CHECK: [[GTID_REF:%.+]] = load i32*, i32** [[GTID_REF_ADDR]],
-// CHECK: [[GTID:%.+]] = load i32, i32* [[GTID_REF]],
-// CHECK: call void @__kmpc_for_static_init_4u([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], i32 33, i32* [[IS_LAST:%[^,]+]], i32* [[OMP_LB:%[^,]+]], i32* [[OMP_UB:%[^,]+]], i32* [[OMP_ST:%[^,]+]], i32 1, i32 5)
+// CHECK: call void @__kmpc_for_static_init_4u([[IDENT_T_TY]]* [[LOOP_LOC]], i32 [[GTID:%.+]], i32 33, i32* [[IS_LAST:%[^,]+]], i32* [[OMP_LB:%[^,]+]], i32* [[OMP_UB:%[^,]+]], i32* [[OMP_ST:%[^,]+]], i32 1, i32 5)
// UB = min(UB, GlobalUB)
// CHECK: [[UB:%.+]] = load i32, i32* [[OMP_UB]]
// CHECK-NEXT: [[UBCMP:%.+]] = icmp ugt i32 [[UB]], 16908288
@@ -170,7 +165,7 @@ void static_chunked(float *a, float *b, float *c, float *d) {
// CHECK-NEXT: store i32 [[ADD_UB]], i32* [[OMP_UB]]
// CHECK: [[O_LOOP1_END]]
-// CHECK: call void @__kmpc_for_static_fini([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]])
+// CHECK: call void @__kmpc_for_static_fini([[IDENT_T_TY]]* [[LOOP_LOC]], i32 [[GTID]])
// CHECK: ret void
}
@@ -180,9 +175,7 @@ void dynamic1(float *a, float *b, float *c, float *d) {
// CHECK: call void ([[IDENT_T_TY]]*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call([[IDENT_T_TY]]* [[DEFAULT_LOC:[@%].+]], i32 4, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, float**, float**, float**, float**)* [[OMP_PARALLEL_FUNC:@.+]] to void (i32*, i32*, ...)*),
// CHECK: define internal void [[OMP_PARALLEL_FUNC]](i32* noalias [[GTID_PARAM_ADDR:%.+]], i32* noalias %{{.+}}, float** dereferenceable(8) %{{.+}}, float** dereferenceable(8) %{{.+}}, float** dereferenceable(8) %{{.+}}, float** dereferenceable(8) %{{.+}})
// CHECK: store i32* [[GTID_PARAM_ADDR]], i32** [[GTID_REF_ADDR:%.+]],
-// CHECK: [[GTID_REF:%.+]] = load i32*, i32** [[GTID_REF_ADDR]],
-// CHECK: [[GTID:%.+]] = load i32, i32* [[GTID_REF]],
-// CHECK: call void @__kmpc_dispatch_init_8u([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], i32 35, i64 0, i64 16908287, i64 1, i64 1)
+// CHECK: call void @__kmpc_dispatch_init_8u([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID:%.+]], i32 35, i64 0, i64 16908287, i64 1, i64 1)
//
// CHECK: [[HASWORK:%.+]] = call i32 @__kmpc_dispatch_next_8u([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], i32* [[OMP_ISLAST:%[^,]+]], i64* [[OMP_LB:%[^,]+]], i64* [[OMP_UB:%[^,]+]], i64* [[OMP_ST:%[^,]+]])
// CHECK-NEXT: [[O_CMP:%.+]] = icmp ne i32 [[HASWORK]], 0
@@ -224,9 +217,7 @@ void guided7(float *a, float *b, float *c, float *d) {
// CHECK: call void ([[IDENT_T_TY]]*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call([[IDENT_T_TY]]* [[DEFAULT_LOC:[@%].+]], i32 4, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, float**, float**, float**, float**)* [[OMP_PARALLEL_FUNC:@.+]] to void (i32*, i32*, ...)*),
// CHECK: define internal void [[OMP_PARALLEL_FUNC]](i32* noalias [[GTID_PARAM_ADDR:%.+]], i32* noalias %{{.+}}, float** dereferenceable(8) %{{.+}}, float** dereferenceable(8) %{{.+}}, float** dereferenceable(8) %{{.+}}, float** dereferenceable(8) %{{.+}})
// CHECK: store i32* [[GTID_PARAM_ADDR]], i32** [[GTID_REF_ADDR:%.+]],
-// CHECK: [[GTID_REF:%.+]] = load i32*, i32** [[GTID_REF_ADDR]],
-// CHECK: [[GTID:%.+]] = load i32, i32* [[GTID_REF]],
-// CHECK: call void @__kmpc_dispatch_init_8u([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], i32 36, i64 0, i64 16908287, i64 1, i64 7)
+// CHECK: call void @__kmpc_dispatch_init_8u([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID:%.+]], i32 36, i64 0, i64 16908287, i64 1, i64 7)
//
// CHECK: [[HASWORK:%.+]] = call i32 @__kmpc_dispatch_next_8u([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], i32* [[OMP_ISLAST:%[^,]+]], i64* [[OMP_LB:%[^,]+]], i64* [[OMP_UB:%[^,]+]], i64* [[OMP_ST:%[^,]+]])
// CHECK-NEXT: [[O_CMP:%.+]] = icmp ne i32 [[HASWORK]], 0
@@ -270,12 +261,8 @@ void test_auto(float *a, float *b, float *c, float *d) {
// CHECK: call void ([[IDENT_T_TY]]*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call([[IDENT_T_TY]]* [[DEFAULT_LOC:[@%].+]], i32 6, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*, i32*, float**, float**, float**, float**)* [[OMP_PARALLEL_FUNC:@.+]] to void (i32*, i32*, ...)*),
// CHECK: define internal void [[OMP_PARALLEL_FUNC]](i32* noalias [[GTID_PARAM_ADDR:%.+]], i32* noalias %{{.+}}, i32* dereferenceable(4) %{{.+}}, i32* dereferenceable(4) %{{.+}}, float** dereferenceable(8) %{{.+}}, float** dereferenceable(8) %{{.+}}, float** dereferenceable(8) %{{.+}}, float** dereferenceable(8) %{{.+}})
// CHECK: store i32* [[GTID_PARAM_ADDR]], i32** [[GTID_REF_ADDR:%.+]],
-// CHECK: [[GTID_REF:%.+]] = load i32*, i32** [[GTID_REF_ADDR]],
-// CHECK: [[GTID:%.+]] = load i32, i32* [[GTID_REF]],
-// CHECK: call void @__kmpc_dispatch_init_8([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], i32 38, i64 0, i64 [[LAST_ITER:%[^,]+]], i64 1, i64 1)
+// CHECK: call void @__kmpc_dispatch_init_8([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID:%.+]], i32 38, i64 0, i64 [[LAST_ITER:%[^,]+]], i64 1, i64 1)
//
-// CHECK: [[GTID_REF:%.+]] = load i32*, i32** [[GTID_REF_ADDR]],
-// CHECK: [[GTID:%.+]] = load i32, i32* [[GTID_REF]],
// CHECK: [[HASWORK:%.+]] = call i32 @__kmpc_dispatch_next_8([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], i32* [[OMP_ISLAST:%[^,]+]], i64* [[OMP_LB:%[^,]+]], i64* [[OMP_UB:%[^,]+]], i64* [[OMP_ST:%[^,]+]])
// CHECK-NEXT: [[O_CMP:%.+]] = icmp ne i32 [[HASWORK]], 0
// CHECK-NEXT: br i1 [[O_CMP]], label %[[O_LOOP1_BODY:[^,]+]], label %[[O_LOOP1_END:[^,]+]]
@@ -318,9 +305,7 @@ void runtime(float *a, float *b, float *c, float *d) {
// CHECK: call void ([[IDENT_T_TY]]*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call([[IDENT_T_TY]]* [[DEFAULT_LOC:[@%].+]], i32 5, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*, float**, float**, float**, float**)* [[OMP_PARALLEL_FUNC:@.+]] to void (i32*, i32*, ...)*),
// CHECK: define internal void [[OMP_PARALLEL_FUNC]](i32* noalias [[GTID_PARAM_ADDR:%.+]], i32* noalias %{{.+}}, i32* dereferenceable(4) %{{.+}}, float** dereferenceable(8) %{{.+}}, float** dereferenceable(8) %{{.+}}, float** dereferenceable(8) %{{.+}}, float** dereferenceable(8) %{{.+}})
// CHECK: store i32* [[GTID_PARAM_ADDR]], i32** [[GTID_REF_ADDR:%.+]],
-// CHECK: [[GTID_REF:%.+]] = load i32*, i32** [[GTID_REF_ADDR]],
-// CHECK: [[GTID:%.+]] = load i32, i32* [[GTID_REF]],
-// CHECK: call void @__kmpc_dispatch_init_4([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], i32 37, i32 0, i32 199, i32 1, i32 1)
+// CHECK: call void @__kmpc_dispatch_init_4([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID:%.+]], i32 37, i32 0, i32 199, i32 1, i32 1)
//
// CHECK: [[HASWORK:%.+]] = call i32 @__kmpc_dispatch_next_4([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], i32* [[OMP_ISLAST:%[^,]+]], i32* [[OMP_LB:%[^,]+]], i32* [[OMP_UB:%[^,]+]], i32* [[OMP_ST:%[^,]+]])
// CHECK-NEXT: [[O_CMP:%.+]] = icmp ne i32 [[HASWORK]], 0
diff --git a/test/OpenMP/parallel_for_lastprivate_messages.cpp b/test/OpenMP/parallel_for_lastprivate_messages.cpp
index ccfe2ea407b1..134100bc1753 100644
--- a/test/OpenMP/parallel_for_lastprivate_messages.cpp
+++ b/test/OpenMP/parallel_for_lastprivate_messages.cpp
@@ -18,9 +18,9 @@ public:
S2 &operator=(const S2 &);
const S2 &operator=(const S2 &) const;
static float S2s; // expected-note {{static data member is predetermined as shared}}
- static const float S2sc;
+ static const float S2sc; // expected-note {{static data member is predetermined as shared}}
};
-const float S2::S2sc = 0; // expected-note {{static data member is predetermined as shared}}
+const float S2::S2sc = 0;
const S2 b;
const S2 ba[5];
class S3 {
diff --git a/test/OpenMP/parallel_for_linear_codegen.cpp b/test/OpenMP/parallel_for_linear_codegen.cpp
index d0968d7cd146..2c3cfddbd571 100644
--- a/test/OpenMP/parallel_for_linear_codegen.cpp
+++ b/test/OpenMP/parallel_for_linear_codegen.cpp
@@ -49,6 +49,7 @@ int main() {
for (int i = 0; i < 2; ++i) {
// LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, i32* dereferenceable(4) %{{.+}})
// LAMBDA: alloca i{{[0-9]+}},
+ // LAMBDA: alloca i{{[0-9]+}},
// LAMBDA: [[G_START_ADDR:%.+]] = alloca i{{[0-9]+}},
// LAMBDA: alloca i{{[0-9]+}},
// LAMBDA: alloca i{{[0-9]+}},
@@ -96,6 +97,7 @@ int main() {
for (int i = 0; i < 2; ++i) {
// BLOCKS: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, i32* dereferenceable(4) %{{.+}})
// BLOCKS: alloca i{{[0-9]+}},
+ // BLOCKS: alloca i{{[0-9]+}},
// BLOCKS: [[G_START_ADDR:%.+]] = alloca i{{[0-9]+}},
// BLOCKS: alloca i{{[0-9]+}},
// BLOCKS: alloca i{{[0-9]+}},
@@ -155,13 +157,13 @@ int main() {
// CHECK: define internal void [[MAIN_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, float** dereferenceable(8) %{{.+}}, i64* dereferenceable(8) %{{.+}})
// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
// CHECK: [[PVAR_START:%.+]] = alloca float*,
// CHECK: [[LVAR_START:%.+]] = alloca i64,
// CHECK: alloca i{{[0-9]+}},
// CHECK: alloca i{{[0-9]+}},
// CHECK: alloca i{{[0-9]+}},
// CHECK: alloca i{{[0-9]+}},
-// CHECK: alloca i{{[0-9]+}},
// CHECK: [[PVAR_PRIV:%.+]] = alloca float*,
// CHECK: [[LVAR_PRIV:%.+]] = alloca i64,
// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_REF:%.+]]
@@ -205,13 +207,13 @@ int main() {
//
// CHECK: define internal void [[TMAIN_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i32** dereferenceable(8) %{{.+}}, i32* dereferenceable(4) %{{.+}})
// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
// CHECK: [[PVAR_START:%.+]] = alloca i32*,
// CHECK: [[LVAR_START:%.+]] = alloca i32,
// CHECK: alloca i{{[0-9]+}},
// CHECK: alloca i{{[0-9]+}},
// CHECK: alloca i{{[0-9]+}},
// CHECK: alloca i{{[0-9]+}},
-// CHECK: alloca i{{[0-9]+}},
// CHECK: [[PVAR_PRIV:%.+]] = alloca i32*,
// CHECK: [[LVAR_PRIV:%.+]] = alloca i32,
// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_REF:%.+]]
diff --git a/test/OpenMP/parallel_for_reduction_messages.cpp b/test/OpenMP/parallel_for_reduction_messages.cpp
index 57ab1fac9c11..6499ef593a3d 100644
--- a/test/OpenMP/parallel_for_reduction_messages.cpp
+++ b/test/OpenMP/parallel_for_reduction_messages.cpp
@@ -25,9 +25,9 @@ public:
S2() : a(0) {}
S2(S2 &s2) : a(s2.a) {}
static float S2s; // expected-note 2 {{static data member is predetermined as shared}}
- static const float S2sc;
+ static const float S2sc; // expected-note 2 {{'S2sc' declared here}}
};
-const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}}
+const float S2::S2sc = 0;
S2 b; // expected-note 3 {{'b' defined here}}
const S2 ba[5]; // expected-note 2 {{'ba' defined here}}
class S3 {
@@ -61,6 +61,12 @@ class S5 {
public:
S5(int v) : a(v) {}
+ void foo() {
+#pragma omp parallel private(a) // expected-note {{defined as private}}
+#pragma omp for reduction(+:a) // expected-error {{reduction variable must be shared}}
+ for (int i = 0; i < 10; ++i)
+ ::foo();
+ }
};
class S6 { // expected-note 3 {{candidate function (the implicit copy assignment operator) not viable: no known conversion from 'int' to 'const S6' for 1st argument}}
#if __cplusplus >= 201103L // C++11 or later
diff --git a/test/OpenMP/parallel_for_simd_codegen.cpp b/test/OpenMP/parallel_for_simd_codegen.cpp
index 06d96353ee9b..369ea17844e9 100644
--- a/test/OpenMP/parallel_for_simd_codegen.cpp
+++ b/test/OpenMP/parallel_for_simd_codegen.cpp
@@ -114,6 +114,7 @@ void simple(float *a, float *b, float *c, float *d) {
int lin = 12;
#pragma omp parallel for simd linear(lin : get_val()), linear(g_ptr)
+// CHECK: alloca i32,
// Init linear private var.
// CHECK: [[LIN_VAR:%.+]] = load i32*, i32** %
// CHECK: [[LIN_LOAD:%.+]] = load i32, i32* [[LIN_VAR]]
diff --git a/test/OpenMP/parallel_for_simd_lastprivate_messages.cpp b/test/OpenMP/parallel_for_simd_lastprivate_messages.cpp
index bd1a6d505572..8670e55c6e2b 100644
--- a/test/OpenMP/parallel_for_simd_lastprivate_messages.cpp
+++ b/test/OpenMP/parallel_for_simd_lastprivate_messages.cpp
@@ -17,9 +17,9 @@ public:
S2(S2 &s2) : a(s2.a) {}
const S2 &operator=(const S2 &) const;
static float S2s; // expected-note {{static data member is predetermined as shared}}
- static const float S2sc;
+ static const float S2sc; // expected-note {{static data member is predetermined as shared}}
};
-const float S2::S2sc = 0; // expected-note {{static data member is predetermined as shared}}
+const float S2::S2sc = 0;
const S2 b;
const S2 ba[5];
class S3 {
diff --git a/test/OpenMP/parallel_for_simd_reduction_messages.cpp b/test/OpenMP/parallel_for_simd_reduction_messages.cpp
index 60a947dd5f84..8ff246e35f6a 100644
--- a/test/OpenMP/parallel_for_simd_reduction_messages.cpp
+++ b/test/OpenMP/parallel_for_simd_reduction_messages.cpp
@@ -25,9 +25,9 @@ public:
S2() : a(0) {}
S2(S2 &s2) : a(s2.a) {}
static float S2s; // expected-note 2 {{static data member is predetermined as shared}}
- static const float S2sc;
+ static const float S2sc; // expected-note 2 {{'S2sc' declared here}}
};
-const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}}
+const float S2::S2sc = 0;
S2 b; // expected-note 3 {{'b' defined here}}
const S2 ba[5]; // expected-note 2 {{'ba' defined here}}
class S3 {
diff --git a/test/OpenMP/parallel_reduction_messages.cpp b/test/OpenMP/parallel_reduction_messages.cpp
index 947353fc2dd4..96f4b58ec8a4 100644
--- a/test/OpenMP/parallel_reduction_messages.cpp
+++ b/test/OpenMP/parallel_reduction_messages.cpp
@@ -24,9 +24,9 @@ public:
S2() : a(0) {}
S2(S2 &s2) : a(s2.a) {}
static float S2s; // expected-note 2 {{static data member is predetermined as shared}}
- static const float S2sc;
+ static const float S2sc; // expected-note 2 {{'S2sc' declared here}}
};
-const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}}
+const float S2::S2sc = 0;
S2 b; // expected-note 3 {{'b' defined here}}
const S2 ba[5]; // expected-note 2 {{'ba' defined here}}
class S3 {
diff --git a/test/OpenMP/parallel_sections_codegen.cpp b/test/OpenMP/parallel_sections_codegen.cpp
index 6fc687d0c503..a26147303611 100644
--- a/test/OpenMP/parallel_sections_codegen.cpp
+++ b/test/OpenMP/parallel_sections_codegen.cpp
@@ -28,9 +28,7 @@ int main() {
{
// CHECK: store i32 0, i32* [[LB_PTR:%.+]],
// CHECK: store i32 1, i32* [[UB_PTR:%.+]],
-// CHECK: [[GTID_REF:%.+]] = load i32*, i32** [[GTID_REF_ADDR]],
-// CHECK: [[GTID:%.+]] = load i32, i32* [[GTID_REF]],
-// CHECK: call void @__kmpc_for_static_init_4(%{{.+}}* @{{.+}}, i32 [[GTID]], i32 34, i32* [[IS_LAST_PTR:%.+]], i32* [[LB_PTR]], i32* [[UB_PTR]], i32* [[STRIDE_PTR:%.+]], i32 1, i32 1)
+// CHECK: call void @__kmpc_for_static_init_4(%{{.+}}* @{{.+}}, i32 [[GTID:%.+]], i32 34, i32* [[IS_LAST_PTR:%.+]], i32* [[LB_PTR]], i32* [[UB_PTR]], i32* [[STRIDE_PTR:%.+]], i32 1, i32 1)
// <<UB = min(UB, GlobalUB);>>
// CHECK: [[UB:%.+]] = load i32, i32* [[UB_PTR]]
// CHECK: [[CMP:%.+]] = icmp slt i32 [[UB]], 1
diff --git a/test/OpenMP/parallel_sections_lastprivate_messages.cpp b/test/OpenMP/parallel_sections_lastprivate_messages.cpp
index af3c5e2a575b..eccbfc5e7e02 100644
--- a/test/OpenMP/parallel_sections_lastprivate_messages.cpp
+++ b/test/OpenMP/parallel_sections_lastprivate_messages.cpp
@@ -17,9 +17,9 @@ public:
S2(S2 &s2) : a(s2.a) {}
const S2 &operator=(const S2 &) const;
static float S2s; // expected-note {{static data member is predetermined as shared}}
- static const float S2sc;
+ static const float S2sc; // expected-note {{static data member is predetermined as shared}}
};
-const float S2::S2sc = 0; // expected-note {{static data member is predetermined as shared}}
+const float S2::S2sc = 0;
const S2 b;
const S2 ba[5];
class S3 {
diff --git a/test/OpenMP/parallel_sections_reduction_messages.cpp b/test/OpenMP/parallel_sections_reduction_messages.cpp
index 05cc7f0f6c5f..26b3a5355c19 100644
--- a/test/OpenMP/parallel_sections_reduction_messages.cpp
+++ b/test/OpenMP/parallel_sections_reduction_messages.cpp
@@ -26,9 +26,9 @@ public:
S2() : a(0) {}
S2(S2 &s2) : a(s2.a) {}
static float S2s; // expected-note 2 {{static data member is predetermined as shared}}
- static const float S2sc;
+ static const float S2sc; // expected-note 2 {{'S2sc' declared here}}
};
-const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}}
+const float S2::S2sc = 0;
S2 b; // expected-note 3 {{'b' defined here}}
const S2 ba[5]; // expected-note 2 {{'ba' defined here}}
class S3 {
diff --git a/test/OpenMP/sections_codegen.cpp b/test/OpenMP/sections_codegen.cpp
index 65747e7b912f..94ded37db95d 100644
--- a/test/OpenMP/sections_codegen.cpp
+++ b/test/OpenMP/sections_codegen.cpp
@@ -4,7 +4,8 @@
// expected-no-diagnostics
#ifndef HEADER
#define HEADER
-// CHECK: [[IMPLICIT_BARRIER_SECTIONS_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 194, i32 0, i32 0, i8*
+// CHECK-DAG: [[IMPLICIT_BARRIER_SECTIONS_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 194, i32 0, i32 0, i8*
+// CHECK-DAG: [[SECTIONS_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 1026, i32 0, i32 0, i8*
// CHECK-LABEL: foo
void foo() {};
// CHECK-LABEL: bar
@@ -29,7 +30,7 @@ int main() {
{
// CHECK: store i32 0, i32* [[LB_PTR:%.+]],
// CHECK: store i32 1, i32* [[UB_PTR:%.+]],
-// CHECK: call void @__kmpc_for_static_init_4(%{{.+}}* @{{.+}}, i32 [[GTID]], i32 34, i32* [[IS_LAST_PTR:%.+]], i32* [[LB_PTR]], i32* [[UB_PTR]], i32* [[STRIDE_PTR:%.+]], i32 1, i32 1)
+// CHECK: call void @__kmpc_for_static_init_4(%{{.+}}* [[SECTIONS_LOC]], i32 [[GTID]], i32 34, i32* [[IS_LAST_PTR:%.+]], i32* [[LB_PTR]], i32* [[UB_PTR]], i32* [[STRIDE_PTR:%.+]], i32 1, i32 1)
// <<UB = min(UB, GlobalUB);>>
// CHECK: [[UB:%.+]] = load i32, i32* [[UB_PTR]]
// CHECK: [[CMP:%.+]] = icmp slt i32 [[UB]], 1
@@ -69,7 +70,7 @@ int main() {
// CHECK-NEXT: br label %[[INNER_FOR_COND]]
// CHECK: [[INNER_LOOP_END]]
}
-// CHECK: call void @__kmpc_for_static_fini(%{{.+}}* @{{.+}}, i32 [[GTID]])
+// CHECK: call void @__kmpc_for_static_fini(%{{.+}}* [[SECTIONS_LOC]], i32 [[GTID]])
// CHECK: call void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_SECTIONS_LOC]],
#pragma omp sections nowait
{
diff --git a/test/OpenMP/sections_firstprivate_codegen.cpp b/test/OpenMP/sections_firstprivate_codegen.cpp
index a5426f8bf956..227bb076374f 100644
--- a/test/OpenMP/sections_firstprivate_codegen.cpp
+++ b/test/OpenMP/sections_firstprivate_codegen.cpp
@@ -256,11 +256,7 @@ int main() {
// CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT]]()
// CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]],
// CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR:@.+]]([[S_INT_TY]]* [[TEST]])
-// CHECK: [[T_VARVAL:%.+]] = load i32, i32* %{{.+}},
-// CHECK: [[T_VARCONV:%.+]] = bitcast i64* [[T_VARCAST:%.+]] to i32*
-// CHECK: store i32 [[T_VARVAL]], i32* [[T_VARCONV]],
-// CHECK: [[T_VARPVT:%.+]] = load i64, i64* [[T_VARCAST]],
-// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 4, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, i64, [2 x i32]*, [2 x [[S_INT_TY]]]*, [[S_INT_TY]]*)* [[TMAIN_MICROTASK:@.+]] to void {{.*}}i64 [[T_VARPVT]],
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 4, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, i32*, [2 x i32]*, [2 x [[S_INT_TY]]]*, [[S_INT_TY]]*)* [[TMAIN_MICROTASK:@.+]] to void
// CHECK: call {{.*}} [[S_INT_TY_DESTR:@.+]]([[S_INT_TY]]*
// CHECK: ret
//
@@ -271,14 +267,13 @@ int main() {
// CHECK: alloca i{{[0-9]+}},
// CHECK: alloca i{{[0-9]+}},
// CHECK: alloca i{{[0-9]+}},
-// CHECK: alloca i{{[0-9]+}},
// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_INT_TY]]],
// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_INT_TY]],
// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]],
-// CHECK-NOT: load i{{[0-9]+}}*, i{{[0-9]+}}** %
+// CHECK: [[T_VAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** %
// CHECK: [[VEC_REF:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** %
// CHECK: [[S_ARR:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** %
// CHECK: [[VAR_REF:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** %
diff --git a/test/OpenMP/sections_lastprivate_messages.cpp b/test/OpenMP/sections_lastprivate_messages.cpp
index 5f6b420cb8ea..01bb13de5510 100644
--- a/test/OpenMP/sections_lastprivate_messages.cpp
+++ b/test/OpenMP/sections_lastprivate_messages.cpp
@@ -17,9 +17,9 @@ public:
S2(S2 &s2) : a(s2.a) {}
const S2 &operator=(const S2 &) const;
static float S2s; // expected-note {{static data member is predetermined as shared}}
- static const float S2sc;
+ static const float S2sc; // expected-note {{static data member is predetermined as shared}}
};
-const float S2::S2sc = 0; // expected-note {{static data member is predetermined as shared}}
+const float S2::S2sc = 0;
const S2 b;
const S2 ba[5];
class S3 {
diff --git a/test/OpenMP/sections_reduction_messages.cpp b/test/OpenMP/sections_reduction_messages.cpp
index f13c5b3f2862..58b22a5a61d0 100644
--- a/test/OpenMP/sections_reduction_messages.cpp
+++ b/test/OpenMP/sections_reduction_messages.cpp
@@ -27,9 +27,9 @@ public:
S2() : a(0) {}
S2(S2 &s2) : a(s2.a) {}
static float S2s; // expected-note 2 {{static data member is predetermined as shared}}
- static const float S2sc;
+ static const float S2sc; // expected-note 2 {{'S2sc' declared here}}
};
-const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}}
+const float S2::S2sc = 0;
S2 b; // expected-note 3 {{'b' defined here}}
const S2 ba[5]; // expected-note 2 {{'ba' defined here}}
class S3 {
diff --git a/test/OpenMP/simd_lastprivate_messages.cpp b/test/OpenMP/simd_lastprivate_messages.cpp
index 16223db71ad5..349d6a5b904d 100644
--- a/test/OpenMP/simd_lastprivate_messages.cpp
+++ b/test/OpenMP/simd_lastprivate_messages.cpp
@@ -17,9 +17,9 @@ public:
S2(S2 &s2) : a(s2.a) {}
const S2 &operator=(const S2 &) const;
static float S2s; // expected-note {{static data member is predetermined as shared}}
- static const float S2sc;
+ static const float S2sc; // expected-note {{static data member is predetermined as shared}}
};
-const float S2::S2sc = 0; // expected-note {{static data member is predetermined as shared}}
+const float S2::S2sc = 0;
const S2 b;
const S2 ba[5];
class S3 {
diff --git a/test/OpenMP/simd_reduction_messages.cpp b/test/OpenMP/simd_reduction_messages.cpp
index 1e1a233ec499..bdf429d1967c 100644
--- a/test/OpenMP/simd_reduction_messages.cpp
+++ b/test/OpenMP/simd_reduction_messages.cpp
@@ -25,9 +25,9 @@ public:
S2() : a(0) {}
S2(S2 &s2) : a(s2.a) {}
static float S2s; // expected-note 2 {{static data member is predetermined as shared}}
- static const float S2sc;
+ static const float S2sc; // expected-note 2 {{'S2sc' declared here}}
};
-const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}}
+const float S2::S2sc = 0;
S2 b; // expected-note 3 {{'b' defined here}}
const S2 ba[5]; // expected-note 2 {{'ba' defined here}}
class S3 {
diff --git a/test/OpenMP/single_firstprivate_codegen.cpp b/test/OpenMP/single_firstprivate_codegen.cpp
index 9f059e970470..4a91bc2d5bc5 100644
--- a/test/OpenMP/single_firstprivate_codegen.cpp
+++ b/test/OpenMP/single_firstprivate_codegen.cpp
@@ -222,24 +222,18 @@ int main() {
// CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT]]()
// CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]],
// CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR:@.+]]([[S_INT_TY]]* [[TEST]])
-// CHECK: [[T_VARVAL:%.+]] = load i32, i32* [[T_VAR:%.+]],
-// CHECK: [[T_VARCONV:%.+]] = bitcast i64* [[T_VARCAST:%.+]] to i32*
-// CHECK: store i32 [[T_VARVAL]], i32* [[T_VARCONV]],
-// CHECK: [[T_VARPVT:%.+]] = load i64, i64* [[T_VARCAST]],
-// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 4, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, i64, [2 x i32]*, [2 x [[S_INT_TY]]]*, [[S_INT_TY]]*)* [[TMAIN_MICROTASK:@.+]] to void {{.*}}i64 [[T_VARPVT:%.+]],
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 4, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, i32*, [2 x i32]*, [2 x [[S_INT_TY]]]*, [[S_INT_TY]]*)* [[TMAIN_MICROTASK:@.+]] to void
// CHECK: call {{.*}} [[S_INT_TY_DESTR:@.+]]([[S_INT_TY]]*
// CHECK: ret
//
-// CHECK: define internal void [[TMAIN_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i64 {{.*}}%{{.+}}, [2 x i32]* dereferenceable(8) %{{.+}}, [2 x [[S_INT_TY]]]* dereferenceable(8) %{{.+}}, [[S_INT_TY]]* dereferenceable(4) %{{.+}})
-// CHECK: [[T_VAR_ARG:%.+]] = alloca i{{[0-9]+}},
+// CHECK: define internal void [[TMAIN_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i32* dereferenceable(4) %{{.+}}, [2 x i32]* dereferenceable(8) %{{.+}}, [2 x [[S_INT_TY]]]* dereferenceable(8) %{{.+}}, [[S_INT_TY]]* dereferenceable(4) %{{.+}})
// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_INT_TY]]],
// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_INT_TY]],
// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]],
-// CHECK-NOT: load i{{[0-9]+}}*, i{{[0-9]+}}** %
-// CHECK: [[T_VAR_CONV:%.+]] = bitcast i64* [[T_VAR_ARG]] to i32*
+// CHECK: [[T_VAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** %
// CHECK: [[VEC_REF:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** %
// CHECK: [[S_ARR:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** %
// CHECK: [[VAR_REF:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** %
diff --git a/test/OpenMP/target_codegen.cpp b/test/OpenMP/target_codegen.cpp
index c457045c17c7..20bc96b84cbf 100644
--- a/test/OpenMP/target_codegen.cpp
+++ b/test/OpenMP/target_codegen.cpp
@@ -34,16 +34,18 @@
// code, only 6 will have mapped arguments, and only 4 have all-constant map
// sizes.
-// CHECK-DAG: [[SIZET2:@.+]] = private unnamed_addr constant [1 x i{{32|64}}] [i[[SZ:32|64]] 2]
-// CHECK-DAG: [[MAPT2:@.+]] = private unnamed_addr constant [1 x i32] [i32 288]
+// CHECK-DAG: [[SIZET:@.+]] = private unnamed_addr constant [2 x i[[SZ]]] [i[[SZ]] 0, i[[SZ]] 4]
+// CHECK-DAG: [[MAPT:@.+]] = private unnamed_addr constant [2 x i64] [i64 32, i64 288]
+// CHECK-DAG: [[SIZET2:@.+]] = private unnamed_addr constant [1 x i{{32|64}}] [i[[SZ]] 2]
+// CHECK-DAG: [[MAPT2:@.+]] = private unnamed_addr constant [1 x i64] [i64 288]
// CHECK-DAG: [[SIZET3:@.+]] = private unnamed_addr constant [2 x i[[SZ]]] [i[[SZ]] 4, i[[SZ]] 2]
-// CHECK-DAG: [[MAPT3:@.+]] = private unnamed_addr constant [2 x i32] [i32 288, i32 288]
-// CHECK-DAG: [[MAPT4:@.+]] = private unnamed_addr constant [9 x i32] [i32 288, i32 35, i32 288, i32 35, i32 35, i32 288, i32 288, i32 35, i32 35]
+// CHECK-DAG: [[MAPT3:@.+]] = private unnamed_addr constant [2 x i64] [i64 288, i64 288]
+// CHECK-DAG: [[MAPT4:@.+]] = private unnamed_addr constant [9 x i64] [i64 288, i64 547, i64 288, i64 547, i64 547, i64 288, i64 288, i64 547, i64 547]
// CHECK-DAG: [[SIZET5:@.+]] = private unnamed_addr constant [3 x i[[SZ]]] [i[[SZ]] 4, i[[SZ]] 2, i[[SZ]] 40]
-// CHECK-DAG: [[MAPT5:@.+]] = private unnamed_addr constant [3 x i32] [i32 288, i32 288, i32 35]
+// CHECK-DAG: [[MAPT5:@.+]] = private unnamed_addr constant [3 x i64] [i64 288, i64 288, i64 547]
// CHECK-DAG: [[SIZET6:@.+]] = private unnamed_addr constant [4 x i[[SZ]]] [i[[SZ]] 4, i[[SZ]] 2, i[[SZ]] 1, i[[SZ]] 40]
-// CHECK-DAG: [[MAPT6:@.+]] = private unnamed_addr constant [4 x i32] [i32 288, i32 288, i32 288, i32 35]
-// CHECK-DAG: [[MAPT7:@.+]] = private unnamed_addr constant [5 x i32] [i32 35, i32 288, i32 288, i32 288, i32 35]
+// CHECK-DAG: [[MAPT6:@.+]] = private unnamed_addr constant [4 x i64] [i64 288, i64 288, i64 288, i64 547]
+// CHECK-DAG: [[MAPT7:@.+]] = private unnamed_addr constant [5 x i64] [i64 547, i64 288, i64 288, i64 288, i64 547]
// CHECK-DAG: @{{.*}} = private constant i8 0
// CHECK-DAG: @{{.*}} = private constant i8 0
// CHECK-DAG: @{{.*}} = private constant i8 0
@@ -59,6 +61,7 @@
// TCHECK: @{{.+}} = constant [[ENTTY]]
// TCHECK: @{{.+}} = constant [[ENTTY]]
// TCHECK: @{{.+}} = constant [[ENTTY]]
+// TCHECK: @{{.+}} = {{.*}}constant [[ENTTY]]
// TCHECK-NOT: @{{.+}} = constant [[ENTTY]]
// Check if offloading descriptor is created.
@@ -79,6 +82,9 @@ struct TT{
ty Y;
};
+int global;
+extern int global;
+
// CHECK: define {{.*}}[[FOO:@.+]](
int foo(int n) {
int a = 0;
@@ -88,31 +94,60 @@ int foo(int n) {
double c[5][10];
double cn[5][n];
TT<long long, char> d;
+ static long *plocal;
- // CHECK: [[RET:%.+]] = call i32 @__tgt_target(i32 -1, i8* @{{[^,]+}}, i32 0, i8** null, i8** null, i[[SZ]]* null, i32* null)
- // CHECK: store i32 [[RET]], i32* [[RHV:%.+]], align 4
- // CHECK: [[RET2:%.+]] = load i32, i32* [[RHV]], align 4
- // CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+ // CHECK: [[ADD:%.+]] = add nsw i32
+ // CHECK: [[DEVICE:%.+]] = sext i32 [[ADD]] to i64
+ // CHECK: [[RET:%.+]] = call i32 @__tgt_target(i64 [[DEVICE]], i8* @{{[^,]+}}, i32 0, i8** null, i8** null, i[[SZ]]* null, i64* null)
+ // CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
// CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:[^,]+]], label %[[END:[^,]+]]
// CHECK: [[FAIL]]
// CHECK: call void [[HVT0:@.+]]()
// CHECK-NEXT: br label %[[END]]
// CHECK: [[END]]
- #pragma omp target
+ #pragma omp target device(global + a)
{
}
- // CHECK: store i32 0, i32* [[RHV:%.+]], align 4
- // CHECK: store i32 -1, i32* [[RHV]], align 4
- // CHECK: [[RET2:%.+]] = load i32, i32* [[RHV]], align 4
- // CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+ // CHECK-DAG: [[ADD:%.+]] = add nsw i32
+ // CHECK-DAG: [[DEVICE:%.+]] = sext i32 [[ADD]] to i64
+ // CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_nowait(i64 [[DEVICE]], i8* @{{[^,]+}}, i32 2, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* getelementptr inbounds ([2 x i[[SZ]]], [2 x i[[SZ]]]* [[SIZET]], i32 0, i32 0), i64* getelementptr inbounds ([2 x i64], [2 x i64]* [[MAPT]], i32 0, i32 0)
+ // CHECK-DAG: [[BPR]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[BP:%[^,]+]], i32 0, i32 0
+ // CHECK-DAG: [[PR]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[P:%[^,]+]], i32 0, i32 0
+
+ // CHECK-DAG: [[BPADDR0:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[BP]], i32 0, i32 0
+ // CHECK-DAG: [[PADDR0:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[P]], i32 0, i32 0
+ // CHECK-DAG: [[CBPADDR0:%.+]] = bitcast i8** [[BPADDR0]] to i[[SZ]]**
+ // CHECK-DAG: [[CPADDR0:%.+]] = bitcast i8** [[PADDR0]] to i[[SZ]]**
+ // CHECK-DAG: store i[[SZ]]* [[BP0:%[^,]+]], i[[SZ]]** [[CBPADDR0]]
+ // CHECK-DAG: store i[[SZ]]* [[BP0]], i[[SZ]]** [[CPADDR0]]
+
+ // CHECK-DAG: [[BPADDR1:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[BP]], i32 0, i32 1
+ // CHECK-DAG: [[PADDR1:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[P]], i32 0, i32 1
+ // CHECK-DAG: [[CBPADDR1:%.+]] = bitcast i8** [[BPADDR1]] to i[[SZ]]*
+ // CHECK-DAG: [[CPADDR1:%.+]] = bitcast i8** [[PADDR1]] to i[[SZ]]*
+ // CHECK-DAG: store i[[SZ]] [[BP1:%[^,]+]], i[[SZ]]* [[CBPADDR1]]
+ // CHECK-DAG: store i[[SZ]] [[BP1]], i[[SZ]]* [[CPADDR1]]
+ // CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
+ // CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:[^,]+]], label %[[END:[^,]+]]
+ // CHECK: [[FAIL]]
+ // CHECK: call void [[HVT0_:@.+]](i[[SZ]]* [[BP0]], i[[SZ]] [[BP1]])
+ // CHECK-NEXT: br label %[[END]]
+ // CHECK: [[END]]
+ #pragma omp target device(global + a) nowait
+ {
+ static int local1;
+ *plocal = global;
+ local1 = global;
+ }
+
// CHECK: call void [[HVT1:@.+]](i[[SZ]] {{[^,]+}})
- #pragma omp target if(0)
+ #pragma omp target if(0) firstprivate(global)
{
- a += 1;
+ global += 1;
}
- // CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target(i32 -1, i8* @{{[^,]+}}, i32 1, i8** [[BP:%[^,]+]], i8** [[P:%[^,]+]], i[[SZ]]* getelementptr inbounds ([1 x i[[SZ]]], [1 x i[[SZ]]]* [[SIZET2]], i32 0, i32 0), i32* getelementptr inbounds ([1 x i32], [1 x i32]* [[MAPT2]], i32 0, i32 0))
+ // CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target(i64 -1, i8* @{{[^,]+}}, i32 1, i8** [[BP:%[^,]+]], i8** [[P:%[^,]+]], i[[SZ]]* getelementptr inbounds ([1 x i[[SZ]]], [1 x i[[SZ]]]* [[SIZET2]], i32 0, i32 0), i64* getelementptr inbounds ([1 x i64], [1 x i64]* [[MAPT2]], i32 0, i32 0))
// CHECK-DAG: [[BP]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[BPR:%[^,]+]], i32 0, i32 0
// CHECK-DAG: [[P]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[PR:%[^,]+]], i32 0, i32 0
// CHECK-DAG: [[BPADDR0:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[BPR]], i32 0, i32 [[IDX0:[0-9]+]]
@@ -122,9 +157,7 @@ int foo(int n) {
// CHECK-DAG: store i[[SZ]] [[BP0:%[^,]+]], i[[SZ]]* [[CBPADDR0]]
// CHECK-DAG: store i[[SZ]] [[P0:%[^,]+]], i[[SZ]]* [[CPADDR0]]
- // CHECK: store i32 [[RET]], i32* [[RHV:%.+]], align 4
- // CHECK: [[RET2:%.+]] = load i32, i32* [[RHV]], align 4
- // CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+ // CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
// CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:[^,]+]], label %[[END:[^,]+]]
// CHECK: [[FAIL]]
// CHECK: call void [[HVT2:@.+]](i[[SZ]] {{[^,]+}})
@@ -138,7 +171,7 @@ int foo(int n) {
// CHECK: [[IF:%.+]] = icmp sgt i32 {{[^,]+}}, 10
// CHECK: br i1 [[IF]], label %[[IFTHEN:[^,]+]], label %[[IFELSE:[^,]+]]
// CHECK: [[IFTHEN]]
- // CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target(i32 -1, i8* @{{[^,]+}}, i32 2, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* getelementptr inbounds ([2 x i[[SZ]]], [2 x i[[SZ]]]* [[SIZET3]], i32 0, i32 0), i32* getelementptr inbounds ([2 x i32], [2 x i32]* [[MAPT3]], i32 0, i32 0))
+ // CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target(i64 -1, i8* @{{[^,]+}}, i32 2, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* getelementptr inbounds ([2 x i[[SZ]]], [2 x i[[SZ]]]* [[SIZET3]], i32 0, i32 0), i64* getelementptr inbounds ([2 x i64], [2 x i64]* [[MAPT3]], i32 0, i32 0))
// CHECK-DAG: [[BPR]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[BP:%[^,]+]], i32 0, i32 0
// CHECK-DAG: [[PR]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[P:%[^,]+]], i32 0, i32 0
@@ -155,21 +188,18 @@ int foo(int n) {
// CHECK-DAG: [[CPADDR1:%.+]] = bitcast i8** [[PADDR1]] to i[[SZ]]*
// CHECK-DAG: store i[[SZ]] [[BP1:%[^,]+]], i[[SZ]]* [[CBPADDR1]]
// CHECK-DAG: store i[[SZ]] [[P1:%[^,]+]], i[[SZ]]* [[CPADDR1]]
- // CHECK: store i32 [[RET]], i32* [[RHV:%.+]], align 4
- // CHECK-NEXT: br label %[[IFEND:.+]]
-
- // CHECK: [[IFELSE]]
- // CHECK: store i32 -1, i32* [[RHV]], align 4
- // CHECK-NEXT: br label %[[IFEND:.+]]
-
- // CHECK: [[IFEND]]
- // CHECK: [[RET2:%.+]] = load i32, i32* [[RHV]], align 4
- // CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+ // CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
// CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
// CHECK: [[FAIL]]
// CHECK: call void [[HVT3:@.+]]({{[^,]+}}, {{[^,]+}})
// CHECK-NEXT: br label %[[END]]
// CHECK: [[END]]
+ // CHECK-NEXT: br label %[[IFEND:.+]]
+ // CHECK: [[IFELSE]]
+ // CHECK: call void [[HVT3]]({{[^,]+}}, {{[^,]+}})
+ // CHECK-NEXT: br label %[[IFEND]]
+
+ // CHECK: [[IFEND]]
#pragma omp target if(n>10)
{
a += 1;
@@ -191,9 +221,9 @@ int foo(int n) {
// CHECK: [[CNSIZE:%.+]] = mul nuw i[[SZ]] [[CNELEMSIZE2]], 8
// CHECK: [[IF:%.+]] = icmp sgt i32 {{[^,]+}}, 20
- // CHECK: br i1 [[IF]], label %[[TRY:[^,]+]], label %[[FAIL:[^,]+]]
+ // CHECK: br i1 [[IF]], label %[[TRY:[^,]+]], label %[[IFELSE:[^,]+]]
// CHECK: [[TRY]]
- // CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target(i32 -1, i8* @{{[^,]+}}, i32 9, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* [[SR:%[^,]+]], i32* getelementptr inbounds ([9 x i32], [9 x i32]* [[MAPT4]], i32 0, i32 0))
+ // CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target(i64 -1, i8* @{{[^,]+}}, i32 9, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* [[SR:%[^,]+]], i64* getelementptr inbounds ([9 x i64], [9 x i64]* [[MAPT4]], i32 0, i32 0))
// CHECK-DAG: [[BPR]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP:%[^,]+]], i32 0, i32 0
// CHECK-DAG: [[PR]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P:%[^,]+]], i32 0, i32 0
// CHECK-DAG: [[SR]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S:%[^,]+]], i32 0, i32 0
@@ -282,15 +312,18 @@ int foo(int n) {
// CHECK-DAG: store [[TT]]* %{{.+}}, [[TT]]** [[CPADDR8]]
// CHECK-DAG: store i[[SZ]] {{12|16}}, i[[SZ]]* [[SADDR8]]
- // CHECK: store i32 [[RET]], i32* [[RHV:%.+]], align 4
- // CHECK: [[RET2:%.+]] = load i32, i32* [[RHV]], align 4
- // CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
- // CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:[^,]+]], label %[[END:[^,]+]]
-
+ // CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
+ // CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
// CHECK: [[FAIL]]
// CHECK: call void [[HVT4:@.+]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}})
// CHECK-NEXT: br label %[[END]]
// CHECK: [[END]]
+ // CHECK-NEXT: br label %[[IFEND:.+]]
+ // CHECK: [[IFELSE]]
+ // CHECK: call void [[HVT4]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}})
+ // CHECK-NEXT: br label %[[IFEND]]
+
+ // CHECK: [[IFEND]]
#pragma omp target if(n>20)
{
a += 1;
@@ -464,9 +497,9 @@ int bar(int n){
// CHECK: [[CSIZE:%.+]] = mul nuw i[[SZ]] [[CELEMSIZE2]], 2
// CHECK: [[IF:%.+]] = icmp sgt i32 {{[^,]+}}, 60
-// CHECK: br i1 [[IF]], label %[[TRY:[^,]+]], label %[[FAIL:[^,]+]]
+// CHECK: br i1 [[IF]], label %[[TRY:[^,]+]], label %[[IFELSE:[^,]+]]
// CHECK: [[TRY]]
-// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target(i32 -1, i8* @{{[^,]+}}, i32 5, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* [[SR:%[^,]+]], i32* getelementptr inbounds ([5 x i32], [5 x i32]* [[MAPT7]], i32 0, i32 0))
+// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target(i64 -1, i8* @{{[^,]+}}, i32 5, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* [[SR:%[^,]+]], i64* getelementptr inbounds ([5 x i64], [5 x i64]* [[MAPT7]], i32 0, i32 0))
// CHECK-DAG: [[BPR]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[BP:%.+]], i32 0, i32 0
// CHECK-DAG: [[PR]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[P:%.+]], i32 0, i32 0
// CHECK-DAG: [[SR]] = getelementptr inbounds [5 x i[[SZ]]], [5 x i[[SZ]]]* [[S:%.+]], i32 0, i32 0
@@ -507,9 +540,9 @@ int bar(int n){
// CHECK-DAG: store i[[SZ]] 4, i[[SZ]]* [[SADDR1]]
// CHECK-DAG: [[CBPADDR0:%.+]] = bitcast i8** [[BPADDR0]] to [[S1]]**
-// CHECK-DAG: [[CPADDR0:%.+]] = bitcast i8** [[PADDR0]] to [[S1]]**
+// CHECK-DAG: [[CPADDR0:%.+]] = bitcast i8** [[PADDR0]] to double**
// CHECK-DAG: store [[S1]]* %{{.+}}, [[S1]]** [[CBPADDR0]]
-// CHECK-DAG: store [[S1]]* %{{.+}}, [[S1]]** [[CPADDR0]]
+// CHECK-DAG: store double* %{{.+}}, double** [[CPADDR0]]
// CHECK-DAG: store i[[SZ]] 8, i[[SZ]]* [[SADDR0]]
// CHECK-DAG: [[CBPADDR4:%.+]] = bitcast i8** [[BPADDR4]] to i16**
@@ -518,15 +551,18 @@ int bar(int n){
// CHECK-DAG: store i16* %{{.+}}, i16** [[CPADDR4]]
// CHECK-DAG: store i[[SZ]] [[CSIZE]], i[[SZ]]* [[SADDR4]]
-// CHECK: store i32 [[RET]], i32* [[RHV:%.+]], align 4
-// CHECK: [[RET2:%.+]] = load i32, i32* [[RHV]], align 4
-// CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
-// CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:[^,]+]], label %[[END:[^,]+]]
-
+// CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
+// CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
// CHECK: [[FAIL]]
// CHECK: call void [[HVT7:@.+]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}})
// CHECK-NEXT: br label %[[END]]
// CHECK: [[END]]
+// CHECK-NEXT: br label %[[IFEND:.+]]
+// CHECK: [[IFELSE]]
+// CHECK: call void [[HVT7]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}})
+// CHECK-NEXT: br label %[[IFEND]]
+
+// CHECK: [[IFEND]]
//
// CHECK: define {{.*}}[[FSTATIC]]
@@ -534,7 +570,7 @@ int bar(int n){
// CHECK: [[IF:%.+]] = icmp sgt i32 {{[^,]+}}, 50
// CHECK: br i1 [[IF]], label %[[IFTHEN:[^,]+]], label %[[IFELSE:[^,]+]]
// CHECK: [[IFTHEN]]
-// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target(i32 -1, i8* @{{[^,]+}}, i32 4, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* getelementptr inbounds ([4 x i[[SZ]]], [4 x i[[SZ]]]* [[SIZET6]], i32 0, i32 0), i32* getelementptr inbounds ([4 x i32], [4 x i32]* [[MAPT6]], i32 0, i32 0))
+// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target(i64 -1, i8* @{{[^,]+}}, i32 4, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* getelementptr inbounds ([4 x i[[SZ]]], [4 x i[[SZ]]]* [[SIZET6]], i32 0, i32 0), i64* getelementptr inbounds ([4 x i64], [4 x i64]* [[MAPT6]], i32 0, i32 0))
// CHECK-DAG: [[BPR]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[BP:%.+]], i32 0, i32 0
// CHECK-DAG: [[PR]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[P:%.+]], i32 0, i32 0
@@ -566,21 +602,18 @@ int bar(int n){
// CHECK-DAG: store [10 x i32]* [[VAL3:%[^,]+]], [10 x i32]** [[CBPADDR3]]
// CHECK-DAG: store [10 x i32]* [[VAL3]], [10 x i32]** [[CPADDR3]]
-// CHECK: store i32 [[RET]], i32* [[RHV:%.+]], align 4
-// CHECK-NEXT: br label %[[IFEND:.+]]
-
-// CHECK: [[IFELSE]]
-// CHECK: store i32 -1, i32* [[RHV]], align 4
-// CHECK-NEXT: br label %[[IFEND:.+]]
-
-// CHECK: [[IFEND]]
-// CHECK: [[RET2:%.+]] = load i32, i32* [[RHV]], align 4
-// CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+// CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
// CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
// CHECK: [[FAIL]]
// CHECK: call void [[HVT6:@.+]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}})
// CHECK-NEXT: br label %[[END]]
// CHECK: [[END]]
+// CHECK-NEXT: br label %[[IFEND:.+]]
+// CHECK: [[IFELSE]]
+// CHECK: call void [[HVT6]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}})
+// CHECK-NEXT: br label %[[IFEND]]
+
+// CHECK: [[IFEND]]
//
// CHECK: define {{.*}}[[FTEMPLATE]]
@@ -588,7 +621,7 @@ int bar(int n){
// CHECK: [[IF:%.+]] = icmp sgt i32 {{[^,]+}}, 40
// CHECK: br i1 [[IF]], label %[[IFTHEN:[^,]+]], label %[[IFELSE:[^,]+]]
// CHECK: [[IFTHEN]]
-// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target(i32 -1, i8* @{{[^,]+}}, i32 3, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* getelementptr inbounds ([3 x i[[SZ]]], [3 x i[[SZ]]]* [[SIZET5]], i32 0, i32 0), i32* getelementptr inbounds ([3 x i32], [3 x i32]* [[MAPT5]], i32 0, i32 0))
+// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target(i64 -1, i8* @{{[^,]+}}, i32 3, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* getelementptr inbounds ([3 x i[[SZ]]], [3 x i[[SZ]]]* [[SIZET5]], i32 0, i32 0), i64* getelementptr inbounds ([3 x i64], [3 x i64]* [[MAPT5]], i32 0, i32 0))
// CHECK-DAG: [[BPR]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BP:%.+]], i32 0, i32 0
// CHECK-DAG: [[PR]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[P:%.+]], i32 0, i32 0
@@ -613,22 +646,18 @@ int bar(int n){
// CHECK-DAG: store [10 x i32]* [[VAL2:%[^,]+]], [10 x i32]** [[CBPADDR2]]
// CHECK-DAG: store [10 x i32]* [[VAL2]], [10 x i32]** [[CPADDR2]]
-// CHECK: store i32 [[RET]], i32* [[RHV:%.+]], align 4
-// CHECK-NEXT: br label %[[IFEND:.+]]
-
-// CHECK: [[IFELSE]]
-// CHECK: store i32 -1, i32* [[RHV]], align 4
-// CHECK-NEXT: br label %[[IFEND:.+]]
-
-// CHECK: [[IFEND]]
-// CHECK: [[RET2:%.+]] = load i32, i32* [[RHV]], align 4
-// CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+// CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
// CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
// CHECK: [[FAIL]]
// CHECK: call void [[HVT5:@.+]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}})
// CHECK-NEXT: br label %[[END]]
// CHECK: [[END]]
+// CHECK-NEXT: br label %[[IFEND:.+]]
+// CHECK: [[IFELSE]]
+// CHECK: call void [[HVT5]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}})
+// CHECK-NEXT: br label %[[IFEND]]
+// CHECK: [[IFEND]]
// Check that the offloading functions are emitted and that the arguments are
diff --git a/test/OpenMP/target_codegen_registration.cpp b/test/OpenMP/target_codegen_registration.cpp
index 064c15b8d8f1..5684b2573b6e 100644
--- a/test/OpenMP/target_codegen_registration.cpp
+++ b/test/OpenMP/target_codegen_registration.cpp
@@ -63,40 +63,40 @@
// CHECK-DAG: {{@.+}} = private constant i8 0
// TCHECK-NOT: {{@.+}} = private constant i8 0
// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
-// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
// CHECK-DAG: {{@.+}} = private constant i8 0
// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
-// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
// CHECK-DAG: {{@.+}} = private constant i8 0
// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
-// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
// CHECK-DAG: {{@.+}} = private constant i8 0
// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
-// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
// CHECK-DAG: {{@.+}} = private constant i8 0
// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
-// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
// CHECK-DAG: {{@.+}} = private constant i8 0
// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
-// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
// CHECK-DAG: {{@.+}} = private constant i8 0
// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
-// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
// CHECK-DAG: {{@.+}} = private constant i8 0
// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
-// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
// CHECK-DAG: {{@.+}} = private constant i8 0
// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
-// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
// CHECK-DAG: {{@.+}} = private constant i8 0
// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
-// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
// CHECK-DAG: {{@.+}} = private constant i8 0
// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
-// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
// CHECK-DAG: {{@.+}} = private constant i8 0
// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
-// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
// CHECK-NTARGET-NOT: private constant i8 0
// CHECK-NTARGET-NOT: private unnamed_addr constant [1 x i
diff --git a/test/OpenMP/target_data_codegen.cpp b/test/OpenMP/target_data_codegen.cpp
index 7e5e267d13b6..2c9526de73e1 100644
--- a/test/OpenMP/target_data_codegen.cpp
+++ b/test/OpenMP/target_data_codegen.cpp
@@ -22,15 +22,15 @@ ST<int> gb;
double gc[100];
// CK1: [[SIZE00:@.+]] = {{.+}}constant [1 x i[[sz:64|32]]] [i{{64|32}} 800]
-// CK1: [[MTYPE00:@.+]] = {{.+}}constant [1 x i32] [i32 34]
+// CK1: [[MTYPE00:@.+]] = {{.+}}constant [1 x i64] [i64 34]
// CK1: [[SIZE02:@.+]] = {{.+}}constant [1 x i[[sz]]] [i[[sz]] 4]
-// CK1: [[MTYPE02:@.+]] = {{.+}}constant [1 x i32] [i32 33]
+// CK1: [[MTYPE02:@.+]] = {{.+}}constant [1 x i64] [i64 33]
-// CK1: [[MTYPE03:@.+]] = {{.+}}constant [1 x i32] [i32 37]
+// CK1: [[MTYPE03:@.+]] = {{.+}}constant [1 x i64] [i64 37]
// CK1: [[SIZE04:@.+]] = {{.+}}constant [2 x i[[sz]]] [i[[sz]] {{8|4}}, i[[sz]] 24]
-// CK1: [[MTYPE04:@.+]] = {{.+}}constant [2 x i32] [i32 33, i32 17]
+// CK1: [[MTYPE04:@.+]] = {{.+}}constant [2 x i64] [i64 33, i64 17]
// CK1-LABEL: _Z3fooi
void foo(int arg) {
@@ -38,8 +38,9 @@ void foo(int arg) {
float lb[arg];
// Region 00
- // CK1-DAG: call void @__tgt_target_data_begin(i32 [[DEV:%[^,]+]], i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE00]]{{.+}})
- // CK1-DAG: [[DEV]] = load i32, i32* %{{[^,]+}},
+ // CK1-DAG: call void @__tgt_target_data_begin(i64 [[DEV:%[^,]+]], i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE00]]{{.+}})
+ // CK1-DAG: [[DEV]] = sext i32 [[DEVi32:%[^,]+]] to i64
+ // CK1-DAG: [[DEVi32]] = load i32, i32* %{{[^,]+}},
// CK1-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK1-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -52,8 +53,9 @@ void foo(int arg) {
// CK1: %{{.+}} = add nsw i32 %{{[^,]+}}, 1
- // CK1-DAG: call void @__tgt_target_data_end(i32 [[DEV:%[^,]+]], i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE00]]{{.+}})
- // CK1-DAG: [[DEV]] = load i32, i32* %{{[^,]+}},
+ // CK1-DAG: call void @__tgt_target_data_end(i64 [[DEV:%[^,]+]], i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE00]]{{.+}})
+ // CK1-DAG: [[DEV]] = sext i32 [[DEVi32:%[^,]+]] to i64
+ // CK1-DAG: [[DEVi32]] = load i32, i32* %{{[^,]+}},
// CK1-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP]]
// CK1-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P]]
#pragma omp target data if(1+3-5) device(arg) map(from: gc)
@@ -67,7 +69,7 @@ void foo(int arg) {
// Region 02
// CK1: br i1 %{{[^,]+}}, label %[[IFTHEN:[^,]+]], label %[[IFELSE:[^,]+]]
// CK1: [[IFTHEN]]
- // CK1-DAG: call void @__tgt_target_data_begin(i32 4, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE02]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE02]]{{.+}})
+ // CK1-DAG: call void @__tgt_target_data_begin(i64 4, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE02]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE02]]{{.+}})
// CK1-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK1-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -86,7 +88,7 @@ void foo(int arg) {
// CK1: br i1 %{{[^,]+}}, label %[[IFTHEN:[^,]+]], label %[[IFELSE:[^,]+]]
// CK1: [[IFTHEN]]
- // CK1-DAG: call void @__tgt_target_data_end(i32 4, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE02]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE02]]{{.+}})
+ // CK1-DAG: call void @__tgt_target_data_end(i64 4, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE02]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE02]]{{.+}})
// CK1-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP]]
// CK1-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P]]
// CK1: br label %[[IFEND:[^,]+]]
@@ -97,7 +99,7 @@ void foo(int arg) {
{++arg;}
// Region 03
- // CK1-DAG: call void @__tgt_target_data_begin(i32 -1, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[sz]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE03]]{{.+}})
+ // CK1-DAG: call void @__tgt_target_data_begin(i64 -1, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[sz]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE03]]{{.+}})
// CK1-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK1-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
// CK1-DAG: [[GEPS]] = getelementptr inbounds {{.+}}[[S:%[^,]+]]
@@ -113,7 +115,7 @@ void foo(int arg) {
// CK1-DAG: [[CSVAL0]] = mul nuw i[[sz]] %{{[^,]+}}, 4
// CK1: %{{.+}} = add nsw i32 %{{[^,]+}}, 1
- // CK1-DAG: call void @__tgt_target_data_end(i32 -1, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[sz]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE03]]{{.+}})
+ // CK1-DAG: call void @__tgt_target_data_end(i64 -1, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[sz]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE03]]{{.+}})
// CK1-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP]]
// CK1-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P]]
// CK1-DAG: [[GEPS]] = getelementptr inbounds {{.+}}[[S]]
@@ -124,7 +126,7 @@ void foo(int arg) {
{++arg;}
// Region 04
- // CK1-DAG: call void @__tgt_target_data_begin(i32 -1, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE04]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE04]]{{.+}})
+ // CK1-DAG: call void @__tgt_target_data_begin(i64 -1, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE04]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE04]]{{.+}})
// CK1-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK1-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -147,7 +149,7 @@ void foo(int arg) {
// CK1: %{{.+}} = add nsw i32 %{{[^,]+}}, 1
- // CK1-DAG: call void @__tgt_target_data_end(i32 -1, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE04]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE04]]{{.+}})
+ // CK1-DAG: call void @__tgt_target_data_end(i64 -1, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE04]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE04]]{{.+}})
// CK1-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP]]
// CK1-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P]]
#pragma omp target data map(to: gb.b[:3])
@@ -178,7 +180,7 @@ struct ST {
};
// CK2: [[SIZE00:@.+]] = {{.+}}constant [2 x i[[sz:64|32]]] [i{{64|32}} {{8|4}}, i{{64|32}} 24]
-// CK2: [[MTYPE00:@.+]] = {{.+}}constant [2 x i32] [i32 37, i32 21]
+// CK2: [[MTYPE00:@.+]] = {{.+}}constant [2 x i64] [i64 37, i64 21]
// CK2-LABEL: _Z3bari
int bar(int arg){
@@ -189,8 +191,9 @@ int bar(int arg){
// Region 00
// CK2: br i1 %{{[^,]+}}, label %[[IFTHEN:[^,]+]], label %[[IFELSE:[^,]+]]
// CK2: [[IFTHEN]]
-// CK2-DAG: call void @__tgt_target_data_begin(i32 [[DEV:%[^,]+]], i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE00]]{{.+}})
-// CK2-DAG: [[DEV]] = load i32, i32* %{{[^,]+}},
+// CK2-DAG: call void @__tgt_target_data_begin(i64 [[DEV:%[^,]+]], i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE00]]{{.+}})
+// CK2-DAG: [[DEV]] = sext i32 [[DEVi32:%[^,]+]] to i64
+// CK2-DAG: [[DEVi32]] = load i32, i32* %{{[^,]+}},
// CK2-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK2-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -222,8 +225,9 @@ int bar(int arg){
// CK2: br i1 %{{[^,]+}}, label %[[IFTHEN:[^,]+]], label %[[IFELSE:[^,]+]]
// CK2: [[IFTHEN]]
-// CK2-DAG: call void @__tgt_target_data_end(i32 [[DEV:%[^,]+]], i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE00]]{{.+}})
-// CK2-DAG: [[DEV]] = load i32, i32* %{{[^,]+}},
+// CK2-DAG: call void @__tgt_target_data_end(i64 [[DEV:%[^,]+]], i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE00]]{{.+}})
+// CK2-DAG: [[DEV]] = sext i32 [[DEVi32:%[^,]+]] to i64
+// CK2-DAG: [[DEVi32]] = load i32, i32* %{{[^,]+}},
// CK2-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP]]
// CK2-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P]]
// CK2: br label %[[IFEND:[^,]+]]
diff --git a/test/OpenMP/target_data_use_device_ptr_codegen.cpp b/test/OpenMP/target_data_use_device_ptr_codegen.cpp
index 5e275565170e..36c42e32ea3f 100644
--- a/test/OpenMP/target_data_use_device_ptr_codegen.cpp
+++ b/test/OpenMP/target_data_use_device_ptr_codegen.cpp
@@ -14,18 +14,18 @@
double *g;
// CK1: @g = global double*
-// CK1: [[MTYPE00:@.+]] = {{.*}}constant [1 x i32] [i32 99]
-// CK1: [[MTYPE01:@.+]] = {{.*}}constant [1 x i32] [i32 99]
-// CK1: [[MTYPE03:@.+]] = {{.*}}constant [1 x i32] [i32 99]
-// CK1: [[MTYPE04:@.+]] = {{.*}}constant [1 x i32] [i32 99]
-// CK1: [[MTYPE05:@.+]] = {{.*}}constant [1 x i32] [i32 99]
-// CK1: [[MTYPE06:@.+]] = {{.*}}constant [1 x i32] [i32 99]
-// CK1: [[MTYPE07:@.+]] = {{.*}}constant [1 x i32] [i32 99]
-// CK1: [[MTYPE08:@.+]] = {{.*}}constant [2 x i32] [{{i32 35, i32 99|i32 99, i32 35}}]
-// CK1: [[MTYPE09:@.+]] = {{.*}}constant [2 x i32] [i32 99, i32 99]
-// CK1: [[MTYPE10:@.+]] = {{.*}}constant [2 x i32] [i32 99, i32 99]
-// CK1: [[MTYPE11:@.+]] = {{.*}}constant [2 x i32] [i32 96, i32 35]
-// CK1: [[MTYPE12:@.+]] = {{.*}}constant [2 x i32] [i32 96, i32 35]
+// CK1: [[MTYPE00:@.+]] = {{.*}}constant [1 x i64] [i64 99]
+// CK1: [[MTYPE01:@.+]] = {{.*}}constant [1 x i64] [i64 99]
+// CK1: [[MTYPE03:@.+]] = {{.*}}constant [1 x i64] [i64 99]
+// CK1: [[MTYPE04:@.+]] = {{.*}}constant [1 x i64] [i64 99]
+// CK1: [[MTYPE05:@.+]] = {{.*}}constant [1 x i64] [i64 99]
+// CK1: [[MTYPE06:@.+]] = {{.*}}constant [1 x i64] [i64 99]
+// CK1: [[MTYPE07:@.+]] = {{.*}}constant [1 x i64] [i64 99]
+// CK1: [[MTYPE08:@.+]] = {{.*}}constant [2 x i64] [{{i64 35, i64 99|i64 99, i64 35}}]
+// CK1: [[MTYPE09:@.+]] = {{.*}}constant [2 x i64] [i64 99, i64 99]
+// CK1: [[MTYPE10:@.+]] = {{.*}}constant [2 x i64] [i64 99, i64 99]
+// CK1: [[MTYPE11:@.+]] = {{.*}}constant [2 x i64] [i64 96, i64 35]
+// CK1: [[MTYPE12:@.+]] = {{.*}}constant [2 x i64] [i64 96, i64 35]
// CK1-LABEL: @_Z3foo
template<typename T>
@@ -330,10 +330,10 @@ void bar(float *&a, int *&b) {
#ifdef CK2
// CK2: [[ST:%.+]] = type { double*, double** }
-// CK2: [[MTYPE00:@.+]] = {{.*}}constant [2 x i32] [i32 35, i32 83]
-// CK2: [[MTYPE01:@.+]] = {{.*}}constant [3 x i32] [i32 32, i32 19, i32 83]
-// CK2: [[MTYPE02:@.+]] = {{.*}}constant [2 x i32] [i32 96, i32 35]
-// CK2: [[MTYPE03:@.+]] = {{.*}}constant [4 x i32] [i32 96, i32 32, i32 19, i32 83]
+// CK2: [[MTYPE00:@.+]] = {{.*}}constant [2 x i64] [i64 35, i64 83]
+// CK2: [[MTYPE01:@.+]] = {{.*}}constant [3 x i64] [i64 32, i64 19, i64 83]
+// CK2: [[MTYPE02:@.+]] = {{.*}}constant [2 x i64] [i64 96, i64 35]
+// CK2: [[MTYPE03:@.+]] = {{.*}}constant [4 x i64] [i64 96, i64 32, i64 19, i64 83]
template <typename T>
struct ST {
diff --git a/test/OpenMP/target_depend_messages.cpp b/test/OpenMP/target_depend_messages.cpp
index 48bd94180c1e..3eb3af132d8f 100644
--- a/test/OpenMP/target_depend_messages.cpp
+++ b/test/OpenMP/target_depend_messages.cpp
@@ -36,21 +36,21 @@ int main(int argc, char **argv, char *env[]) {
foo();
#pragma omp target depend (out: ) // expected-error {{expected expression}}
foo();
- #pragma omp target depend (inout : foobool(argc)), depend (in, argc) // expected-error {{expected variable name, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}}
+ #pragma omp target depend (inout : foobool(argc)), depend (in, argc) // expected-error {{expected addressable lvalue expression, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}}
foo();
#pragma omp target depend (out :S1) // expected-error {{'S1' does not refer to a value}}
foo();
- #pragma omp target depend(in : argv[1][1] = '2') // expected-error {{expected variable name, array element or array section}}
+ #pragma omp target depend(in : argv[1][1] = '2')
foo();
- #pragma omp target depend (in : vec[1]) // expected-error {{expected variable name, array element or array section}}
+ #pragma omp target depend (in : vec[1]) // expected-error {{expected addressable lvalue expression, array element or array section}}
foo();
#pragma omp target depend (in : argv[0])
foo();
#pragma omp target depend (in : ) // expected-error {{expected expression}}
foo();
- #pragma omp target depend (in : main) // expected-error {{expected variable name, array element or array section}}
+ #pragma omp target depend (in : main)
foo();
- #pragma omp target depend(in : a[0]) // expected-error{{expected variable name, array element or array section}}
+ #pragma omp target depend(in : a[0]) // expected-error{{expected addressable lvalue expression, array element or array section}}
foo();
#pragma omp target depend (in : vec[1:2]) // expected-error {{ value is not an array or pointer}}
foo();
diff --git a/test/OpenMP/target_enter_data_codegen.cpp b/test/OpenMP/target_enter_data_codegen.cpp
index 683cd976d395..08b6c7c2702e 100644
--- a/test/OpenMP/target_enter_data_codegen.cpp
+++ b/test/OpenMP/target_enter_data_codegen.cpp
@@ -22,15 +22,15 @@ ST<int> gb;
double gc[100];
// CK1: [[SIZE00:@.+]] = {{.+}}constant [1 x i[[sz:64|32]]] [i{{64|32}} 800]
-// CK1: [[MTYPE00:@.+]] = {{.+}}constant [1 x i32] [i32 32]
+// CK1: [[MTYPE00:@.+]] = {{.+}}constant [1 x i64] [i64 32]
// CK1: [[SIZE02:@.+]] = {{.+}}constant [1 x i[[sz]]] [i[[sz]] 4]
-// CK1: [[MTYPE02:@.+]] = {{.+}}constant [1 x i32] [i32 33]
+// CK1: [[MTYPE02:@.+]] = {{.+}}constant [1 x i64] [i64 33]
-// CK1: [[MTYPE03:@.+]] = {{.+}}constant [1 x i32] [i32 37]
+// CK1: [[MTYPE03:@.+]] = {{.+}}constant [1 x i64] [i64 37]
// CK1: [[SIZE04:@.+]] = {{.+}}constant [2 x i[[sz]]] [i[[sz]] {{8|4}}, i[[sz]] 24]
-// CK1: [[MTYPE04:@.+]] = {{.+}}constant [2 x i32] [i32 33, i32 17]
+// CK1: [[MTYPE04:@.+]] = {{.+}}constant [2 x i64] [i64 33, i64 17]
// CK1-LABEL: _Z3fooi
void foo(int arg) {
@@ -38,8 +38,9 @@ void foo(int arg) {
float lb[arg];
// Region 00
- // CK1-DAG: call void @__tgt_target_data_begin(i32 [[DEV:%[^,]+]], i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE00]]{{.+}})
- // CK1-DAG: [[DEV]] = load i32, i32* %{{[^,]+}},
+ // CK1-DAG: call void @__tgt_target_data_begin_nowait(i64 [[DEV:%[^,]+]], i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE00]]{{.+}})
+ // CK1-DAG: [[DEV]] = sext i32 [[DEVi32:%[^,]+]] to i64
+ // CK1-DAG: [[DEVi32]] = load i32, i32* %{{[^,]+}},
// CK1-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK1-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -52,7 +53,7 @@ void foo(int arg) {
// CK1: %{{.+}} = add nsw i32 %{{[^,]+}}, 1
// CK1-NOT: __tgt_target_data_end
- #pragma omp target enter data if(1+3-5) device(arg) map(alloc: gc)
+ #pragma omp target enter data if(1+3-5) device(arg) map(alloc: gc) nowait
{++arg;}
// Region 01
@@ -63,7 +64,7 @@ void foo(int arg) {
// Region 02
// CK1: br i1 %{{[^,]+}}, label %[[IFTHEN:[^,]+]], label %[[IFELSE:[^,]+]]
// CK1: [[IFTHEN]]
- // CK1-DAG: call void @__tgt_target_data_begin(i32 4, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE02]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE02]]{{.+}})
+ // CK1-DAG: call void @__tgt_target_data_begin(i64 4, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE02]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE02]]{{.+}})
// CK1-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK1-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -87,7 +88,7 @@ void foo(int arg) {
{++arg;}
// Region 03
- // CK1-DAG: call void @__tgt_target_data_begin(i32 -1, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[sz]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE03]]{{.+}})
+ // CK1-DAG: call void @__tgt_target_data_begin(i64 -1, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[sz]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE03]]{{.+}})
// CK1-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK1-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
// CK1-DAG: [[GEPS]] = getelementptr inbounds {{.+}}[[S:%[^,]+]]
@@ -110,7 +111,7 @@ void foo(int arg) {
{++arg;}
// Region 04
- // CK1-DAG: call void @__tgt_target_data_begin(i32 -1, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE04]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE04]]{{.+}})
+ // CK1-DAG: call void @__tgt_target_data_begin(i64 -1, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE04]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE04]]{{.+}})
// CK1-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK1-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -161,7 +162,7 @@ struct ST {
};
// CK2: [[SIZE00:@.+]] = {{.+}}constant [2 x i[[sz:64|32]]] [i{{64|32}} {{8|4}}, i{{64|32}} 24]
-// CK2: [[MTYPE00:@.+]] = {{.+}}constant [2 x i32] [i32 37, i32 21]
+// CK2: [[MTYPE00:@.+]] = {{.+}}constant [2 x i64] [i64 37, i64 21]
// CK2-LABEL: _Z3bari
int bar(int arg){
@@ -172,8 +173,9 @@ int bar(int arg){
// Region 00
// CK2: br i1 %{{[^,]+}}, label %[[IFTHEN:[^,]+]], label %[[IFELSE:[^,]+]]
// CK2: [[IFTHEN]]
-// CK2-DAG: call void @__tgt_target_data_begin(i32 [[DEV:%[^,]+]], i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE00]]{{.+}})
-// CK2-DAG: [[DEV]] = load i32, i32* %{{[^,]+}},
+// CK2-DAG: call void @__tgt_target_data_begin(i64 [[DEV:%[^,]+]], i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE00]]{{.+}})
+// CK2-DAG: [[DEV]] = sext i32 [[DEVi32:%[^,]+]] to i64
+// CK2-DAG: [[DEVi32]] = load i32, i32* %{{[^,]+}},
// CK2-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK2-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
diff --git a/test/OpenMP/target_enter_data_depend_messages.cpp b/test/OpenMP/target_enter_data_depend_messages.cpp
index 4aa122355ba5..77e7039e8e20 100644
--- a/test/OpenMP/target_enter_data_depend_messages.cpp
+++ b/test/OpenMP/target_enter_data_depend_messages.cpp
@@ -38,21 +38,21 @@ int tmain(T argc, S **argv, R *env[]) {
foo();
#pragma omp target enter data map(to: i) depend (out: ) // expected-error {{expected expression}}
foo();
- #pragma omp target enter data map(to: i) depend (inout : foobool(argc)), depend (in, argc) // expected-error {{expected variable name, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}}
+ #pragma omp target enter data map(to: i) depend (inout : foobool(argc)), depend (in, argc) // expected-error {{expected addressable lvalue expression, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}}
foo();
#pragma omp target enter data map(to: i) depend (out :S1) // expected-error {{'S1' does not refer to a value}}
foo();
- #pragma omp target enter data map(to: i) depend(in : argv[1][1] = '2') // expected-error {{expected variable name, array element or array section}}
+ #pragma omp target enter data map(to: i) depend(in : argv[1][1] = '2') // expected-error {{expected addressable lvalue expression, array element or array section}}
foo();
- #pragma omp target enter data map(to: i) depend (in : vec[1]) // expected-error {{expected variable name, array element or array section}}
+ #pragma omp target enter data map(to: i) depend (in : vec[1]) // expected-error {{expected addressable lvalue expression, array element or array section}}
foo();
#pragma omp target enter data map(to: i) depend (in : argv[0])
foo();
#pragma omp target enter data map(to: i) depend (in : ) // expected-error {{expected expression}}
foo();
- #pragma omp target enter data map(to: i) depend (in : tmain) // expected-error {{expected variable name, array element or array section}}
+ #pragma omp target enter data map(to: i) depend (in : tmain)
foo();
- #pragma omp target enter data map(to: i) depend(in : a[0]) // expected-error{{expected variable name, array element or array section}}
+ #pragma omp target enter data map(to: i) depend(in : a[0]) // expected-error{{expected addressable lvalue expression, array element or array section}}
foo();
#pragma omp target enter data map(to: i) depend (in : vec[1:2]) // expected-error {{ value is not an array or pointer}}
foo();
@@ -113,21 +113,21 @@ int main(int argc, char **argv, char *env[]) {
foo();
#pragma omp target enter data map(to: i) depend (out: ) // expected-error {{expected expression}}
foo();
- #pragma omp target enter data map(to: i) depend (inout : foobool(argc)), depend (in, argc) // expected-error {{expected variable name, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}}
+ #pragma omp target enter data map(to: i) depend (inout : foobool(argc)), depend (in, argc) // expected-error {{expected addressable lvalue expression, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}}
foo();
#pragma omp target enter data map(to: i) depend (out :S1) // expected-error {{'S1' does not refer to a value}}
foo();
- #pragma omp target enter data map(to: i) depend(in : argv[1][1] = '2') // expected-error {{expected variable name, array element or array section}}
+ #pragma omp target enter data map(to: i) depend(in : argv[1][1] = '2')
foo();
- #pragma omp target enter data map(to: i) depend (in : vec[1]) // expected-error {{expected variable name, array element or array section}}
+ #pragma omp target enter data map(to: i) depend (in : vec[1]) // expected-error {{expected addressable lvalue expression, array element or array section}}
foo();
#pragma omp target enter data map(to: i) depend (in : argv[0])
foo();
#pragma omp target enter data map(to: i) depend (in : ) // expected-error {{expected expression}}
foo();
- #pragma omp target enter data map(to: i) depend (in : main) // expected-error {{expected variable name, array element or array section}}
+ #pragma omp target enter data map(to: i) depend (in : main)
foo();
- #pragma omp target enter data map(to: i) depend(in : a[0]) // expected-error{{expected variable name, array element or array section}}
+ #pragma omp target enter data map(to: i) depend(in : a[0]) // expected-error{{expected addressable lvalue expression, array element or array section}}
foo();
#pragma omp target enter data map(to: i) depend (in : vec[1:2]) // expected-error {{ value is not an array or pointer}}
foo();
diff --git a/test/OpenMP/target_exit_data_codegen.cpp b/test/OpenMP/target_exit_data_codegen.cpp
index a82c1c6c4aac..9359e3be451b 100644
--- a/test/OpenMP/target_exit_data_codegen.cpp
+++ b/test/OpenMP/target_exit_data_codegen.cpp
@@ -22,15 +22,15 @@ ST<int> gb;
double gc[100];
// CK1: [[SIZE00:@.+]] = {{.+}}constant [1 x i[[sz:64|32]]] [i{{64|32}} 800]
-// CK1: [[MTYPE00:@.+]] = {{.+}}constant [1 x i32] [i32 34]
+// CK1: [[MTYPE00:@.+]] = {{.+}}constant [1 x i64] [i64 34]
// CK1: [[SIZE02:@.+]] = {{.+}}constant [1 x i[[sz]]] [i[[sz]] 4]
-// CK1: [[MTYPE02:@.+]] = {{.+}}constant [1 x i32] [i32 32]
+// CK1: [[MTYPE02:@.+]] = {{.+}}constant [1 x i64] [i64 32]
-// CK1: [[MTYPE03:@.+]] = {{.+}}constant [1 x i32] [i32 38]
+// CK1: [[MTYPE03:@.+]] = {{.+}}constant [1 x i64] [i64 38]
// CK1: [[SIZE04:@.+]] = {{.+}}constant [2 x i[[sz]]] [i[[sz]] {{8|4}}, i[[sz]] 24]
-// CK1: [[MTYPE04:@.+]] = {{.+}}constant [2 x i32] [i32 32, i32 16]
+// CK1: [[MTYPE04:@.+]] = {{.+}}constant [2 x i64] [i64 32, i64 16]
// CK1-LABEL: _Z3fooi
void foo(int arg) {
@@ -39,8 +39,9 @@ void foo(int arg) {
// Region 00
// CK1-NOT: __tgt_target_data_begin
- // CK1-DAG: call void @__tgt_target_data_end(i32 [[DEV:%[^,]+]], i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE00]]{{.+}})
- // CK1-DAG: [[DEV]] = load i32, i32* %{{[^,]+}},
+ // CK1-DAG: call void @__tgt_target_data_end_nowait(i64 [[DEV:%[^,]+]], i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE00]]{{.+}})
+ // CK1-DAG: [[DEV]] = sext i32 [[DEVi32:%[^,]+]] to i64
+ // CK1-DAG: [[DEVi32]] = load i32, i32* %{{[^,]+}},
// CK1-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK1-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -52,7 +53,7 @@ void foo(int arg) {
// CK1-DAG: store [100 x double]* @gc, [100 x double]** [[PC0]]
// CK1: %{{.+}} = add nsw i32 %{{[^,]+}}, 1
- #pragma omp target exit data if(1+3-5) device(arg) map(from: gc)
+ #pragma omp target exit data if(1+3-5) device(arg) map(from: gc) nowait
{++arg;}
// Region 01
@@ -64,7 +65,7 @@ void foo(int arg) {
// CK1-NOT: __tgt_target_data_begin
// CK1: br i1 %{{[^,]+}}, label %[[IFTHEN:[^,]+]], label %[[IFELSE:[^,]+]]
// CK1: [[IFTHEN]]
- // CK1-DAG: call void @__tgt_target_data_end(i32 4, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE02]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE02]]{{.+}})
+ // CK1-DAG: call void @__tgt_target_data_end(i64 4, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE02]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE02]]{{.+}})
// CK1-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK1-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -88,7 +89,7 @@ void foo(int arg) {
// Region 03
// CK1-NOT: __tgt_target_data_begin
- // CK1-DAG: call void @__tgt_target_data_end(i32 -1, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[sz]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE03]]{{.+}})
+ // CK1-DAG: call void @__tgt_target_data_end(i64 -1, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[sz]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE03]]{{.+}})
// CK1-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK1-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
// CK1-DAG: [[GEPS]] = getelementptr inbounds {{.+}}[[S:%[^,]+]]
@@ -111,7 +112,7 @@ void foo(int arg) {
// Region 04
// CK1-NOT: __tgt_target_data_begin
- // CK1-DAG: call void @__tgt_target_data_end(i32 -1, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE04]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE04]]{{.+}})
+ // CK1-DAG: call void @__tgt_target_data_end(i64 -1, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE04]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE04]]{{.+}})
// CK1-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK1-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -161,7 +162,7 @@ struct ST {
};
// CK2: [[SIZE00:@.+]] = {{.+}}constant [2 x i[[sz:64|32]]] [i{{64|32}} {{8|4}}, i{{64|32}} 24]
-// CK2: [[MTYPE00:@.+]] = {{.+}}constant [2 x i32] [i32 36, i32 20]
+// CK2: [[MTYPE00:@.+]] = {{.+}}constant [2 x i64] [i64 36, i64 20]
// CK2-LABEL: _Z3bari
int bar(int arg){
@@ -173,8 +174,9 @@ int bar(int arg){
// CK2-NOT: __tgt_target_data_begin
// CK2: br i1 %{{[^,]+}}, label %[[IFTHEN:[^,]+]], label %[[IFELSE:[^,]+]]
// CK2: [[IFTHEN]]
-// CK2-DAG: call void @__tgt_target_data_end(i32 [[DEV:%[^,]+]], i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE00]]{{.+}})
-// CK2-DAG: [[DEV]] = load i32, i32* %{{[^,]+}},
+// CK2-DAG: call void @__tgt_target_data_end(i64 [[DEV:%[^,]+]], i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE00]]{{.+}})
+// CK2-DAG: [[DEV]] = sext i32 [[DEVi32:%[^,]+]] to i64
+// CK2-DAG: [[DEVi32]] = load i32, i32* %{{[^,]+}},
// CK2-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK2-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
diff --git a/test/OpenMP/target_exit_data_depend_messages.cpp b/test/OpenMP/target_exit_data_depend_messages.cpp
index cdefbeed08bd..ce8d237f75e9 100644
--- a/test/OpenMP/target_exit_data_depend_messages.cpp
+++ b/test/OpenMP/target_exit_data_depend_messages.cpp
@@ -38,21 +38,21 @@ int tmain(T argc, S **argv, R *env[]) {
foo();
#pragma omp target exit data map(from: i) depend (out: ) // expected-error {{expected expression}}
foo();
- #pragma omp target exit data map(from: i) depend (inout : foobool(argc)), depend (in, argc) // expected-error {{expected variable name, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}}
+ #pragma omp target exit data map(from: i) depend (inout : foobool(argc)), depend (in, argc) // expected-error {{expected addressable lvalue expression, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}}
foo();
#pragma omp target exit data map(from: i) depend (out :S1) // expected-error {{'S1' does not refer to a value}}
foo();
- #pragma omp target exit data map(from: i) depend(in : argv[1][1] = '2') // expected-error {{expected variable name, array element or array section}}
+ #pragma omp target exit data map(from: i) depend(in : argv[1][1] = '2') // expected-error {{expected addressable lvalue expression, array element or array section}}
foo();
- #pragma omp target exit data map(from: i) depend (in : vec[1]) // expected-error {{expected variable name, array element or array section}}
+ #pragma omp target exit data map(from: i) depend (in : vec[1]) // expected-error {{expected addressable lvalue expression, array element or array section}}
foo();
#pragma omp target exit data map(from: i) depend (in : argv[0])
foo();
#pragma omp target exit data map(from: i) depend (in : ) // expected-error {{expected expression}}
foo();
- #pragma omp target exit data map(from: i) depend (in : tmain) // expected-error {{expected variable name, array element or array section}}
+ #pragma omp target exit data map(from: i) depend (in : tmain)
foo();
- #pragma omp target exit data map(from: i) depend(in : a[0]) // expected-error{{expected variable name, array element or array section}}
+ #pragma omp target exit data map(from: i) depend(in : a[0]) // expected-error{{expected addressable lvalue expression, array element or array section}}
foo();
#pragma omp target exit data map(from: i) depend (in : vec[1:2]) // expected-error {{ value is not an array or pointer}}
foo();
@@ -113,21 +113,21 @@ int main(int argc, char **argv, char *env[]) {
foo();
#pragma omp target exit data map(from: i) depend (out: ) // expected-error {{expected expression}}
foo();
- #pragma omp target exit data map(from: i) depend (inout : foobool(argc)), depend (in, argc) // expected-error {{expected variable name, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}}
+ #pragma omp target exit data map(from: i) depend (inout : foobool(argc)), depend (in, argc) // expected-error {{expected addressable lvalue expression, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}}
foo();
#pragma omp target exit data map(from: i) depend (out :S1) // expected-error {{'S1' does not refer to a value}}
foo();
- #pragma omp target exit data map(from: i) depend(in : argv[1][1] = '2') // expected-error {{expected variable name, array element or array section}}
+ #pragma omp target exit data map(from: i) depend(in : argv[1][1] = '2')
foo();
- #pragma omp target exit data map(from: i) depend (in : vec[1]) // expected-error {{expected variable name, array element or array section}}
+ #pragma omp target exit data map(from: i) depend (in : vec[1]) // expected-error {{expected addressable lvalue expression, array element or array section}}
foo();
#pragma omp target exit data map(from: i) depend (in : argv[0])
foo();
#pragma omp target exit data map(from: i) depend (in : ) // expected-error {{expected expression}}
foo();
- #pragma omp target exit data map(from: i) depend (in : main) // expected-error {{expected variable name, array element or array section}}
+ #pragma omp target exit data map(from: i) depend (in : main)
foo();
- #pragma omp target exit data map(from: i) depend(in : a[0]) // expected-error{{expected variable name, array element or array section}}
+ #pragma omp target exit data map(from: i) depend(in : a[0]) // expected-error{{expected addressable lvalue expression, array element or array section}}
foo();
#pragma omp target exit data map(from: i) depend (in : vec[1:2]) // expected-error {{ value is not an array or pointer}}
foo();
diff --git a/test/OpenMP/target_firstprivate_codegen.cpp b/test/OpenMP/target_firstprivate_codegen.cpp
index 1fb0ef9e848c..c2909c6f18b8 100644
--- a/test/OpenMP/target_firstprivate_codegen.cpp
+++ b/test/OpenMP/target_firstprivate_codegen.cpp
@@ -33,15 +33,15 @@ struct TT{
// TCHECK: [[S1:%.+]] = type { double }
// CHECK-DAG: [[SIZET:@.+]] = private unnamed_addr constant [1 x i{{32|64}}] [i[[SZ:32|64]] 4]
-// CHECK: [[MAPT:@.+]] = private unnamed_addr constant [1 x i32] [i32 288]
-// CHECK-DAG: [[MAPT2:@.+]] = private unnamed_addr constant [9 x i32] [i32 288, i32 161, i32 288, i32 161, i32 161, i32 288, i32 288, i32 161, i32 161]
+// CHECK: [[MAPT:@.+]] = private unnamed_addr constant [1 x i64] [i64 288]
+// CHECK-DAG: [[MAPT2:@.+]] = private unnamed_addr constant [9 x i64] [i64 288, i64 161, i64 288, i64 161, i64 161, i64 288, i64 288, i64 161, i64 161]
// CHECK-DAG: [[SIZET3:@.+]] = private unnamed_addr constant [1 x i{{32|64}}] zeroinitializer
-// CHECK-DAG: [[MAPT3:@.+]] = private unnamed_addr constant [1 x i32] [i32 32]
-// CHECK-DAG: [[MAPT4:@.+]] = private unnamed_addr constant [5 x i32] [i32 35, i32 288, i32 288, i32 288, i32 161]
+// CHECK-DAG: [[MAPT3:@.+]] = private unnamed_addr constant [1 x i64] [i64 32]
+// CHECK-DAG: [[MAPT4:@.+]] = private unnamed_addr constant [5 x i64] [i64 547, i64 288, i64 288, i64 288, i64 161]
// CHECK-DAG: [[SIZET5:@.+]] = private unnamed_addr constant [3 x i{{32|64}}] [i[[SZ]] 4, i[[SZ]] 1, i[[SZ]] 40]
-// CHECK-DAG: [[MAPT5:@.+]] = private unnamed_addr constant [3 x i32] [i32 288, i32 288, i32 161]
+// CHECK-DAG: [[MAPT5:@.+]] = private unnamed_addr constant [3 x i64] [i64 288, i64 288, i64 161]
// CHECK-DAG: [[SIZET6:@.+]] = private unnamed_addr constant [2 x i{{32|64}}] [i[[SZ]] 4, i[[SZ]] 40]
-// CHECK-DAG: [[MAPT6:@.+]] = private unnamed_addr constant [2 x i32] [i32 288, i32 161]
+// CHECK-DAG: [[MAPT6:@.+]] = private unnamed_addr constant [2 x i64] [i64 288, i64 161]
// CHECK: define {{.*}}[[FOO:@.+]](
@@ -68,7 +68,6 @@ int foo(int n, double *ptr) {
// CHECK: [[C:%.+]] = alloca [5 x [10 x double]],
// CHECK: [[D:%.+]] = alloca [[TT]],
// CHECK: [[ACAST:%.+]] = alloca i{{[0-9]+}},
- // CHECK: {{.+}} = alloca i{{[0-9]+}},
// CHECK: [[BASE_PTR_ARR:%.+]] = alloca [1 x i8*],
// CHECK: [[PTR_ARR:%.+]] = alloca [1 x i8*],
// CHECK: [[A2CAST:%.+]] = alloca i{{[0-9]+}},
@@ -101,7 +100,7 @@ int foo(int n, double *ptr) {
// CHECK: store i{{[0-9]+}} [[ACAST_VAL]], i{{[0-9]+}}* [[ACAST_TOPTR2]],
// CHECK: [[BASE_PTR_GEP_ARG:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[BASE_PTR_ARR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
// CHECK: [[PTR_GEP_ARG:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[PTR_ARR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
- // CHECK: {{.+}} = call i32 @__tgt_target(i32 -1, {{.+}}, i32 1, i8** [[BASE_PTR_GEP_ARG]], i8** [[PTR_GEP_ARG]], i[[SZ]]* getelementptr inbounds ([1 x i[[SZ]]], [1 x i[[SZ]]]* [[SIZET]], i32 0, i32 0), i32* getelementptr inbounds ([1 x i32], [1 x i32]* [[MAPT]], i32 0, i32 0))
+ // CHECK: {{.+}} = call i32 @__tgt_target(i64 -1, {{.+}}, i32 1, i8** [[BASE_PTR_GEP_ARG]], i8** [[PTR_GEP_ARG]], i[[SZ]]* getelementptr inbounds ([1 x i[[SZ]]], [1 x i[[SZ]]]* [[SIZET]], i32 0, i32 0), i64* getelementptr inbounds ([1 x i64], [1 x i64]* [[MAPT]], i32 0, i32 0))
// TCHECK: define void @__omp_offloading_{{.+}}(i{{[0-9]+}} [[A_IN:%.+]])
// TCHECK: [[A_ADDR:%.+]] = alloca i{{[0-9]+}},
@@ -220,11 +219,11 @@ int foo(int n, double *ptr) {
// CHECK: [[BASE_PTR_GEP_ARG2:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BASE_PTR_ARR2]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
// CHECK: [[PTR_GEP_ARG2:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[PTR_ARR2]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
// CHECK: [[SIZES_ARG2:%.+]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[SIZET2]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
- // CHECK: {{.+}} = call i32 @__tgt_target(i32 -1, {{.+}}, i32 9, i8** [[BASE_PTR_GEP_ARG2]], i8** [[PTR_GEP_ARG2]], i[[SZ]]* [[SIZES_ARG2]], i32* getelementptr inbounds ([9 x i32], [9 x i32]* [[MAPT2]], i32 0, i32 0))
+ // CHECK: {{.+}} = call i32 @__tgt_target(i64 -1, {{.+}}, i32 9, i8** [[BASE_PTR_GEP_ARG2]], i8** [[PTR_GEP_ARG2]], i[[SZ]]* [[SIZES_ARG2]], i64* getelementptr inbounds ([9 x i64], [9 x i64]* [[MAPT2]], i32 0, i32 0))
// make sure that firstprivate variables are generated in all cases and that we use those instances for operations inside the
// target region
- // TCHECK: define {{.*}}void @__omp_offloading_{{.+}}(i{{[0-9]+}} [[A2_IN:%.+]], [10 x float]* {{.+}} [[B_IN:%.+]], i{{[0-9]+}} [[BN_SZ:%.+]], float* [[BN_IN:%.+]], [5 x [10 x double]]* {{.+}} [[C_IN:%.+]], i{{[0-9]+}} [[CN_SZ1:%.+]], i{{[0-9]+}} [[CN_SZ2:%.+]], double* [[CN_IN:%.+]], [[TT]]* {{.+}} [[D_IN:%.+]])
+ // TCHECK: define {{.*}}void @__omp_offloading_{{.+}}(i{{[0-9]+}} [[A2_IN:%.+]], [10 x float]* {{.+}} [[B_IN:%.+]], i{{[0-9]+}} [[BN_SZ:%.+]], float* {{.+}} [[BN_IN:%.+]], [5 x [10 x double]]* {{.+}} [[C_IN:%.+]], i{{[0-9]+}} [[CN_SZ1:%.+]], i{{[0-9]+}} [[CN_SZ2:%.+]], double* {{.+}} [[CN_IN:%.+]], [[TT]]* {{.+}} [[D_IN:%.+]])
// TCHECK: [[A2_ADDR:%.+]] = alloca i{{[0-9]+}},
// TCHECK: [[B_ADDR:%.+]] = alloca [10 x float]*,
// TCHECK: [[VLA_ADDR:%.+]] = alloca i{{[0-9]+}},
@@ -311,7 +310,7 @@ int foo(int n, double *ptr) {
// CHECK: [[BASE_PTR_GEP_ARG3:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[BASE_PTR_ARR3]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
// CHECK: [[PTR_GEP_ARG3:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[PTR_ARR3]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
- // CHECK: {{.+}} = call i32 @__tgt_target(i32 -1, {{.+}}, i32 1, i8** [[BASE_PTR_GEP_ARG3]], i8** [[PTR_GEP_ARG3]], i[[SZ]]* getelementptr inbounds ([1 x i[[SZ]]], [1 x i[[SZ]]]* [[SIZET3]], i32 0, i32 0), i32* getelementptr inbounds ([1 x i32], [1 x i32]* [[MAPT3]], i32 0, i32 0))
+ // CHECK: {{.+}} = call i32 @__tgt_target(i64 -1, {{.+}}, i32 1, i8** [[BASE_PTR_GEP_ARG3]], i8** [[PTR_GEP_ARG3]], i[[SZ]]* getelementptr inbounds ([1 x i[[SZ]]], [1 x i[[SZ]]]* [[SIZET3]], i32 0, i32 0), i64* getelementptr inbounds ([1 x i64], [1 x i64]* [[MAPT3]], i32 0, i32 0))
// TCHECK: define void @__omp_offloading_{{.+}}(double* [[PTR_IN:%.+]])
// TCHECK: [[PTR_ADDR:%.+]] = alloca double*,
@@ -447,7 +446,7 @@ struct S1 {
// CHECK: store i{{[0-9]+}} [[B_SIZE:%.+]], i{{[0-9]+}}* [[SIZES_GEP4_4]],
// only check that we use the map types stored in the global variable
- // CHECK: call i32 @__tgt_target(i32 -1, {{.+}}, i32 5, i8** {{.+}}, i8** {{.+}}, i{{[0-9]+}}* {{.+}}, i32* getelementptr inbounds ([5 x i32], [5 x i32]* [[MAPT4]], i32 0, i32 0))
+ // CHECK: call i32 @__tgt_target(i64 -1, {{.+}}, i32 5, i8** {{.+}}, i8** {{.+}}, i{{[0-9]+}}* {{.+}}, i64* getelementptr inbounds ([5 x i64], [5 x i64]* [[MAPT4]], i32 0, i32 0))
// TCHECK: define void @__omp_offloading_{{.+}}([[S1]]* [[TH:%.+]], i{{[0-9]+}} [[B_IN:%.+]], i{{[0-9]+}} [[VLA:%.+]], i{{[0-9]+}} [[VLA1:%.+]], i{{[0-9]+}}{{.+}} [[C_IN:%.+]])
// TCHECK: [[TH_ADDR:%.+]] = alloca [[S1]]*,
@@ -520,7 +519,7 @@ struct S1 {
// CHECK: store [10 x i{{[0-9]+}}]* [[B]], [10 x i{{[0-9]+}}]** [[BCAST_TOPTR]],
// only check that the right sizes and map types are used
- // CHECK: call i32 @__tgt_target(i32 -1, {{.+}}, i32 3, i8** {{.+}}, i8** {{.+}}, i[[SZ]]* getelementptr inbounds ([3 x i[[SZ]]], [3 x i[[SZ]]]* [[SIZET5]], i32 0, i32 0), i32* getelementptr inbounds ([3 x i32], [3 x i32]* [[MAPT5]], i32 0, i32 0))
+ // CHECK: call i32 @__tgt_target(i64 -1, {{.+}}, i32 3, i8** {{.+}}, i8** {{.+}}, i[[SZ]]* getelementptr inbounds ([3 x i[[SZ]]], [3 x i[[SZ]]]* [[SIZET5]], i32 0, i32 0), i64* getelementptr inbounds ([3 x i64], [3 x i64]* [[MAPT5]], i32 0, i32 0))
};
@@ -558,7 +557,7 @@ int bar(int n, double *ptr){
// CHECK: [[BCAST_TOPTR:%.+]] = bitcast i8** [[PTRS_GEP6_1]] to [10 x i{{[0-9]+}}]**
// CHECK: store [10 x i{{[0-9]+}}]* [[B]], [10 x i{{[0-9]+}}]** [[BCAST_TOPTR]],
-// CHECK: call i32 @__tgt_target(i32 -1, {{.+}}, i32 2, i8** {{.+}}, i8** {{.+}}, i[[SZ]]* getelementptr inbounds ([2 x i[[SZ]]], [2 x i[[SZ]]]* [[SIZET6]], i32 0, i32 0), i32* getelementptr inbounds ([2 x i32], [2 x i32]* [[MAPT6]], i32 0, i32 0))
+// CHECK: call i32 @__tgt_target(i64 -1, {{.+}}, i32 2, i8** {{.+}}, i8** {{.+}}, i[[SZ]]* getelementptr inbounds ([2 x i[[SZ]]], [2 x i[[SZ]]]* [[SIZET6]], i32 0, i32 0), i64* getelementptr inbounds ([2 x i64], [2 x i64]* [[MAPT6]], i32 0, i32 0))
// TCHECK: define void @__omp_offloading_{{.+}}(i{{[0-9]+}} [[A_IN:%.+]], [10 x i{{[0-9]+}}]*{{.+}} [[B_IN:%.+]])
diff --git a/test/OpenMP/target_is_device_ptr_codegen.cpp b/test/OpenMP/target_is_device_ptr_codegen.cpp
index 1a54aa18c00b..1491f41a787f 100644
--- a/test/OpenMP/target_is_device_ptr_codegen.cpp
+++ b/test/OpenMP/target_is_device_ptr_codegen.cpp
@@ -15,25 +15,25 @@ double *g;
// CK1: @g = global double*
// CK1: [[SIZES00:@.+]] = {{.+}}constant [1 x i[[sz:64|32]]] [i{{64|32}} {{8|4}}]
-// CK1: [[TYPES00:@.+]] = {{.+}}constant [1 x i32] [i32 288]
+// CK1: [[TYPES00:@.+]] = {{.+}}constant [1 x i64] [i64 288]
// CK1: [[SIZES01:@.+]] = {{.+}}constant [1 x i[[sz]]] [i[[sz]] {{8|4}}]
-// CK1: [[TYPES01:@.+]] = {{.+}}constant [1 x i32] [i32 288]
+// CK1: [[TYPES01:@.+]] = {{.+}}constant [1 x i64] [i64 288]
// CK1: [[SIZES02:@.+]] = {{.+}}constant [1 x i[[sz]]] [i[[sz]] {{8|4}}]
-// CK1: [[TYPES02:@.+]] = {{.+}}constant [1 x i32] [i32 288]
+// CK1: [[TYPES02:@.+]] = {{.+}}constant [1 x i64] [i64 288]
// CK1: [[SIZES03:@.+]] = {{.+}}constant [1 x i[[sz]]] [i[[sz]] {{8|4}}]
-// CK1: [[TYPES03:@.+]] = {{.+}}constant [1 x i32] [i32 288]
+// CK1: [[TYPES03:@.+]] = {{.+}}constant [1 x i64] [i64 288]
// CK1: [[SIZES04:@.+]] = {{.+}}constant [1 x i[[sz]]] [i[[sz]] {{8|4}}]
-// CK1: [[TYPES04:@.+]] = {{.+}}constant [1 x i32] [i32 288]
+// CK1: [[TYPES04:@.+]] = {{.+}}constant [1 x i64] [i64 288]
// CK1: [[SIZES05:@.+]] = {{.+}}constant [1 x i[[sz]]] [i[[sz]] {{8|4}}]
-// CK1: [[TYPES05:@.+]] = {{.+}}constant [1 x i32] [i32 288]
+// CK1: [[TYPES05:@.+]] = {{.+}}constant [1 x i64] [i64 288]
// CK1: [[SIZES06:@.+]] = {{.+}}constant [2 x i[[sz]]] [i[[sz]] {{8|4}}, i[[sz]] {{8|4}}]
-// CK1: [[TYPES06:@.+]] = {{.+}}constant [2 x i32] [i32 288, i32 288]
+// CK1: [[TYPES06:@.+]] = {{.+}}constant [2 x i64] [i64 288, i64 288]
// CK1-LABEL: @_Z3foo
template<typename T>
@@ -41,7 +41,7 @@ void foo(float *&lr, T *&tr) {
float *l;
T *t;
- // CK1-DAG: call i32 @__tgt_target(i32 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES00]]{{.+}}, {{.+}}[[TYPES00]]{{.+}})
+ // CK1-DAG: call i32 @__tgt_target(i64 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES00]]{{.+}}, {{.+}}[[TYPES00]]{{.+}})
// CK1-DAG: [[BPGEP]] = getelementptr inbounds {{.+}}[[BPS:%[^,]+]], i32 0, i32 0
// CK1-DAG: [[PGEP]] = getelementptr inbounds {{.+}}[[PS:%[^,]+]], i32 0, i32 0
// CK1-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BPS]], i32 0, i32 0
@@ -58,7 +58,7 @@ void foo(float *&lr, T *&tr) {
++g;
}
- // CK1-DAG: call i32 @__tgt_target(i32 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES01]]{{.+}}, {{.+}}[[TYPES01]]{{.+}})
+ // CK1-DAG: call i32 @__tgt_target(i64 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES01]]{{.+}}, {{.+}}[[TYPES01]]{{.+}})
// CK1-DAG: [[BPGEP]] = getelementptr inbounds {{.+}}[[BPS:%[^,]+]], i32 0, i32 0
// CK1-DAG: [[PGEP]] = getelementptr inbounds {{.+}}[[PS:%[^,]+]], i32 0, i32 0
// CK1-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BPS]], i32 0, i32 0
@@ -75,7 +75,7 @@ void foo(float *&lr, T *&tr) {
++l;
}
- // CK1-DAG: call i32 @__tgt_target(i32 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES02]]{{.+}}, {{.+}}[[TYPES02]]{{.+}})
+ // CK1-DAG: call i32 @__tgt_target(i64 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES02]]{{.+}}, {{.+}}[[TYPES02]]{{.+}})
// CK1-DAG: [[BPGEP]] = getelementptr inbounds {{.+}}[[BPS:%[^,]+]], i32 0, i32 0
// CK1-DAG: [[PGEP]] = getelementptr inbounds {{.+}}[[PS:%[^,]+]], i32 0, i32 0
// CK1-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BPS]], i32 0, i32 0
@@ -92,7 +92,7 @@ void foo(float *&lr, T *&tr) {
++t;
}
- // CK1-DAG: call i32 @__tgt_target(i32 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES03]]{{.+}}, {{.+}}[[TYPES03]]{{.+}})
+ // CK1-DAG: call i32 @__tgt_target(i64 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES03]]{{.+}}, {{.+}}[[TYPES03]]{{.+}})
// CK1-DAG: [[BPGEP]] = getelementptr inbounds {{.+}}[[BPS:%[^,]+]], i32 0, i32 0
// CK1-DAG: [[PGEP]] = getelementptr inbounds {{.+}}[[PS:%[^,]+]], i32 0, i32 0
// CK1-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BPS]], i32 0, i32 0
@@ -110,7 +110,7 @@ void foo(float *&lr, T *&tr) {
++lr;
}
- // CK1-DAG: call i32 @__tgt_target(i32 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES04]]{{.+}}, {{.+}}[[TYPES04]]{{.+}})
+ // CK1-DAG: call i32 @__tgt_target(i64 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES04]]{{.+}}, {{.+}}[[TYPES04]]{{.+}})
// CK1-DAG: [[BPGEP]] = getelementptr inbounds {{.+}}[[BPS:%[^,]+]], i32 0, i32 0
// CK1-DAG: [[PGEP]] = getelementptr inbounds {{.+}}[[PS:%[^,]+]], i32 0, i32 0
// CK1-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BPS]], i32 0, i32 0
@@ -128,7 +128,7 @@ void foo(float *&lr, T *&tr) {
++tr;
}
- // CK1-DAG: call i32 @__tgt_target(i32 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES05]]{{.+}}, {{.+}}[[TYPES05]]{{.+}})
+ // CK1-DAG: call i32 @__tgt_target(i64 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES05]]{{.+}}, {{.+}}[[TYPES05]]{{.+}})
// CK1-DAG: [[BPGEP]] = getelementptr inbounds {{.+}}[[BPS:%[^,]+]], i32 0, i32 0
// CK1-DAG: [[PGEP]] = getelementptr inbounds {{.+}}[[PS:%[^,]+]], i32 0, i32 0
// CK1-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BPS]], i32 0, i32 0
@@ -146,7 +146,7 @@ void foo(float *&lr, T *&tr) {
++tr;
}
- // CK1-DAG: call i32 @__tgt_target(i32 {{.+}}, i8* {{.+}}, i32 2, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES06]]{{.+}}, {{.+}}[[TYPES06]]{{.+}})
+ // CK1-DAG: call i32 @__tgt_target(i64 {{.+}}, i8* {{.+}}, i32 2, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES06]]{{.+}}, {{.+}}[[TYPES06]]{{.+}})
// CK1-DAG: [[BPGEP]] = getelementptr inbounds {{.+}}[[BPS:%[^,]+]], i32 0, i32 0
// CK1-DAG: [[PGEP]] = getelementptr inbounds {{.+}}[[PS:%[^,]+]], i32 0, i32 0
// CK1-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BPS]], i32 0, i32 0
@@ -191,13 +191,13 @@ void bar(float *&a, int *&b) {
// CK2: [[ST:%.+]] = type { double*, double** }
// CK2: [[SIZE00:@.+]] = {{.+}}constant [1 x i[[sz:64|32]]] [i{{64|32}} {{8|4}}]
-// CK2: [[MTYPE00:@.+]] = {{.+}}constant [1 x i32] [i32 33]
+// CK2: [[MTYPE00:@.+]] = {{.+}}constant [1 x i64] [i64 33]
// CK2: [[SIZE01:@.+]] = {{.+}}constant [2 x i[[sz]]] [i[[sz]] {{8|4}}, i[[sz]] {{8|4}}]
-// CK2: [[MTYPE01:@.+]] = {{.+}}constant [2 x i32] [i32 32, i32 17]
+// CK2: [[MTYPE01:@.+]] = {{.+}}constant [2 x i64] [i64 32, i64 17]
// CK2: [[SIZE02:@.+]] = {{.+}}constant [3 x i[[sz]]] [i[[sz]] {{8|4}}, i[[sz]] {{8|4}}, i[[sz]] {{8|4}}]
-// CK2: [[MTYPE02:@.+]] = {{.+}}constant [3 x i32] [i32 33, i32 0, i32 17]
+// CK2: [[MTYPE02:@.+]] = {{.+}}constant [3 x i64] [i64 33, i64 0, i64 17]
template <typename T>
struct ST {
@@ -209,7 +209,7 @@ struct ST {
void foo(double *&arg) {
int *la = 0;
- // CK2-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE00]]{{.+}})
+ // CK2-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE00]]{{.+}})
// CK2-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK2-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -225,7 +225,7 @@ struct ST {
a++;
}
- // CK2-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE01]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE01]]{{.+}})
+ // CK2-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE01]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE01]]{{.+}})
// CK2-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK2-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -249,7 +249,7 @@ struct ST {
b++;
}
- // CK2-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 3, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[3 x i{{.+}}]* [[SIZE02]], {{.+}}getelementptr {{.+}}[3 x i{{.+}}]* [[MTYPE02]]{{.+}})
+ // CK2-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 3, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[3 x i{{.+}}]* [[SIZE02]], {{.+}}getelementptr {{.+}}[3 x i{{.+}}]* [[MTYPE02]]{{.+}})
// CK2-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK2-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
diff --git a/test/OpenMP/target_map_codegen.cpp b/test/OpenMP/target_map_codegen.cpp
index 69e80bb9505b..34b239504462 100644
--- a/test/OpenMP/target_map_codegen.cpp
+++ b/test/OpenMP/target_map_codegen.cpp
@@ -15,15 +15,33 @@
// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32
#ifdef CK1
+class B {
+public:
+ static double VAR;
+ B() {
+ }
+
+ static void modify(int &res) {
+#pragma omp target map(tofrom \
+ : res)
+ {
+ res = B::VAR;
+ }
+ }
+};
+double B::VAR = 1.0;
+
// CK1-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i[[sz:64|32]]] [i{{64|32}} 4]
// Map types: OMP_MAP_PRIVATE_VAL | OMP_MAP_IS_FIRST = 288
-// CK1-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 288]
+// CK1-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i64] [i64 288]
// CK1-LABEL: implicit_maps_integer
void implicit_maps_integer (int a){
+ // CK1: call void{{.*}}modify
+ B::modify(a);
int i = a;
- // CK1-DAG: call i32 @__tgt_target(i32 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES]]{{.+}}, {{.+}}[[TYPES]]{{.+}})
+ // CK1-DAG: call i32 @__tgt_target(i64 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES]]{{.+}}, {{.+}}[[TYPES]]{{.+}})
// CK1-DAG: [[BPGEP]] = getelementptr inbounds {{.+}}[[BPS:%[^,]+]], i32 0, i32 0
// CK1-DAG: [[PGEP]] = getelementptr inbounds {{.+}}[[PS:%[^,]+]], i32 0, i32 0
// CK1-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BPS]], i32 0, i32 0
@@ -62,15 +80,15 @@ void implicit_maps_integer (int a){
// CK2: [[SIZES:@.+]] = {{.+}}constant [1 x i[[sz:64|32]]] [i{{64|32}} 4]
// Map types: OMP_MAP_PRIVATE_VAL | OMP_MAP_IS_FIRST = 288
-// CK2: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 288]
+// CK2: [[TYPES:@.+]] = {{.+}}constant [1 x i64] [i64 288]
// CK2: [[SIZES2:@.+]] = {{.+}}constant [1 x i[[sz]]] zeroinitializer
// Map types: OMP_MAP_IS_PTR = 32
-// CK2: [[TYPES2:@.+]] = {{.+}}constant [1 x i32] [i32 32]
+// CK2: [[TYPES2:@.+]] = {{.+}}constant [1 x i64] [i64 32]
// CK2-LABEL: implicit_maps_reference
void implicit_maps_reference (int a, int *b){
int &i = a;
- // CK2-DAG: call i32 @__tgt_target(i32 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES]]{{.+}}, {{.+}}[[TYPES]]{{.+}})
+ // CK2-DAG: call i32 @__tgt_target(i64 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES]]{{.+}}, {{.+}}[[TYPES]]{{.+}})
// CK2-DAG: [[BPGEP]] = getelementptr inbounds {{.+}}[[BPS:%[^,]+]], i32 0, i32 0
// CK2-DAG: [[PGEP]] = getelementptr inbounds {{.+}}[[PS:%[^,]+]], i32 0, i32 0
// CK2-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BPS]], i32 0, i32 0
@@ -90,7 +108,7 @@ void implicit_maps_reference (int a, int *b){
}
int *&p = b;
- // CK2-DAG: call i32 @__tgt_target(i32 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES2]]{{.+}}, {{.+}}[[TYPES2]]{{.+}})
+ // CK2-DAG: call i32 @__tgt_target(i64 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES2]]{{.+}}, {{.+}}[[TYPES2]]{{.+}})
// CK2-DAG: [[BPGEP]] = getelementptr inbounds {{.+}}[[BPS:%[^,]+]], i32 0, i32 0
// CK2-DAG: [[PGEP]] = getelementptr inbounds {{.+}}[[PS:%[^,]+]], i32 0, i32 0
// CK2-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BPS]], i32 0, i32 0
@@ -141,12 +159,12 @@ void implicit_maps_reference (int a, int *b){
// CK3-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i[[sz:64|32]]] [i{{64|32}} 4]
// Map types: OMP_MAP_PRIVATE_VAL | OMP_MAP_IS_FIRST = 288
-// CK3-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 288]
+// CK3-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i64] [i64 288]
// CK3-LABEL: implicit_maps_parameter
void implicit_maps_parameter (int a){
- // CK3-DAG: call i32 @__tgt_target(i32 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES]]{{.+}}, {{.+}}[[TYPES]]{{.+}})
+ // CK3-DAG: call i32 @__tgt_target(i64 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES]]{{.+}}, {{.+}}[[TYPES]]{{.+}})
// CK3-DAG: [[BPGEP]] = getelementptr inbounds {{.+}}[[BPS:%[^,]+]], i32 0, i32 0
// CK3-DAG: [[PGEP]] = getelementptr inbounds {{.+}}[[PS:%[^,]+]], i32 0, i32 0
// CK3-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BPS]], i32 0, i32 0
@@ -185,7 +203,7 @@ void implicit_maps_parameter (int a){
// CK4-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i[[sz:64|32]]] [i{{64|32}} 4]
// Map types: OMP_MAP_PRIVATE_VAL | OMP_MAP_IS_FIRST = 288
-// CK4-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 288]
+// CK4-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i64] [i64 288]
// CK4-LABEL: implicit_maps_nested_integer
void implicit_maps_nested_integer (int a){
@@ -198,7 +216,7 @@ void implicit_maps_nested_integer (int a){
// CK4: define internal void [[KERNELP1]](i32* {{[^,]+}}, i32* {{[^,]+}}, i32* {{[^,]+}})
#pragma omp parallel
{
- // CK4-DAG: call i32 @__tgt_target(i32 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES]]{{.+}}, {{.+}}[[TYPES]]{{.+}})
+ // CK4-DAG: call i32 @__tgt_target(i64 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES]]{{.+}}, {{.+}}[[TYPES]]{{.+}})
// CK4-DAG: [[BPGEP]] = getelementptr inbounds {{.+}}[[BPS:%[^,]+]], i32 0, i32 0
// CK4-DAG: [[PGEP]] = getelementptr inbounds {{.+}}[[PS:%[^,]+]], i32 0, i32 0
// CK4-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BPS]], i32 0, i32 0
@@ -241,7 +259,7 @@ void implicit_maps_nested_integer (int a){
// CK5-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i[[sz:64|32]]] [i{{64|32}} 4]
// Map types: OMP_MAP_PRIVATE_VAL | OMP_MAP_IS_FIRST = 288
-// CK5-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 288]
+// CK5-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i64] [i64 288]
// CK5-LABEL: implicit_maps_nested_integer_and_enum
void implicit_maps_nested_integer_and_enum (int a){
@@ -252,7 +270,7 @@ void implicit_maps_nested_integer_and_enum (int a){
// Using an enum should not change the mapping information.
int i = a;
- // CK5-DAG: call i32 @__tgt_target(i32 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES]]{{.+}}, {{.+}}[[TYPES]]{{.+}})
+ // CK5-DAG: call i32 @__tgt_target(i64 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES]]{{.+}}, {{.+}}[[TYPES]]{{.+}})
// CK5-DAG: [[BPGEP]] = getelementptr inbounds {{.+}}[[BPS:%[^,]+]], i32 0, i32 0
// CK5-DAG: [[PGEP]] = getelementptr inbounds {{.+}}[[PS:%[^,]+]], i32 0, i32 0
// CK5-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BPS]], i32 0, i32 0
@@ -292,12 +310,12 @@ void implicit_maps_nested_integer_and_enum (int a){
// CK6-DAG: [[GBL:@Gi]] = global i32 0
// CK6-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i[[sz:64|32]]] [i{{64|32}} 4]
// Map types: OMP_MAP_PRIVATE_VAL | OMP_MAP_IS_FIRST = 288
-// CK6-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 288]
+// CK6-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i64] [i64 288]
// CK6-LABEL: implicit_maps_host_global
int Gi;
void implicit_maps_host_global (int a){
- // CK6-DAG: call i32 @__tgt_target(i32 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES]]{{.+}}, {{.+}}[[TYPES]]{{.+}})
+ // CK6-DAG: call i32 @__tgt_target(i64 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES]]{{.+}}, {{.+}}[[TYPES]]{{.+}})
// CK6-DAG: [[BPGEP]] = getelementptr inbounds {{.+}}[[BPS:%[^,]+]], i32 0, i32 0
// CK6-DAG: [[PGEP]] = getelementptr inbounds {{.+}}[[PS:%[^,]+]], i32 0, i32 0
// CK6-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BPS]], i32 0, i32 0
@@ -341,15 +359,15 @@ void implicit_maps_host_global (int a){
// CK7-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i[[sz:64|32]]] [i{{64|32}} 8]
// Map types: OMP_MAP_PRIVATE_VAL | OMP_MAP_IS_FIRST = 288
-// CK7-64-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 288]
-// Map types: OMP_MAP_TO | OMP_MAP_IS_FIRST = 33
-// CK7-32-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 33]
+// CK7-64-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i64] [i64 288]
+// Map types: OMP_MAP_TO | OMP_MAP_PRIVATE_PTR | OMP_MAP_FIRST_REF = 161
+// CK7-32-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i64] [i64 161]
// CK7-LABEL: implicit_maps_double
void implicit_maps_double (int a){
double d = (double)a;
- // CK7-DAG: call i32 @__tgt_target(i32 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES]]{{.+}}, {{.+}}[[TYPES]]{{.+}})
+ // CK7-DAG: call i32 @__tgt_target(i64 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES]]{{.+}}, {{.+}}[[TYPES]]{{.+}})
// CK7-DAG: [[BPGEP]] = getelementptr inbounds {{.+}}[[BPS:%[^,]+]], i32 0, i32 0
// CK7-DAG: [[PGEP]] = getelementptr inbounds {{.+}}[[PS:%[^,]+]], i32 0, i32 0
// CK7-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BPS]], i32 0, i32 0
@@ -400,13 +418,13 @@ void implicit_maps_double (int a){
// CK8-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i[[sz:64|32]]] [i{{64|32}} 4]
// Map types: OMP_MAP_PRIVATE_VAL | OMP_MAP_IS_FIRST = 288
-// CK8-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 288]
+// CK8-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i64] [i64 288]
// CK8-LABEL: implicit_maps_float
void implicit_maps_float (int a){
float f = (float)a;
- // CK8-DAG: call i32 @__tgt_target(i32 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES]]{{.+}}, {{.+}}[[TYPES]]{{.+}})
+ // CK8-DAG: call i32 @__tgt_target(i64 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES]]{{.+}}, {{.+}}[[TYPES]]{{.+}})
// CK8-DAG: [[BPGEP]] = getelementptr inbounds {{.+}}[[BPS:%[^,]+]], i32 0, i32 0
// CK8-DAG: [[PGEP]] = getelementptr inbounds {{.+}}[[PS:%[^,]+]], i32 0, i32 0
// CK8-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BPS]], i32 0, i32 0
@@ -443,14 +461,14 @@ void implicit_maps_float (int a){
#ifdef CK9
// CK9-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i[[sz:64|32]]] [i{{64|32}} 16]
-// Map types: OMP_MAP_TO + OMP_MAP_FROM + OMP_MAP_IS_FIRST = 35
-// CK9-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 35]
+// Map types: OMP_MAP_TO + OMP_MAP_FROM + OMP_MAP_IS_FIRST + OMP_MAP_IMPLICIT = 547
+// CK9-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i64] [i64 547]
// CK9-LABEL: implicit_maps_array
void implicit_maps_array (int a){
double darr[2] = {(double)a, (double)a};
- // CK9-DAG: call i32 @__tgt_target(i32 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES]]{{.+}}, {{.+}}[[TYPES]]{{.+}})
+ // CK9-DAG: call i32 @__tgt_target(i64 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES]]{{.+}}, {{.+}}[[TYPES]]{{.+}})
// CK9-DAG: [[BPGEP]] = getelementptr inbounds {{.+}}[[BPS:%[^,]+]], i32 0, i32 0
// CK9-DAG: [[PGEP]] = getelementptr inbounds {{.+}}[[PS:%[^,]+]], i32 0, i32 0
// CK9-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BPS]], i32 0, i32 0
@@ -485,13 +503,13 @@ void implicit_maps_array (int a){
// CK10-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i[[sz:64|32]]] zeroinitializer
// Map types: OMP_MAP_IS_FIRST = 32
-// CK10-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 32]
+// CK10-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i64] [i64 32]
// CK10-LABEL: implicit_maps_pointer
void implicit_maps_pointer (){
double *ddyn;
- // CK10-DAG: call i32 @__tgt_target(i32 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES]]{{.+}}, {{.+}}[[TYPES]]{{.+}})
+ // CK10-DAG: call i32 @__tgt_target(i64 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES]]{{.+}}, {{.+}}[[TYPES]]{{.+}})
// CK10-DAG: [[BPGEP]] = getelementptr inbounds {{.+}}[[BPS:%[^,]+]], i32 0, i32 0
// CK10-DAG: [[PGEP]] = getelementptr inbounds {{.+}}[[PS:%[^,]+]], i32 0, i32 0
// CK10-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BPS]], i32 0, i32 0
@@ -526,14 +544,14 @@ void implicit_maps_pointer (){
#ifdef CK11
// CK11-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i[[sz:64|32]]] [i{{64|32}} 16]
-// Map types: OMP_MAP_TO + OMP_MAP_IS_FIRST = 33
-// CK11-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 33]
+// Map types: OMP_MAP_TO + OMP_MAP_FROM + OMP_MAP_IS_FIRST + OMP_MAP_IMPLICIT = 547
+// CK11-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i64] [i64 547]
// CK11-LABEL: implicit_maps_double_complex
void implicit_maps_double_complex (int a){
double _Complex dc = (double)a;
- // CK11-DAG: call i32 @__tgt_target(i32 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES]]{{.+}}, {{.+}}[[TYPES]]{{.+}})
+ // CK11-DAG: call i32 @__tgt_target(i64 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES]]{{.+}}, {{.+}}[[TYPES]]{{.+}})
// CK11-DAG: [[BPGEP]] = getelementptr inbounds {{.+}}[[BPS:%[^,]+]], i32 0, i32 0
// CK11-DAG: [[PGEP]] = getelementptr inbounds {{.+}}[[PS:%[^,]+]], i32 0, i32 0
// CK11-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BPS]], i32 0, i32 0
@@ -544,7 +562,7 @@ void implicit_maps_double_complex (int a){
// CK11-DAG: store { double, double }* [[PTR]], { double, double }** [[CP1]]
// CK11: call void [[KERNEL:@.+]]({ double, double }* [[PTR]])
- #pragma omp target
+ #pragma omp target defaultmap(tofrom:scalar)
{
dc *= dc;
}
@@ -570,15 +588,15 @@ void implicit_maps_double_complex (int a){
// CK12-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i[[sz:64|32]]] [i{{64|32}} 8]
// Map types: OMP_MAP_PRIVATE_VAL + OMP_MAP_IS_FIRST = 288
-// CK12-64-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 288]
-// Map types: OMP_MAP_TO + OMP_MAP_IS_FIRST = 33
-// CK12-32-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 33]
+// CK12-64-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i64] [i64 288]
+// Map types: OMP_MAP_TO | OMP_MAP_PRIVATE_PTR | OMP_MAP_FIRST_REF = 161
+// CK12-32-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i64] [i64 161]
// CK12-LABEL: implicit_maps_float_complex
void implicit_maps_float_complex (int a){
float _Complex fc = (float)a;
- // CK12-DAG: call i32 @__tgt_target(i32 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES]]{{.+}}, {{.+}}[[TYPES]]{{.+}})
+ // CK12-DAG: call i32 @__tgt_target(i64 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES]]{{.+}}, {{.+}}[[TYPES]]{{.+}})
// CK12-DAG: [[BPGEP]] = getelementptr inbounds {{.+}}[[BPS:%[^,]+]], i32 0, i32 0
// CK12-DAG: [[PGEP]] = getelementptr inbounds {{.+}}[[PS:%[^,]+]], i32 0, i32 0
// CK12-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BPS]], i32 0, i32 0
@@ -630,14 +648,14 @@ void implicit_maps_float_complex (int a){
// Map types:
// - OMP_MAP_PRIVATE_VAL + OMP_MAP_IS_FIRST = 288 (vla size)
// - OMP_MAP_PRIVATE_VAL + OMP_MAP_IS_FIRST = 288 (vla size)
-// - OMP_MAP_TO + OMP_MAP_FROM + OMP_MAP_IS_FIRST = 35
-// CK13-DAG: [[TYPES:@.+]] = {{.+}}constant [3 x i32] [i32 288, i32 288, i32 35]
+// - OMP_MAP_TO + OMP_MAP_FROM + OMP_MAP_IS_FIRST + OMP_IMPICIT_MAP = 547
+// CK13-DAG: [[TYPES:@.+]] = {{.+}}constant [3 x i64] [i64 288, i64 288, i64 547]
// CK13-LABEL: implicit_maps_variable_length_array
void implicit_maps_variable_length_array (int a){
double vla[2][a];
- // CK13-DAG: call i32 @__tgt_target(i32 {{.+}}, i8* {{.+}}, i32 3, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], i[[sz:64|32]]* [[SGEP:%[^,]+]], {{.+}}[[TYPES]]{{.+}})
+ // CK13-DAG: call i32 @__tgt_target(i64 {{.+}}, i8* {{.+}}, i32 3, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], i[[sz:64|32]]* [[SGEP:%[^,]+]], {{.+}}[[TYPES]]{{.+}})
// CK13-DAG: [[BPGEP]] = getelementptr inbounds {{.+}}[[BPS:%[^,]+]], i32 0, i32 0
// CK13-DAG: [[PGEP]] = getelementptr inbounds {{.+}}[[PS:%[^,]+]], i32 0, i32 0
// CK13-DAG: [[SGEP]] = getelementptr inbounds {{.+}}[[SS:%[^,]+]], i32 0, i32 0
@@ -699,11 +717,12 @@ void implicit_maps_variable_length_array (int a){
#ifdef CK14
// CK14-DAG: [[ST:%.+]] = type { i32, double }
-// CK14-DAG: [[SIZES:@.+]] = {{.+}}constant [2 x i[[sz:64|32]]] [i{{64|32}} {{16|12}}, i{{64|32}} 4]
+// CK14-DAG: [[SIZES:@.+]] = {{.+}}constant [3 x i[[sz:64|32]]] [i{{64|32}} 4, i{{64|32}} 8, i{{64|32}} 4]
// Map types:
-// - OMP_MAP_TO + OMP_MAP_FROM + OMP_MAP_IS_FIRST = 35
+// - OMP_MAP_TO + OMP_MAP_FROM + OMP_MAP_IS_FIRST + OMP_IMPLICIT_MAP = 547
+// - OMP_MAP_TO + OMP_MAP_FROM + OMP_IMPLICIT_MAP = 515
// - OMP_MAP_PRIVATE_VAL + OMP_MAP_IS_FIRST = 288
-// CK14-DAG: [[TYPES:@.+]] = {{.+}}constant [2 x i32] [i32 35, i32 288]
+// CK14-DAG: [[TYPES:@.+]] = {{.+}}constant [3 x i64] [i64 547, i64 515, i64 288]
class SSS {
public:
@@ -726,19 +745,26 @@ void implicit_maps_class (int a){
SSS sss(a, (double)a);
// CK14: define {{.*}}void @{{.+}}foo{{.+}}([[ST]]* {{[^,]+}}, i32 {{[^,]+}})
- // CK14-DAG: call i32 @__tgt_target(i32 {{.+}}, i8* {{.+}}, i32 2, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES]]{{.+}}, {{.+}}[[TYPES]]{{.+}})
+ // CK14-DAG: call i32 @__tgt_target(i64 {{.+}}, i8* {{.+}}, i32 3, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES]]{{.+}}, {{.+}}[[TYPES]]{{.+}})
// CK14-DAG: [[BPGEP]] = getelementptr inbounds {{.+}}[[BPS:%[^,]+]], i32 0, i32 0
// CK14-DAG: [[PGEP]] = getelementptr inbounds {{.+}}[[PS:%[^,]+]], i32 0, i32 0
// CK14-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BPS]], i32 0, i32 0
// CK14-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[PS]], i32 0, i32 0
// CK14-DAG: [[CBP0:%.+]] = bitcast i8** [[BP0]] to [[ST]]**
- // CK14-DAG: [[CP0:%.+]] = bitcast i8** [[P0]] to [[ST]]**
+ // CK14-DAG: [[CP0:%.+]] = bitcast i8** [[P0]] to i32**
// CK14-DAG: store [[ST]]* [[DECL:%.+]], [[ST]]** [[CBP0]]
- // CK14-DAG: store [[ST]]* [[DECL]], [[ST]]** [[CP0]]
+ // CK14-DAG: store i32* %{{.+}}, i32** [[CP0]]
// CK14-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BPS]], i32 0, i32 1
// CK14-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[PS]], i32 0, i32 1
+ // CK14-DAG: [[CBP1:%.+]] = bitcast i8** [[BP1]] to [[ST]]**
+ // CK14-DAG: [[CP1:%.+]] = bitcast i8** [[P1]] to double**
+ // CK14-DAG: store [[ST]]* [[DECL]], [[ST]]** [[CBP1]]
+ // CK14-DAG: store double* %{{.+}}, double** [[CP1]]
+
+ // CK14-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BPS]], i32 0, i32 2
+ // CK14-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[PS]], i32 0, i32 2
// CK14-DAG: [[CBP1:%.+]] = bitcast i8** [[BP1]] to i[[sz]]*
// CK14-DAG: [[CP1:%.+]] = bitcast i8** [[P1]] to i[[sz]]*
// CK14-DAG: store i[[sz]] [[VAL:%.+]], i[[sz]]* [[CBP1]]
@@ -773,17 +799,17 @@ void implicit_maps_class (int a){
#ifdef CK15
// CK15: [[ST:%.+]] = type { i32, double, i32* }
-// CK15: [[SIZES:@.+]] = {{.+}}constant [2 x i[[sz:64|32]]] [i{{64|32}} {{24|16}}, i{{64|32}} 4]
+// CK15: [[SIZES:@.+]] = {{.+}}constant [5 x i[[sz:64|32]]] [i{{64|32}} 4, i{{64|32}} 8, i{{64|32}} {{8|4}}, i{{64|32}} 4, i{{64|32}} 4]
// Map types:
-// - OMP_MAP_TO + OMP_MAP_FROM + OMP_MAP_IS_FIRST = 35
+// - OMP_MAP_TO + OMP_MAP_FROM + OMP_MAP_IS_FIRST + OMP_MAP_IMPLICIT = 547
// - OMP_MAP_PRIVATE_VAL + OMP_MAP_IS_FIRST = 288
-// CK15: [[TYPES:@.+]] = {{.+}}constant [2 x i32] [i32 35, i32 288]
+// CK15: [[TYPES:@.+]] = {{.+}}constant [5 x i64] [i64 547, i64 515, i64 512, i64 531, i64 288]
-// CK15: [[SIZES2:@.+]] = {{.+}}constant [2 x i[[sz]]] [i{{64|32}} {{24|16}}, i{{64|32}} 4]
+// CK15: [[SIZES2:@.+]] = {{.+}}constant [5 x i[[sz]]] [i{{64|32}} 4, i{{64|32}} 8, i{{64|32}} {{8|4}}, i{{64|32}} 4, i{{64|32}} 4]
// Map types:
// - OMP_MAP_TO + OMP_MAP_FROM + OMP_MAP_IS_FIRST = 35
// - OMP_MAP_PRIVATE_VAL + OMP_MAP_IS_FIRST = 288
-// CK15: [[TYPES2:@.+]] = {{.+}}constant [2 x i32] [i32 35, i32 288]
+// CK15: [[TYPES2:@.+]] = {{.+}}constant [5 x i64] [i64 547, i64 515, i64 512, i64 531, i64 288]
template<int x>
class SSST {
@@ -818,23 +844,44 @@ void implicit_maps_templated_class (int a){
SSST<123> ssst(a, (double)a, a);
// CK15: define {{.*}}void @{{.+}}foo{{.+}}([[ST]]* {{[^,]+}}, i32 {{[^,]+}})
- // CK15-DAG: call i32 @__tgt_target(i32 {{.+}}, i8* {{.+}}, i32 2, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES]]{{.+}}, {{.+}}[[TYPES]]{{.+}})
+ // CK15-DAG: call i32 @__tgt_target(i64 {{.+}}, i8* {{.+}}, i32 5, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES]]{{.+}}, {{.+}}[[TYPES]]{{.+}})
// CK15-DAG: [[BPGEP]] = getelementptr inbounds {{.+}}[[BPS:%[^,]+]], i32 0, i32 0
// CK15-DAG: [[PGEP]] = getelementptr inbounds {{.+}}[[PS:%[^,]+]], i32 0, i32 0
// CK15-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BPS]], i32 0, i32 0
// CK15-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[PS]], i32 0, i32 0
// CK15-DAG: [[CBP0:%.+]] = bitcast i8** [[BP0]] to [[ST]]**
- // CK15-DAG: [[CP0:%.+]] = bitcast i8** [[P0]] to [[ST]]**
+ // CK15-DAG: [[CP0:%.+]] = bitcast i8** [[P0]] to i32**
// CK15-DAG: store [[ST]]* [[DECL:%.+]], [[ST]]** [[CBP0]]
- // CK15-DAG: store [[ST]]* [[DECL]], [[ST]]** [[CP0]]
+ // CK15-DAG: store i32* %{{.+}}, i32** [[CP0]]
// CK15-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BPS]], i32 0, i32 1
// CK15-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[PS]], i32 0, i32 1
- // CK15-DAG: [[CBP1:%.+]] = bitcast i8** [[BP1]] to i[[sz]]*
- // CK15-DAG: [[CP1:%.+]] = bitcast i8** [[P1]] to i[[sz]]*
- // CK15-DAG: store i[[sz]] [[VAL:%.+]], i[[sz]]* [[CBP1]]
- // CK15-DAG: store i[[sz]] [[VAL]], i[[sz]]* [[CP1]]
+ // CK15-DAG: [[CBP1:%.+]] = bitcast i8** [[BP1]] to [[ST]]**
+ // CK15-DAG: [[CP1:%.+]] = bitcast i8** [[P1]] to double**
+ // CK15-DAG: store [[ST]]* [[DECL]], [[ST]]** [[CBP1]]
+ // CK15-DAG: store double* %{{.+}}, double** [[CP1]]
+
+ // CK15-DAG: [[BP2:%.+]] = getelementptr inbounds {{.+}}[[BPS]], i32 0, i32 2
+ // CK15-DAG: [[P2:%.+]] = getelementptr inbounds {{.+}}[[PS]], i32 0, i32 2
+ // CK15-DAG: [[CBP2:%.+]] = bitcast i8** [[BP2]] to [[ST]]**
+ // CK15-DAG: [[CP2:%.+]] = bitcast i8** [[P2]] to i32***
+ // CK15-DAG: store [[ST]]* [[DECL]], [[ST]]** [[CBP2]]
+ // CK15-DAG: store i32** %{{.+}}, i32*** [[CP2]]
+
+ // CK15-DAG: [[BP3:%.+]] = getelementptr inbounds {{.+}}[[BPS]], i32 0, i32 3
+ // CK15-DAG: [[P3:%.+]] = getelementptr inbounds {{.+}}[[PS]], i32 0, i32 3
+ // CK15-DAG: [[CBP3:%.+]] = bitcast i8** [[BP3]] to i32***
+ // CK15-DAG: [[CP3:%.+]] = bitcast i8** [[P3]] to i32**
+ // CK15-DAG: store i32** %{{.+}}, i32*** [[CBP3]]
+ // CK15-DAG: store i32* %{{.+}}, i32** [[CP3]]
+
+ // CK15-DAG: [[BP4:%.+]] = getelementptr inbounds {{.+}}[[BPS]], i32 0, i32 4
+ // CK15-DAG: [[P4:%.+]] = getelementptr inbounds {{.+}}[[PS]], i32 0, i32 4
+ // CK15-DAG: [[CBP4:%.+]] = bitcast i8** [[BP4]] to i[[sz]]*
+ // CK15-DAG: [[CP4:%.+]] = bitcast i8** [[P4]] to i[[sz]]*
+ // CK15-DAG: store i[[sz]] [[VAL:%.+]], i[[sz]]* [[CBP4]]
+ // CK15-DAG: store i[[sz]] [[VAL]], i[[sz]]* [[CP4]]
// CK15-DAG: [[VAL]] = load i[[sz]], i[[sz]]* [[ADDR:%.+]],
// CK15-64-DAG: [[CADDR:%.+]] = bitcast i[[sz]]* [[ADDR]] to i32*
// CK15-64-DAG: store i32 {{.+}}, i32* [[CADDR]],
@@ -843,23 +890,44 @@ void implicit_maps_templated_class (int a){
ssst.foo(456);
// CK15: define {{.*}}void @{{.+}}bar{{.+}}([[ST]]* {{[^,]+}}, i32 {{[^,]+}})
- // CK15-DAG: call i32 @__tgt_target(i32 {{.+}}, i8* {{.+}}, i32 2, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES2]]{{.+}}, {{.+}}[[TYPES2]]{{.+}})
+ // CK15-DAG: call i32 @__tgt_target(i64 {{.+}}, i8* {{.+}}, i32 5, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES2]]{{.+}}, {{.+}}[[TYPES2]]{{.+}})
// CK15-DAG: [[BPGEP]] = getelementptr inbounds {{.+}}[[BPS:%[^,]+]], i32 0, i32 0
// CK15-DAG: [[PGEP]] = getelementptr inbounds {{.+}}[[PS:%[^,]+]], i32 0, i32 0
// CK15-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BPS]], i32 0, i32 0
// CK15-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[PS]], i32 0, i32 0
// CK15-DAG: [[CBP0:%.+]] = bitcast i8** [[BP0]] to [[ST]]**
- // CK15-DAG: [[CP0:%.+]] = bitcast i8** [[P0]] to [[ST]]**
- // CK15-DAG: store [[ST]]* [[DECL:%.+]], [[ST]]** [[CBP0]]
- // CK15-DAG: store [[ST]]* [[DECL]], [[ST]]** [[CP0]]
+ // CK15-DAG: [[CP0:%.+]] = bitcast i8** [[P0]] to i32**
+ // CK15-DAG: store [[ST]]* [[DECL]], [[ST]]** [[CBP0]]
+ // CK15-DAG: store i32* %{{.+}}, i32** [[CP0]]
// CK15-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BPS]], i32 0, i32 1
// CK15-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[PS]], i32 0, i32 1
- // CK15-DAG: [[CBP1:%.+]] = bitcast i8** [[BP1]] to i[[sz]]*
- // CK15-DAG: [[CP1:%.+]] = bitcast i8** [[P1]] to i[[sz]]*
- // CK15-DAG: store i[[sz]] [[VAL:%.+]], i[[sz]]* [[CBP1]]
- // CK15-DAG: store i[[sz]] [[VAL]], i[[sz]]* [[CP1]]
+ // CK15-DAG: [[CBP1:%.+]] = bitcast i8** [[BP1]] to [[ST]]**
+ // CK15-DAG: [[CP1:%.+]] = bitcast i8** [[P1]] to double**
+ // CK15-DAG: store [[ST]]* [[DECL]], [[ST]]** [[CBP1]]
+ // CK15-DAG: store double* %{{.+}}, double** [[CP1]]
+
+ // CK15-DAG: [[BP2:%.+]] = getelementptr inbounds {{.+}}[[BPS]], i32 0, i32 2
+ // CK15-DAG: [[P2:%.+]] = getelementptr inbounds {{.+}}[[PS]], i32 0, i32 2
+ // CK15-DAG: [[CBP2:%.+]] = bitcast i8** [[BP2]] to [[ST]]**
+ // CK15-DAG: [[CP2:%.+]] = bitcast i8** [[P2]] to i32***
+ // CK15-DAG: store [[ST]]* [[DECL]], [[ST]]** [[CBP2]]
+ // CK15-DAG: store i32** %{{.+}}, i32*** [[CP2]]
+
+ // CK15-DAG: [[BP3:%.+]] = getelementptr inbounds {{.+}}[[BPS]], i32 0, i32 3
+ // CK15-DAG: [[P3:%.+]] = getelementptr inbounds {{.+}}[[PS]], i32 0, i32 3
+ // CK15-DAG: [[CBP3:%.+]] = bitcast i8** [[BP3]] to i32***
+ // CK15-DAG: [[CP3:%.+]] = bitcast i8** [[P3]] to i32**
+ // CK15-DAG: store i32** %{{.+}}, i32*** [[CBP3]]
+ // CK15-DAG: store i32* %{{.+}}, i32** [[CP3]]
+
+ // CK15-DAG: [[BP4:%.+]] = getelementptr inbounds {{.+}}[[BPS]], i32 0, i32 4
+ // CK15-DAG: [[P4:%.+]] = getelementptr inbounds {{.+}}[[PS]], i32 0, i32 4
+ // CK15-DAG: [[CBP4:%.+]] = bitcast i8** [[BP4]] to i[[sz]]*
+ // CK15-DAG: [[CP4:%.+]] = bitcast i8** [[P4]] to i[[sz]]*
+ // CK15-DAG: store i[[sz]] [[VAL:%.+]], i[[sz]]* [[CBP4]]
+ // CK15-DAG: store i[[sz]] [[VAL]], i[[sz]]* [[CP4]]
// CK15-DAG: [[VAL]] = load i[[sz]], i[[sz]]* [[ADDR:%.+]],
// CK15-64-DAG: [[CADDR:%.+]] = bitcast i[[sz]]* [[ADDR]] to i32*
// CK15-64-DAG: store i32 {{.+}}, i32* [[CADDR]],
@@ -903,7 +971,7 @@ void implicit_maps_templated_class (int a){
// CK16-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i[[sz:64|32]]] [i{{64|32}} 4]
// Map types:
// - OMP_MAP_PRIVATE_VAL + OMP_MAP_IS_FIRST = 288
-// CK16-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 288]
+// CK16-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i64] [i64 288]
template<int y>
int foo(int d) {
@@ -919,7 +987,7 @@ void implicit_maps_templated_function (int a){
int i = a;
// CK16: define {{.*}}i32 @{{.+}}foo{{.+}}(i32 {{[^,]+}})
- // CK16-DAG: call i32 @__tgt_target(i32 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES]]{{.+}}, {{.+}}[[TYPES]]{{.+}})
+ // CK16-DAG: call i32 @__tgt_target(i64 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES]]{{.+}}, {{.+}}[[TYPES]]{{.+}})
// CK16-DAG: [[BPGEP]] = getelementptr inbounds {{.+}}[[BPS:%[^,]+]], i32 0, i32 0
// CK16-DAG: [[PGEP]] = getelementptr inbounds {{.+}}[[PS:%[^,]+]], i32 0, i32 0
@@ -955,8 +1023,8 @@ void implicit_maps_templated_function (int a){
// CK17-DAG: [[ST:%.+]] = type { i32, double }
// CK17-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i[[sz:64|32]]] [i{{64|32}} {{16|12}}]
-// Map types: OMP_MAP_TO + OMP_MAP_FROM + OMP_MAP_IS_FIRST = 35
-// CK17-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 35]
+// Map types: OMP_MAP_TO + OMP_MAP_FROM + OMP_MAP_IS_FIRST + OMP_MAP_IMPLICIT = 547
+// CK17-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i64] [i64 547]
class SSS {
public:
@@ -968,7 +1036,7 @@ public:
void implicit_maps_struct (int a){
SSS s = {a, (double)a};
- // CK17-DAG: call i32 @__tgt_target(i32 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES]]{{.+}}, {{.+}}[[TYPES]]{{.+}})
+ // CK17-DAG: call i32 @__tgt_target(i64 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES]]{{.+}}, {{.+}}[[TYPES]]{{.+}})
// CK17-DAG: [[BPGEP]] = getelementptr inbounds {{.+}}[[BPS:%[^,]+]], i32 0, i32 0
// CK17-DAG: [[PGEP]] = getelementptr inbounds {{.+}}[[PS:%[^,]+]], i32 0, i32 0
// CK17-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BPS]], i32 0, i32 0
@@ -1004,7 +1072,7 @@ void implicit_maps_struct (int a){
// CK18-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i[[sz:64|32]]] [i{{64|32}} 4]
// Map types:
// - OMP_MAP_PRIVATE_VAL + OMP_MAP_IS_FIRST = 288
-// CK18-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 288]
+// CK18-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i64] [i64 288]
template<typename T>
int foo(T d) {
@@ -1019,7 +1087,7 @@ void implicit_maps_template_type_capture (int a){
int i = a;
// CK18: define {{.*}}i32 @{{.+}}foo{{.+}}(i32 {{[^,]+}})
- // CK18-DAG: call i32 @__tgt_target(i32 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES]]{{.+}}, {{.+}}[[TYPES]]{{.+}})
+ // CK18-DAG: call i32 @__tgt_target(i64 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES]]{{.+}}, {{.+}}[[TYPES]]{{.+}})
// CK18-DAG: [[BPGEP]] = getelementptr inbounds {{.+}}[[BPS:%[^,]+]], i32 0, i32 0
// CK18-DAG: [[PGEP]] = getelementptr inbounds {{.+}}[[PS:%[^,]+]], i32 0, i32 0
@@ -1054,125 +1122,125 @@ void implicit_maps_template_type_capture (int a){
#ifdef CK19
// CK19: [[SIZE00:@.+]] = private {{.*}}constant [1 x i[[Z:64|32]]] [i[[Z:64|32]] 4]
-// CK19: [[MTYPE00:@.+]] = private {{.*}}constant [1 x i32] [i32 32]
+// CK19: [[MTYPE00:@.+]] = private {{.*}}constant [1 x i64] [i64 32]
// CK19: [[SIZE00n:@.+]] = private {{.*}}constant [1 x i[[Z:64|32]]] [i[[Z:64|32]] 4]
-// CK19: [[MTYPE00n:@.+]] = private {{.*}}constant [1 x i32] [i32 32]
+// CK19: [[MTYPE00n:@.+]] = private {{.*}}constant [1 x i64] [i64 32]
// CK19: [[SIZE01:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 400]
-// CK19: [[MTYPE01:@.+]] = private {{.*}}constant [1 x i32] [i32 33]
+// CK19: [[MTYPE01:@.+]] = private {{.*}}constant [1 x i64] [i64 33]
// CK19: [[SIZE02:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 240]
-// CK19: [[MTYPE02:@.+]] = private {{.*}}constant [1 x i32] [i32 34]
+// CK19: [[MTYPE02:@.+]] = private {{.*}}constant [1 x i64] [i64 34]
// CK19: [[SIZE03:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 240]
-// CK19: [[MTYPE03:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+// CK19: [[MTYPE03:@.+]] = private {{.*}}constant [1 x i64] [i64 35]
// CK19: [[SIZE04:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 400]
-// CK19: [[MTYPE04:@.+]] = private {{.*}}constant [1 x i32] [i32 32]
+// CK19: [[MTYPE04:@.+]] = private {{.*}}constant [1 x i64] [i64 32]
// CK19: [[SIZE05:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 4]
-// CK19: [[MTYPE05:@.+]] = private {{.*}}constant [1 x i32] [i32 33]
+// CK19: [[MTYPE05:@.+]] = private {{.*}}constant [1 x i64] [i64 33]
-// CK19: [[MTYPE06:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+// CK19: [[MTYPE06:@.+]] = private {{.*}}constant [1 x i64] [i64 35]
-// CK19: [[MTYPE07:@.+]] = private {{.*}}constant [1 x i32] [i32 32]
+// CK19: [[MTYPE07:@.+]] = private {{.*}}constant [1 x i64] [i64 32]
// CK19: [[SIZE08:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 4]
-// CK19: [[MTYPE08:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+// CK19: [[MTYPE08:@.+]] = private {{.*}}constant [1 x i64] [i64 35]
// CK19: [[SIZE09:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] {{8|4}}]
-// CK19: [[MTYPE09:@.+]] = private {{.*}}constant [1 x i32] [i32 34]
+// CK19: [[MTYPE09:@.+]] = private {{.*}}constant [1 x i64] [i64 34]
// CK19: [[SIZE10:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 240]
-// CK19: [[MTYPE10:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+// CK19: [[MTYPE10:@.+]] = private {{.*}}constant [1 x i64] [i64 35]
// CK19: [[SIZE11:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 240]
-// CK19: [[MTYPE11:@.+]] = private {{.*}}constant [1 x i32] [i32 32]
+// CK19: [[MTYPE11:@.+]] = private {{.*}}constant [1 x i64] [i64 32]
// CK19: [[SIZE12:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 4]
-// CK19: [[MTYPE12:@.+]] = private {{.*}}constant [1 x i32] [i32 33]
+// CK19: [[MTYPE12:@.+]] = private {{.*}}constant [1 x i64] [i64 33]
-// CK19: [[MTYPE13:@.+]] = private {{.*}}constant [1 x i32] [i32 32]
+// CK19: [[MTYPE13:@.+]] = private {{.*}}constant [1 x i64] [i64 32]
-// CK19: [[MTYPE14:@.+]] = private {{.*}}constant [1 x i32] [i32 33]
+// CK19: [[MTYPE14:@.+]] = private {{.*}}constant [1 x i64] [i64 33]
// CK19: [[SIZE15:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 4]
-// CK19: [[MTYPE15:@.+]] = private {{.*}}constant [1 x i32] [i32 34]
+// CK19: [[MTYPE15:@.+]] = private {{.*}}constant [1 x i64] [i64 34]
-// CK19: [[MTYPE16:@.+]] = private {{.*}}constant [2 x i32] [i32 288, i32 33]
+// CK19: [[MTYPE16:@.+]] = private {{.*}}constant [2 x i64] [i64 288, i64 33]
// CK19: [[SIZE17:@.+]] = private {{.*}}constant [2 x i[[Z]]] [i[[Z]] {{8|4}}, i[[Z]] 240]
-// CK19: [[MTYPE17:@.+]] = private {{.*}}constant [2 x i32] [i32 288, i32 34]
+// CK19: [[MTYPE17:@.+]] = private {{.*}}constant [2 x i64] [i64 288, i64 34]
// CK19: [[SIZE18:@.+]] = private {{.*}}constant [2 x i[[Z]]] [i[[Z]] {{8|4}}, i[[Z]] 240]
-// CK19: [[MTYPE18:@.+]] = private {{.*}}constant [2 x i32] [i32 288, i32 35]
+// CK19: [[MTYPE18:@.+]] = private {{.*}}constant [2 x i64] [i64 288, i64 35]
-// CK19: [[MTYPE19:@.+]] = private {{.*}}constant [2 x i32] [i32 288, i32 32]
+// CK19: [[MTYPE19:@.+]] = private {{.*}}constant [2 x i64] [i64 288, i64 32]
// CK19: [[SIZE20:@.+]] = private {{.*}}constant [2 x i[[Z]]] [i[[Z]] {{8|4}}, i[[Z]] 4]
-// CK19: [[MTYPE20:@.+]] = private {{.*}}constant [2 x i32] [i32 288, i32 33]
+// CK19: [[MTYPE20:@.+]] = private {{.*}}constant [2 x i64] [i64 288, i64 33]
-// CK19: [[MTYPE21:@.+]] = private {{.*}}constant [2 x i32] [i32 288, i32 35]
+// CK19: [[MTYPE21:@.+]] = private {{.*}}constant [2 x i64] [i64 288, i64 35]
// CK19: [[SIZE22:@.+]] = private {{.*}}constant [2 x i[[Z]]] [i[[Z]] {{8|4}}, i[[Z]] 4]
-// CK19: [[MTYPE22:@.+]] = private {{.*}}constant [2 x i32] [i32 288, i32 35]
+// CK19: [[MTYPE22:@.+]] = private {{.*}}constant [2 x i64] [i64 288, i64 35]
// CK19: [[SIZE23:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 4]
-// CK19: [[MTYPE23:@.+]] = private {{.*}}constant [1 x i32] [i32 39]
+// CK19: [[MTYPE23:@.+]] = private {{.*}}constant [1 x i64] [i64 39]
// CK19: [[SIZE24:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 480]
-// CK19: [[MTYPE24:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+// CK19: [[MTYPE24:@.+]] = private {{.*}}constant [1 x i64] [i64 35]
// CK19: [[SIZE25:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 16]
-// CK19: [[MTYPE25:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+// CK19: [[MTYPE25:@.+]] = private {{.*}}constant [1 x i64] [i64 35]
// CK19: [[SIZE26:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 24]
-// CK19: [[MTYPE26:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+// CK19: [[MTYPE26:@.+]] = private {{.*}}constant [1 x i64] [i64 35]
// CK19: [[SIZE27:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 4]
-// CK19: [[MTYPE27:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+// CK19: [[MTYPE27:@.+]] = private {{.*}}constant [1 x i64] [i64 35]
// CK19: [[SIZE28:@.+]] = private {{.*}}constant [3 x i[[Z]]] [i[[Z]] {{8|4}}, i[[Z]] {{8|4}}, i[[Z]] 16]
-// CK19: [[MTYPE28:@.+]] = private {{.*}}constant [3 x i32] [i32 35, i32 19, i32 19]
+// CK19: [[MTYPE28:@.+]] = private {{.*}}constant [3 x i64] [i64 35, i64 19, i64 19]
// CK19: [[SIZE29:@.+]] = private {{.*}}constant [3 x i[[Z]]] [i[[Z]] {{8|4}}, i[[Z]] {{8|4}}, i[[Z]] 4]
-// CK19: [[MTYPE29:@.+]] = private {{.*}}constant [3 x i32] [i32 35, i32 19, i32 19]
+// CK19: [[MTYPE29:@.+]] = private {{.*}}constant [3 x i64] [i64 35, i64 19, i64 19]
-// CK19: [[MTYPE30:@.+]] = private {{.*}}constant [4 x i32] [i32 288, i32 288, i32 288, i32 35]
+// CK19: [[MTYPE30:@.+]] = private {{.*}}constant [4 x i64] [i64 288, i64 288, i64 288, i64 35]
// CK19: [[SIZE31:@.+]] = private {{.*}}constant [4 x i[[Z]]] [i[[Z]] {{8|4}}, i[[Z]] {{8|4}}, i[[Z]] {{8|4}}, i[[Z]] 40]
-// CK19: [[MTYPE31:@.+]] = private {{.*}}constant [4 x i32] [i32 288, i32 288, i32 288, i32 35]
+// CK19: [[MTYPE31:@.+]] = private {{.*}}constant [4 x i64] [i64 288, i64 288, i64 288, i64 35]
// CK19: [[SIZE32:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 13728]
-// CK19: [[MTYPE32:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+// CK19: [[MTYPE32:@.+]] = private {{.*}}constant [1 x i64] [i64 35]
// CK19: [[SIZE33:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 13728]
-// CK19: [[MTYPE33:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+// CK19: [[MTYPE33:@.+]] = private {{.*}}constant [1 x i64] [i64 35]
// CK19: [[SIZE34:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 13728]
-// CK19: [[MTYPE34:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+// CK19: [[MTYPE34:@.+]] = private {{.*}}constant [1 x i64] [i64 35]
-// CK19: [[MTYPE35:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+// CK19: [[MTYPE35:@.+]] = private {{.*}}constant [1 x i64] [i64 35]
// CK19: [[SIZE36:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 208]
-// CK19: [[MTYPE36:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+// CK19: [[MTYPE36:@.+]] = private {{.*}}constant [1 x i64] [i64 35]
-// CK19: [[MTYPE37:@.+]] = private {{.*}}constant [3 x i32] [i32 288, i32 288, i32 35]
+// CK19: [[MTYPE37:@.+]] = private {{.*}}constant [3 x i64] [i64 288, i64 288, i64 35]
-// CK19: [[MTYPE38:@.+]] = private {{.*}}constant [3 x i32] [i32 288, i32 288, i32 35]
+// CK19: [[MTYPE38:@.+]] = private {{.*}}constant [3 x i64] [i64 288, i64 288, i64 35]
-// CK19: [[MTYPE39:@.+]] = private {{.*}}constant [3 x i32] [i32 288, i32 288, i32 35]
+// CK19: [[MTYPE39:@.+]] = private {{.*}}constant [3 x i64] [i64 288, i64 288, i64 35]
-// CK19: [[MTYPE40:@.+]] = private {{.*}}constant [3 x i32] [i32 288, i32 288, i32 35]
+// CK19: [[MTYPE40:@.+]] = private {{.*}}constant [3 x i64] [i64 288, i64 288, i64 35]
// CK19: [[SIZE41:@.+]] = private {{.*}}constant [3 x i[[Z]]] [i[[Z]] {{8|4}}, i[[Z]] {{8|4}}, i[[Z]] 208]
-// CK19: [[MTYPE41:@.+]] = private {{.*}}constant [3 x i32] [i32 288, i32 288, i32 35]
+// CK19: [[MTYPE41:@.+]] = private {{.*}}constant [3 x i64] [i64 288, i64 288, i64 35]
// CK19: [[SIZE42:@.+]] = private {{.*}}constant [3 x i[[Z]]] [i[[Z]] {{8|4}}, i[[Z]] {{8|4}}, i[[Z]] 104]
-// CK19: [[MTYPE42:@.+]] = private {{.*}}constant [3 x i32] [i32 35, i32 19, i32 19]
+// CK19: [[MTYPE42:@.+]] = private {{.*}}constant [3 x i64] [i64 35, i64 19, i64 19]
-// CK19: [[MTYPE43:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+// CK19: [[MTYPE43:@.+]] = private {{.*}}constant [1 x i64] [i64 35]
// CK19-LABEL: explicit_maps_single
void explicit_maps_single (int ii){
@@ -1180,7 +1248,7 @@ void explicit_maps_single (int ii){
int a = ii;
// Region 00
- // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE00]]{{.+}})
+ // CK19-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE00]]{{.+}})
// CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -1201,7 +1269,7 @@ void explicit_maps_single (int ii){
int b = a;
// Region 00n
- // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE00n]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE00n]]{{.+}})
+ // CK19-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE00n]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE00n]]{{.+}})
// CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -1223,7 +1291,7 @@ void explicit_maps_single (int ii){
int arra[100];
// Region 01
- // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE01]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE01]]{{.+}})
+ // CK19-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE01]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE01]]{{.+}})
// CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -1241,7 +1309,7 @@ void explicit_maps_single (int ii){
}
// Region 02
- // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE02]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE02]]{{.+}})
+ // CK19-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE02]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE02]]{{.+}})
// CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -1260,7 +1328,7 @@ void explicit_maps_single (int ii){
}
// Region 03
- // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE03]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE03]]{{.+}})
+ // CK19-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE03]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE03]]{{.+}})
// CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -1279,7 +1347,7 @@ void explicit_maps_single (int ii){
}
// Region 04
- // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE04]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE04]]{{.+}})
+ // CK19-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE04]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE04]]{{.+}})
// CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -1298,7 +1366,7 @@ void explicit_maps_single (int ii){
}
// Region 05
- // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE05]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE05]]{{.+}})
+ // CK19-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE05]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE05]]{{.+}})
// CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -1317,7 +1385,7 @@ void explicit_maps_single (int ii){
}
// Region 06
- // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[Z]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE06]]{{.+}})
+ // CK19-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[Z]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE06]]{{.+}})
// CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
// CK19-DAG: [[GEPS]] = getelementptr inbounds {{.+}}[[S:%[^,]+]]
@@ -1340,7 +1408,7 @@ void explicit_maps_single (int ii){
}
// Region 07
- // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[Z]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE07]]{{.+}})
+ // CK19-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[Z]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE07]]{{.+}})
// CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
// CK19-DAG: [[GEPS]] = getelementptr inbounds {{.+}}[[S:%[^,]+]]
@@ -1363,7 +1431,7 @@ void explicit_maps_single (int ii){
}
// Region 08
- // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE08]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE08]]{{.+}})
+ // CK19-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE08]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE08]]{{.+}})
// CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -1385,7 +1453,7 @@ void explicit_maps_single (int ii){
int *pa;
// Region 09
- // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE09]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE09]]{{.+}})
+ // CK19-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE09]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE09]]{{.+}})
// CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -1403,7 +1471,7 @@ void explicit_maps_single (int ii){
}
// Region 10
- // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE10]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE10]]{{.+}})
+ // CK19-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE10]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE10]]{{.+}})
// CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -1424,7 +1492,7 @@ void explicit_maps_single (int ii){
}
// Region 11
- // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE11]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE11]]{{.+}})
+ // CK19-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE11]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE11]]{{.+}})
// CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -1445,7 +1513,7 @@ void explicit_maps_single (int ii){
}
// Region 12
- // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE12]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE12]]{{.+}})
+ // CK19-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE12]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE12]]{{.+}})
// CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -1466,7 +1534,7 @@ void explicit_maps_single (int ii){
}
// Region 13
- // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[Z]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE13]]{{.+}})
+ // CK19-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[Z]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE13]]{{.+}})
// CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
// CK19-DAG: [[GEPS]] = getelementptr inbounds {{.+}}[[S:%[^,]+]]
@@ -1491,7 +1559,7 @@ void explicit_maps_single (int ii){
}
// Region 14
- // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[Z]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE14]]{{.+}})
+ // CK19-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[Z]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE14]]{{.+}})
// CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
// CK19-DAG: [[GEPS]] = getelementptr inbounds {{.+}}[[S:%[^,]+]]
@@ -1516,7 +1584,7 @@ void explicit_maps_single (int ii){
}
// Region 15
- // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE15]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE15]]{{.+}})
+ // CK19-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE15]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE15]]{{.+}})
// CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -1540,7 +1608,7 @@ void explicit_maps_single (int ii){
int va[ii];
// Region 16
- // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[Z]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE16]]{{.+}})
+ // CK19-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[Z]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE16]]{{.+}})
// CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
// CK19-DAG: [[GEPS]] = getelementptr inbounds {{.+}}[[S:%[^,]+]]
@@ -1571,7 +1639,7 @@ void explicit_maps_single (int ii){
}
// Region 17
- // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE17]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE17]]{{.+}})
+ // CK19-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE17]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE17]]{{.+}})
// CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -1597,7 +1665,7 @@ void explicit_maps_single (int ii){
}
// Region 18
- // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE18]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE18]]{{.+}})
+ // CK19-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE18]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE18]]{{.+}})
// CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -1623,7 +1691,7 @@ void explicit_maps_single (int ii){
}
// Region 19
- // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[Z]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE19]]{{.+}})
+ // CK19-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[Z]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE19]]{{.+}})
// CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
// CK19-DAG: [[GEPS]] = getelementptr inbounds {{.+}}[[S:%[^,]+]]
@@ -1655,7 +1723,7 @@ void explicit_maps_single (int ii){
}
// Region 20
- // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE20]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE20]]{{.+}})
+ // CK19-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE20]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE20]]{{.+}})
// CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -1681,7 +1749,7 @@ void explicit_maps_single (int ii){
}
// Region 21
- // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[Z]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE21]]{{.+}})
+ // CK19-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[Z]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE21]]{{.+}})
// CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
// CK19-DAG: [[GEPS]] = getelementptr inbounds {{.+}}[[S:%[^,]+]]
@@ -1713,7 +1781,7 @@ void explicit_maps_single (int ii){
}
// Region 22
- // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE22]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE22]]{{.+}})
+ // CK19-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE22]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE22]]{{.+}})
// CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -1740,7 +1808,7 @@ void explicit_maps_single (int ii){
// Always.
// Region 23
- // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE23]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE23]]{{.+}})
+ // CK19-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE23]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE23]]{{.+}})
// CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -1762,7 +1830,7 @@ void explicit_maps_single (int ii){
int ***mptr;
// Region 24
- // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE24]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE24]]{{.+}})
+ // CK19-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE24]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE24]]{{.+}})
// CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -1780,7 +1848,7 @@ void explicit_maps_single (int ii){
}
// Region 25
- // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE25]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE25]]{{.+}})
+ // CK19-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE25]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE25]]{{.+}})
// CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -1801,7 +1869,7 @@ void explicit_maps_single (int ii){
}
// Region 26
- // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE26]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE26]]{{.+}})
+ // CK19-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE26]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE26]]{{.+}})
// CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -1822,7 +1890,7 @@ void explicit_maps_single (int ii){
}
// Region 27
- // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE27]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE27]]{{.+}})
+ // CK19-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE27]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE27]]{{.+}})
// CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -1843,7 +1911,7 @@ void explicit_maps_single (int ii){
}
// Region 28
- // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 3, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[3 x i{{.+}}]* [[SIZE28]], {{.+}}getelementptr {{.+}}[3 x i{{.+}}]* [[MTYPE28]]{{.+}})
+ // CK19-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 3, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[3 x i{{.+}}]* [[SIZE28]], {{.+}}getelementptr {{.+}}[3 x i{{.+}}]* [[MTYPE28]]{{.+}})
// CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -1888,7 +1956,7 @@ void explicit_maps_single (int ii){
}
// Region 29
- // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 3, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[3 x i{{.+}}]* [[SIZE29]], {{.+}}getelementptr {{.+}}[3 x i{{.+}}]* [[MTYPE29]]{{.+}})
+ // CK19-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 3, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[3 x i{{.+}}]* [[SIZE29]], {{.+}}getelementptr {{.+}}[3 x i{{.+}}]* [[MTYPE29]]{{.+}})
// CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -1936,7 +2004,7 @@ void explicit_maps_single (int ii){
double mva[23][ii][ii+5];
// Region 30
- // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 4, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[Z]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[4 x i{{.+}}]* [[MTYPE30]]{{.+}})
+ // CK19-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 4, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[Z]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[4 x i{{.+}}]* [[MTYPE30]]{{.+}})
// CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
// CK19-DAG: [[GEPS]] = getelementptr inbounds {{.+}}[[S:%[^,]+]]
@@ -1989,7 +2057,7 @@ void explicit_maps_single (int ii){
}
// Region 31
- // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 4, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[4 x i{{.+}}]* [[SIZE31]], {{.+}}getelementptr {{.+}}[4 x i{{.+}}]* [[MTYPE31]]{{.+}})
+ // CK19-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 4, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[4 x i{{.+}}]* [[SIZE31]], {{.+}}getelementptr {{.+}}[4 x i{{.+}}]* [[MTYPE31]]{{.+}})
// CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
//
@@ -2038,7 +2106,7 @@ void explicit_maps_single (int ii){
double ***mptras;
// Region 32
- // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE32]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE32]]{{.+}})
+ // CK19-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE32]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE32]]{{.+}})
// CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -2056,7 +2124,7 @@ void explicit_maps_single (int ii){
}
// Region 33
- // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE33]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE33]]{{.+}})
+ // CK19-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE33]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE33]]{{.+}})
// CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -2075,7 +2143,7 @@ void explicit_maps_single (int ii){
}
// Region 34
- // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE34]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE34]]{{.+}})
+ // CK19-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE34]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE34]]{{.+}})
// CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -2094,7 +2162,7 @@ void explicit_maps_single (int ii){
}
// Region 35
- // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[Z]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE35]]{{.+}})
+ // CK19-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[Z]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE35]]{{.+}})
// CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
// CK19-DAG: [[GEPS]] = getelementptr inbounds {{.+}}[[S:%[^,]+]]
@@ -2119,7 +2187,7 @@ void explicit_maps_single (int ii){
}
// Region 36
- // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE36]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE36]]{{.+}})
+ // CK19-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE36]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE36]]{{.+}})
// CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -2140,7 +2208,7 @@ void explicit_maps_single (int ii){
}
// Region 37
- // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 3, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[Z]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[3 x i{{.+}}]* [[MTYPE37]]{{.+}})
+ // CK19-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 3, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[Z]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[3 x i{{.+}}]* [[MTYPE37]]{{.+}})
// CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
// CK19-DAG: [[GEPS]] = getelementptr inbounds {{.+}}[[S:%[^,]+]]
@@ -2180,7 +2248,7 @@ void explicit_maps_single (int ii){
}
// Region 38
- // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 3, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[Z]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[3 x i{{.+}}]* [[MTYPE38]]{{.+}})
+ // CK19-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 3, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[Z]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[3 x i{{.+}}]* [[MTYPE38]]{{.+}})
// CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
// CK19-DAG: [[GEPS]] = getelementptr inbounds {{.+}}[[S:%[^,]+]]
@@ -2222,7 +2290,7 @@ void explicit_maps_single (int ii){
}
// Region 39
- // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 3, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[Z]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[3 x i{{.+}}]* [[MTYPE39]]{{.+}})
+ // CK19-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 3, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[Z]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[3 x i{{.+}}]* [[MTYPE39]]{{.+}})
// CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
// CK19-DAG: [[GEPS]] = getelementptr inbounds {{.+}}[[S:%[^,]+]]
@@ -2264,7 +2332,7 @@ void explicit_maps_single (int ii){
}
// Region 40
- // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 3, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[Z]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[3 x i{{.+}}]* [[MTYPE40]]{{.+}})
+ // CK19-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 3, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[Z]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[3 x i{{.+}}]* [[MTYPE40]]{{.+}})
// CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
// CK19-DAG: [[GEPS]] = getelementptr inbounds {{.+}}[[S:%[^,]+]]
@@ -2306,7 +2374,7 @@ void explicit_maps_single (int ii){
}
// Region 41
- // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 3, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[3 x i{{.+}}]* [[SIZE41]], {{.+}}getelementptr {{.+}}[3 x i{{.+}}]* [[MTYPE41]]{{.+}})
+ // CK19-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 3, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[3 x i{{.+}}]* [[SIZE41]], {{.+}}getelementptr {{.+}}[3 x i{{.+}}]* [[MTYPE41]]{{.+}})
// CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
//
@@ -2341,7 +2409,7 @@ void explicit_maps_single (int ii){
}
// Region 42
- // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 3, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[3 x i{{.+}}]* [[SIZE42]], {{.+}}getelementptr {{.+}}[3 x i{{.+}}]* [[MTYPE42]]{{.+}})
+ // CK19-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 3, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[3 x i{{.+}}]* [[SIZE42]], {{.+}}getelementptr {{.+}}[3 x i{{.+}}]* [[MTYPE42]]{{.+}})
// CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -2386,7 +2454,7 @@ void explicit_maps_single (int ii){
}
// Region 43 - the memory is not contiguous for this map - will map the whole last dimension.
- // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[Z]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE43]]{{.+}})
+ // CK19-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[Z]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE43]]{{.+}})
// CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
// CK19-DAG: [[GEPS]] = getelementptr inbounds {{.+}}[[S:%[^,]+]]
@@ -2469,16 +2537,16 @@ void explicit_maps_single (int ii){
#ifdef CK20
// CK20: [[SIZE00:@.+]] = private {{.*}}constant [1 x i[[Z:64|32]]] [i[[Z:64|32]] 4]
-// CK20: [[MTYPE00:@.+]] = private {{.*}}constant [1 x i32] [i32 33]
+// CK20: [[MTYPE00:@.+]] = private {{.*}}constant [1 x i64] [i64 33]
// CK20: [[SIZE01:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 20]
-// CK20: [[MTYPE01:@.+]] = private {{.*}}constant [1 x i32] [i32 33]
+// CK20: [[MTYPE01:@.+]] = private {{.*}}constant [1 x i64] [i64 33]
// CK20: [[SIZE02:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 4]
-// CK20: [[MTYPE02:@.+]] = private {{.*}}constant [1 x i32] [i32 34]
+// CK20: [[MTYPE02:@.+]] = private {{.*}}constant [1 x i64] [i64 34]
// CK20: [[SIZE03:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 12]
-// CK20: [[MTYPE03:@.+]] = private {{.*}}constant [1 x i32] [i32 34]
+// CK20: [[MTYPE03:@.+]] = private {{.*}}constant [1 x i64] [i64 34]
// CK20-LABEL: explicit_maps_references_and_function_args
void explicit_maps_references_and_function_args (int a, float b, int (&c)[10], float *d){
@@ -2489,7 +2557,7 @@ void explicit_maps_references_and_function_args (int a, float b, int (&c)[10], f
float *&dd = d;
// Region 00
- // CK20-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE00]]{{.+}})
+ // CK20-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE00]]{{.+}})
// CK20-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK20-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -2509,7 +2577,7 @@ void explicit_maps_references_and_function_args (int a, float b, int (&c)[10], f
}
// Region 01
- // CK20-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE01]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE01]]{{.+}})
+ // CK20-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE01]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE01]]{{.+}})
// CK20-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK20-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -2530,7 +2598,7 @@ void explicit_maps_references_and_function_args (int a, float b, int (&c)[10], f
}
// Region 02
- // CK20-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE02]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE02]]{{.+}})
+ // CK20-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE02]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE02]]{{.+}})
// CK20-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK20-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -2548,7 +2616,7 @@ void explicit_maps_references_and_function_args (int a, float b, int (&c)[10], f
}
// Region 03
- // CK20-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE03]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE03]]{{.+}})
+ // CK20-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE03]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE03]]{{.+}})
// CK20-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK20-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -2586,22 +2654,22 @@ void explicit_maps_references_and_function_args (int a, float b, int (&c)[10], f
// CK21: [[ST:%.+]] = type { i32, i32, float* }
// CK21: [[SIZE00:@.+]] = private {{.*}}constant [1 x i[[Z:64|32]]] [i[[Z:64|32]] 4]
-// CK21: [[MTYPE00:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+// CK21: [[MTYPE00:@.+]] = private {{.*}}constant [1 x i64] [i64 35]
// CK21: [[SIZE01:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 492]
-// CK21: [[MTYPE01:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+// CK21: [[MTYPE01:@.+]] = private {{.*}}constant [1 x i64] [i64 35]
// CK21: [[SIZE02:@.+]] = private {{.*}}constant [2 x i[[Z]]] [i[[Z]] {{8|4}}, i[[Z]] 500]
-// CK21: [[MTYPE02:@.+]] = private {{.*}}constant [2 x i32] [i32 34, i32 18]
+// CK21: [[MTYPE02:@.+]] = private {{.*}}constant [2 x i64] [i64 34, i64 18]
// CK21: [[SIZE03:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 492]
-// CK21: [[MTYPE03:@.+]] = private {{.*}}constant [1 x i32] [i32 34]
+// CK21: [[MTYPE03:@.+]] = private {{.*}}constant [1 x i64] [i64 34]
// CK21: [[SIZE04:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 4]
-// CK21: [[MTYPE04:@.+]] = private {{.*}}constant [1 x i32] [i32 34]
+// CK21: [[MTYPE04:@.+]] = private {{.*}}constant [1 x i64] [i64 34]
// CK21: [[SIZE05:@.+]] = private {{.*}}constant [2 x i[[Z]]] [i[[Z]] 4, i[[Z]] 4]
-// CK21: [[MTYPE05:@.+]] = private {{.*}}constant [2 x i32] [i32 35, i32 3]
+// CK21: [[MTYPE05:@.+]] = private {{.*}}constant [2 x i64] [i64 35, i64 3]
// CK21-LABEL: explicit_maps_template_args_and_members
@@ -2616,7 +2684,7 @@ struct CC {
T *lb;
// Region 00
- // CK21-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE00]]{{.+}})
+ // CK21-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE00]]{{.+}})
// CK21-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK21-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -2635,7 +2703,7 @@ struct CC {
}
// Region 01
- // CK21-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE01]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE01]]{{.+}})
+ // CK21-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE01]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE01]]{{.+}})
// CK21-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK21-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -2656,7 +2724,7 @@ struct CC {
}
// Region 02
- // CK21-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE02]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE02]]{{.+}})
+ // CK21-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE02]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE02]]{{.+}})
// CK21-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK21-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -2685,7 +2753,7 @@ struct CC {
}
// Region 03
- // CK21-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE03]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE03]]{{.+}})
+ // CK21-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE03]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE03]]{{.+}})
// CK21-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK21-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -2703,7 +2771,7 @@ struct CC {
}
// Region 04
- // CK21-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE04]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE04]]{{.+}})
+ // CK21-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE04]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE04]]{{.+}})
// CK21-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK21-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -2722,7 +2790,7 @@ struct CC {
// Make sure the extra flag is passed to the second map.
// Region 05
- // CK21-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE05]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE05]]{{.+}})
+ // CK21-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE05]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE05]]{{.+}})
// CK21-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK21-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -2777,49 +2845,49 @@ int explicit_maps_template_args_and_members(int a){
// CK22-DAG: [[STT:%.+]] = type { i32 }
// CK22: [[SIZE00:@.+]] = private {{.*}}constant [1 x i[[Z:64|32]]] [i[[Z:64|32]] 4]
-// CK22: [[MTYPE00:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+// CK22: [[MTYPE00:@.+]] = private {{.*}}constant [1 x i64] [i64 35]
// CK22: [[SIZE01:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 400]
-// CK22: [[MTYPE01:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+// CK22: [[MTYPE01:@.+]] = private {{.*}}constant [1 x i64] [i64 35]
// CK22: [[SIZE02:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] {{8|4}}]
-// CK22: [[MTYPE02:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+// CK22: [[MTYPE02:@.+]] = private {{.*}}constant [1 x i64] [i64 35]
// CK22: [[SIZE03:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 16]
-// CK22: [[MTYPE03:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+// CK22: [[MTYPE03:@.+]] = private {{.*}}constant [1 x i64] [i64 35]
// CK22: [[SIZE04:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 20]
-// CK22: [[MTYPE04:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+// CK22: [[MTYPE04:@.+]] = private {{.*}}constant [1 x i64] [i64 35]
// CK22: [[SIZE05:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 4]
-// CK22: [[MTYPE05:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+// CK22: [[MTYPE05:@.+]] = private {{.*}}constant [1 x i64] [i64 35]
// CK22: [[SIZE06:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 400]
-// CK22: [[MTYPE06:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+// CK22: [[MTYPE06:@.+]] = private {{.*}}constant [1 x i64] [i64 35]
// CK22: [[SIZE07:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] {{8|4}}]
-// CK22: [[MTYPE07:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+// CK22: [[MTYPE07:@.+]] = private {{.*}}constant [1 x i64] [i64 35]
// CK22: [[SIZE08:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 16]
-// CK22: [[MTYPE08:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+// CK22: [[MTYPE08:@.+]] = private {{.*}}constant [1 x i64] [i64 35]
// CK22: [[SIZE09:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 20]
-// CK22: [[MTYPE09:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+// CK22: [[MTYPE09:@.+]] = private {{.*}}constant [1 x i64] [i64 35]
// CK22: [[SIZE10:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 4]
-// CK22: [[MTYPE10:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+// CK22: [[MTYPE10:@.+]] = private {{.*}}constant [1 x i64] [i64 35]
// CK22: [[SIZE11:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 400]
-// CK22: [[MTYPE11:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+// CK22: [[MTYPE11:@.+]] = private {{.*}}constant [1 x i64] [i64 35]
// CK22: [[SIZE12:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] {{8|4}}]
-// CK22: [[MTYPE12:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+// CK22: [[MTYPE12:@.+]] = private {{.*}}constant [1 x i64] [i64 35]
// CK22: [[SIZE13:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 16]
-// CK22: [[MTYPE13:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+// CK22: [[MTYPE13:@.+]] = private {{.*}}constant [1 x i64] [i64 35]
// CK22: [[SIZE14:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 20]
-// CK22: [[MTYPE14:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+// CK22: [[MTYPE14:@.+]] = private {{.*}}constant [1 x i64] [i64 35]
int a;
int c[100];
@@ -2845,7 +2913,7 @@ STT<int> *std;
// CK22-LABEL: explicit_maps_globals
int explicit_maps_globals(void){
// Region 00
- // CK22-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE00]]{{.+}})
+ // CK22-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE00]]{{.+}})
// CK22-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK22-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -2861,7 +2929,7 @@ int explicit_maps_globals(void){
{ a+=1; }
// Region 01
- // CK22-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE01]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE01]]{{.+}})
+ // CK22-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE01]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE01]]{{.+}})
// CK22-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK22-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -2877,7 +2945,7 @@ int explicit_maps_globals(void){
{ c[3]+=1; }
// Region 02
- // CK22-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE02]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE02]]{{.+}})
+ // CK22-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE02]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE02]]{{.+}})
// CK22-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK22-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -2893,7 +2961,7 @@ int explicit_maps_globals(void){
{ d[3]+=1; }
// Region 03
- // CK22-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE03]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE03]]{{.+}})
+ // CK22-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE03]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE03]]{{.+}})
// CK22-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK22-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -2909,7 +2977,7 @@ int explicit_maps_globals(void){
{ c[3]+=1; }
// Region 04
- // CK22-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE04]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE04]]{{.+}})
+ // CK22-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE04]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE04]]{{.+}})
// CK22-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK22-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -2928,7 +2996,7 @@ int explicit_maps_globals(void){
{ d[3]+=1; }
// Region 05
- // CK22-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE05]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE05]]{{.+}})
+ // CK22-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE05]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE05]]{{.+}})
// CK22-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK22-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -2944,7 +3012,7 @@ int explicit_maps_globals(void){
{ sa.fa+=1; }
// Region 06
- // CK22-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE06]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE06]]{{.+}})
+ // CK22-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE06]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE06]]{{.+}})
// CK22-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK22-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -2960,7 +3028,7 @@ int explicit_maps_globals(void){
{ sc[3].fa+=1; }
// Region 07
- // CK22-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE07]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE07]]{{.+}})
+ // CK22-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE07]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE07]]{{.+}})
// CK22-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK22-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -2976,7 +3044,7 @@ int explicit_maps_globals(void){
{ sd[3].fa+=1; }
// Region 08
- // CK22-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE08]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE08]]{{.+}})
+ // CK22-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE08]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE08]]{{.+}})
// CK22-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK22-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -2992,7 +3060,7 @@ int explicit_maps_globals(void){
{ sc[3].fa+=1; }
// Region 09
- // CK22-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE09]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE09]]{{.+}})
+ // CK22-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE09]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE09]]{{.+}})
// CK22-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK22-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -3011,7 +3079,7 @@ int explicit_maps_globals(void){
{ sd[3].fa+=1; }
// Region 10
- // CK22-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE10]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE10]]{{.+}})
+ // CK22-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE10]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE10]]{{.+}})
// CK22-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK22-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -3027,7 +3095,7 @@ int explicit_maps_globals(void){
{ sta.fa+=1; }
// Region 11
- // CK22-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE11]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE11]]{{.+}})
+ // CK22-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE11]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE11]]{{.+}})
// CK22-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK22-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -3043,7 +3111,7 @@ int explicit_maps_globals(void){
{ stc[3].fa+=1; }
// Region 12
- // CK22-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE12]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE12]]{{.+}})
+ // CK22-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE12]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE12]]{{.+}})
// CK22-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK22-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -3059,7 +3127,7 @@ int explicit_maps_globals(void){
{ std[3].fa+=1; }
// Region 13
- // CK22-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE13]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE13]]{{.+}})
+ // CK22-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE13]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE13]]{{.+}})
// CK22-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK22-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -3075,7 +3143,7 @@ int explicit_maps_globals(void){
{ stc[3].fa+=1; }
// Region 14
- // CK22-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE14]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE14]]{{.+}})
+ // CK22-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE14]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE14]]{{.+}})
// CK22-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK22-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -3121,22 +3189,22 @@ int explicit_maps_globals(void){
#ifdef CK23
// CK23: [[SIZE00:@.+]] = private {{.*}}constant [1 x i[[Z:64|32]]] [i[[Z:64|32]] 4]
-// CK23: [[MTYPE00:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+// CK23: [[MTYPE00:@.+]] = private {{.*}}constant [1 x i64] [i64 35]
// CK23: [[SIZE01:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 4]
-// CK23: [[MTYPE01:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+// CK23: [[MTYPE01:@.+]] = private {{.*}}constant [1 x i64] [i64 35]
// CK23: [[SIZE02:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 400]
-// CK23: [[MTYPE02:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+// CK23: [[MTYPE02:@.+]] = private {{.*}}constant [1 x i64] [i64 35]
// CK23: [[SIZE03:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] {{8|4}}]
-// CK23: [[MTYPE03:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+// CK23: [[MTYPE03:@.+]] = private {{.*}}constant [1 x i64] [i64 35]
// CK23: [[SIZE04:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 16]
-// CK23: [[MTYPE04:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+// CK23: [[MTYPE04:@.+]] = private {{.*}}constant [1 x i64] [i64 35]
// CK23: [[SIZE05:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 16]
-// CK23: [[MTYPE05:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+// CK23: [[MTYPE05:@.+]] = private {{.*}}constant [1 x i64] [i64 35]
// CK23-LABEL: explicit_maps_inside_captured
int explicit_maps_inside_captured(int a){
@@ -3148,7 +3216,7 @@ int explicit_maps_inside_captured(int a){
// CK23: define {{.*}}explicit_maps_inside_captured{{.*}}
[&](void){
// Region 00
- // CK23-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE00]]{{.+}})
+ // CK23-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE00]]{{.+}})
// CK23-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK23-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -3167,7 +3235,7 @@ int explicit_maps_inside_captured(int a){
#pragma omp target map(a)
{ a+=1; }
// Region 01
- // CK23-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE01]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE01]]{{.+}})
+ // CK23-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE01]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE01]]{{.+}})
// CK23-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK23-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -3186,7 +3254,7 @@ int explicit_maps_inside_captured(int a){
#pragma omp target map(b)
{ b+=1; }
// Region 02
- // CK23-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE02]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE02]]{{.+}})
+ // CK23-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE02]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE02]]{{.+}})
// CK23-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK23-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -3206,7 +3274,7 @@ int explicit_maps_inside_captured(int a){
{ c[3]+=1; }
// Region 03
- // CK23-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE03]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE03]]{{.+}})
+ // CK23-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE03]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE03]]{{.+}})
// CK23-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK23-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -3225,7 +3293,7 @@ int explicit_maps_inside_captured(int a){
#pragma omp target map(d)
{ d[3]+=1; }
// Region 04
- // CK23-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE04]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE04]]{{.+}})
+ // CK23-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE04]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE04]]{{.+}})
// CK23-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK23-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -3246,7 +3314,7 @@ int explicit_maps_inside_captured(int a){
{ c[3]+=1; }
// Region 05
- // CK23-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE05]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE05]]{{.+}})
+ // CK23-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE05]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE05]]{{.+}})
// CK23-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK23-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -3311,76 +3379,43 @@ struct SC{
};
// CK24: [[SIZE01:@.+]] = private {{.*}}constant [1 x i[[Z:64|32]]] [i[[Z:64|32]] 4]
-// CK24: [[MTYPE01:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
-
-// CK24: [[SIZE02:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] {{56|48}}]
-// CK24: [[MTYPE02:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
-
-// CK24: [[SIZE03:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 4]
-// CK24: [[MTYPE03:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
-
-// CK24: [[SIZE04:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 20]
-// CK24: [[MTYPE04:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
-
-// CK24: [[SIZE05:@.+]] = private {{.*}}constant [2 x i[[Z]]] [i[[Z]] {{8|4}}, i[[Z]] {{3560|2880}}]
-// CK24: [[MTYPE05:@.+]] = private {{.*}}constant [2 x i32] [i32 35, i32 19]
-
-// CK24: [[SIZE06:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 4]
-// CK24: [[MTYPE06:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
-
-// CK24: [[SIZE07:@.+]] = private {{.*}}constant [2 x i[[Z]]] [i[[Z]] {{8|4}}, i[[Z]] 4]
-// CK24: [[MTYPE07:@.+]] = private {{.*}}constant [2 x i32] [i32 35, i32 19]
-
-// CK24: [[SIZE08:@.+]] = private {{.*}}constant [2 x i[[Z]]] [i[[Z]] {{8|4}}, i[[Z]] 4]
-// CK24: [[MTYPE08:@.+]] = private {{.*}}constant [2 x i32] [i32 35, i32 19]
-
-// CK24: [[SIZE09:@.+]] = private {{.*}}constant [2 x i[[Z]]] [i[[Z]] {{8|4}}, i[[Z]] 4]
-// CK24: [[MTYPE09:@.+]] = private {{.*}}constant [2 x i32] [i32 35, i32 19]
-
-// CK24: [[SIZE10:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 8]
-// CK24: [[MTYPE10:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
-
-// CK24: [[SIZE11:@.+]] = private {{.*}}constant [2 x i[[Z]]] [i[[Z]] {{8|4}}, i[[Z]] {{8|4}}]
-// CK24: [[MTYPE11:@.+]] = private {{.*}}constant [2 x i32] [i32 35, i32 19]
-
-// CK24: [[SIZE12:@.+]] = private {{.*}}constant [4 x i[[Z]]] [i[[Z]] {{8|4}}, i[[Z]] {{8|4}}, i[[Z]] {{8|4}}, i[[Z]] 4]
-// CK24: [[MTYPE12:@.+]] = private {{.*}}constant [4 x i32] [i32 35, i32 19, i32 19, i32 19]
+// CK24: [[MTYPE01:@.+]] = private {{.*}}constant [1 x i64] [i64 35]
// CK24: [[SIZE13:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 4]
-// CK24: [[MTYPE13:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+// CK24: [[MTYPE13:@.+]] = private {{.*}}constant [1 x i64] [i64 35]
// CK24: [[SIZE14:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] {{56|48}}]
-// CK24: [[MTYPE14:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+// CK24: [[MTYPE14:@.+]] = private {{.*}}constant [1 x i64] [i64 35]
// CK24: [[SIZE15:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 4]
-// CK24: [[MTYPE15:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+// CK24: [[MTYPE15:@.+]] = private {{.*}}constant [1 x i64] [i64 35]
// CK24: [[SIZE16:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 20]
-// CK24: [[MTYPE16:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+// CK24: [[MTYPE16:@.+]] = private {{.*}}constant [1 x i64] [i64 35]
// CK24: [[SIZE17:@.+]] = private {{.*}}constant [2 x i[[Z]]] [i[[Z]] {{8|4}}, i[[Z]] {{3560|2880}}]
-// CK24: [[MTYPE17:@.+]] = private {{.*}}constant [2 x i32] [i32 35, i32 19]
+// CK24: [[MTYPE17:@.+]] = private {{.*}}constant [2 x i64] [i64 35, i64 19]
// CK24: [[SIZE18:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 4]
-// CK24: [[MTYPE18:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+// CK24: [[MTYPE18:@.+]] = private {{.*}}constant [1 x i64] [i64 35]
// CK24: [[SIZE19:@.+]] = private {{.*}}constant [2 x i[[Z]]] [i[[Z]] {{8|4}}, i[[Z]] 4]
-// CK24: [[MTYPE19:@.+]] = private {{.*}}constant [2 x i32] [i32 35, i32 19]
+// CK24: [[MTYPE19:@.+]] = private {{.*}}constant [2 x i64] [i64 35, i64 19]
// CK24: [[SIZE20:@.+]] = private {{.*}}constant [2 x i[[Z]]] [i[[Z]] {{8|4}}, i[[Z]] 4]
-// CK24: [[MTYPE20:@.+]] = private {{.*}}constant [2 x i32] [i32 35, i32 19]
+// CK24: [[MTYPE20:@.+]] = private {{.*}}constant [2 x i64] [i64 35, i64 19]
// CK24: [[SIZE21:@.+]] = private {{.*}}constant [2 x i[[Z]]] [i[[Z]] {{8|4}}, i[[Z]] 4]
-// CK24: [[MTYPE21:@.+]] = private {{.*}}constant [2 x i32] [i32 35, i32 19]
+// CK24: [[MTYPE21:@.+]] = private {{.*}}constant [2 x i64] [i64 35, i64 19]
// CK24: [[SIZE22:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] {{8|4}}]
-// CK24: [[MTYPE22:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+// CK24: [[MTYPE22:@.+]] = private {{.*}}constant [1 x i64] [i64 35]
// CK24: [[SIZE23:@.+]] = private {{.*}}constant [2 x i[[Z]]] [i[[Z]] {{8|4}}, i[[Z]] {{8|4}}]
-// CK24: [[MTYPE23:@.+]] = private {{.*}}constant [2 x i32] [i32 35, i32 19]
+// CK24: [[MTYPE23:@.+]] = private {{.*}}constant [2 x i64] [i64 35, i64 19]
// CK24: [[SIZE24:@.+]] = private {{.*}}constant [4 x i[[Z]]] [i[[Z]] {{8|4}}, i[[Z]] {{8|4}}, i[[Z]] {{8|4}}, i[[Z]] 4]
-// CK24: [[MTYPE24:@.+]] = private {{.*}}constant [4 x i32] [i32 35, i32 19, i32 19, i32 19]
+// CK24: [[MTYPE24:@.+]] = private {{.*}}constant [4 x i64] [i64 35, i64 19, i64 19, i64 19]
// CK24-LABEL: explicit_maps_struct_fields
int explicit_maps_struct_fields(int a){
@@ -3388,7 +3423,7 @@ int explicit_maps_struct_fields(int a){
SC *p;
// Region 01
-// CK24-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE01]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE01]]{{.+}})
+// CK24-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE01]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE01]]{{.+}})
// CK24-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK24-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -3404,303 +3439,11 @@ int explicit_maps_struct_fields(int a){
#pragma omp target map(s.a)
{ s.a++; }
-// Region 02
-// CK24-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE02]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE02]]{{.+}})
-// CK24-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
-// CK24-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
-
-// CK24-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
-// CK24-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
-// CK24-DAG: [[CBP0:%.+]] = bitcast i8** [[BP0]] to [[SC]]**
-// CK24-DAG: [[CP0:%.+]] = bitcast i8** [[P0]] to [[SA]]**
-// CK24-DAG: store [[SC]]* [[VAR0:%.+]], [[SC]]** [[CBP0]]
-// CK24-DAG: store [[SA]]* [[SEC0:%.+]], [[SA]]** [[CP0]]
-// CK24-DAG: [[SEC0]] = getelementptr {{.*}}[[SB]]* [[SEC00:%[^,]+]], i{{.+}} 0, i{{.+}} 1
-// CK24-DAG: [[SEC00]] = getelementptr {{.*}}[[SC]]* [[VAR0]], i{{.+}} 0, i{{.+}} 1
-
-// CK24: call void [[CALL02:@.+]]([[SC]]* {{[^,]+}})
-#pragma omp target map(s.s.s)
- { s.a++; }
-
-// Region 03
-// CK24-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE03]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE03]]{{.+}})
-// CK24-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
-// CK24-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
-
-// CK24-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
-// CK24-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
-// CK24-DAG: [[CBP0:%.+]] = bitcast i8** [[BP0]] to [[SC]]**
-// CK24-DAG: [[CP0:%.+]] = bitcast i8** [[P0]] to i32**
-// CK24-DAG: store [[SC]]* [[VAR0:%.+]], [[SC]]** [[CBP0]]
-// CK24-DAG: store i32* [[SEC0:%.+]], i32** [[CP0]]
-// CK24-DAG: [[SEC0]] = getelementptr {{.*}}[[SA]]* [[SEC00:%[^,]+]], i{{.+}} 0, i{{.+}} 0
-// CK24-DAG: [[SEC00]] = getelementptr {{.*}}[[SB]]* [[SEC000:%[^,]+]], i{{.+}} 0, i{{.+}} 1
-// CK24-DAG: [[SEC000]] = getelementptr {{.*}}[[SC]]* [[VAR0]], i{{.+}} 0, i{{.+}} 1
-
-// CK24: call void [[CALL03:@.+]]([[SC]]* {{[^,]+}})
-#pragma omp target map(s.s.s.a)
- { s.a++; }
-
-// Region 04
-// CK24-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE04]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE04]]{{.+}})
-// CK24-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
-// CK24-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
-
-// CK24-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
-// CK24-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
-// CK24-DAG: [[CBP0:%.+]] = bitcast i8** [[BP0]] to [[SC]]**
-// CK24-DAG: [[CP0:%.+]] = bitcast i8** [[P0]] to i32**
-// CK24-DAG: store [[SC]]* [[VAR0:%.+]], [[SC]]** [[CBP0]]
-// CK24-DAG: store i32* [[SEC0:%.+]], i32** [[CP0]]
-// CK24-DAG: [[SEC0]] = getelementptr {{.*}}[10 x i32]* [[SEC00:%[^,]+]], i{{.+}} 0, i{{.+}} 0
-// CK24-DAG: [[SEC00]] = getelementptr {{.*}}[[SC]]* [[VAR0]], i{{.+}} 0, i{{.+}} 3
-
-// CK24: call void [[CALL04:@.+]]([[SC]]* {{[^,]+}})
-#pragma omp target map(s.b[:5])
- { s.a++; }
-
-// Region 05
-// CK24-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE05]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE05]]{{.+}})
-// CK24-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
-// CK24-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
-
-// CK24-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
-// CK24-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
-// CK24-DAG: [[CBP0:%.+]] = bitcast i8** [[BP0]] to [[SC]]**
-// CK24-DAG: [[CP0:%.+]] = bitcast i8** [[P0]] to [[SB]]***
-// CK24-DAG: store [[SC]]* [[VAR0:%.+]], [[SC]]** [[CBP0]]
-// CK24-DAG: store [[SB]]** [[SEC0:%.+]], [[SB]]*** [[CP0]]
-// CK24-DAG: [[SEC0]] = getelementptr {{.*}}[[SC]]* [[VAR0]], i{{.+}} 0, i{{.+}} 2
-
-// CK24-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1
-// CK24-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1
-// CK24-DAG: [[CBP1:%.+]] = bitcast i8** [[BP1]] to [[SB]]***
-// CK24-DAG: [[CP1:%.+]] = bitcast i8** [[P1]] to [[SB]]**
-// CK24-DAG: store [[SB]]** [[SEC0]], [[SB]]*** [[CBP1]]
-// CK24-DAG: store [[SB]]* [[SEC1:%.+]], [[SB]]** [[CP1]]
-// CK24-DAG: [[SEC1]] = getelementptr {{.*}}[[SB]]* [[SEC11:%[^,]+]], i{{.+}} 0
-// CK24-DAG: [[SEC11]] = load [[SB]]*, [[SB]]** [[SEC111:%[^,]+]],
-// CK24-DAG: [[SEC111]] = getelementptr {{.*}}[[SC]]* [[VAR0]], i{{.+}} 0, i{{.+}} 2
-
-// CK24: call void [[CALL05:@.+]]([[SC]]* {{[^,]+}})
-#pragma omp target map(s.p[:5])
- { s.a++; }
-
-// Region 06
-// CK24-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE06]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE06]]{{.+}})
-// CK24-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
-// CK24-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
-
-// CK24-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
-// CK24-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
-// CK24-DAG: [[CBP0:%.+]] = bitcast i8** [[BP0]] to [[SC]]**
-// CK24-DAG: [[CP0:%.+]] = bitcast i8** [[P0]] to i32**
-// CK24-DAG: store [[SC]]* [[VAR0:%.+]], [[SC]]** [[CBP0]]
-// CK24-DAG: store i32* [[SEC0:%.+]], i32** [[CP0]]
-// CK24-DAG: [[SEC0]] = getelementptr {{.*}}[[SA]]* [[SEC00:%[^,]+]], i{{.+}} 0, i{{.+}} 0
-// CK24-DAG: [[SEC00]] = getelementptr {{.*}}[10 x [[SA]]]* [[SEC000:%[^,]+]], i{{.+}} 0, i{{.+}} 3
-// CK24-DAG: [[SEC000]] = getelementptr {{.*}}[[SB]]* [[SEC0000:%[^,]+]], i{{.+}} 0, i{{.+}} 2
-// CK24-DAG: [[SEC0000]] = getelementptr {{.*}}[[SC]]* [[VAR0]], i{{.+}} 0, i{{.+}} 1
-
-// CK24: call void [[CALL06:@.+]]([[SC]]* {{[^,]+}})
-#pragma omp target map(s.s.sa[3].a)
- { s.a++; }
-
-// Region 07
-// CK24-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE07]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE07]]{{.+}})
-// CK24-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
-// CK24-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
-
-// CK24-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
-// CK24-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
-// CK24-DAG: [[CBP0:%.+]] = bitcast i8** [[BP0]] to [[SC]]**
-// CK24-DAG: [[CP0:%.+]] = bitcast i8** [[P0]] to [[SA]]***
-// CK24-DAG: store [[SC]]* [[VAR0:%.+]], [[SC]]** [[CBP0]]
-// CK24-DAG: store [[SA]]** [[SEC0:%.+]], [[SA]]*** [[CP0]]
-// CK24-DAG: [[SEC0]] = getelementptr {{.*}}[10 x [[SA]]*]* [[SEC00:%[^,]+]], i{{.+}} 0, i{{.+}} 3
-// CK24-DAG: [[SEC00]] = getelementptr {{.*}}[[SB]]* [[SEC000:%[^,]+]], i{{.+}} 0, i{{.+}} 3
-// CK24-DAG: [[SEC000]] = getelementptr {{.*}}[[SC]]* [[VAR0]], i{{.+}} 0, i{{.+}} 1
-
-// CK24-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1
-// CK24-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1
-// CK24-DAG: [[CBP1:%.+]] = bitcast i8** [[BP1]] to [[SA]]***
-// CK24-DAG: [[CP1:%.+]] = bitcast i8** [[P1]] to i32**
-// CK24-DAG: store [[SA]]** [[SEC0]], [[SA]]*** [[CBP1]]
-// CK24-DAG: store i32* [[SEC1:%.+]], i32** [[CP1]]
-// CK24-DAG: [[SEC1]] = getelementptr {{.*}}[[SA]]* [[SEC11:%[^,]+]], i{{.+}} 0, i{{.+}} 0
-// CK24-DAG: [[SEC11]] = load [[SA]]*, [[SA]]** [[SEC111:%[^,]+]],
-// CK24-DAG: [[SEC111]] = getelementptr {{.*}}[10 x [[SA]]*]* [[SEC1111:%[^,]+]], i{{.+}} 0, i{{.+}} 3
-// CK24-DAG: [[SEC1111]] = getelementptr {{.*}}[[SB]]* [[SEC11111:%[^,]+]], i{{.+}} 0, i{{.+}} 3
-// CK24-DAG: [[SEC11111]] = getelementptr {{.*}}[[SC]]* [[VAR0]], i{{.+}} 0, i{{.+}} 1
-
-// CK24: call void [[CALL07:@.+]]([[SC]]* {{[^,]+}})
-#pragma omp target map(s.s.sp[3]->a)
- { s.a++; }
-
-// Region 08
-// CK24-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE08]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE08]]{{.+}})
-// CK24-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
-// CK24-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
-
-// CK24-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
-// CK24-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
-// CK24-DAG: [[CBP0:%.+]] = bitcast i8** [[BP0]] to [[SC]]**
-// CK24-DAG: [[CP0:%.+]] = bitcast i8** [[P0]] to [[SB]]***
-// CK24-DAG: store [[SC]]* [[VAR0:%.+]], [[SC]]** [[CBP0]]
-// CK24-DAG: store [[SB]]** [[SEC0:%.+]], [[SB]]*** [[CP0]]
-// CK24-DAG: [[SEC0]] = getelementptr {{.*}}[[SC]]* [[VAR0]], i{{.+}} 0, i{{.+}} 2
-
-// CK24-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1
-// CK24-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1
-// CK24-DAG: [[CBP1:%.+]] = bitcast i8** [[BP1]] to [[SB]]***
-// CK24-DAG: [[CP1:%.+]] = bitcast i8** [[P1]] to i32**
-// CK24-DAG: store [[SB]]** [[SEC0]], [[SB]]*** [[CBP1]]
-// CK24-DAG: store i32* [[SEC1:%.+]], i32** [[CP1]]
-// CK24-DAG: [[SEC1]] = getelementptr {{.*}}[[SB]]* [[SEC11:%[^,]+]], i{{.+}} 0
-// CK24-DAG: [[SEC11]] = load [[SB]]*, [[SB]]** [[SEC111:%[^,]+]],
-// CK24-DAG: [[SEC111]] = getelementptr {{.*}}[[SC]]* [[VAR0]], i{{.+}} 0, i{{.+}} 2
-
-// CK24: call void [[CALL08:@.+]]([[SC]]* {{[^,]+}})
-#pragma omp target map(s.p->a)
- { s.a++; }
-
-// Region 09
-// CK24-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE09]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE09]]{{.+}})
-// CK24-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
-// CK24-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
-
-// CK24-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
-// CK24-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
-// CK24-DAG: [[CBP0:%.+]] = bitcast i8** [[BP0]] to [[SC]]**
-// CK24-DAG: [[CP0:%.+]] = bitcast i8** [[P0]] to [[SA]]***
-// CK24-DAG: store [[SC]]* [[VAR0:%.+]], [[SC]]** [[CBP0]]
-// CK24-DAG: store [[SA]]** [[SEC0:%.+]], [[SA]]*** [[CP0]]
-// CK24-DAG: [[SEC0]] = getelementptr {{.*}}[[SB]]* [[SEC00:[^,]+]], i{{.+}} 0, i{{.+}} 4
-// CK24-DAG: [[SEC00]] = getelementptr {{.*}}[[SC]]* [[VAR0]], i{{.+}} 0, i{{.+}} 1
-
-// CK24-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1
-// CK24-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1
-// CK24-DAG: [[CBP1:%.+]] = bitcast i8** [[BP1]] to [[SA]]***
-// CK24-DAG: [[CP1:%.+]] = bitcast i8** [[P1]] to i32**
-// CK24-DAG: store [[SA]]** [[SEC0]], [[SA]]*** [[CBP1]]
-// CK24-DAG: store i32* [[SEC1:%.+]], i32** [[CP1]]
-// CK24-DAG: [[SEC1]] = getelementptr {{.*}}[[SA]]* [[SEC11:%[^,]+]], i{{.+}} 0
-// CK24-DAG: [[SEC11]] = load [[SA]]*, [[SA]]** [[SEC111:%[^,]+]],
-// CK24-DAG: [[SEC111]] = getelementptr {{.*}}[[SB]]* [[SEC1111:[^,]+]], i{{.+}} 0, i{{.+}} 4
-// CK24-DAG: [[SEC1111]] = getelementptr {{.*}}[[SC]]* [[VAR0]], i{{.+}} 0, i{{.+}} 1
-
-// CK24: call void [[CALL09:@.+]]([[SC]]* {{[^,]+}})
-#pragma omp target map(s.s.p->a)
- { s.a++; }
-
-// Region 10
-// CK24-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE10]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE10]]{{.+}})
-// CK24-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
-// CK24-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
-
-// CK24-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
-// CK24-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
-// CK24-DAG: [[CBP0:%.+]] = bitcast i8** [[BP0]] to [[SC]]**
-// CK24-DAG: [[CP0:%.+]] = bitcast i8** [[P0]] to i32**
-// CK24-DAG: store [[SC]]* [[VAR0:%.+]], [[SC]]** [[CBP0]]
-// CK24-DAG: store i32* [[SEC0:%.+]], i32** [[CP0]]
-// CK24-DAG: [[SEC0]] = getelementptr {{.*}}[10 x i32]* [[SEC00:%[^,]+]], i{{.+}} 0, i{{.+}} 0
-// CK24-DAG: [[SEC00]] = getelementptr {{.*}}[[SA]]* [[SEC000:%[^,]+]], i{{.+}} 0, i{{.+}} 2
-// CK24-DAG: [[SEC000]] = getelementptr {{.*}}[[SB]]* [[SEC0000:%[^,]+]], i{{.+}} 0, i{{.+}} 1
-// CK24-DAG: [[SEC0000]] = getelementptr {{.*}}[[SC]]* [[VAR0]], i{{.+}} 0, i{{.+}} 1
-
-// CK24: call void [[CALL10:@.+]]([[SC]]* {{[^,]+}})
-#pragma omp target map(s.s.s.b[:2])
- { s.a++; }
-
-// Region 11
-// CK24-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE11]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE11]]{{.+}})
-// CK24-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
-// CK24-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
-
-// CK24-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
-// CK24-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
-// CK24-DAG: [[CBP0:%.+]] = bitcast i8** [[BP0]] to [[SC]]**
-// CK24-DAG: [[CP0:%.+]] = bitcast i8** [[P0]] to [[SA]]***
-// CK24-DAG: store [[SC]]* [[VAR0:%.+]], [[SC]]** [[CBP0]]
-// CK24-DAG: store [[SA]]** [[SEC0:%.+]], [[SA]]*** [[CP0]]
-// CK24-DAG: [[SEC0]] = getelementptr {{.*}}[[SB]]* [[SEC00:%[^,]+]], i{{.+}} 0, i{{.+}} 4
-// CK24-DAG: [[SEC00]] = getelementptr {{.*}}[[SC]]* [[VAR0]], i{{.+}} 0, i{{.+}} 1
-
-// CK24-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1
-// CK24-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1
-// CK24-DAG: [[CBP1:%.+]] = bitcast i8** [[BP1]] to [[SA]]***
-// CK24-DAG: [[CP1:%.+]] = bitcast i8** [[P1]] to i32**
-// CK24-DAG: store [[SA]]** [[SEC0]], [[SA]]*** [[CBP1]]
-// CK24-DAG: store i32* [[SEC1:%.+]], i32** [[CP1]]
-// CK24-DAG: [[SEC1]] = getelementptr {{.*}}[10 x i32]* [[SEC11:%[^,]+]], i{{.+}} 0, i{{.+}} 0
-// CK24-DAG: [[SEC11]] = getelementptr {{.*}}[[SA]]* [[SEC111:%[^,]+]], i{{.+}} 0, i{{.+}} 2
-// CK24-DAG: [[SEC111]] = load [[SA]]*, [[SA]]** [[SEC1111:%[^,]+]],
-// CK24-DAG: [[SEC1111]] = getelementptr {{.*}}[[SB]]* [[SEC11111:%[^,]+]], i{{.+}} 0, i{{.+}} 4
-// CK24-DAG: [[SEC11111]] = getelementptr {{.*}}[[SC]]* [[VAR0]], i{{.+}} 0, i{{.+}} 1
-
-// CK24: call void [[CALL11:@.+]]([[SC]]* {{[^,]+}})
-#pragma omp target map(s.s.p->b[:2])
- { s.a++; }
-
-// Region 12
-// CK24-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 4, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[4 x i{{.+}}]* [[SIZE12]], {{.+}}getelementptr {{.+}}[4 x i{{.+}}]* [[MTYPE12]]{{.+}})
-// CK24-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
-// CK24-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
-
-// CK24-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
-// CK24-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
-// CK24-DAG: [[CBP0:%.+]] = bitcast i8** [[BP0]] to [[SC]]**
-// CK24-DAG: [[CP0:%.+]] = bitcast i8** [[P0]] to [[SB]]***
-// CK24-DAG: store [[SC]]* [[VAR0:%.+]], [[SC]]** [[CBP0]]
-// CK24-DAG: store [[SB]]** [[SEC0:%.+]], [[SB]]*** [[CP0]]
-// CK24-DAG: [[SEC0]] = getelementptr {{.*}}[[SC]]* [[VAR0]], i{{.+}} 0, i{{.+}} 2
-
-// CK24-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1
-// CK24-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1
-// CK24-DAG: [[CBP1:%.+]] = bitcast i8** [[BP1]] to [[SB]]***
-// CK24-DAG: [[CP1:%.+]] = bitcast i8** [[P1]] to [[SA]]***
-// CK24-DAG: store [[SB]]** [[SEC0:%.+]], [[SB]]*** [[CBP1]]
-// CK24-DAG: store [[SA]]** [[SEC1:%.+]], [[SA]]*** [[CP1]]
-// CK24-DAG: [[SEC1]] = getelementptr {{.*}}[[SB]]* [[SEC11:%[^,]+]], i{{.+}} 0, i{{.+}} 4
-// CK24-DAG: [[SEC11]] = load [[SB]]*, [[SB]]** [[SEC111:%[^,]+]],
-// CK24-DAG: [[SEC111]] = getelementptr {{.*}}[[SC]]* [[VAR0]], i{{.+}} 0, i{{.+}} 2
-
-// CK24-DAG: [[BP2:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 2
-// CK24-DAG: [[P2:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 2
-// CK24-DAG: [[CBP2:%.+]] = bitcast i8** [[BP2]] to [[SA]]***
-// CK24-DAG: [[CP2:%.+]] = bitcast i8** [[P2]] to [[SA]]***
-// CK24-DAG: store [[SA]]** [[SEC1:%.+]], [[SA]]*** [[CBP2]]
-// CK24-DAG: store [[SA]]** [[SEC2:%.+]], [[SA]]*** [[CP2]]
-// CK24-DAG: [[SEC2]] = getelementptr {{.*}}[[SA]]* [[SEC22:%[^,]+]], i{{.+}} 0, i{{.+}} 1
-// CK24-DAG: [[SEC22]] = load [[SA]]*, [[SA]]** [[SEC222:%[^,]+]],
-// CK24-DAG: [[SEC222]] = getelementptr {{.*}}[[SB]]* [[SEC2222:%[^,]+]], i{{.+}} 0, i{{.+}} 4
-// CK24-DAG: [[SEC2222]] = load [[SB]]*, [[SB]]** [[SEC22222:%[^,]+]],
-// CK24-DAG: [[SEC22222]] = getelementptr {{.*}}[[SC]]* [[VAR0]], i{{.+}} 0, i{{.+}} 2
-
-// CK24-DAG: [[BP3:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 3
-// CK24-DAG: [[P3:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 3
-// CK24-DAG: [[CBP3:%.+]] = bitcast i8** [[BP3]] to [[SA]]***
-// CK24-DAG: [[CP3:%.+]] = bitcast i8** [[P3]] to i32**
-// CK24-DAG: store [[SA]]** [[SEC2]], [[SA]]*** [[CBP3]]
-// CK24-DAG: store i32* [[SEC3:%.+]], i32** [[CP3]]
-// CK24-DAG: [[SEC3]] = getelementptr {{.*}}[[SA]]* [[SEC33:%[^,]+]], i{{.+}} 0, i{{.+}} 0
-// CK24-DAG: [[SEC33]] = load [[SA]]*, [[SA]]** [[SEC333:%[^,]+]],
-// CK24-DAG: [[SEC333]] = getelementptr {{.*}}[[SA]]* [[SEC3333:%[^,]+]], i{{.+}} 0, i{{.+}} 1
-// CK24-DAG: [[SEC3333]] = load [[SA]]*, [[SA]]** [[SEC33333:%[^,]+]],
-// CK24-DAG: [[SEC33333]] = getelementptr {{.*}}[[SB]]* [[SEC333333:%[^,]+]], i{{.+}} 0, i{{.+}} 4
-// CK24-DAG: [[SEC333333]] = load [[SB]]*, [[SB]]** [[SEC3333333:%[^,]+]],
-// CK24-DAG: [[SEC3333333]] = getelementptr {{.*}}[[SC]]* [[VAR0]], i{{.+}} 0, i{{.+}} 2
-
-// CK24: call void [[CALL12:@.+]]([[SC]]* {{[^,]+}})
-#pragma omp target map(s.p->p->p->a)
- { s.a++; }
-
//
// Same thing but starting from a pointer.
//
// Region 13
-// CK24-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE13]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE13]]{{.+}})
+// CK24-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE13]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE13]]{{.+}})
// CK24-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK24-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -3720,7 +3463,7 @@ int explicit_maps_struct_fields(int a){
{ p->a++; }
// Region 14
-// CK24-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE14]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE14]]{{.+}})
+// CK24-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE14]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE14]]{{.+}})
// CK24-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK24-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -3741,7 +3484,7 @@ int explicit_maps_struct_fields(int a){
{ p->a++; }
// Region 15
-// CK24-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE15]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE15]]{{.+}})
+// CK24-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE15]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE15]]{{.+}})
// CK24-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK24-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -3763,7 +3506,7 @@ int explicit_maps_struct_fields(int a){
{ p->a++; }
// Region 16
-// CK24-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE16]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE16]]{{.+}})
+// CK24-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE16]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE16]]{{.+}})
// CK24-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK24-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -3784,7 +3527,7 @@ int explicit_maps_struct_fields(int a){
{ p->a++; }
// Region 17
-// CK24-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE17]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE17]]{{.+}})
+// CK24-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE17]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE17]]{{.+}})
// CK24-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK24-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -3815,7 +3558,7 @@ int explicit_maps_struct_fields(int a){
{ p->a++; }
// Region 18
-// CK24-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE18]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE18]]{{.+}})
+// CK24-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE18]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE18]]{{.+}})
// CK24-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK24-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -3838,7 +3581,7 @@ int explicit_maps_struct_fields(int a){
{ p->a++; }
// Region 19
-// CK24-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE19]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE19]]{{.+}})
+// CK24-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE19]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE19]]{{.+}})
// CK24-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK24-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -3873,7 +3616,7 @@ int explicit_maps_struct_fields(int a){
{ p->a++; }
// Region 20
-// CK24-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE20]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE20]]{{.+}})
+// CK24-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE20]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE20]]{{.+}})
// CK24-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK24-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -3904,7 +3647,7 @@ int explicit_maps_struct_fields(int a){
{ p->a++; }
// Region 21
-// CK24-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE21]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE21]]{{.+}})
+// CK24-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE21]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE21]]{{.+}})
// CK24-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK24-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -3937,7 +3680,7 @@ int explicit_maps_struct_fields(int a){
{ p->a++; }
// Region 22
-// CK24-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE22]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE22]]{{.+}})
+// CK24-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE22]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE22]]{{.+}})
// CK24-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK24-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -3960,7 +3703,7 @@ int explicit_maps_struct_fields(int a){
{ p->a++; }
// Region 23
-// CK24-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE23]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE23]]{{.+}})
+// CK24-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE23]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE23]]{{.+}})
// CK24-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK24-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -3994,7 +3737,7 @@ int explicit_maps_struct_fields(int a){
{ p->a++; }
// Region 24
-// CK24-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 4, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[4 x i{{.+}}]* [[SIZE24]], {{.+}}getelementptr {{.+}}[4 x i{{.+}}]* [[MTYPE24]]{{.+}})
+// CK24-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 4, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[4 x i{{.+}}]* [[SIZE24]], {{.+}}getelementptr {{.+}}[4 x i{{.+}}]* [[MTYPE24]]{{.+}})
// CK24-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK24-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -4056,17 +3799,6 @@ int explicit_maps_struct_fields(int a){
}
// CK24: define {{.+}}[[CALL01]]
-// CK24: define {{.+}}[[CALL02]]
-// CK24: define {{.+}}[[CALL03]]
-// CK24: define {{.+}}[[CALL04]]
-// CK24: define {{.+}}[[CALL05]]
-// CK24: define {{.+}}[[CALL06]]
-// CK24: define {{.+}}[[CALL07]]
-// CK24: define {{.+}}[[CALL08]]
-// CK24: define {{.+}}[[CALL09]]
-// CK24: define {{.+}}[[CALL10]]
-// CK24: define {{.+}}[[CALL11]]
-// CK24: define {{.+}}[[CALL12]]
// CK24: define {{.+}}[[CALL13]]
// CK24: define {{.+}}[[CALL14]]
// CK24: define {{.+}}[[CALL15]]
@@ -4093,10 +3825,10 @@ int explicit_maps_struct_fields(int a){
// CK25: [[CA01:%.+]] = type { i32* }
// CK25: [[SIZE00:@.+]] = private {{.*}}constant [1 x i[[Z:64|32]]] [i[[Z:64|32]] 4]
-// CK25: [[MTYPE00:@.+]] = private {{.*}}constant [1 x i32] [i32 33]
+// CK25: [[MTYPE00:@.+]] = private {{.*}}constant [1 x i64] [i64 33]
// CK25: [[SIZE01:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 4]
-// CK25: [[MTYPE01:@.+]] = private {{.*}}constant [1 x i32] [i32 33]
+// CK25: [[MTYPE01:@.+]] = private {{.*}}constant [1 x i64] [i64 33]
// CK25-LABEL: explicit_maps_with_inner_lambda
@@ -4107,7 +3839,7 @@ struct CC {
int foo(T arg) {
// Region 00
- // CK25-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE00]]{{.+}})
+ // CK25-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE00]]{{.+}})
// CK25-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK25-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -4128,7 +3860,7 @@ struct CC {
}
// Region 01
- // CK25-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE01]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE01]]{{.+}})
+ // CK25-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE01]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE01]]{{.+}})
// CK25-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK25-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -4185,16 +3917,16 @@ int explicit_maps_with_inner_lambda(int a){
// CK26: [[ST:%.+]] = type { i32, float*, i32, float* }
// CK26: [[SIZE00:@.+]] = private {{.*}}constant [2 x i[[Z:64|32]]] [i[[Z:64|32]] {{32|16}}, i[[Z:64|32]] 4]
-// CK26: [[MTYPE00:@.+]] = private {{.*}}constant [2 x i32] [i32 35, i32 35]
+// CK26: [[MTYPE00:@.+]] = private {{.*}}constant [2 x i64] [i64 35, i64 35]
// CK26: [[SIZE01:@.+]] = private {{.*}}constant [2 x i[[Z]]] [i[[Z]] {{32|16}}, i[[Z]] 4]
-// CK26: [[MTYPE01:@.+]] = private {{.*}}constant [2 x i32] [i32 35, i32 35]
+// CK26: [[MTYPE01:@.+]] = private {{.*}}constant [2 x i64] [i64 35, i64 35]
// CK26: [[SIZE02:@.+]] = private {{.*}}constant [2 x i[[Z]]] [i[[Z]] {{32|16}}, i[[Z]] 4]
-// CK26: [[MTYPE02:@.+]] = private {{.*}}constant [2 x i32] [i32 35, i32 35]
+// CK26: [[MTYPE02:@.+]] = private {{.*}}constant [2 x i64] [i64 35, i64 35]
// CK26: [[SIZE03:@.+]] = private {{.*}}constant [2 x i[[Z]]] [i[[Z]] {{32|16}}, i[[Z]] 4]
-// CK26: [[MTYPE03:@.+]] = private {{.*}}constant [2 x i32] [i32 35, i32 35]
+// CK26: [[MTYPE03:@.+]] = private {{.*}}constant [2 x i64] [i64 35, i64 35]
// CK26-LABEL: explicit_maps_with_private_class_members
@@ -4211,7 +3943,7 @@ struct CC {
#pragma omp parallel firstprivate(fA,fB) private(pA,pB)
{
// Region 00
- // CK26-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE00]]{{.+}})
+ // CK26-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE00]]{{.+}})
// CK26-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK26-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -4238,7 +3970,7 @@ struct CC {
}
// Region 01
- // CK26-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE01]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE01]]{{.+}})
+ // CK26-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE01]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE01]]{{.+}})
// CK26-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK26-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -4265,7 +3997,7 @@ struct CC {
}
// Region 02
- // CK26-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE02]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE02]]{{.+}})
+ // CK26-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE02]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE02]]{{.+}})
// CK26-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK26-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -4292,7 +4024,7 @@ struct CC {
}
// Region 01
- // CK26-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE03]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE03]]{{.+}})
+ // CK26-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE03]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE03]]{{.+}})
// CK26-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK26-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -4368,25 +4100,25 @@ int explicit_maps_with_private_class_members(){
#ifdef CK27
// CK27: [[SIZE00:@.+]] = private {{.*}}constant [1 x i[[Z:64|32]]] zeroinitializer
-// CK27: [[MTYPE00:@.+]] = private {{.*}}constant [1 x i32] [i32 32]
+// CK27: [[MTYPE00:@.+]] = private {{.*}}constant [1 x i64] [i64 32]
// CK27: [[SIZE01:@.+]] = private {{.*}}constant [1 x i[[Z]]] zeroinitializer
-// CK27: [[MTYPE01:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+// CK27: [[MTYPE01:@.+]] = private {{.*}}constant [1 x i64] [i64 35]
// CK27: [[SIZE02:@.+]] = private {{.*}}constant [1 x i[[Z]]] zeroinitializer
-// CK27: [[MTYPE02:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+// CK27: [[MTYPE02:@.+]] = private {{.*}}constant [1 x i64] [i64 35]
// CK27: [[SIZE03:@.+]] = private {{.*}}constant [1 x i[[Z]]] zeroinitializer
-// CK27: [[MTYPE03:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+// CK27: [[MTYPE03:@.+]] = private {{.*}}constant [1 x i64] [i64 35]
// CK27: [[SIZE05:@.+]] = private {{.*}}constant [1 x i[[Z]]] zeroinitializer
-// CK27: [[MTYPE05:@.+]] = private {{.*}}constant [1 x i32] [i32 32]
+// CK27: [[MTYPE05:@.+]] = private {{.*}}constant [1 x i64] [i64 32]
// CK27: [[SIZE07:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 4]
-// CK27: [[MTYPE07:@.+]] = private {{.*}}constant [1 x i32] [i32 288]
+// CK27: [[MTYPE07:@.+]] = private {{.*}}constant [1 x i64] [i64 288]
// CK27: [[SIZE09:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 40]
-// CK27: [[MTYPE09:@.+]] = private {{.*}}constant [1 x i32] [i32 161]
+// CK27: [[MTYPE09:@.+]] = private {{.*}}constant [1 x i64] [i64 161]
// CK27-LABEL: zero_size_section_and_private_maps
void zero_size_section_and_private_maps (int ii){
@@ -4395,7 +4127,7 @@ void zero_size_section_and_private_maps (int ii){
int *pa;
// Region 00
- // CK27-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE00]]{{.+}})
+ // CK27-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE00]]{{.+}})
// CK27-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK27-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -4413,7 +4145,7 @@ void zero_size_section_and_private_maps (int ii){
}
// Region 01
- // CK27-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE01]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE01]]{{.+}})
+ // CK27-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE01]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE01]]{{.+}})
// CK27-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK27-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -4434,7 +4166,7 @@ void zero_size_section_and_private_maps (int ii){
}
// Region 02
- // CK27-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE02]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE02]]{{.+}})
+ // CK27-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE02]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE02]]{{.+}})
// CK27-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK27-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -4455,7 +4187,7 @@ void zero_size_section_and_private_maps (int ii){
}
// Region 03
- // CK27-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE03]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE03]]{{.+}})
+ // CK27-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE03]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE03]]{{.+}})
// CK27-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK27-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -4480,7 +4212,7 @@ void zero_size_section_and_private_maps (int ii){
int pvtArr[10];
// Region 04
- // CK27: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 0, i8** null, i8** null, i{{64|32}}* null, i32* null)
+ // CK27: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 0, i8** null, i8** null, i{{64|32}}* null, i64* null)
// CK27: call void [[CALL04:@.+]]()
#pragma omp target private(pvtPtr)
{
@@ -4488,7 +4220,7 @@ void zero_size_section_and_private_maps (int ii){
}
// Region 05
- // CK27-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE05]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE05]]{{.+}})
+ // CK27-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE05]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE05]]{{.+}})
// CK27-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK27-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -4506,7 +4238,7 @@ void zero_size_section_and_private_maps (int ii){
}
// Region 06
- // CK27: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 0, i8** null, i8** null, i{{64|32}}* null, i32* null)
+ // CK27: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 0, i8** null, i8** null, i{{64|32}}* null, i64* null)
// CK27: call void [[CALL06:@.+]]()
#pragma omp target private(pvtScl)
{
@@ -4514,7 +4246,7 @@ void zero_size_section_and_private_maps (int ii){
}
// Region 07
- // CK27-DAG: call i32 @__tgt_target(i32 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZE07]]{{.+}}, {{.+}}[[MTYPE07]]{{.+}})
+ // CK27-DAG: call i32 @__tgt_target(i64 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZE07]]{{.+}}, {{.+}}[[MTYPE07]]{{.+}})
// CK27-DAG: [[BPGEP]] = getelementptr inbounds {{.+}}[[BPS:%[^,]+]], i32 0, i32 0
// CK27-DAG: [[PGEP]] = getelementptr inbounds {{.+}}[[PS:%[^,]+]], i32 0, i32 0
// CK27-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BPS]], i32 0, i32 0
@@ -4534,7 +4266,7 @@ void zero_size_section_and_private_maps (int ii){
}
// Region 08
- // CK27: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 0, i8** null, i8** null, i{{64|32}}* null, i32* null)
+ // CK27: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 0, i8** null, i8** null, i{{64|32}}* null, i64* null)
// CK27: call void [[CALL08:@.+]]()
#pragma omp target private(pvtArr)
{
@@ -4542,7 +4274,7 @@ void zero_size_section_and_private_maps (int ii){
}
// Region 09
- // CK27-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE09]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE09]]{{.+}})
+ // CK27-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE09]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE09]]{{.+}})
// CK27-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK27-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -4579,17 +4311,17 @@ void zero_size_section_and_private_maps (int ii){
#ifdef CK28
// CK28: [[SIZE00:@.+]] = private {{.*}}constant [1 x i[[Z:64|32]]] [i[[Z:64|32]] {{8|4}}]
-// CK28: [[MTYPE00:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+// CK28: [[MTYPE00:@.+]] = private {{.*}}constant [1 x i64] [i64 35]
// CK28: [[SIZE01:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 400]
-// CK28: [[MTYPE01:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+// CK28: [[MTYPE01:@.+]] = private {{.*}}constant [1 x i64] [i64 35]
// CK28-LABEL: explicit_maps_pointer_references
void explicit_maps_pointer_references (int *p){
int *&a = p;
// Region 00
- // CK28-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE00]]{{.+}})
+ // CK28-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE00]]{{.+}})
// CK28-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK28-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -4609,7 +4341,7 @@ void explicit_maps_pointer_references (int *p){
}
// Region 01
- // CK28-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE01]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE01]]{{.+}})
+ // CK28-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE01]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE01]]{{.+}})
// CK28-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK28-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -4645,13 +4377,13 @@ void explicit_maps_pointer_references (int *p){
// CK29: [[SSB:%.+]] = type { [[SSA]]*, [[SSA]]** }
// CK29: [[SIZE00:@.+]] = private {{.*}}constant [4 x i[[Z:64|32]]] [i[[Z:64|32]] {{8|4}}, i[[Z:64|32]] {{8|4}}, i[[Z:64|32]] {{8|4}}, i[[Z:64|32]] 80]
-// CK29: [[MTYPE00:@.+]] = private {{.*}}constant [4 x i32] [i32 35, i32 16, i32 19, i32 19]
+// CK29: [[MTYPE00:@.+]] = private {{.*}}constant [4 x i64] [i64 35, i64 16, i64 19, i64 19]
// CK29: [[SIZE01:@.+]] = private {{.*}}constant [4 x i[[Z]]] [i[[Z]] {{8|4}}, i[[Z]] {{8|4}}, i[[Z]] {{8|4}}, i[[Z]] 80]
-// CK29: [[MTYPE01:@.+]] = private {{.*}}constant [4 x i32] [i32 32, i32 19, i32 19, i32 19]
+// CK29: [[MTYPE01:@.+]] = private {{.*}}constant [4 x i64] [i64 32, i64 19, i64 19, i64 19]
// CK29: [[SIZE02:@.+]] = private {{.*}}constant [5 x i[[Z]]] [i[[Z]] {{8|4}}, i[[Z]] {{8|4}}, i[[Z]] {{8|4}}, i[[Z]] {{8|4}}, i[[Z]] 80]
-// CK29: [[MTYPE02:@.+]] = private {{.*}}constant [5 x i32] [i32 32, i32 19, i32 16, i32 19, i32 19]
+// CK29: [[MTYPE02:@.+]] = private {{.*}}constant [5 x i64] [i64 32, i64 19, i64 16, i64 19, i64 19]
struct SSA{
double *p;
@@ -4668,7 +4400,7 @@ struct SSB{
void foo() {
// Region 00
- // CK29-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 4, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[4 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[4 x i{{.+}}]* [[MTYPE00]]{{.+}})
+ // CK29-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 4, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[4 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[4 x i{{.+}}]* [[MTYPE00]]{{.+}})
// CK29-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK29-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -4715,7 +4447,7 @@ struct SSB{
}
// Region 01
- // CK29-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 4, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[4 x i{{.+}}]* [[SIZE01]], {{.+}}getelementptr {{.+}}[4 x i{{.+}}]* [[MTYPE01]]{{.+}})
+ // CK29-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 4, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[4 x i{{.+}}]* [[SIZE01]], {{.+}}getelementptr {{.+}}[4 x i{{.+}}]* [[MTYPE01]]{{.+}})
// CK29-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK29-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -4760,7 +4492,7 @@ struct SSB{
}
// Region 02
- // CK29-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 5, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[5 x i{{.+}}]* [[SIZE02]], {{.+}}getelementptr {{.+}}[5 x i{{.+}}]* [[MTYPE02]]{{.+}})
+ // CK29-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 5, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[5 x i{{.+}}]* [[SIZE02]], {{.+}}getelementptr {{.+}}[5 x i{{.+}}]* [[MTYPE02]]{{.+}})
// CK29-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK29-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
diff --git a/test/OpenMP/target_map_messages.cpp b/test/OpenMP/target_map_messages.cpp
index b9640b965d50..9ffbec472572 100644
--- a/test/OpenMP/target_map_messages.cpp
+++ b/test/OpenMP/target_map_messages.cpp
@@ -26,7 +26,14 @@ struct SA {
T d;
float e[I];
T *f;
+ int bf : 20;
void func(int arg) {
+ #pragma omp target
+ {
+ a = 0.0;
+ func(arg);
+ bf = 20;
+ }
#pragma omp target map(arg,a,d)
{}
#pragma omp target map(arg[2:2],a,d) // expected-error {{subscripted value is not an array or pointer}}
@@ -267,8 +274,13 @@ void SAclient(int arg) {
{}
#pragma omp target map((p+1)->A) // expected-error {{expected expression containing only member accesses and/or array sections based on named variables}}
{}
- #pragma omp target map(u.B) // expected-error {{mapped storage cannot be derived from a union}}
+ #pragma omp target map(u.B) // expected-error {{mapping of union members is not allowed}}
{}
+ #pragma omp target
+ {
+ u.B = 0;
+ r.S.foo();
+ }
#pragma omp target data map(to: r.C) //expected-note {{used here}}
{
@@ -319,8 +331,8 @@ class S2 {
public:
S2():a(0) { }
S2(S2 &s2):a(s2.a) { }
- static float S2s; // expected-note 4 {{mappable type cannot contain static members}}
- static const float S2sc; // expected-note 4 {{mappable type cannot contain static members}}
+ static float S2s;
+ static const float S2sc;
};
const float S2::S2sc = 0;
const S2 b;
@@ -353,7 +365,7 @@ template <class T>
struct S6;
template<>
-struct S6<int> // expected-note {{mappable type cannot be polymorphic}}
+struct S6<int>
{
virtual void foo();
};
@@ -420,8 +432,8 @@ T tmain(T argc) {
#pragma omp target data map(tofrom: argc > 0 ? x : y) // expected-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}}
#pragma omp target data map(argc)
#pragma omp target data map(S1) // expected-error {{'S1' does not refer to a value}}
-#pragma omp target data map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} expected-error 2 {{type 'S2' is not mappable to target}}
-#pragma omp target data map(ba) // expected-error 2 {{type 'S2' is not mappable to target}}
+#pragma omp target data map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}}
+#pragma omp target data map(ba)
#pragma omp target data map(ca)
#pragma omp target data map(da)
#pragma omp target data map(S2::S2s)
@@ -454,6 +466,25 @@ T tmain(T argc) {
return 0;
}
+struct SA1{
+ int a;
+ struct SA1 *p;
+ int b[10];
+};
+struct SB1{
+ int a;
+ struct SA1 s;
+ struct SA1 sa[10];
+ struct SA1 *sp[10];
+ struct SA1 *p;
+};
+struct SC1{
+ int a;
+ struct SB1 s;
+ struct SB1 *p;
+ int b[10];
+};
+
int main(int argc, char **argv) {
const int d = 5;
const int da[5] = { 0 };
@@ -467,6 +498,8 @@ int main(int argc, char **argv) {
int y;
int to, tofrom, always;
const int (&l)[5] = da;
+ SC1 s;
+ SC1 *p;
#pragma omp target data map // expected-error {{expected '(' after 'map'}} expected-error {{expected at least one 'map' or 'use_device_ptr' clause for '#pragma omp target data'}}
#pragma omp target data map( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}}
#pragma omp target data map() // expected-error {{expected expression}}
@@ -489,9 +522,9 @@ int main(int argc, char **argv) {
#pragma omp target data map(tofrom: argc > 0 ? argv[1] : argv[2]) // expected-error {{xpected expression containing only member accesses and/or array sections based on named variables}}
#pragma omp target data map(argc)
#pragma omp target data map(S1) // expected-error {{'S1' does not refer to a value}}
-#pragma omp target data map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} expected-error 2 {{type 'S2' is not mappable to target}}
+#pragma omp target data map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}}
#pragma omp target data map(argv[1])
-#pragma omp target data map(ba) // expected-error 2 {{type 'S2' is not mappable to target}}
+#pragma omp target data map(ba)
#pragma omp target data map(ca)
#pragma omp target data map(da)
#pragma omp target data map(S2::S2s)
@@ -525,8 +558,55 @@ int main(int argc, char **argv) {
{}
#pragma omp target firstprivate(j) map(j) // expected-error {{firstprivate variable cannot be in a map clause in '#pragma omp target' directive}} expected-note {{defined as firstprivate}}
{}
-#pragma omp target map(m) // expected-error {{type 'S6<int>' is not mappable to target}}
- {}
+#pragma omp target map(m)
+ {}
+// expected-note@+1 {{used here}}
+#pragma omp target map(s.s.s)
+// expected-error@+1 {{variable already marked as mapped in current construct}}
+ { s.a++; }
+// expected-note@+1 {{used here}}
+#pragma omp target map(s.s.s.a)
+// expected-error@+1 {{variable already marked as mapped in current construct}}
+ { s.a++; }
+// expected-note@+1 {{used here}}
+#pragma omp target map(s.b[:5])
+// expected-error@+1 {{variable already marked as mapped in current construct}}
+ { s.a++; }
+// expected-note@+1 {{used here}}
+#pragma omp target map(s.p[:5])
+// expected-error@+1 {{variable already marked as mapped in current construct}}
+ { s.a++; }
+// expected-note@+1 {{used here}}
+#pragma omp target map(s.s.sa[3].a)
+// expected-error@+1 {{variable already marked as mapped in current construct}}
+ { s.a++; }
+// expected-note@+1 {{used here}}
+#pragma omp target map(s.s.sp[3]->a)
+// expected-error@+1 {{variable already marked as mapped in current construct}}
+ { s.a++; }
+// expected-note@+1 {{used here}}
+#pragma omp target map(s.p->a)
+// expected-error@+1 {{variable already marked as mapped in current construct}}
+ { s.a++; }
+// expected-note@+1 {{used here}}
+#pragma omp target map(s.s.p->a)
+// expected-error@+1 {{variable already marked as mapped in current construct}}
+ { s.a++; }
+// expected-note@+1 {{used here}}
+#pragma omp target map(s.s.s.b[:2])
+// expected-error@+1 {{variable already marked as mapped in current construct}}
+ { s.a++; }
+// expected-note@+1 {{used here}}
+#pragma omp target map(s.s.p->b[:2])
+// expected-error@+1 {{variable already marked as mapped in current construct}}
+ { s.a++; }
+// expected-note@+1 {{used here}}
+#pragma omp target map(s.p->p->p->a)
+// expected-error@+1 {{variable already marked as mapped in current construct}}
+ { s.a++; }
+#pragma omp target map(s.s.s.b[:2])
+ { s.s.s.b[0]++; }
+
return tmain<int, 3>(argc)+tmain<from, 4>(argc); // expected-note {{in instantiation of function template specialization 'tmain<int, 3>' requested here}} expected-note {{in instantiation of function template specialization 'tmain<int, 4>' requested here}}
}
#endif
diff --git a/test/OpenMP/target_messages.cpp b/test/OpenMP/target_messages.cpp
index 6f79f44627fa..77d808493789 100644
--- a/test/OpenMP/target_messages.cpp
+++ b/test/OpenMP/target_messages.cpp
@@ -4,6 +4,8 @@
// RUN: not %clang_cc1 -fopenmp -std=c++11 -triple nvptx64-nvidia-cuda -o - %s 2>&1 | FileCheck --check-prefix CHECK-UNSUPPORTED-HOST-TARGET %s
// RUN: not %clang_cc1 -fopenmp -std=c++11 -triple nvptx-nvidia-cuda -o - %s 2>&1 | FileCheck --check-prefix CHECK-UNSUPPORTED-HOST-TARGET %s
// CHECK-UNSUPPORTED-HOST-TARGET: error: The target '{{nvptx64-nvidia-cuda|nvptx-nvidia-cuda}}' is not a supported OpenMP host target.
+// RUN: not %clang_cc1 -fopenmp -std=c++11 -fopenmp-targets=hexagon-linux-gnu -o - %s 2>&1 | FileCheck --check-prefix CHECK-UNSUPPORTED-DEVICE-TARGET %s
+// CHECK-UNSUPPORTED-DEVICE-TARGET: OpenMP target is invalid: 'hexagon-linux-gnu'
void foo() {
}
diff --git a/test/OpenMP/target_parallel_codegen.cpp b/test/OpenMP/target_parallel_codegen.cpp
index 3063ab16abc8..b9d00da02f45 100644
--- a/test/OpenMP/target_parallel_codegen.cpp
+++ b/test/OpenMP/target_parallel_codegen.cpp
@@ -39,15 +39,15 @@
// sizes.
// CHECK-DAG: [[SIZET2:@.+]] = private unnamed_addr constant [1 x i{{32|64}}] [i[[SZ:32|64]] 2]
-// CHECK-DAG: [[MAPT2:@.+]] = private unnamed_addr constant [1 x i32] [i32 288]
+// CHECK-DAG: [[MAPT2:@.+]] = private unnamed_addr constant [1 x i64] [i64 288]
// CHECK-DAG: [[SIZET3:@.+]] = private unnamed_addr constant [2 x i[[SZ]]] [i[[SZ]] 4, i[[SZ]] 2]
-// CHECK-DAG: [[MAPT3:@.+]] = private unnamed_addr constant [2 x i32] [i32 288, i32 288]
-// CHECK-DAG: [[MAPT4:@.+]] = private unnamed_addr constant [9 x i32] [i32 288, i32 35, i32 288, i32 35, i32 35, i32 288, i32 288, i32 35, i32 35]
+// CHECK-DAG: [[MAPT3:@.+]] = private unnamed_addr constant [2 x i64] [i64 288, i64 288]
+// CHECK-DAG: [[MAPT4:@.+]] = private unnamed_addr constant [9 x i64] [i64 288, i64 547, i64 288, i64 547, i64 547, i64 288, i64 288, i64 547, i64 547]
// CHECK-DAG: [[SIZET5:@.+]] = private unnamed_addr constant [3 x i[[SZ]]] [i[[SZ]] 4, i[[SZ]] 2, i[[SZ]] 40]
-// CHECK-DAG: [[MAPT5:@.+]] = private unnamed_addr constant [3 x i32] [i32 288, i32 288, i32 35]
+// CHECK-DAG: [[MAPT5:@.+]] = private unnamed_addr constant [3 x i64] [i64 288, i64 288, i64 547]
// CHECK-DAG: [[SIZET6:@.+]] = private unnamed_addr constant [4 x i[[SZ]]] [i[[SZ]] 4, i[[SZ]] 2, i[[SZ]] 1, i[[SZ]] 40]
-// CHECK-DAG: [[MAPT6:@.+]] = private unnamed_addr constant [4 x i32] [i32 288, i32 288, i32 288, i32 35]
-// CHECK-DAG: [[MAPT7:@.+]] = private unnamed_addr constant [5 x i32] [i32 35, i32 288, i32 288, i32 288, i32 35]
+// CHECK-DAG: [[MAPT6:@.+]] = private unnamed_addr constant [4 x i64] [i64 288, i64 288, i64 288, i64 547]
+// CHECK-DAG: [[MAPT7:@.+]] = private unnamed_addr constant [5 x i64] [i64 547, i64 288, i64 288, i64 288, i64 547]
// CHECK-DAG: @{{.*}} = private constant i8 0
// CHECK-DAG: @{{.*}} = private constant i8 0
// CHECK-DAG: @{{.*}} = private constant i8 0
@@ -93,30 +93,24 @@ int foo(int n) {
double cn[5][n];
TT<long long, char> d;
- // CHECK: [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 0, i8** null, i8** null, i[[SZ]]* null, i32* null, i32 1, i32 0)
- // CHECK: store i32 [[RET]], i32* [[RHV:%.+]], align 4
- // CHECK: [[RET2:%.+]] = load i32, i32* [[RHV]], align 4
- // CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+ // CHECK: [[RET:%.+]] = call i32 @__tgt_target_teams_nowait(i64 -1, i8* @{{[^,]+}}, i32 0, i8** null, i8** null, i[[SZ]]* null, i64* null, i32 1, i32 0)
+ // CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
// CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:[^,]+]], label %[[END:[^,]+]]
// CHECK: [[FAIL]]
// CHECK: call void [[HVT0:@.+]]()
// CHECK-NEXT: br label %[[END]]
// CHECK: [[END]]
- #pragma omp target parallel
+ #pragma omp target parallel nowait
{
}
- // CHECK: store i32 0, i32* [[RHV:%.+]], align 4
- // CHECK: store i32 -1, i32* [[RHV]], align 4
- // CHECK: [[RET2:%.+]] = load i32, i32* [[RHV]], align 4
- // CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
// CHECK: call void [[HVT1:@.+]](i[[SZ]] {{[^,]+}})
#pragma omp target parallel if(target: 0)
{
a += 1;
}
- // CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 1, i8** [[BP:%[^,]+]], i8** [[P:%[^,]+]], i[[SZ]]* getelementptr inbounds ([1 x i[[SZ]]], [1 x i[[SZ]]]* [[SIZET2]], i32 0, i32 0), i32* getelementptr inbounds ([1 x i32], [1 x i32]* [[MAPT2]], i32 0, i32 0), i32 1, i32 0)
+ // CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 1, i8** [[BP:%[^,]+]], i8** [[P:%[^,]+]], i[[SZ]]* getelementptr inbounds ([1 x i[[SZ]]], [1 x i[[SZ]]]* [[SIZET2]], i32 0, i32 0), i64* getelementptr inbounds ([1 x i64], [1 x i64]* [[MAPT2]], i32 0, i32 0), i32 1, i32 0)
// CHECK-DAG: [[BP]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[BPR:%[^,]+]], i32 0, i32 0
// CHECK-DAG: [[P]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[PR:%[^,]+]], i32 0, i32 0
// CHECK-DAG: [[BPADDR0:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[BPR]], i32 0, i32 [[IDX0:[0-9]+]]
@@ -126,9 +120,7 @@ int foo(int n) {
// CHECK-DAG: store i[[SZ]] [[VAL0:%.+]], i[[SZ]]* [[CBPADDR0]],
// CHECK-DAG: store i[[SZ]] [[VAL0]], i[[SZ]]* [[CPADDR0]],
- // CHECK: store i32 [[RET]], i32* [[RHV:%.+]], align 4
- // CHECK: [[RET2:%.+]] = load i32, i32* [[RHV]], align 4
- // CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+ // CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
// CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:[^,]+]], label %[[END:[^,]+]]
// CHECK: [[FAIL]]
// CHECK: call void [[HVT2:@.+]](i[[SZ]] {{[^,]+}})
@@ -142,7 +134,7 @@ int foo(int n) {
// CHECK: [[IF:%.+]] = icmp sgt i32 {{[^,]+}}, 10
// CHECK: br i1 [[IF]], label %[[IFTHEN:[^,]+]], label %[[IFELSE:[^,]+]]
// CHECK: [[IFTHEN]]
- // CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 2, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* getelementptr inbounds ([2 x i[[SZ]]], [2 x i[[SZ]]]* [[SIZET3]], i32 0, i32 0), i32* getelementptr inbounds ([2 x i32], [2 x i32]* [[MAPT3]], i32 0, i32 0), i32 1, i32 0)
+ // CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 2, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* getelementptr inbounds ([2 x i[[SZ]]], [2 x i[[SZ]]]* [[SIZET3]], i32 0, i32 0), i64* getelementptr inbounds ([2 x i64], [2 x i64]* [[MAPT3]], i32 0, i32 0), i32 1, i32 0)
// CHECK-DAG: [[BPR]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[BP:%[^,]+]], i32 0, i32 0
// CHECK-DAG: [[PR]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[P:%[^,]+]], i32 0, i32 0
@@ -159,21 +151,18 @@ int foo(int n) {
// CHECK-DAG: [[CPADDR1:%.+]] = bitcast i8** [[PADDR1]] to i[[SZ]]*
// CHECK-DAG: store i[[SZ]] [[VAL1:%.+]], i[[SZ]]* [[CBPADDR1]],
// CHECK-DAG: store i[[SZ]] [[VAL1]], i[[SZ]]* [[CPADDR1]],
- // CHECK: store i32 [[RET]], i32* [[RHV:%.+]], align 4
- // CHECK-NEXT: br label %[[IFEND:.+]]
-
- // CHECK: [[IFELSE]]
- // CHECK: store i32 -1, i32* [[RHV]], align 4
- // CHECK-NEXT: br label %[[IFEND:.+]]
-
- // CHECK: [[IFEND]]
- // CHECK: [[RET2:%.+]] = load i32, i32* [[RHV]], align 4
- // CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+ // CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
// CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
// CHECK: [[FAIL]]
// CHECK: call void [[HVT3:@.+]]({{[^,]+}}, {{[^,]+}})
// CHECK-NEXT: br label %[[END]]
// CHECK: [[END]]
+ // CHECK-NEXT: br label %[[IFEND:.+]]
+ // CHECK: [[IFELSE]]
+ // CHECK: call void [[HVT3]]({{[^,]+}}, {{[^,]+}})
+ // CHECK-NEXT: br label %[[IFEND]]
+ // CHECK: [[IFEND]]
+
#pragma omp target parallel if(target: n>10)
{
a += 1;
@@ -197,7 +186,7 @@ int foo(int n) {
// CHECK: [[IF:%.+]] = icmp sgt i32 {{[^,]+}}, 20
// CHECK: br i1 [[IF]], label %[[TRY:[^,]+]], label %[[FAIL:[^,]+]]
// CHECK: [[TRY]]
- // CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 9, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* [[SR:%[^,]+]], i32* getelementptr inbounds ([9 x i32], [9 x i32]* [[MAPT4]], i32 0, i32 0), i32 1, i32 0)
+ // CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 9, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* [[SR:%[^,]+]], i64* getelementptr inbounds ([9 x i64], [9 x i64]* [[MAPT4]], i32 0, i32 0), i32 1, i32 0)
// CHECK-DAG: [[BPR]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP:%[^,]+]], i32 0, i32 0
// CHECK-DAG: [[PR]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P:%[^,]+]], i32 0, i32 0
// CHECK-DAG: [[SR]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S:%[^,]+]], i32 0, i32 0
@@ -286,9 +275,7 @@ int foo(int n) {
// CHECK-DAG: [[CPADDR8]] = bitcast i8** {{%[^,]+}} to [[TT]]**
// CHECK-DAG: store i[[SZ]] {{12|16}}, i[[SZ]]* {{%[^,]+}}
- // CHECK: store i32 [[RET]], i32* [[RHV:%.+]], align 4
- // CHECK: [[RET2:%.+]] = load i32, i32* [[RHV]], align 4
- // CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+ // CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
// CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:[^,]+]], label %[[END:[^,]+]]
// CHECK: [[FAIL]]
@@ -441,7 +428,7 @@ int foo(int n) {
// CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* [[DEF_LOC]], i32 9, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i[[SZ]], [10 x float]*, i[[SZ]], float*, [5 x [10 x double]]*, i[[SZ]], i[[SZ]], double*, [[TT]]*)* [[OMP_OUTLINED4:@.+]] to void (i32*, i32*, ...)*), i[[SZ]] [[REF_A]], [10 x float]* [[REF_B]], i[[SZ]] [[VAL_VLA1]], float* [[REF_BN]], [5 x [10 x double]]* [[REF_C]], i[[SZ]] [[VAL_VLA2]], i[[SZ]] [[VAL_VLA3]], double* [[REF_CN]], [[TT]]* [[REF_D]])
//
//
-// CHECK: define internal {{.*}}void [[OMP_OUTLINED4]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i[[SZ]] %{{.+}}, [10 x float]* {{.+}}, i[[SZ]] %{{.+}}, float* %{{.+}}, [5 x [10 x double]]* {{.+}}, i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, double* %{{.+}}, [[TT]]* {{.+}})
+// CHECK: define internal {{.*}}void [[OMP_OUTLINED4]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i[[SZ]] %{{.+}}, [10 x float]* {{.+}}, i[[SZ]] %{{.+}}, float* {{.+}}, [5 x [10 x double]]* {{.+}}, i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, double* {{.+}}, [[TT]]* {{.+}})
// To reduce complexity, we're only going as far as validating the signature of the outlined parallel function.
template<typename tx>
@@ -533,7 +520,7 @@ int bar(int n){
// CHECK: [[IF:%.+]] = icmp sgt i32 {{[^,]+}}, 60
// CHECK: br i1 [[IF]], label %[[TRY:[^,]+]], label %[[FAIL:[^,]+]]
// CHECK: [[TRY]]
-// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 5, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* [[SR:%[^,]+]], i32* getelementptr inbounds ([5 x i32], [5 x i32]* [[MAPT7]], i32 0, i32 0), i32 1, i32 0)
+// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 5, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* [[SR:%[^,]+]], i64* getelementptr inbounds ([5 x i64], [5 x i64]* [[MAPT7]], i32 0, i32 0), i32 1, i32 0)
// CHECK-DAG: [[BPR]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[BP:%.+]], i32 0, i32 0
// CHECK-DAG: [[PR]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[P:%.+]], i32 0, i32 0
// CHECK-DAG: [[SR]] = getelementptr inbounds [5 x i[[SZ]]], [5 x i[[SZ]]]* [[S:%.+]], i32 0, i32 0
@@ -582,9 +569,7 @@ int bar(int n){
// CHECK-DAG: [[CPADDR4]] = bitcast i8** {{%[^,]+}} to i16**
// CHECK-DAG: store i[[SZ]] [[CSIZE]], i[[SZ]]* {{%[^,]+}}
-// CHECK: store i32 [[RET]], i32* [[RHV:%.+]], align 4
-// CHECK: [[RET2:%.+]] = load i32, i32* [[RHV]], align 4
-// CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+// CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
// CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:[^,]+]], label %[[END:[^,]+]]
// CHECK: [[FAIL]]
@@ -598,7 +583,7 @@ int bar(int n){
// CHECK: [[IF:%.+]] = icmp sgt i32 {{[^,]+}}, 50
// CHECK: br i1 [[IF]], label %[[IFTHEN:[^,]+]], label %[[IFELSE:[^,]+]]
// CHECK: [[IFTHEN]]
-// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 4, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* getelementptr inbounds ([4 x i[[SZ]]], [4 x i[[SZ]]]* [[SIZET6]], i32 0, i32 0), i32* getelementptr inbounds ([4 x i32], [4 x i32]* [[MAPT6]], i32 0, i32 0), i32 1, i32 0)
+// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 4, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* getelementptr inbounds ([4 x i[[SZ]]], [4 x i[[SZ]]]* [[SIZET6]], i32 0, i32 0), i64* getelementptr inbounds ([4 x i64], [4 x i64]* [[MAPT6]], i32 0, i32 0), i32 1, i32 0)
// CHECK-DAG: [[BPR]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[BP:%.+]], i32 0, i32 0
// CHECK-DAG: [[PR]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[P:%.+]], i32 0, i32 0
@@ -630,21 +615,17 @@ int bar(int n){
// CHECK-DAG: store [10 x i32]* [[VAL3:%.+]], [10 x i32]** [[CBPADDR3]],
// CHECK-DAG: store [10 x i32]* [[VAL3]], [10 x i32]** [[CPADDR3]],
-// CHECK: store i32 [[RET]], i32* [[RHV:%.+]], align 4
-// CHECK-NEXT: br label %[[IFEND:.+]]
-
-// CHECK: [[IFELSE]]
-// CHECK: store i32 -1, i32* [[RHV]], align 4
-// CHECK-NEXT: br label %[[IFEND:.+]]
-
-// CHECK: [[IFEND]]
-// CHECK: [[RET2:%.+]] = load i32, i32* [[RHV]], align 4
-// CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+// CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
// CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
// CHECK: [[FAIL]]
// CHECK: call void [[HVT6:@.+]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}})
// CHECK-NEXT: br label %[[END]]
// CHECK: [[END]]
+// CHECK-NEXT: br label %[[IFEND:.+]]
+// CHECK: [[IFELSE]]
+// CHECK: call void [[HVT6]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}})
+// CHECK-NEXT: br label %[[IFEND]]
+// CHECK: [[IFEND]]
//
// CHECK: define {{.*}}[[FTEMPLATE]]
@@ -652,7 +633,7 @@ int bar(int n){
// CHECK: [[IF:%.+]] = icmp sgt i32 {{[^,]+}}, 40
// CHECK: br i1 [[IF]], label %[[IFTHEN:[^,]+]], label %[[IFELSE:[^,]+]]
// CHECK: [[IFTHEN]]
-// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 3, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* getelementptr inbounds ([3 x i[[SZ]]], [3 x i[[SZ]]]* [[SIZET5]], i32 0, i32 0), i32* getelementptr inbounds ([3 x i32], [3 x i32]* [[MAPT5]], i32 0, i32 0), i32 1, i32 0)
+// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 3, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* getelementptr inbounds ([3 x i[[SZ]]], [3 x i[[SZ]]]* [[SIZET5]], i32 0, i32 0), i64* getelementptr inbounds ([3 x i64], [3 x i64]* [[MAPT5]], i32 0, i32 0), i32 1, i32 0)
// CHECK-DAG: [[BPR]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BP:%.+]], i32 0, i32 0
// CHECK-DAG: [[PR]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[P:%.+]], i32 0, i32 0
@@ -677,23 +658,17 @@ int bar(int n){
// CHECK-DAG: store [10 x i32]* [[VAL2:%.+]], [10 x i32]** [[CBPADDR2]],
// CHECK-DAG: store [10 x i32]* [[VAL2]], [10 x i32]** [[CPADDR2]],
-// CHECK: store i32 [[RET]], i32* [[RHV:%.+]], align 4
-// CHECK-NEXT: br label %[[IFEND:.+]]
-
-// CHECK: [[IFELSE]]
-// CHECK: store i32 -1, i32* [[RHV]], align 4
-// CHECK-NEXT: br label %[[IFEND:.+]]
-
-// CHECK: [[IFEND]]
-// CHECK: [[RET2:%.+]] = load i32, i32* [[RHV]], align 4
-// CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+// CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
// CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
// CHECK: [[FAIL]]
// CHECK: call void [[HVT5:@.+]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}})
// CHECK-NEXT: br label %[[END]]
// CHECK: [[END]]
-
-
+// CHECK-NEXT: br label %[[IFEND:.+]]
+// CHECK: [[IFELSE]]
+// CHECK: call void [[HVT:@.+]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}})
+// CHECK-NEXT: br label %[[IFEND]]
+// CHECK: [[IFEND]]
// Check that the offloading functions are emitted and that the arguments are
// correct and loaded correctly for the target regions of the callees of bar().
@@ -728,7 +703,7 @@ int bar(int n){
// CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* [[DEF_LOC]], i32 5, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, [[S1]]*, i[[SZ]], i[[SZ]], i[[SZ]], i16*)* [[OMP_OUTLINED5:@.+]] to void (i32*, i32*, ...)*), [[S1]]* [[REF_THIS]], i[[SZ]] [[REF_B]], i[[SZ]] [[VAL_VLA1]], i[[SZ]] [[VAL_VLA2]], i16* [[REF_C]])
//
//
-// CHECK: define internal {{.*}}void [[OMP_OUTLINED5]](i32* noalias %.global_tid., i32* noalias %.bound_tid., [[S1]]* %{{.+}}, i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, i16* %{{.+}})
+// CHECK: define internal {{.*}}void [[OMP_OUTLINED5]](i32* noalias %.global_tid., i32* noalias %.bound_tid., [[S1]]* %{{.+}}, i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, i16* {{.+}})
// To reduce complexity, we're only going as far as validating the signature of the outlined parallel function.
diff --git a/test/OpenMP/target_parallel_codegen_registration.cpp b/test/OpenMP/target_parallel_codegen_registration.cpp
index 2511bc4c9d3c..d2cb1ec6f778 100644
--- a/test/OpenMP/target_parallel_codegen_registration.cpp
+++ b/test/OpenMP/target_parallel_codegen_registration.cpp
@@ -63,40 +63,40 @@
// CHECK-DAG: {{@.+}} = private constant i8 0
// TCHECK-NOT: {{@.+}} = private constant i8 0
// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
-// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
// CHECK-DAG: {{@.+}} = private constant i8 0
// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
-// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
// CHECK-DAG: {{@.+}} = private constant i8 0
// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
-// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
// CHECK-DAG: {{@.+}} = private constant i8 0
// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
-// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
// CHECK-DAG: {{@.+}} = private constant i8 0
// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
-// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
// CHECK-DAG: {{@.+}} = private constant i8 0
// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
-// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
// CHECK-DAG: {{@.+}} = private constant i8 0
// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
-// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
// CHECK-DAG: {{@.+}} = private constant i8 0
// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
-// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
// CHECK-DAG: {{@.+}} = private constant i8 0
// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
-// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
// CHECK-DAG: {{@.+}} = private constant i8 0
// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
-// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
// CHECK-DAG: {{@.+}} = private constant i8 0
// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
-// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
// CHECK-DAG: {{@.+}} = private constant i8 0
// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
-// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
// CHECK-NTARGET-NOT: private constant i8 0
// CHECK-NTARGET-NOT: private unnamed_addr constant [1 x i
diff --git a/test/OpenMP/target_parallel_debug_codegen.cpp b/test/OpenMP/target_parallel_debug_codegen.cpp
new file mode 100644
index 000000000000..385f7a29cb8f
--- /dev/null
+++ b/test/OpenMP/target_parallel_debug_codegen.cpp
@@ -0,0 +1,123 @@
+// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc
+// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - -debug-info-kind=limited | FileCheck %s
+// expected-no-diagnostics
+
+int main() {
+ /* int(*b)[a]; */
+ /* int *(**c)[a]; */
+ bool bb;
+ int a;
+ int b[10][10];
+ int c[10][10][10];
+#pragma omp target parallel firstprivate(a, b) map(tofrom \
+ : c) map(tofrom \
+ : bb) if (a)
+ {
+ int &f = c[1][1][1];
+ int &g = a;
+ int &h = b[1][1];
+ int d = 15;
+ a = 5;
+ b[0][a] = 10;
+ c[0][0][a] = 11;
+ b[0][a] = c[0][0][a];
+ bb |= b[0][a];
+ }
+#pragma omp target parallel firstprivate(a) map(tofrom \
+ : c, b) map(to \
+ : bb)
+ {
+ int &f = c[1][1][1];
+ int &g = a;
+ int &h = b[1][1];
+ int d = 15;
+ a = 5;
+ b[0][a] = 10;
+ c[0][0][a] = 11;
+ b[0][a] = c[0][0][a];
+ d = bb;
+ }
+#pragma omp target parallel map(tofrom \
+ : a, c, b) map(from \
+ : bb)
+ {
+ int &f = c[1][1][1];
+ int &g = a;
+ int &h = b[1][1];
+ int d = 15;
+ a = 5;
+ b[0][a] = 10;
+ c[0][0][a] = 11;
+ b[0][a] = c[0][0][a];
+ bb = b[0][a];
+ }
+ return 0;
+}
+
+// CHECK: define internal void @__omp_offloading{{[^(]+}}([10 x [10 x [10 x i32]]] addrspace(1)* {{[^,]+}}, i32 {{[^,]+}}, [10 x [10 x i32]]* {{[^,]+}}, i8 addrspace(1)* noalias{{[^,]+}}, i1 {{[^)]+}})
+// CHECK: addrspacecast [10 x [10 x [10 x i32]]] addrspace(1)* %{{.+}} to [10 x [10 x [10 x i32]]]*
+// CHECK: call void [[NONDEBUG_WRAPPER:.+]](i32* {{[^,]+}}, i32* {{[^,]+}}, [10 x [10 x [10 x i32]]]* {{[^,]+}}, i64 {{[^,]+}}, [10 x [10 x i32]]* {{[^,]+}}, i8* {{[^)]+}})
+
+// CHECK: define internal void [[DEBUG_PARALLEL:@.+]](i32* {{[^,]+}}, i32* {{[^,]+}}, [10 x [10 x [10 x i32]]] addrspace(1)* noalias{{[^,]+}}, i32 {{[^,]+}}, [10 x [10 x i32]]* noalias{{[^,]+}}, i8 addrspace(1)* noalias{{[^)]+}})
+// CHECK: addrspacecast [10 x [10 x [10 x i32]]] addrspace(1)* %{{.+}} to [10 x [10 x [10 x i32]]]*
+
+// CHECK: define internal void [[NONDEBUG_WRAPPER]](i32* {{[^,]+}}, i32* {{[^,]+}}, [10 x [10 x [10 x i32]]]* dereferenceable{{[^,]+}}, i64 {{[^,]+}}, [10 x [10 x i32]]* dereferenceable{{[^,]+}}, i8* dereferenceable{{[^)]+}})
+// CHECK: addrspacecast [10 x [10 x [10 x i32]]]* %{{.+}} to [10 x [10 x [10 x i32]]] addrspace(1)*
+// CHECK: call void [[DEBUG_PARALLEL]](i32* {{[^,]+}}, i32* {{[^,]+}}, [10 x [10 x [10 x i32]]] addrspace(1)* {{[^,]+}}, i32 {{[^,]+}}, [10 x [10 x i32]]* {{[^,]+}}, i8 addrspace(1)* {{[^)]+}})
+
+// CHECK: define void @__omp_offloading_{{[^(]+}}([10 x [10 x [10 x i32]]]* dereferenceable{{[^,]+}}, i64 {{[^,]+}}, [10 x [10 x i32]]* dereferenceable{{[^,]+}}, i8* dereferenceable{{[^)]+}})
+// CHECK: addrspacecast [10 x [10 x [10 x i32]]]* %{{.+}} to [10 x [10 x [10 x i32]]] addrspace(1)*
+// CHECK: call void @__omp_offloading_{{[^(]+}}([10 x [10 x [10 x i32]]] addrspace(1)* {{[^,]+}}, i32 {{[^,]+}}, [10 x [10 x i32]]* {{[^,]+}}, i8 addrspace(1)* {{[^)]+}})
+
+// CHECK: define internal void @__omp_offloading_{{[^(]+}}([10 x [10 x [10 x i32]]] addrspace(1)* noalias{{[^,]+}}, i32 {{[^,]+}}, [10 x [10 x i32]] addrspace(1)* noalias{{[^,]+}}, i8 addrspace(1)* noalias{{[^)]+}})
+// CHECK: addrspacecast [10 x [10 x [10 x i32]]] addrspace(1)* %{{.+}} to [10 x [10 x [10 x i32]]]*
+// CHECK: addrspacecast [10 x [10 x i32]] addrspace(1)* %{{.+}} to [10 x [10 x i32]]*
+// CHECK: call void [[NONDEBUG_WRAPPER:.+]](i32* {{[^,]+}}, i32* {{[^,]+}}, [10 x [10 x [10 x i32]]]* {{[^,]+}}, i64 {{[^,]+}}, [10 x [10 x i32]]* {{[^,]+}}, i8* {{[^)]+}})
+
+// CHECK: define internal void [[DEBUG_PARALLEL:@.+]](i32* {{[^,]+}}, i32* {{[^,]+}}, [10 x [10 x [10 x i32]]] addrspace(1)* noalias{{[^,]+}}, i32 {{[^,]+}}, [10 x [10 x i32]] addrspace(1)* noalias{{[^,]+}}, i8 addrspace(1)* {{[^)]+}})
+// CHECK: addrspacecast [10 x [10 x [10 x i32]]] addrspace(1)* %{{.+}} to [10 x [10 x [10 x i32]]]*
+// CHECK: addrspacecast [10 x [10 x i32]] addrspace(1)* %{{.+}} to [10 x [10 x i32]]*
+
+// CHECK: define internal void [[NONDEBUG_WRAPPER]](i32* {{[^,]+}}, i32* {{[^,]+}}, [10 x [10 x [10 x i32]]]* dereferenceable{{[^,]+}}, i64 {{[^,]+}}, [10 x [10 x i32]]* dereferenceable{{[^,]+}}, i8* dereferenceable{{[^)]+}})
+// CHECK: addrspacecast [10 x [10 x [10 x i32]]]* %{{.+}} to [10 x [10 x [10 x i32]]] addrspace(1)*
+// CHECK: addrspacecast [10 x [10 x i32]]* %{{.+}} to [10 x [10 x i32]] addrspace(1)*
+// CHECK: call void [[DEBUG_PARALLEL]](i32* {{[^,]+}}, i32* {{[^,]+}}, [10 x [10 x [10 x i32]]] addrspace(1)* {{[^,]+}}, i32 {{[^,]+}}, [10 x [10 x i32]] addrspace(1)* {{[^,]+}}, i8 addrspace(1)* {{[^)]+}})
+
+// CHECK: define void @__omp_offloading_{{[^(]+}}([10 x [10 x [10 x i32]]]* dereferenceable{{[^,]+}}, i64 {{[^,]+}}, [10 x [10 x i32]]* dereferenceable{{[^,]+}}, i8* dereferenceable{{[^)]+}})
+// CHECK: addrspacecast [10 x [10 x [10 x i32]]]* %{{.+}} to [10 x [10 x [10 x i32]]] addrspace(1)*
+// CHECK: addrspacecast [10 x [10 x i32]]* %{{.+}} to [10 x [10 x i32]] addrspace(1)*
+// CHECK: call void @__omp_offloading_{{[^(]+}}([10 x [10 x [10 x i32]]] addrspace(1)* {{[^,]+}}, i32 {{[^,]+}}, [10 x [10 x i32]] addrspace(1)* {{[^,]+}}, i8 addrspace(1)* {{[^)]+}})
+
+// CHECK: define internal void @__omp_offloading_{{[^(]+}}([10 x [10 x [10 x i32]]] addrspace(1)* noalias{{[^,]+}}, i32 addrspace(1)* noalias{{[^,]+}}, [10 x [10 x i32]] addrspace(1)* noalias{{[^,]+}}, i8 addrspace(1)* noalias{{[^)]+}})
+// CHECK: addrspacecast [10 x [10 x [10 x i32]]] addrspace(1)* %{{.+}} to [10 x [10 x [10 x i32]]]*
+// CHECK: addrspacecast i32 addrspace(1)* %{{.+}} to i32*
+// CHECK: addrspacecast [10 x [10 x i32]] addrspace(1)* %{{.+}} to [10 x [10 x i32]]*
+// CHECK: call void [[NONDEBUG_WRAPPER:@.+]](i32* {{[^,]+}}, i32* {{[^,]+}}, [10 x [10 x [10 x i32]]]* {{[^,]+}}, i32* {{[^,]+}}, [10 x [10 x i32]]* {{[^,]+}}, i8* {{[^)]+}})
+
+// CHECK: define internal void [[DEBUG_PARALLEL:@.+]](i32* {{[^,]+}}, i32* {{[^,]+}}, [10 x [10 x [10 x i32]]] addrspace(1)* noalias{{[^,]+}}, i32 addrspace(1)* noalias{{[^,]+}}, [10 x [10 x i32]] addrspace(1)* noalias{{[^,]+}}, i8 addrspace(1)* noalias{{[^)]+}})
+// CHECK: addrspacecast [10 x [10 x [10 x i32]]] addrspace(1)* %{{.+}} to [10 x [10 x [10 x i32]]]*
+// CHECK: addrspacecast i32 addrspace(1)* %{{.+}} to i32*
+// CHECK: addrspacecast [10 x [10 x i32]] addrspace(1)* %{{.+}} to [10 x [10 x i32]]*
+
+// CHECK: define internal void [[NONDEBUG_WRAPPER]](i32* {{[^,]+}}, i32* {{[^,]+}}, [10 x [10 x [10 x i32]]]* dereferenceable{{[^,]+}}, i32* dereferenceable{{[^,]+}}, [10 x [10 x i32]]* dereferenceable{{[^,]+}}, i8* dereferenceable{{[^)]+}})
+// CHECK: addrspacecast [10 x [10 x [10 x i32]]]* %{{.+}} to [10 x [10 x [10 x i32]]] addrspace(1)*
+// CHECK: addrspacecast i32* %{{.+}} to i32 addrspace(1)*
+// CHECK: addrspacecast [10 x [10 x i32]]* %{{.+}} to [10 x [10 x i32]] addrspace(1)*
+// CHECK: call void [[DEBUG_PARALLEL]](i32* {{[^,]+}}, i32* {{[^,]+}}, [10 x [10 x [10 x i32]]] addrspace(1)* {{[^,]+}}, i32 addrspace(1)* {{[^,]+}}, [10 x [10 x i32]] addrspace(1)* {{[^,]+}}, i8 addrspace(1)* {{[^)]+}})
+
+// CHECK: define void @__omp_offloading_{{[^(]+}}([10 x [10 x [10 x i32]]]* dereferenceable{{[^,]+}}, i32* dereferenceable{{[^,]+}}, [10 x [10 x i32]]* dereferenceable{{[^,]+}}, i8* dereferenceable{{[^)]+}})
+// CHECK: addrspacecast [10 x [10 x [10 x i32]]]* %{{.+}} to [10 x [10 x [10 x i32]]] addrspace(1)*
+// CHECK: addrspacecast i32* %{{.+}} to i32 addrspace(1)*
+// CHECK: addrspacecast [10 x [10 x i32]]* %{{.+}} to [10 x [10 x i32]] addrspace(1)*
+// CHECK: call void @__omp_offloading_{{[^(]+}}([10 x [10 x [10 x i32]]] addrspace(1)* {{[^,]+}}, i32 addrspace(1)* {{[^,]+}}, [10 x [10 x i32]] addrspace(1)* {{[^,]+}}, i8 addrspace(1)* {{[^)]+}})
+
+// CHECK: !DILocalVariable(name: ".global_tid.",
+// CHECK-SAME: DIFlagArtificial
+// CHECK: !DILocalVariable(name: ".bound_tid.",
+// CHECK-SAME: DIFlagArtificial
+// CHECK: !DILocalVariable(name: "c",
+// CHECK-SAMEi-NOT: DIFlagArtificial
+// CHECK: !DILocalVariable(name: "a",
+// CHECK-SAMEi-NOT: DIFlagArtificial
+// CHECK: !DILocalVariable(name: "b",
+// CHECK-SAMEi-NOT: DIFlagArtificial
diff --git a/test/OpenMP/target_parallel_depend_messages.cpp b/test/OpenMP/target_parallel_depend_messages.cpp
index fde940be1aa4..24c69e95cc0a 100644
--- a/test/OpenMP/target_parallel_depend_messages.cpp
+++ b/test/OpenMP/target_parallel_depend_messages.cpp
@@ -36,21 +36,21 @@ int main(int argc, char **argv, char *env[]) {
foo();
#pragma omp target parallel depend (out: ) // expected-error {{expected expression}}
foo();
- #pragma omp target parallel depend (inout : foobool(argc)), depend (in, argc) // expected-error {{expected variable name, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}}
+ #pragma omp target parallel depend (inout : foobool(argc)), depend (in, argc) // expected-error {{expected addressable lvalue expression, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}}
foo();
#pragma omp target parallel depend (out :S1) // expected-error {{'S1' does not refer to a value}}
foo();
- #pragma omp target parallel depend(in : argv[1][1] = '2') // expected-error {{expected variable name, array element or array section}}
+ #pragma omp target parallel depend(in : argv[1][1] = '2')
foo();
- #pragma omp target parallel depend (in : vec[1]) // expected-error {{expected variable name, array element or array section}}
+ #pragma omp target parallel depend (in : vec[1]) // expected-error {{expected addressable lvalue expression, array element or array section}}
foo();
#pragma omp target parallel depend (in : argv[0])
foo();
#pragma omp target parallel depend (in : ) // expected-error {{expected expression}}
foo();
- #pragma omp target parallel depend (in : main) // expected-error {{expected variable name, array element or array section}}
+ #pragma omp target parallel depend (in : main)
foo();
- #pragma omp target parallel depend(in : a[0]) // expected-error{{expected variable name, array element or array section}}
+ #pragma omp target parallel depend(in : a[0]) // expected-error{{expected addressable lvalue expression, array element or array section}}
foo();
#pragma omp target parallel depend (in : vec[1:2]) // expected-error {{ value is not an array or pointer}}
foo();
diff --git a/test/OpenMP/target_parallel_for_codegen.cpp b/test/OpenMP/target_parallel_for_codegen.cpp
new file mode 100644
index 000000000000..58ac10bf9b2c
--- /dev/null
+++ b/test/OpenMP/target_parallel_for_codegen.cpp
@@ -0,0 +1,812 @@
+// Test host codegen.
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+
+// Test target codegen - host bc file has to be created first.
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm-bc %s -o %t-ppc-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-64
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-64
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm-bc %s -o %t-x86-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-32
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-32
+
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+// CHECK-DAG: %ident_t = type { i32, i32, i32, i32, i8* }
+// CHECK-DAG: [[STR:@.+]] = private unnamed_addr constant [23 x i8] c";unknown;unknown;0;0;;\00"
+// CHECK-DAG: [[DEF_LOC:@.+]] = private unnamed_addr constant %ident_t { i32 0, i32 2, i32 0, i32 0, i8* getelementptr inbounds ([23 x i8], [23 x i8]* [[STR]], i32 0, i32 0) }
+
+// CHECK-DAG: [[TT:%.+]] = type { i64, i8 }
+// CHECK-DAG: [[S1:%.+]] = type { double }
+// CHECK-DAG: [[ENTTY:%.+]] = type { i8*, i8*, i[[SZ:32|64]], i32, i32 }
+// CHECK-DAG: [[DEVTY:%.+]] = type { i8*, i8*, [[ENTTY]]*, [[ENTTY]]* }
+// CHECK-DAG: [[DSCTY:%.+]] = type { i32, [[DEVTY]]*, [[ENTTY]]*, [[ENTTY]]* }
+
+// TCHECK: [[ENTTY:%.+]] = type { i8*, i8*, i{{32|64}}, i32, i32 }
+
+// CHECK-DAG: $[[REGFN:\.omp_offloading\..+]] = comdat
+
+// We have 8 target regions, but only 7 that actually will generate offloading
+// code, only 6 will have mapped arguments, and only 4 have all-constant map
+// sizes.
+
+// CHECK-DAG: [[SIZET2:@.+]] = private unnamed_addr constant [3 x i[[SZ]]] [i[[SZ]] 2, i[[SZ]] 4, i[[SZ]] 4]
+// CHECK-DAG: [[MAPT2:@.+]] = private unnamed_addr constant [3 x i64] [i64 288, i64 288, i64 288]
+// CHECK-DAG: [[SIZET3:@.+]] = private unnamed_addr constant [2 x i[[SZ]]] [i[[SZ]] 4, i[[SZ]] 2]
+// CHECK-DAG: [[MAPT3:@.+]] = private unnamed_addr constant [2 x i64] [i64 288, i64 288]
+// CHECK-DAG: [[MAPT4:@.+]] = private unnamed_addr constant [10 x i64] [i64 288, i64 547, i64 288, i64 547, i64 547, i64 288, i64 288, i64 547, i64 547, i64 288]
+// CHECK-DAG: [[SIZET5:@.+]] = private unnamed_addr constant [3 x i[[SZ]]] [i[[SZ]] 4, i[[SZ]] 2, i[[SZ]] 40]
+// CHECK-DAG: [[MAPT5:@.+]] = private unnamed_addr constant [3 x i64] [i64 288, i64 288, i64 547]
+// CHECK-DAG: [[SIZET6:@.+]] = private unnamed_addr constant [4 x i[[SZ]]] [i[[SZ]] 4, i[[SZ]] 2, i[[SZ]] 1, i[[SZ]] 40]
+// CHECK-DAG: [[MAPT6:@.+]] = private unnamed_addr constant [4 x i64] [i64 288, i64 288, i64 288, i64 547]
+// CHECK-DAG: [[MAPT7:@.+]] = private unnamed_addr constant [5 x i64] [i64 547, i64 288, i64 288, i64 288, i64 547]
+// CHECK-DAG: @{{.*}} = private constant i8 0
+// CHECK-DAG: @{{.*}} = private constant i8 0
+// CHECK-DAG: @{{.*}} = private constant i8 0
+// CHECK-DAG: @{{.*}} = private constant i8 0
+// CHECK-DAG: @{{.*}} = private constant i8 0
+// CHECK-DAG: @{{.*}} = private constant i8 0
+// CHECK-DAG: @{{.*}} = private constant i8 0
+
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+// TCHECK-NOT: @{{.+}} = constant [[ENTTY]]
+
+// Check if offloading descriptor is created.
+// CHECK: [[ENTBEGIN:@.+]] = external constant [[ENTTY]]
+// CHECK: [[ENTEND:@.+]] = external constant [[ENTTY]]
+// CHECK: [[DEVBEGIN:@.+]] = external constant i8
+// CHECK: [[DEVEND:@.+]] = external constant i8
+// CHECK: [[IMAGES:@.+]] = internal unnamed_addr constant [1 x [[DEVTY]]] [{{.+}} { i8* [[DEVBEGIN]], i8* [[DEVEND]], [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }], comdat($[[REGFN]])
+// CHECK: [[DESC:@.+]] = internal constant [[DSCTY]] { i32 1, [[DEVTY]]* getelementptr inbounds ([1 x [[DEVTY]]], [1 x [[DEVTY]]]* [[IMAGES]], i32 0, i32 0), [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }, comdat($[[REGFN]])
+
+// Check target registration is registered as a Ctor.
+// CHECK: appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 0, void ()* bitcast (void (i8*)* @[[REGFN]] to void ()*), i8* bitcast (void (i8*)* @[[REGFN]] to i8*) }]
+
+
+template<typename tx, typename ty>
+struct TT{
+ tx X;
+ ty Y;
+};
+
+// CHECK-LABEL: get_val
+long long get_val() { return 0; }
+
+// CHECK: define {{.*}}[[FOO:@.+]](
+int foo(int n) {
+ int a = 0;
+ short aa = 0;
+ float b[10];
+ float bn[n];
+ double c[5][10];
+ double cn[5][n];
+ TT<long long, char> d;
+
+ // CHECK: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 0, i8** null, i8** null, i[[SZ]]* null, i64* null, i32 1, i32 0)
+ // CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
+ // CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:[^,]+]], label %[[END:[^,]+]]
+ // CHECK: [[FAIL]]
+ // CHECK: call void [[HVT0:@.+]]()
+ // CHECK-NEXT: br label %[[END]]
+ // CHECK: [[END]]
+ #pragma omp target parallel for
+ for (int i = 3; i < 32; i += 5) {
+#pragma omp cancel for
+#pragma omp cancellation point for
+ }
+
+ // CHECK: call void [[HVT1:@.+]](i[[SZ]] {{[^,]+}}, i{{32|64}}{{[*]*}} {{[^)]+}})
+ long long k = get_val();
+ #pragma omp target parallel for if(target: 0) linear(k : 3) schedule(dynamic)
+ for (int i = 10; i > 1; i--) {
+ a += 1;
+ }
+
+ // CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams_nowait(i64 -1, i8* @{{[^,]+}}, i32 3, i8** [[BP:%[^,]+]], i8** [[P:%[^,]+]], i[[SZ]]* getelementptr inbounds ([3 x i[[SZ]]], [3 x i[[SZ]]]* [[SIZET2]], i32 0, i32 0), i64* getelementptr inbounds ([3 x i64], [3 x i64]* [[MAPT2]], i32 0, i32 0), i32 1, i32 0)
+ // CHECK-DAG: [[BP]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BPR:%[^,]+]], i32 0, i32 0
+ // CHECK-DAG: [[P]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[PR:%[^,]+]], i32 0, i32 0
+ // CHECK-DAG: [[BPADDR0:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BPR]], i32 0, i32 0
+ // CHECK-DAG: [[PADDR0:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[PR]], i32 0, i32 0
+ // CHECK-DAG: [[CBPADDR0:%.+]] = bitcast i8** [[BPADDR0]] to i[[SZ]]*
+ // CHECK-DAG: [[CPADDR0:%.+]] = bitcast i8** [[PADDR0]] to i[[SZ]]*
+ // CHECK-DAG: store i[[SZ]] [[VAL0:%.+]], i[[SZ]]* [[CBPADDR0]],
+ // CHECK-DAG: store i[[SZ]] [[VAL0]], i[[SZ]]* [[CPADDR0]],
+ // CHECK-DAG: [[BPADDR1:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BPR]], i32 0, i32 1
+ // CHECK-DAG: [[PADDR1:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[PR]], i32 0, i32 1
+ // CHECK-DAG: [[CBPADDR1:%.+]] = bitcast i8** [[BPADDR1]] to i[[SZ]]*
+ // CHECK-DAG: [[CPADDR1:%.+]] = bitcast i8** [[PADDR1]] to i[[SZ]]*
+ // CHECK-DAG: store i[[SZ]] [[VAL1:%.+]], i[[SZ]]* [[CBPADDR1]],
+ // CHECK-DAG: store i[[SZ]] [[VAL1]], i[[SZ]]* [[CPADDR1]],
+ // CHECK-DAG: [[BPADDR2:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BPR]], i32 0, i32 1
+ // CHECK-DAG: [[PADDR2:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[PR]], i32 0, i32 1
+ // CHECK-DAG: [[CBPADDR2:%.+]] = bitcast i8** [[BPADDR2]] to i[[SZ]]*
+ // CHECK-DAG: [[CPADDR2:%.+]] = bitcast i8** [[PADDR2]] to i[[SZ]]*
+ // CHECK-DAG: store i[[SZ]] [[VAL2:%.+]], i[[SZ]]* [[CBPADDR2]],
+ // CHECK-DAG: store i[[SZ]] [[VAL2]], i[[SZ]]* [[CPADDR2]],
+
+ // CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
+ // CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:[^,]+]], label %[[END:[^,]+]]
+ // CHECK: [[FAIL]]
+ // CHECK: call void [[HVT2:@.+]](i[[SZ]] {{[^,]+}}, i[[SZ]] {{[^)]+}})
+ // CHECK-NEXT: br label %[[END]]
+ // CHECK: [[END]]
+ int lin = 12;
+ #pragma omp target parallel for if(target: 1) linear(lin, a : get_val()) nowait
+ for (unsigned long long it = 2000; it >= 600; it-=400) {
+ aa += 1;
+ }
+
+ // CHECK: [[IF:%.+]] = icmp sgt i32 {{[^,]+}}, 10
+ // CHECK: br i1 [[IF]], label %[[IFTHEN:[^,]+]], label %[[IFELSE:[^,]+]]
+ // CHECK: [[IFTHEN]]
+ // CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 2, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* getelementptr inbounds ([2 x i[[SZ]]], [2 x i[[SZ]]]* [[SIZET3]], i32 0, i32 0), i64* getelementptr inbounds ([2 x i64], [2 x i64]* [[MAPT3]], i32 0, i32 0), i32 1, i32 0)
+ // CHECK-DAG: [[BPR]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[BP:%[^,]+]], i32 0, i32 0
+ // CHECK-DAG: [[PR]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[P:%[^,]+]], i32 0, i32 0
+
+ // CHECK-DAG: [[BPADDR0:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[BP]], i32 0, i32 0
+ // CHECK-DAG: [[PADDR0:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[P]], i32 0, i32 0
+ // CHECK-DAG: [[CBPADDR0:%.+]] = bitcast i8** [[BPADDR0]] to i[[SZ]]*
+ // CHECK-DAG: [[CPADDR0:%.+]] = bitcast i8** [[PADDR0]] to i[[SZ]]*
+ // CHECK-DAG: store i[[SZ]] [[VAL0:%.+]], i[[SZ]]* [[CBPADDR0]],
+ // CHECK-DAG: store i[[SZ]] [[VAL0]], i[[SZ]]* [[CPADDR0]],
+
+ // CHECK-DAG: [[BPADDR1:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[BP]], i32 0, i32 1
+ // CHECK-DAG: [[PADDR1:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[P]], i32 0, i32 1
+ // CHECK-DAG: [[CBPADDR1:%.+]] = bitcast i8** [[BPADDR1]] to i[[SZ]]*
+ // CHECK-DAG: [[CPADDR1:%.+]] = bitcast i8** [[PADDR1]] to i[[SZ]]*
+ // CHECK-DAG: store i[[SZ]] [[VAL1:%.+]], i[[SZ]]* [[CBPADDR1]],
+ // CHECK-DAG: store i[[SZ]] [[VAL1]], i[[SZ]]* [[CPADDR1]],
+ // CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
+ // CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
+ // CHECK: [[FAIL]]
+ // CHECK: call void [[HVT3:@.+]]({{[^,]+}}, {{[^,]+}})
+ // CHECK-NEXT: br label %[[END]]
+ // CHECK: [[END]]
+ // CHECK-NEXT: br label %[[IFEND:.+]]
+ // CHECK: [[IFELSE]]
+ // CHECK: call void [[HVT3]]({{[^,]+}}, {{[^,]+}})
+ // CHECK-NEXT: br label %[[IFEND]]
+ // CHECK: [[IFEND]]
+
+ #pragma omp target parallel for if(target: n>10)
+ for (short it = 6; it <= 20; it-=-4) {
+ a += 1;
+ aa += 1;
+ }
+
+ // We capture 3 VLA sizes in this target region
+ // CHECK: [[A_VAL:%.+]] = load i32, i32* %{{.+}},
+ // CHECK: store i32 [[A_VAL]], i32* [[A_CADDR:%.+]],
+ // CHECK-64: [[A_VAL:%.+]] = load i32, i32* %{{.+}},
+ // CHECK-64: [[A_ADDR:%.+]] = bitcast i[[SZ]]* [[A_CADDR:%.+]] to i32*
+ // CHECK-64: store i32 [[A_VAL]], i32* [[A_ADDR]],
+ // CHECK-64: [[A_CVAL:%.+]] = load i[[SZ]], i[[SZ]]* [[A_CADDR]],
+
+ // CHECK-32: [[A_VAL:%.+]] = load i32, i32* %{{.+}},
+ // CHECK-32: store i32 [[A_VAL]], i32* [[A_CADDR:%.+]],
+ // CHECK-32: [[A_CVAL:%.+]] = load i[[SZ]], i[[SZ]]* [[A_CADDR]],
+
+ // CHECK: [[BNSIZE:%.+]] = mul nuw i[[SZ]] [[VLA0:%.+]], 4
+ // CHECK: [[CNELEMSIZE2:%.+]] = mul nuw i[[SZ]] 5, [[VLA1:%.+]]
+ // CHECK: [[CNSIZE:%.+]] = mul nuw i[[SZ]] [[CNELEMSIZE2]], 8
+
+ // CHECK: [[IF:%.+]] = icmp sgt i32 {{[^,]+}}, 20
+ // CHECK: br i1 [[IF]], label %[[TRY:[^,]+]], label %[[FAIL:[^,]+]]
+ // CHECK: [[TRY]]
+ // CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 10, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* [[SR:%[^,]+]], i64* getelementptr inbounds ([10 x i64], [10 x i64]* [[MAPT4]], i32 0, i32 0), i32 1, i32 0)
+ // CHECK-DAG: [[BPR]] = getelementptr inbounds [10 x i8*], [10 x i8*]* [[BP:%[^,]+]], i32 0, i32 0
+ // CHECK-DAG: [[PR]] = getelementptr inbounds [10 x i8*], [10 x i8*]* [[P:%[^,]+]], i32 0, i32 0
+ // CHECK-DAG: [[SR]] = getelementptr inbounds [10 x i[[SZ]]], [10 x i[[SZ]]]* [[S:%[^,]+]], i32 0, i32 0
+
+ // CHECK-DAG: [[SADDR0:%.+]] = getelementptr inbounds [10 x i[[SZ]]], [10 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX0:[0-9]+]]
+ // CHECK-DAG: [[BPADDR0:%.+]] = getelementptr inbounds [10 x i8*], [10 x i8*]* [[BP]], i32 0, i32 [[IDX0]]
+ // CHECK-DAG: [[PADDR0:%.+]] = getelementptr inbounds [10 x i8*], [10 x i8*]* [[P]], i32 0, i32 [[IDX0]]
+ // CHECK-DAG: [[SADDR1:%.+]] = getelementptr inbounds [10 x i[[SZ]]], [10 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX1:[0-9]+]]
+ // CHECK-DAG: [[BPADDR1:%.+]] = getelementptr inbounds [10 x i8*], [10 x i8*]* [[BP]], i32 0, i32 [[IDX1]]
+ // CHECK-DAG: [[PADDR1:%.+]] = getelementptr inbounds [10 x i8*], [10 x i8*]* [[P]], i32 0, i32 [[IDX1]]
+ // CHECK-DAG: [[SADDR2:%.+]] = getelementptr inbounds [10 x i[[SZ]]], [10 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX2:[0-9]+]]
+ // CHECK-DAG: [[BPADDR2:%.+]] = getelementptr inbounds [10 x i8*], [10 x i8*]* [[BP]], i32 0, i32 [[IDX2]]
+ // CHECK-DAG: [[PADDR2:%.+]] = getelementptr inbounds [10 x i8*], [10 x i8*]* [[P]], i32 0, i32 [[IDX2]]
+ // CHECK-DAG: [[SADDR3:%.+]] = getelementptr inbounds [10 x i[[SZ]]], [10 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX3:[0-9]+]]
+ // CHECK-DAG: [[BPADDR3:%.+]] = getelementptr inbounds [10 x i8*], [10 x i8*]* [[BP]], i32 0, i32 [[IDX3]]
+ // CHECK-DAG: [[PADDR3:%.+]] = getelementptr inbounds [10 x i8*], [10 x i8*]* [[P]], i32 0, i32 [[IDX3]]
+ // CHECK-DAG: [[SADDR4:%.+]] = getelementptr inbounds [10 x i[[SZ]]], [10 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX4:[0-9]+]]
+ // CHECK-DAG: [[BPADDR4:%.+]] = getelementptr inbounds [10 x i8*], [10 x i8*]* [[BP]], i32 0, i32 [[IDX4]]
+ // CHECK-DAG: [[PADDR4:%.+]] = getelementptr inbounds [10 x i8*], [10 x i8*]* [[P]], i32 0, i32 [[IDX4]]
+ // CHECK-DAG: [[SADDR5:%.+]] = getelementptr inbounds [10 x i[[SZ]]], [10 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX5:[0-9]+]]
+ // CHECK-DAG: [[BPADDR5:%.+]] = getelementptr inbounds [10 x i8*], [10 x i8*]* [[BP]], i32 0, i32 [[IDX5]]
+ // CHECK-DAG: [[PADDR5:%.+]] = getelementptr inbounds [10 x i8*], [10 x i8*]* [[P]], i32 0, i32 [[IDX5]]
+ // CHECK-DAG: [[SADDR6:%.+]] = getelementptr inbounds [10 x i[[SZ]]], [10 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX6:[0-9]+]]
+ // CHECK-DAG: [[BPADDR6:%.+]] = getelementptr inbounds [10 x i8*], [10 x i8*]* [[BP]], i32 0, i32 [[IDX6]]
+ // CHECK-DAG: [[PADDR6:%.+]] = getelementptr inbounds [10 x i8*], [10 x i8*]* [[P]], i32 0, i32 [[IDX6]]
+ // CHECK-DAG: [[SADDR7:%.+]] = getelementptr inbounds [10 x i[[SZ]]], [10 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX7:[0-9]+]]
+ // CHECK-DAG: [[BPADDR7:%.+]] = getelementptr inbounds [10 x i8*], [10 x i8*]* [[BP]], i32 0, i32 [[IDX7]]
+ // CHECK-DAG: [[PADDR7:%.+]] = getelementptr inbounds [10 x i8*], [10 x i8*]* [[P]], i32 0, i32 [[IDX7]]
+ // CHECK-DAG: [[SADDR8:%.+]] = getelementptr inbounds [10 x i[[SZ]]], [10 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX8:[0-9]+]]
+ // CHECK-DAG: [[BPADDR8:%.+]] = getelementptr inbounds [10 x i8*], [10 x i8*]* [[BP]], i32 0, i32 [[IDX8]]
+ // CHECK-DAG: [[PADDR8:%.+]] = getelementptr inbounds [10 x i8*], [10 x i8*]* [[P]], i32 0, i32 [[IDX8]]
+
+ // The names below are not necessarily consistent with the names used for the
+ // addresses above as some are repeated.
+ // CHECK-DAG: store i[[SZ]] [[VLA0]], i[[SZ]]* [[CBPADDR0:%.+]],
+ // CHECK-DAG: store i[[SZ]] [[VLA0]], i[[SZ]]* [[CPADDR0:%.+]],
+ // CHECK-DAG: [[CBPADDR0]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+ // CHECK-DAG: [[CPADDR0]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+ // CHECK-DAG: store i[[SZ]] {{4|8}}, i[[SZ]]* {{%[^,]+}}
+
+ // CHECK-DAG: store i[[SZ]] [[VLA1]], i[[SZ]]* [[CBPADDR1:%.+]],
+ // CHECK-DAG: store i[[SZ]] [[VLA1]], i[[SZ]]* [[CPADDR1:%.+]],
+ // CHECK-DAG: [[CBPADDR1]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+ // CHECK-DAG: [[CPADDR1]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+ // CHECK-DAG: store i[[SZ]] {{4|8}}, i[[SZ]]* {{%[^,]+}}
+
+ // CHECK-DAG: store i[[SZ]] 5, i[[SZ]]* [[CBPADDR2:%.+]],
+ // CHECK-DAG: store i[[SZ]] 5, i[[SZ]]* [[CPADDR2:%.+]],
+ // CHECK-DAG: [[CBPADDR2]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+ // CHECK-DAG: [[CPADDR2]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+ // CHECK-DAG: store i[[SZ]] {{4|8}}, i[[SZ]]* {{%[^,]+}}
+
+ // CHECK-DAG: store i[[SZ]] [[A_CVAL]], i[[SZ]]* [[CBPADDR3:%.+]],
+ // CHECK-DAG: store i[[SZ]] [[A_CVAL]], i[[SZ]]* [[CPADDR3:%.+]],
+ // CHECK-DAG: [[CBPADDR3]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+ // CHECK-DAG: [[CPADDR3]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+ // CHECK-DAG: store i[[SZ]] 4, i[[SZ]]* {{%[^,]+}}
+
+ // CHECK-DAG: store [10 x float]* %{{.+}}, [10 x float]** [[CBPADDR4:%.+]],
+ // CHECK-DAG: store [10 x float]* %{{.+}}, [10 x float]** [[CPADDR4:%.+]],
+ // CHECK-DAG: [[CBPADDR4]] = bitcast i8** {{%[^,]+}} to [10 x float]**
+ // CHECK-DAG: [[CPADDR4]] = bitcast i8** {{%[^,]+}} to [10 x float]**
+ // CHECK-DAG: store i[[SZ]] 40, i[[SZ]]* {{%[^,]+}}
+
+ // CHECK-DAG: store float* %{{.+}}, float** [[CBPADDR5:%.+]],
+ // CHECK-DAG: store float* %{{.+}}, float** [[CPADDR5:%.+]],
+ // CHECK-DAG: [[CBPADDR5]] = bitcast i8** {{%[^,]+}} to float**
+ // CHECK-DAG: [[CPADDR5]] = bitcast i8** {{%[^,]+}} to float**
+ // CHECK-DAG: store i[[SZ]] [[BNSIZE]], i[[SZ]]* {{%[^,]+}}
+
+ // CHECK-DAG: store [5 x [10 x double]]* %{{.+}}, [5 x [10 x double]]** [[CBPADDR6:%.+]],
+ // CHECK-DAG: store [5 x [10 x double]]* %{{.+}}, [5 x [10 x double]]** [[CPADDR6:%.+]],
+ // CHECK-DAG: [[CBPADDR6]] = bitcast i8** {{%[^,]+}} to [5 x [10 x double]]**
+ // CHECK-DAG: [[CPADDR6]] = bitcast i8** {{%[^,]+}} to [5 x [10 x double]]**
+ // CHECK-DAG: store i[[SZ]] 400, i[[SZ]]* {{%[^,]+}}
+
+ // CHECK-DAG: store double* %{{.+}}, double** [[CBPADDR7:%.+]],
+ // CHECK-DAG: store double* %{{.+}}, double** [[CPADDR7:%.+]],
+ // CHECK-DAG: [[CBPADDR7]] = bitcast i8** {{%[^,]+}} to double**
+ // CHECK-DAG: [[CPADDR7]] = bitcast i8** {{%[^,]+}} to double**
+ // CHECK-DAG: store i[[SZ]] [[CNSIZE]], i[[SZ]]* {{%[^,]+}}
+
+ // CHECK-DAG: store [[TT]]* %{{.+}}, [[TT]]** [[CBPADDR8:%.+]],
+ // CHECK-DAG: store [[TT]]* %{{.+}}, [[TT]]** [[CPADDR8:%.+]],
+ // CHECK-DAG: [[CBPADDR8]] = bitcast i8** {{%[^,]+}} to [[TT]]**
+ // CHECK-DAG: [[CPADDR8]] = bitcast i8** {{%[^,]+}} to [[TT]]**
+ // CHECK-DAG: store i[[SZ]] {{12|16}}, i[[SZ]]* {{%[^,]+}}
+
+ // CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
+ // CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:[^,]+]], label %[[END:[^,]+]]
+
+ // CHECK: [[FAIL]]
+ // CHECK: call void [[HVT4:@.+]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^)]+}})
+ // CHECK-NEXT: br label %[[END]]
+ // CHECK: [[END]]
+ #pragma omp target parallel for if(target: n>20) schedule(static, a)
+ for (unsigned char it = 'z'; it >= 'a'; it+=-1) {
+ a += 1;
+ b[2] += 1.0;
+ bn[3] += 1.0;
+ c[1][2] += 1.0;
+ cn[1][3] += 1.0;
+ d.X += 1;
+ d.Y += 1;
+ }
+
+ return a;
+}
+
+// Check that the offloading functions are emitted and that the arguments are
+// correct and loaded correctly for the target regions in foo().
+
+// CHECK: define internal void [[HVT0]]()
+// CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* [[DEF_LOC]], i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* [[OMP_OUTLINED:@.+]] to void (i32*, i32*, ...)*))
+//
+//
+// CHECK: define internal {{.*}}void [[OMP_OUTLINED]](i32* noalias %.global_tid., i32* noalias %.bound_tid.)
+// CHECK: call i32 @__kmpc_cancel(%ident_t* @
+// CHECK: call i32 @__kmpc_cancellationpoint(%ident_t* @
+// CHECK: ret void
+// CHECK: }
+
+
+// CHECK: define internal void [[HVT1]](i[[SZ]] %{{.+}}, i{{32|64}}{{[*]*.*}} %{{.+}})
+// Create stack storage and store argument in there.
+// CHECK: [[AA_ADDR:%.+]] = alloca i[[SZ]], align
+// CHECK: alloca i{{32|64}}{{[*]*}}, align
+// CHECK: [[AA_CASTED:%.+]] = alloca i[[SZ]], align
+// CHECK: store i[[SZ]] %{{.+}}, i[[SZ]]* [[AA_ADDR]], align
+// CHECK-64: [[AA_CADDR:%.+]] = bitcast i[[SZ]]* [[AA_ADDR]] to i32*
+// CHECK-64: [[AA:%.+]] = load i32, i32* [[AA_CADDR]], align
+// CHECK-32: [[AA:%.+]] = load i32, i32* [[AA_ADDR]], align
+// CHECK-64: [[AA_C:%.+]] = bitcast i[[SZ]]* [[AA_CASTED]] to i32*
+// CHECK-64: store i32 [[AA]], i32* [[AA_C]], align
+// CHECK-32: store i32 [[AA]], i32* [[AA_CASTED]], align
+// CHECK: [[PARAM:%.+]] = load i[[SZ]], i[[SZ]]* [[AA_CASTED]], align
+// CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* [[DEF_LOC]], i32 2, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i[[SZ]], i{{32|64}}{{[*]*}})* [[OMP_OUTLINED1:@.+]] to void (i32*, i32*, ...)*), i[[SZ]] [[PARAM]], i{{32|64}}{{[*]*}} %{{.+}})
+//
+//
+// CHECK: define internal {{.*}}void [[OMP_OUTLINED1]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i[[SZ]] %{{.+}})
+// CHECK: [[AA_ADDR:%.+]] = alloca i[[SZ]], align
+// CHECK: store i[[SZ]] %{{.+}}, i[[SZ]]* [[AA_ADDR]], align
+// CHECK-64: [[AA_CADDR:%.+]] = bitcast i[[SZ]]* [[AA_ADDR]] to i32*
+// CHECK-64: [[AA:%.+]] = load i32, i32* [[AA_CADDR]], align
+// CHECK-32: [[AA:%.+]] = load i32, i32* [[AA_ADDR]], align
+// CHECK: ret void
+// CHECK-NEXT: }
+
+// CHECK: define internal void [[HVT2]](i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}})
+// Create stack storage and store argument in there.
+// CHECK: [[AA_ADDR:%.+]] = alloca i[[SZ]], align
+// CHECK: alloca i[[SZ]], align
+// CHECK: alloca i[[SZ]], align
+// CHECK: [[AA_CASTED:%.+]] = alloca i[[SZ]], align
+// CHECK: store i[[SZ]] %{{.+}}, i[[SZ]]* [[AA_ADDR]], align
+// CHECK: [[AA_CADDR:%.+]] = bitcast i[[SZ]]* [[AA_ADDR]] to i16*
+// CHECK: [[AA:%.+]] = load i16, i16* [[AA_CADDR]], align
+// CHECK: [[AA_C:%.+]] = bitcast i[[SZ]]* [[AA_CASTED]] to i16*
+// CHECK: store i16 [[AA]], i16* [[AA_C]], align
+// CHECK: [[PARAM:%.+]] = load i[[SZ]], i[[SZ]]* [[AA_CASTED]], align
+// CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* [[DEF_LOC]], i32 3, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i[[SZ]], i[[SZ]], i[[SZ]])* [[OMP_OUTLINED2:@.+]] to void (i32*, i32*, ...)*), i[[SZ]] [[PARAM]], i[[SZ]] {{.+}}, i[[SZ]] {{.+}})
+//
+//
+// CHECK: define internal {{.*}}void [[OMP_OUTLINED2]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}})
+// CHECK: [[AA_ADDR:%.+]] = alloca i[[SZ]], align
+// CHECK: store i[[SZ]] %{{.+}}, i[[SZ]]* [[AA_ADDR]], align
+// CHECK: [[AA_CADDR:%.+]] = bitcast i[[SZ]]* [[AA_ADDR]] to i16*
+// CHECK: [[AA:%.+]] = load i16, i16* [[AA_CADDR]], align
+// CHECK: ret void
+// CHECK-NEXT: }
+
+// CHECK: define internal void [[HVT3]]
+// Create stack storage and store argument in there.
+// CHECK: [[A_ADDR:%.+]] = alloca i[[SZ]], align
+// CHECK: [[AA_ADDR:%.+]] = alloca i[[SZ]], align
+// CHECK: [[A_CASTED:%.+]] = alloca i[[SZ]], align
+// CHECK: [[AA_CASTED:%.+]] = alloca i[[SZ]], align
+// CHECK-DAG: store i[[SZ]] %{{.+}}, i[[SZ]]* [[A_ADDR]], align
+// CHECK-DAG: store i[[SZ]] %{{.+}}, i[[SZ]]* [[AA_ADDR]], align
+// CHECK-64-DAG:[[A_CADDR:%.+]] = bitcast i[[SZ]]* [[A_ADDR]] to i32*
+// CHECK-DAG: [[AA_CADDR:%.+]] = bitcast i[[SZ]]* [[AA_ADDR]] to i16*
+// CHECK-64-DAG:[[A:%.+]] = load i32, i32* [[A_CADDR]], align
+// CHECK-32-DAG:[[A:%.+]] = load i32, i32* [[A_ADDR]], align
+// CHECK-64-DAG:[[A_C:%.+]] = bitcast i[[SZ]]* [[A_CASTED]] to i32*
+// CHECK-64-DAG:store i32 [[A]], i32* [[A_C]], align
+// CHECK-32-DAG:store i32 [[A]], i32* [[A_CASTED]], align
+// CHECK-DAG: [[AA:%.+]] = load i16, i16* [[AA_CADDR]], align
+// CHECK-DAG: [[AA_C:%.+]] = bitcast i[[SZ]]* [[AA_CASTED]] to i16*
+// CHECK-DAG: store i16 [[AA]], i16* [[AA_C]], align
+// CHECK-DAG: [[PARAM1:%.+]] = load i[[SZ]], i[[SZ]]* [[A_CASTED]], align
+// CHECK-DAG: [[PARAM2:%.+]] = load i[[SZ]], i[[SZ]]* [[AA_CASTED]], align
+// CHECK-DAG: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* [[DEF_LOC]], i32 2, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i[[SZ]], i[[SZ]])* [[OMP_OUTLINED3:@.+]] to void (i32*, i32*, ...)*), i[[SZ]] [[PARAM1]], i[[SZ]] [[PARAM2]])
+//
+//
+// CHECK: define internal {{.*}}void [[OMP_OUTLINED3]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}})
+// CHECK: [[A_ADDR:%.+]] = alloca i[[SZ]], align
+// CHECK: [[AA_ADDR:%.+]] = alloca i[[SZ]], align
+// CHECK-DAG: store i[[SZ]] %{{.+}}, i[[SZ]]* [[A_ADDR]], align
+// CHECK-DAG: store i[[SZ]] %{{.+}}, i[[SZ]]* [[AA_ADDR]], align
+// CHECK-64-DAG:[[A_CADDR:%.+]] = bitcast i[[SZ]]* [[A_ADDR]] to i32*
+// CHECK-DAG: [[AA_CADDR:%.+]] = bitcast i[[SZ]]* [[AA_ADDR]] to i16*
+// CHECK: ret void
+// CHECK-NEXT: }
+
+// CHECK: define internal void [[HVT4]]
+// Create local storage for each capture.
+// CHECK: [[LOCAL_A:%.+]] = alloca i[[SZ]]
+// CHECK: [[LOCAL_B:%.+]] = alloca [10 x float]*
+// CHECK: [[LOCAL_VLA1:%.+]] = alloca i[[SZ]]
+// CHECK: [[LOCAL_BN:%.+]] = alloca float*
+// CHECK: [[LOCAL_C:%.+]] = alloca [5 x [10 x double]]*
+// CHECK: [[LOCAL_VLA2:%.+]] = alloca i[[SZ]]
+// CHECK: [[LOCAL_VLA3:%.+]] = alloca i[[SZ]]
+// CHECK: [[LOCAL_CN:%.+]] = alloca double*
+// CHECK: [[LOCAL_D:%.+]] = alloca [[TT]]*
+// CHECK: alloca i[[SZ]]
+// CHECK: [[LOCAL_A_CASTED:%.+]] = alloca i[[SZ]]
+// CHECK-DAG: store i[[SZ]] [[ARG_A:%.+]], i[[SZ]]* [[LOCAL_A]]
+// CHECK-DAG: store [10 x float]* [[ARG_B:%.+]], [10 x float]** [[LOCAL_B]]
+// CHECK-DAG: store i[[SZ]] [[ARG_VLA1:%.+]], i[[SZ]]* [[LOCAL_VLA1]]
+// CHECK-DAG: store float* [[ARG_BN:%.+]], float** [[LOCAL_BN]]
+// CHECK-DAG: store [5 x [10 x double]]* [[ARG_C:%.+]], [5 x [10 x double]]** [[LOCAL_C]]
+// CHECK-DAG: store i[[SZ]] [[ARG_VLA2:%.+]], i[[SZ]]* [[LOCAL_VLA2]]
+// CHECK-DAG: store i[[SZ]] [[ARG_VLA3:%.+]], i[[SZ]]* [[LOCAL_VLA3]]
+// CHECK-DAG: store double* [[ARG_CN:%.+]], double** [[LOCAL_CN]]
+// CHECK-DAG: store [[TT]]* [[ARG_D:%.+]], [[TT]]** [[LOCAL_D]]
+
+// CHECK-64-DAG:[[CONV_AP:%.+]] = bitcast i[[SZ]]* [[LOCAL_A]] to i32*
+// CHECK-DAG: [[REF_B:%.+]] = load [10 x float]*, [10 x float]** [[LOCAL_B]],
+// CHECK-DAG: [[VAL_VLA1:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_VLA1]],
+// CHECK-DAG: [[REF_BN:%.+]] = load float*, float** [[LOCAL_BN]],
+// CHECK-DAG: [[REF_C:%.+]] = load [5 x [10 x double]]*, [5 x [10 x double]]** [[LOCAL_C]],
+// CHECK-DAG: [[VAL_VLA2:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_VLA2]],
+// CHECK-DAG: [[VAL_VLA3:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_VLA3]],
+// CHECK-DAG: [[REF_CN:%.+]] = load double*, double** [[LOCAL_CN]],
+// CHECK-DAG: [[REF_D:%.+]] = load [[TT]]*, [[TT]]** [[LOCAL_D]],
+
+// CHECK-64-DAG:[[CONV_A:%.+]] = load i32, i32* [[CONV_AP]]
+// CHECK-64-DAG:[[CONV:%.+]] = bitcast i[[SZ]]* [[LOCAL_A_CASTED]] to i32*
+// CHECK-64-DAG:store i32 [[CONV_A]], i32* [[CONV]], align
+// CHECK-32-DAG:[[LOCAL_AV:%.+]] = load i32, i32* [[LOCAL_A]]
+// CHECK-32-DAG:store i32 [[LOCAL_AV]], i32* [[LOCAL_A_CASTED]], align
+// CHECK-DAG: [[REF_A:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_A_CASTED]],
+
+// CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* [[DEF_LOC]], i32 10, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i[[SZ]], [10 x float]*, i[[SZ]], float*, [5 x [10 x double]]*, i[[SZ]], i[[SZ]], double*, [[TT]]*, i[[SZ]])* [[OMP_OUTLINED4:@.+]] to void (i32*, i32*, ...)*), i[[SZ]] [[REF_A]], [10 x float]* [[REF_B]], i[[SZ]] [[VAL_VLA1]], float* [[REF_BN]], [5 x [10 x double]]* [[REF_C]], i[[SZ]] [[VAL_VLA2]], i[[SZ]] [[VAL_VLA3]], double* [[REF_CN]], [[TT]]* [[REF_D]], i[[SZ]] %{{.+}})
+//
+//
+// CHECK: define internal {{.*}}void [[OMP_OUTLINED4]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i[[SZ]] %{{.+}}, [10 x float]* {{.+}}, i[[SZ]] %{{.+}}, float* {{.+}}, [5 x [10 x double]]* {{.+}}, i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, double* {{.+}}, [[TT]]* {{.+}})
+// To reduce complexity, we're only going as far as validating the signature of the outlined parallel function.
+
+template<typename tx>
+tx ftemplate(int n) {
+ tx a = 0;
+ short aa = 0;
+ tx b[10];
+
+ #pragma omp target parallel for if(target: n>40)
+ for (long long i = -10; i < 10; i += 3) {
+ a += 1;
+ aa += 1;
+ b[2] += 1;
+ }
+
+ return a;
+}
+
+static
+int fstatic(int n) {
+ int a = 0;
+ short aa = 0;
+ char aaa = 0;
+ int b[10];
+
+ #pragma omp target parallel for if(target: n>50)
+ for (unsigned i=100; i<10; i+=10) {
+ a += 1;
+ aa += 1;
+ aaa += 1;
+ b[2] += 1;
+ }
+
+ return a;
+}
+
+struct S1 {
+ double a;
+
+ int r1(int n){
+ int b = n+1;
+ short int c[2][n];
+
+ #pragma omp target parallel for if(target: n>60)
+ for (unsigned long long it = 2000; it >= 600; it -= 400) {
+ this->a = (double)b + 1.5;
+ c[1][1] = ++a;
+ }
+
+ return c[1][1] + (int)b;
+ }
+};
+
+// CHECK: define {{.*}}@{{.*}}bar{{.*}}
+int bar(int n){
+ int a = 0;
+
+ // CHECK: call {{.*}}i32 [[FOO]](i32 {{.*}})
+ a += foo(n);
+
+ S1 S;
+ // CHECK: call {{.*}}i32 [[FS1:@.+]]([[S1]]* {{.*}}, i32 {{.*}})
+ a += S.r1(n);
+
+ // CHECK: call {{.*}}i32 [[FSTATIC:@.+]](i32 {{.*}})
+ a += fstatic(n);
+
+ // CHECK: call {{.*}}i32 [[FTEMPLATE:@.+]](i32 {{.*}})
+ a += ftemplate<int>(n);
+
+ return a;
+}
+
+//
+// CHECK: define {{.*}}[[FS1]]
+//
+// CHECK: i8* @llvm.stacksave()
+// CHECK-64: [[B_ADDR:%.+]] = bitcast i[[SZ]]* [[B_CADDR:%.+]] to i32*
+// CHECK-64: store i32 %{{.+}}, i32* [[B_ADDR]],
+// CHECK-64: [[B_CVAL:%.+]] = load i[[SZ]], i[[SZ]]* [[B_CADDR]],
+
+// CHECK-32: store i32 %{{.+}}, i32* [[B_ADDR:%.+]],
+// CHECK-32: [[B_CVAL:%.+]] = load i[[SZ]], i[[SZ]]* [[B_ADDR]],
+
+// We capture 2 VLA sizes in this target region
+// CHECK: [[CELEMSIZE2:%.+]] = mul nuw i[[SZ]] 2, [[VLA0:%.+]]
+// CHECK: [[CSIZE:%.+]] = mul nuw i[[SZ]] [[CELEMSIZE2]], 2
+
+// CHECK: [[IF:%.+]] = icmp sgt i32 {{[^,]+}}, 60
+// CHECK: br i1 [[IF]], label %[[TRY:[^,]+]], label %[[FAIL:[^,]+]]
+// CHECK: [[TRY]]
+// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 5, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* [[SR:%[^,]+]], i64* getelementptr inbounds ([5 x i64], [5 x i64]* [[MAPT7]], i32 0, i32 0), i32 1, i32 0)
+// CHECK-DAG: [[BPR]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[BP:%.+]], i32 0, i32 0
+// CHECK-DAG: [[PR]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[P:%.+]], i32 0, i32 0
+// CHECK-DAG: [[SR]] = getelementptr inbounds [5 x i[[SZ]]], [5 x i[[SZ]]]* [[S:%.+]], i32 0, i32 0
+// CHECK-DAG: [[SADDR0:%.+]] = getelementptr inbounds [5 x i[[SZ]]], [5 x i[[SZ]]]* [[S]], i32 [[IDX0:[0-9]+]]
+// CHECK-DAG: [[BPADDR0:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[BP]], i32 [[IDX0]]
+// CHECK-DAG: [[PADDR0:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[P]], i32 [[IDX0]]
+// CHECK-DAG: [[SADDR1:%.+]] = getelementptr inbounds [5 x i[[SZ]]], [5 x i[[SZ]]]* [[S]], i32 [[IDX1:[0-9]+]]
+// CHECK-DAG: [[BPADDR1:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[BP]], i32 [[IDX1]]
+// CHECK-DAG: [[PADDR1:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[P]], i32 [[IDX1]]
+// CHECK-DAG: [[SADDR2:%.+]] = getelementptr inbounds [5 x i[[SZ]]], [5 x i[[SZ]]]* [[S]], i32 [[IDX2:[0-9]+]]
+// CHECK-DAG: [[BPADDR2:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[BP]], i32 [[IDX2]]
+// CHECK-DAG: [[PADDR2:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[P]], i32 [[IDX2]]
+// CHECK-DAG: [[SADDR3:%.+]] = getelementptr inbounds [5 x i[[SZ]]], [5 x i[[SZ]]]* [[S]], i32 [[IDX3:[0-9]+]]
+// CHECK-DAG: [[BPADDR3:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[BP]], i32 [[IDX3]]
+// CHECK-DAG: [[PADDR3:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[P]], i32 [[IDX3]]
+
+// The names below are not necessarily consistent with the names used for the
+// addresses above as some are repeated.
+// CHECK-DAG: store i[[SZ]] [[VLA0]], i[[SZ]]* [[CBPADDR0:%.+]],
+// CHECK-DAG: store i[[SZ]] [[VLA0]], i[[SZ]]* [[CPADDR0:%.+]],
+// CHECK-DAG: [[CBPADDR0]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+// CHECK-DAG: [[CPADDR0]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+// CHECK-DAG: store i[[SZ]] {{4|8}}, i[[SZ]]* {{%[^,]+}}
+
+// CHECK-DAG: store i[[SZ]] 2, i[[SZ]]* [[CBPADDR1:%.+]],
+// CHECK-DAG: store i[[SZ]] 2, i[[SZ]]* [[CPADDR1:%.+]],
+// CHECK-DAG: [[CBPADDR1]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+// CHECK-DAG: [[CPADDR1]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+// CHECK-DAG: store i[[SZ]] {{4|8}}, i[[SZ]]* {{%[^,]+}}
+
+// CHECK-DAG: store i[[SZ]] [[B_CVAL]], i[[SZ]]* [[CBPADDR2:%.+]],
+// CHECK-DAG: store i[[SZ]] [[B_CVAL]], i[[SZ]]* [[CPADDR2:%.+]],
+// CHECK-DAG: [[CBPADDR2]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+// CHECK-DAG: [[CPADDR2]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+// CHECK-DAG: store i[[SZ]] 4, i[[SZ]]* {{%[^,]+}}
+
+// CHECK-DAG: store [[S1]]* %{{.+}}, [[S1]]** [[CBPADDR3:%.+]],
+// CHECK-DAG: store [[S1]]* %{{.+}}, [[S1]]** [[CPADDR3:%.+]],
+// CHECK-DAG: [[CBPADDR3]] = bitcast i8** {{%[^,]+}} to [[S1]]**
+// CHECK-DAG: [[CPADDR3]] = bitcast i8** {{%[^,]+}} to [[S1]]**
+// CHECK-DAG: store i[[SZ]] 8, i[[SZ]]* {{%[^,]+}}
+
+// CHECK-DAG: store i16* %{{.+}}, i16** [[CBPADDR4:%.+]],
+// CHECK-DAG: store i16* %{{.+}}, i16** [[CPADDR4:%.+]],
+// CHECK-DAG: [[CBPADDR4]] = bitcast i8** {{%[^,]+}} to i16**
+// CHECK-DAG: [[CPADDR4]] = bitcast i8** {{%[^,]+}} to i16**
+// CHECK-DAG: store i[[SZ]] [[CSIZE]], i[[SZ]]* {{%[^,]+}}
+
+// CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
+// CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:[^,]+]], label %[[END:[^,]+]]
+
+// CHECK: [[FAIL]]
+// CHECK: call void [[HVT7:@.+]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}})
+// CHECK-NEXT: br label %[[END]]
+// CHECK: [[END]]
+
+//
+// CHECK: define {{.*}}[[FSTATIC]]
+//
+// CHECK: [[IF:%.+]] = icmp sgt i32 {{[^,]+}}, 50
+// CHECK: br i1 [[IF]], label %[[IFTHEN:[^,]+]], label %[[IFELSE:[^,]+]]
+// CHECK: [[IFTHEN]]
+// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 4, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* getelementptr inbounds ([4 x i[[SZ]]], [4 x i[[SZ]]]* [[SIZET6]], i32 0, i32 0), i64* getelementptr inbounds ([4 x i64], [4 x i64]* [[MAPT6]], i32 0, i32 0), i32 1, i32 0)
+// CHECK-DAG: [[BPR]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[BP:%.+]], i32 0, i32 0
+// CHECK-DAG: [[PR]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[P:%.+]], i32 0, i32 0
+
+// CHECK-DAG: [[BPADDR0:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[BP]], i32 0, i32 0
+// CHECK-DAG: [[PADDR0:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[P]], i32 0, i32 0
+// CHECK-DAG: [[CBPADDR0:%.+]] = bitcast i8** [[BPADDR0]] to i[[SZ]]*
+// CHECK-DAG: [[CPADDR0:%.+]] = bitcast i8** [[PADDR0]] to i[[SZ]]*
+// CHECK-DAG: store i[[SZ]] [[VAL0:%.+]], i[[SZ]]* [[CBPADDR0]],
+// CHECK-DAG: store i[[SZ]] [[VAL0]], i[[SZ]]* [[CPADDR0]],
+
+// CHECK-DAG: [[BPADDR1:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[BP]], i32 0, i32 1
+// CHECK-DAG: [[PADDR1:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[P]], i32 0, i32 1
+// CHECK-DAG: [[CBPADDR1:%.+]] = bitcast i8** [[BPADDR1]] to i[[SZ]]*
+// CHECK-DAG: [[CPADDR1:%.+]] = bitcast i8** [[PADDR1]] to i[[SZ]]*
+// CHECK-DAG: store i[[SZ]] [[VAL1:%.+]], i[[SZ]]* [[CBPADDR1]],
+// CHECK-DAG: store i[[SZ]] [[VAL1]], i[[SZ]]* [[CPADDR1]],
+
+// CHECK-DAG: [[BPADDR2:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[BP]], i32 0, i32 2
+// CHECK-DAG: [[PADDR2:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[P]], i32 0, i32 2
+// CHECK-DAG: [[CBPADDR2:%.+]] = bitcast i8** [[BPADDR2]] to i[[SZ]]*
+// CHECK-DAG: [[CPADDR2:%.+]] = bitcast i8** [[PADDR2]] to i[[SZ]]*
+// CHECK-DAG: store i[[SZ]] [[VAL2:%.+]], i[[SZ]]* [[CBPADDR2]],
+// CHECK-DAG: store i[[SZ]] [[VAL2]], i[[SZ]]* [[CPADDR2]],
+
+// CHECK-DAG: [[BPADDR3:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[BP]], i32 0, i32 3
+// CHECK-DAG: [[PADDR3:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[P]], i32 0, i32 3
+// CHECK-DAG: [[CBPADDR3:%.+]] = bitcast i8** [[BPADDR3]] to [10 x i32]**
+// CHECK-DAG: [[CPADDR3:%.+]] = bitcast i8** [[PADDR3]] to [10 x i32]**
+// CHECK-DAG: store [10 x i32]* [[VAL3:%.+]], [10 x i32]** [[CBPADDR3]],
+// CHECK-DAG: store [10 x i32]* [[VAL3]], [10 x i32]** [[CPADDR3]],
+
+// CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
+// CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
+// CHECK: [[FAIL]]
+// CHECK: call void [[HVT6:@.+]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}})
+// CHECK-NEXT: br label %[[END]]
+// CHECK: [[END]]
+// CHECK-NEXT: br label %[[IFEND:.+]]
+// CHECK: [[IFELSE]]
+// CHECK: call void [[HVT6]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}})
+// CHECK-NEXT: br label %[[IFEND]]
+// CHECK: [[IFEND]]
+
+//
+// CHECK: define {{.*}}[[FTEMPLATE]]
+//
+// CHECK: [[IF:%.+]] = icmp sgt i32 {{[^,]+}}, 40
+// CHECK: br i1 [[IF]], label %[[IFTHEN:[^,]+]], label %[[IFELSE:[^,]+]]
+// CHECK: [[IFTHEN]]
+// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 3, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* getelementptr inbounds ([3 x i[[SZ]]], [3 x i[[SZ]]]* [[SIZET5]], i32 0, i32 0), i64* getelementptr inbounds ([3 x i64], [3 x i64]* [[MAPT5]], i32 0, i32 0), i32 1, i32 0)
+// CHECK-DAG: [[BPR]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BP:%.+]], i32 0, i32 0
+// CHECK-DAG: [[PR]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[P:%.+]], i32 0, i32 0
+
+// CHECK-DAG: [[BPADDR0:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BP]], i32 0, i32 0
+// CHECK-DAG: [[PADDR0:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[P]], i32 0, i32 0
+// CHECK-DAG: [[CBPADDR0:%.+]] = bitcast i8** [[BPADDR0]] to i[[SZ]]*
+// CHECK-DAG: [[CPADDR0:%.+]] = bitcast i8** [[PADDR0]] to i[[SZ]]*
+// CHECK-DAG: store i[[SZ]] [[VAL0:%.+]], i[[SZ]]* [[CBPADDR0]],
+// CHECK-DAG: store i[[SZ]] [[VAL0]], i[[SZ]]* [[CPADDR0]],
+
+// CHECK-DAG: [[BPADDR1:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BP]], i32 0, i32 1
+// CHECK-DAG: [[PADDR1:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[P]], i32 0, i32 1
+// CHECK-DAG: [[CBPADDR1:%.+]] = bitcast i8** [[BPADDR1]] to i[[SZ]]*
+// CHECK-DAG: [[CPADDR1:%.+]] = bitcast i8** [[PADDR1]] to i[[SZ]]*
+// CHECK-DAG: store i[[SZ]] [[VAL1:%.+]], i[[SZ]]* [[CBPADDR1]],
+// CHECK-DAG: store i[[SZ]] [[VAL1]], i[[SZ]]* [[CPADDR1]],
+
+// CHECK-DAG: [[BPADDR2:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BP]], i32 0, i32 2
+// CHECK-DAG: [[PADDR2:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[P]], i32 0, i32 2
+// CHECK-DAG: [[CBPADDR2:%.+]] = bitcast i8** [[BPADDR2]] to [10 x i32]**
+// CHECK-DAG: [[CPADDR2:%.+]] = bitcast i8** [[PADDR2]] to [10 x i32]**
+// CHECK-DAG: store [10 x i32]* [[VAL2:%.+]], [10 x i32]** [[CBPADDR2]],
+// CHECK-DAG: store [10 x i32]* [[VAL2]], [10 x i32]** [[CPADDR2]],
+
+// CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
+// CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
+// CHECK: [[FAIL]]
+// CHECK: call void [[HVT5:@.+]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}})
+// CHECK-NEXT: br label %[[END]]
+// CHECK: [[END]]
+// CHECK-NEXT: br label %[[IFEND:.+]]
+// CHECK: [[IFELSE]]
+// CHECK: call void [[HVT:@.+]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}})
+// CHECK-NEXT: br label %[[IFEND]]
+// CHECK: [[IFEND]]
+
+// Check that the offloading functions are emitted and that the arguments are
+// correct and loaded correctly for the target regions of the callees of bar().
+
+// CHECK: define internal void [[HVT7]]
+// Create local storage for each capture.
+// CHECK: [[LOCAL_THIS:%.+]] = alloca [[S1]]*
+// CHECK: [[LOCAL_B:%.+]] = alloca i[[SZ]]
+// CHECK: [[LOCAL_VLA1:%.+]] = alloca i[[SZ]]
+// CHECK: [[LOCAL_VLA2:%.+]] = alloca i[[SZ]]
+// CHECK: [[LOCAL_C:%.+]] = alloca i16*
+// CHECK: [[LOCAL_B_CASTED:%.+]] = alloca i[[SZ]]
+// CHECK-DAG: store [[S1]]* [[ARG_THIS:%.+]], [[S1]]** [[LOCAL_THIS]]
+// CHECK-DAG: store i[[SZ]] [[ARG_B:%.+]], i[[SZ]]* [[LOCAL_B]]
+// CHECK-DAG: store i[[SZ]] [[ARG_VLA1:%.+]], i[[SZ]]* [[LOCAL_VLA1]]
+// CHECK-DAG: store i[[SZ]] [[ARG_VLA2:%.+]], i[[SZ]]* [[LOCAL_VLA2]]
+// CHECK-DAG: store i16* [[ARG_C:%.+]], i16** [[LOCAL_C]]
+// Store captures in the context.
+// CHECK-DAG: [[REF_THIS:%.+]] = load [[S1]]*, [[S1]]** [[LOCAL_THIS]],
+// CHECK-64-DAG:[[CONV_BP:%.+]] = bitcast i[[SZ]]* [[LOCAL_B]] to i32*
+// CHECK-DAG: [[VAL_VLA1:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_VLA1]],
+// CHECK-DAG: [[VAL_VLA2:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_VLA2]],
+// CHECK-DAG: [[REF_C:%.+]] = load i16*, i16** [[LOCAL_C]],
+
+// CHECK-64-DAG:[[CONV_B:%.+]] = load i32, i32* [[CONV_BP]]
+// CHECK-64-DAG:[[CONV:%.+]] = bitcast i[[SZ]]* [[LOCAL_B_CASTED]] to i32*
+// CHECK-64-DAG:store i32 [[CONV_B]], i32* [[CONV]], align
+// CHECK-32-DAG:[[LOCAL_BV:%.+]] = load i32, i32* [[LOCAL_B]]
+// CHECK-32-DAG:store i32 [[LOCAL_BV]], i32* [[LOCAL_B_CASTED]], align
+// CHECK-DAG: [[REF_B:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_B_CASTED]],
+
+// CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* [[DEF_LOC]], i32 5, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, [[S1]]*, i[[SZ]], i[[SZ]], i[[SZ]], i16*)* [[OMP_OUTLINED5:@.+]] to void (i32*, i32*, ...)*), [[S1]]* [[REF_THIS]], i[[SZ]] [[REF_B]], i[[SZ]] [[VAL_VLA1]], i[[SZ]] [[VAL_VLA2]], i16* [[REF_C]])
+//
+//
+// CHECK: define internal {{.*}}void [[OMP_OUTLINED5]](i32* noalias %.global_tid., i32* noalias %.bound_tid., [[S1]]* %{{.+}}, i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, i16* {{.+}})
+// To reduce complexity, we're only going as far as validating the signature of the outlined parallel function.
+
+
+// CHECK: define internal void [[HVT6]]
+// Create local storage for each capture.
+// CHECK: [[LOCAL_A:%.+]] = alloca i[[SZ]]
+// CHECK: [[LOCAL_AA:%.+]] = alloca i[[SZ]]
+// CHECK: [[LOCAL_AAA:%.+]] = alloca i[[SZ]]
+// CHECK: [[LOCAL_B:%.+]] = alloca [10 x i32]*
+// CHECK: [[LOCAL_A_CASTED:%.+]] = alloca i[[SZ]]
+// CHECK: [[LOCAL_AA_CASTED:%.+]] = alloca i[[SZ]]
+// CHECK: [[LOCAL_AAA_CASTED:%.+]] = alloca i[[SZ]]
+// CHECK-DAG: store i[[SZ]] [[ARG_A:%.+]], i[[SZ]]* [[LOCAL_A]]
+// CHECK-DAG: store i[[SZ]] [[ARG_AA:%.+]], i[[SZ]]* [[LOCAL_AA]]
+// CHECK-DAG: store i[[SZ]] [[ARG_AAA:%.+]], i[[SZ]]* [[LOCAL_AAA]]
+// CHECK-DAG: store [10 x i32]* [[ARG_B:%.+]], [10 x i32]** [[LOCAL_B]]
+// Store captures in the context.
+// CHECK-64-DAG:[[CONV_AP:%.+]] = bitcast i[[SZ]]* [[LOCAL_A]] to i32*
+// CHECK-DAG: [[CONV_AAP:%.+]] = bitcast i[[SZ]]* [[LOCAL_AA]] to i16*
+// CHECK-DAG: [[CONV_AAAP:%.+]] = bitcast i[[SZ]]* [[LOCAL_AAA]] to i8*
+// CHECK-DAG: [[REF_B:%.+]] = load [10 x i32]*, [10 x i32]** [[LOCAL_B]],
+
+// CHECK-64-DAG:[[CONV_A:%.+]] = load i32, i32* [[CONV_AP]]
+// CHECK-64-DAG:[[CONV:%.+]] = bitcast i[[SZ]]* [[LOCAL_A_CASTED]] to i32*
+// CHECK-64-DAG:store i32 [[CONV_A]], i32* [[CONV]], align
+// CHECK-32-DAG:[[LOCAL_AV:%.+]] = load i32, i32* [[LOCAL_A]]
+// CHECK-32-DAG:store i32 [[LOCAL_AV]], i32* [[LOCAL_A_CASTED]], align
+// CHECK-DAG: [[REF_A:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_A_CASTED]],
+
+// CHECK-DAG: [[CONV_AA:%.+]] = load i16, i16* [[CONV_AAP]]
+// CHECK-DAG: [[CONV:%.+]] = bitcast i[[SZ]]* [[LOCAL_AA_CASTED]] to i16*
+// CHECK-DAG: store i16 [[CONV_AA]], i16* [[CONV]], align
+// CHECK-DAG: [[REF_AA:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_AA_CASTED]],
+
+// CHECK-DAG: [[CONV_AAA:%.+]] = load i8, i8* [[CONV_AAAP]]
+// CHECK-DAG: [[CONV:%.+]] = bitcast i[[SZ]]* [[LOCAL_AAA_CASTED]] to i8*
+// CHECK-DAG: store i8 [[CONV_AAA]], i8* [[CONV]], align
+// CHECK-DAG: [[REF_AAA:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_AAA_CASTED]],
+
+// CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* [[DEF_LOC]], i32 4, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i[[SZ]], i[[SZ]], i[[SZ]], [10 x i32]*)* [[OMP_OUTLINED6:@.+]] to void (i32*, i32*, ...)*), i[[SZ]] [[REF_A]], i[[SZ]] [[REF_AA]], i[[SZ]] [[REF_AAA]], [10 x i32]* [[REF_B]])
+//
+//
+// CHECK: define internal {{.*}}void [[OMP_OUTLINED6]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, [10 x i32]* {{.+}})
+// To reduce complexity, we're only going as far as validating the signature of the outlined parallel function.
+
+// CHECK: define internal void [[HVT5]]
+// Create local storage for each capture.
+// CHECK: [[LOCAL_A:%.+]] = alloca i[[SZ]]
+// CHECK: [[LOCAL_AA:%.+]] = alloca i[[SZ]]
+// CHECK: [[LOCAL_B:%.+]] = alloca [10 x i32]*
+// CHECK: [[LOCAL_A_CASTED:%.+]] = alloca i[[SZ]]
+// CHECK: [[LOCAL_AA_CASTED:%.+]] = alloca i[[SZ]]
+// CHECK-DAG: store i[[SZ]] [[ARG_A:%.+]], i[[SZ]]* [[LOCAL_A]]
+// CHECK-DAG: store i[[SZ]] [[ARG_AA:%.+]], i[[SZ]]* [[LOCAL_AA]]
+// CHECK-DAG: store [10 x i32]* [[ARG_B:%.+]], [10 x i32]** [[LOCAL_B]]
+// Store captures in the context.
+// CHECK-64-DAG:[[CONV_AP:%.+]] = bitcast i[[SZ]]* [[LOCAL_A]] to i32*
+// CHECK-DAG: [[CONV_AAP:%.+]] = bitcast i[[SZ]]* [[LOCAL_AA]] to i16*
+// CHECK-DAG: [[REF_B:%.+]] = load [10 x i32]*, [10 x i32]** [[LOCAL_B]],
+
+// CHECK-64-DAG:[[CONV_A:%.+]] = load i32, i32* [[CONV_AP]]
+// CHECK-64-DAG:[[CONV:%.+]] = bitcast i[[SZ]]* [[LOCAL_A_CASTED]] to i32*
+// CHECK-64-DAG:store i32 [[CONV_A]], i32* [[CONV]], align
+// CHECK-32-DAG:[[LOCAL_AV:%.+]] = load i32, i32* [[LOCAL_A]]
+// CHECK-32-DAG:store i32 [[LOCAL_AV]], i32* [[LOCAL_A_CASTED]], align
+// CHECK-DAG: [[REF_A:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_A_CASTED]],
+
+// CHECK-DAG: [[CONV_AA:%.+]] = load i16, i16* [[CONV_AAP]]
+// CHECK-DAG: [[CONV:%.+]] = bitcast i[[SZ]]* [[LOCAL_AA_CASTED]] to i16*
+// CHECK-DAG: store i16 [[CONV_AA]], i16* [[CONV]], align
+// CHECK-DAG: [[REF_AA:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_AA_CASTED]],
+
+// CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* [[DEF_LOC]], i32 3, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i[[SZ]], i[[SZ]], [10 x i32]*)* [[OMP_OUTLINED7:@.+]] to void (i32*, i32*, ...)*), i[[SZ]] [[REF_A]], i[[SZ]] [[REF_AA]], [10 x i32]* [[REF_B]])
+//
+//
+// CHECK: define internal {{.*}}void [[OMP_OUTLINED7]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, [10 x i32]* {{.+}})
+// To reduce complexity, we're only going as far as validating the signature of the outlined parallel function.
+
+#endif
diff --git a/test/OpenMP/target_parallel_for_codegen_registration.cpp b/test/OpenMP/target_parallel_for_codegen_registration.cpp
new file mode 100644
index 000000000000..24f0c06771ec
--- /dev/null
+++ b/test/OpenMP/target_parallel_for_codegen_registration.cpp
@@ -0,0 +1,451 @@
+// Test host codegen.
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+
+// Test target parallel for codegen - host bc file has to be created first.
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm-bc %s -o %t-ppc-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s -check-prefix=TCHECK
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s -check-prefix=TCHECK
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm-bc %s -o %t-x86-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s -check-prefix=TCHECK
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s -check-prefix=TCHECK
+
+// Check that no target code is emmitted if no omptests flag was provided.
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s -check-prefix=CHECK-NTARGET
+
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+// CHECK-DAG: [[SA:%.+]] = type { [4 x i32] }
+// CHECK-DAG: [[SB:%.+]] = type { [8 x i32] }
+// CHECK-DAG: [[SC:%.+]] = type { [16 x i32] }
+// CHECK-DAG: [[SD:%.+]] = type { [32 x i32] }
+// CHECK-DAG: [[SE:%.+]] = type { [64 x i32] }
+// CHECK-DAG: [[ST1:%.+]] = type { [228 x i32] }
+// CHECK-DAG: [[ST2:%.+]] = type { [1128 x i32] }
+// CHECK-DAG: [[ENTTY:%.+]] = type { i8*, i8*, i[[SZ:32|64]], i32, i32 }
+// CHECK-DAG: [[DEVTY:%.+]] = type { i8*, i8*, [[ENTTY]]*, [[ENTTY]]* }
+// CHECK-DAG: [[DSCTY:%.+]] = type { i32, [[DEVTY]]*, [[ENTTY]]*, [[ENTTY]]* }
+
+// TCHECK: [[ENTTY:%.+]] = type { i8*, i8*, i[[SZ:32|64]], i32, i32 }
+
+// CHECK-DAG: $[[REGFN:\.omp_offloading\..+]] = comdat
+
+// CHECK-DAG: [[A1:@.+]] = internal global [[SA]]
+// CHECK-DAG: [[A2:@.+]] = global [[SA]]
+// CHECK-DAG: [[B1:@.+]] = global [[SB]]
+// CHECK-DAG: [[B2:@.+]] = global [[SB]]
+// CHECK-DAG: [[C1:@.+]] = internal global [[SC]]
+// CHECK-DAG: [[D1:@.+]] = global [[SD]]
+// CHECK-DAG: [[E1:@.+]] = global [[SE]]
+// CHECK-DAG: [[T1:@.+]] = global [[ST1]]
+// CHECK-DAG: [[T2:@.+]] = global [[ST2]]
+
+// CHECK-NTARGET-DAG: [[SA:%.+]] = type { [4 x i32] }
+// CHECK-NTARGET-DAG: [[SB:%.+]] = type { [8 x i32] }
+// CHECK-NTARGET-DAG: [[SC:%.+]] = type { [16 x i32] }
+// CHECK-NTARGET-DAG: [[SD:%.+]] = type { [32 x i32] }
+// CHECK-NTARGET-DAG: [[SE:%.+]] = type { [64 x i32] }
+// CHECK-NTARGET-DAG: [[ST1:%.+]] = type { [228 x i32] }
+// CHECK-NTARGET-DAG: [[ST2:%.+]] = type { [1128 x i32] }
+// CHECK-NTARGET-NOT: type { i8*, i8*, %
+// CHECK-NTARGET-NOT: type { i32, %
+
+// We have 7 target regions
+
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// TCHECK-NOT: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
+
+// CHECK-NTARGET-NOT: private constant i8 0
+// CHECK-NTARGET-NOT: private unnamed_addr constant [1 x i
+
+// CHECK-DAG: [[NAMEPTR1:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME1:__omp_offloading_[0-9a-f]+_[0-9a-f]+__Z.+_l[0-9]+]]\00"
+// CHECK-DAG: [[ENTRY1:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR1]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR2:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME2:.+]]\00"
+// CHECK-DAG: [[ENTRY2:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR2]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR3:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME3:.+]]\00"
+// CHECK-DAG: [[ENTRY3:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR3]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR4:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME4:.+]]\00"
+// CHECK-DAG: [[ENTRY4:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR4]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR5:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME5:.+]]\00"
+// CHECK-DAG: [[ENTRY5:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR5]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR6:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME6:.+]]\00"
+// CHECK-DAG: [[ENTRY6:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR6]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR7:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME7:.+]]\00"
+// CHECK-DAG: [[ENTRY7:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR7]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR8:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME8:.+]]\00"
+// CHECK-DAG: [[ENTRY8:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR8]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR9:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME9:.+]]\00"
+// CHECK-DAG: [[ENTRY9:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR9]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR10:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME10:.+]]\00"
+// CHECK-DAG: [[ENTRY10:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR10]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR11:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME11:.+]]\00"
+// CHECK-DAG: [[ENTRY11:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR11]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR12:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME12:.+]]\00"
+// CHECK-DAG: [[ENTRY12:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR12]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+
+// TCHECK-DAG: [[NAMEPTR1:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME1:__omp_offloading_[0-9a-f]+_[0-9a-f]+__Z.+_l[0-9]+]]\00"
+// TCHECK-DAG: [[ENTRY1:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR1]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR2:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME2:.+]]\00"
+// TCHECK-DAG: [[ENTRY2:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR2]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR3:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME3:.+]]\00"
+// TCHECK-DAG: [[ENTRY3:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR3]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR4:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME4:.+]]\00"
+// TCHECK-DAG: [[ENTRY4:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR4]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR5:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME5:.+]]\00"
+// TCHECK-DAG: [[ENTRY5:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR5]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR6:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME6:.+]]\00"
+// TCHECK-DAG: [[ENTRY6:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR6]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR7:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME7:.+]]\00"
+// TCHECK-DAG: [[ENTRY7:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR7]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR8:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME8:.+]]\00"
+// TCHECK-DAG: [[ENTRY8:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR8]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR9:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME9:.+]]\00"
+// TCHECK-DAG: [[ENTRY9:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR9]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR10:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME10:.+]]\00"
+// TCHECK-DAG: [[ENTRY10:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR10]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR11:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME11:.+]]\00"
+// TCHECK-DAG: [[ENTRY11:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR11]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR12:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME12:.+]]\00"
+// TCHECK-DAG: [[ENTRY12:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR12]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+
+// CHECK: [[ENTBEGIN:@.+]] = external constant [[ENTTY]]
+// CHECK: [[ENTEND:@.+]] = external constant [[ENTTY]]
+// CHECK: [[DEVBEGIN:@.+]] = external constant i8
+// CHECK: [[DEVEND:@.+]] = external constant i8
+// CHECK: [[IMAGES:@.+]] = internal unnamed_addr constant [1 x [[DEVTY]]] [{{.+}} { i8* [[DEVBEGIN]], i8* [[DEVEND]], [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }], comdat($[[REGFN]])
+// CHECK: [[DESC:@.+]] = internal constant [[DSCTY]] { i32 1, [[DEVTY]]* getelementptr inbounds ([1 x [[DEVTY]]], [1 x [[DEVTY]]]* [[IMAGES]], i32 0, i32 0), [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }, comdat($[[REGFN]])
+
+// We have 4 initializers, one for the 500 priority, another one for 501, or more for the default priority, and the last one for the offloading registration function.
+// CHECK: @llvm.global_ctors = appending global [4 x { i32, void ()*, i8* }] [
+// CHECK-SAME: { i32, void ()*, i8* } { i32 500, void ()* [[P500:@[^,]+]], i8* null },
+// CHECK-SAME: { i32, void ()*, i8* } { i32 501, void ()* [[P501:@[^,]+]], i8* null },
+// CHECK-SAME: { i32, void ()*, i8* } { i32 65535, void ()* [[PMAX:@[^,]+]], i8* null },
+// CHECK-SAME: { i32, void ()*, i8* } { i32 0, void ()* bitcast (void (i8*)* @[[REGFN]] to void ()*), i8* bitcast (void (i8*)* @[[REGFN]] to i8*) }]
+
+// CHECK-NTARGET: @llvm.global_ctors = appending global [3 x { i32, void ()*, i8* }] [
+
+extern int *R;
+
+struct SA {
+ int arr[4];
+ void foo() {
+ int a = *R;
+ a += 1;
+ *R = a;
+ }
+ SA() {
+ int a = *R;
+ a += 2;
+ *R = a;
+ }
+ ~SA() {
+ int a = *R;
+ a += 3;
+ *R = a;
+ }
+};
+
+struct SB {
+ int arr[8];
+ void foo() {
+ int a = *R;
+ #pragma omp target parallel for
+ for (int i = 0; i < 10; ++i)
+ a += 4;
+ *R = a;
+ }
+ SB() {
+ int a = *R;
+ a += 5;
+ *R = a;
+ }
+ ~SB() {
+ int a = *R;
+ a += 6;
+ *R = a;
+ }
+};
+
+struct SC {
+ int arr[16];
+ void foo() {
+ int a = *R;
+ a += 7;
+ *R = a;
+ }
+ SC() {
+ int a = *R;
+ #pragma omp target parallel for
+ for (int i = 0; i < 10; ++i)
+ a += 8;
+ *R = a;
+ }
+ ~SC() {
+ int a = *R;
+ a += 9;
+ *R = a;
+ }
+};
+
+struct SD {
+ int arr[32];
+ void foo() {
+ int a = *R;
+ a += 10;
+ *R = a;
+ }
+ SD() {
+ int a = *R;
+ a += 11;
+ *R = a;
+ }
+ ~SD() {
+ int a = *R;
+ #pragma omp target parallel for
+ for (int i = 0; i < 10; ++i)
+ a += 12;
+ *R = a;
+ }
+};
+
+struct SE {
+ int arr[64];
+ void foo() {
+ int a = *R;
+ #pragma omp target parallel for if(target: 0)
+ for (int i = 0; i < 10; ++i)
+ a += 13;
+ *R = a;
+ }
+ SE() {
+ int a = *R;
+ #pragma omp target parallel for
+ for (int i = 0; i < 10; ++i)
+ a += 14;
+ *R = a;
+ }
+ ~SE() {
+ int a = *R;
+ #pragma omp target parallel for
+ for (int i = 0; i < 10; ++i)
+ a += 15;
+ *R = a;
+ }
+};
+
+template <int x>
+struct ST {
+ int arr[128 + x];
+ void foo() {
+ int a = *R;
+ #pragma omp target parallel for
+ for (int i = 0; i < 10; ++i)
+ a += 16 + x;
+ *R = a;
+ }
+ ST() {
+ int a = *R;
+ #pragma omp target parallel for
+ for (int i = 0; i < 10; ++i)
+ a += 17 + x;
+ *R = a;
+ }
+ ~ST() {
+ int a = *R;
+ #pragma omp target parallel for
+ for (int i = 0; i < 10; ++i)
+ a += 18 + x;
+ *R = a;
+ }
+};
+
+// We have to make sure we us all the target regions:
+//CHECK-DAG: define internal void @[[NAME1]](
+//CHECK-DAG: call void @[[NAME1]](
+//CHECK-DAG: define internal void @[[NAME2]](
+//CHECK-DAG: call void @[[NAME2]](
+//CHECK-DAG: define internal void @[[NAME3]](
+//CHECK-DAG: call void @[[NAME3]](
+//CHECK-DAG: define internal void @[[NAME4]](
+//CHECK-DAG: call void @[[NAME4]](
+//CHECK-DAG: define internal void @[[NAME5]](
+//CHECK-DAG: call void @[[NAME5]](
+//CHECK-DAG: define internal void @[[NAME6]](
+//CHECK-DAG: call void @[[NAME6]](
+//CHECK-DAG: define internal void @[[NAME7]](
+//CHECK-DAG: call void @[[NAME7]](
+//CHECK-DAG: define internal void @[[NAME8]](
+//CHECK-DAG: call void @[[NAME8]](
+//CHECK-DAG: define internal void @[[NAME9]](
+//CHECK-DAG: call void @[[NAME9]](
+//CHECK-DAG: define internal void @[[NAME10]](
+//CHECK-DAG: call void @[[NAME10]](
+//CHECK-DAG: define internal void @[[NAME11]](
+//CHECK-DAG: call void @[[NAME11]](
+//CHECK-DAG: define internal void @[[NAME12]](
+//CHECK-DAG: call void @[[NAME12]](
+
+//TCHECK-DAG: define void @[[NAME1]](
+//TCHECK-DAG: define void @[[NAME2]](
+//TCHECK-DAG: define void @[[NAME3]](
+//TCHECK-DAG: define void @[[NAME4]](
+//TCHECK-DAG: define void @[[NAME5]](
+//TCHECK-DAG: define void @[[NAME6]](
+//TCHECK-DAG: define void @[[NAME7]](
+//TCHECK-DAG: define void @[[NAME8]](
+//TCHECK-DAG: define void @[[NAME9]](
+//TCHECK-DAG: define void @[[NAME10]](
+//TCHECK-DAG: define void @[[NAME11]](
+//TCHECK-DAG: define void @[[NAME12]](
+
+// CHECK-NTARGET-NOT: __tgt_target
+// CHECK-NTARGET-NOT: __tgt_register_lib
+// CHECK-NTARGET-NOT: __tgt_unregister_lib
+
+// TCHECK-NOT: __tgt_target
+// TCHECK-NOT: __tgt_register_lib
+// TCHECK-NOT: __tgt_unregister_lib
+
+// We have 2 initializers with priority 500
+//CHECK: define internal void [[P500]](
+//CHECK: call void @{{.+}}()
+//CHECK: call void @{{.+}}()
+//CHECK-NOT: call void @{{.+}}()
+//CHECK: ret void
+
+// We have 1 initializers with priority 501
+//CHECK: define internal void [[P501]](
+//CHECK: call void @{{.+}}()
+//CHECK-NOT: call void @{{.+}}()
+//CHECK: ret void
+
+// We have 6 initializers with default priority
+//CHECK: define internal void [[PMAX]](
+//CHECK: call void @{{.+}}()
+//CHECK: call void @{{.+}}()
+//CHECK: call void @{{.+}}()
+//CHECK: call void @{{.+}}()
+//CHECK: call void @{{.+}}()
+//CHECK: call void @{{.+}}()
+//CHECK-NOT: call void @{{.+}}()
+//CHECK: ret void
+
+// Check registration and unregistration
+
+//CHECK: define internal void @[[UNREGFN:.+]](i8*)
+//CHECK-SAME: comdat($[[REGFN]]) {
+//CHECK: call i32 @__tgt_unregister_lib([[DSCTY]]* [[DESC]])
+//CHECK: ret void
+//CHECK: declare i32 @__tgt_unregister_lib([[DSCTY]]*)
+
+//CHECK: define linkonce hidden void @[[REGFN]](i8*)
+//CHECK-SAME: comdat {
+//CHECK: call i32 @__tgt_register_lib([[DSCTY]]* [[DESC]])
+//CHECK: call i32 @__cxa_atexit(void (i8*)* @[[UNREGFN]], i8* bitcast ([[DSCTY]]* [[DESC]] to i8*),
+//CHECK: ret void
+//CHECK: declare i32 @__tgt_register_lib([[DSCTY]]*)
+
+static __attribute__((init_priority(500))) SA a1;
+SA a2;
+SB __attribute__((init_priority(500))) b1;
+SB __attribute__((init_priority(501))) b2;
+static SC c1;
+SD d1;
+SE e1;
+ST<100> t1;
+ST<1000> t2;
+
+
+int bar(int a){
+ int r = a;
+
+ a1.foo();
+ a2.foo();
+ b1.foo();
+ b2.foo();
+ c1.foo();
+ d1.foo();
+ e1.foo();
+ t1.foo();
+ t2.foo();
+
+ #pragma omp target parallel for
+ for (int i = 0; i < 10; ++i)
+ ++r;
+
+ return r + *R;
+}
+
+// Check metadata is properly generated:
+// CHECK: !omp_offload.info = !{!{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID:-?[0-9]+]], i32 [[FILEID:-?[0-9]+]], !"_ZN2SB3fooEv", i32 195, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SDD1Ev", i32 247, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SEC1Ev", i32 265, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SED1Ev", i32 272, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EE3fooEv", i32 284, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EEC1Ev", i32 291, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_Z3bari", i32 415, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EED1Ev", i32 298, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EEC1Ev", i32 291, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EED1Ev", i32 298, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EE3fooEv", i32 284, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SCC1Ev", i32 221, i32 {{[0-9]+}}}
+
+// TCHECK: !omp_offload.info = !{!{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID:-?[0-9]+]], i32 [[FILEID:-?[0-9]+]], !"_ZN2SB3fooEv", i32 195, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SDD1Ev", i32 247, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SEC1Ev", i32 265, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SED1Ev", i32 272, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EE3fooEv", i32 284, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EEC1Ev", i32 291, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_Z3bari", i32 415, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EED1Ev", i32 298, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EEC1Ev", i32 291, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EED1Ev", i32 298, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EE3fooEv", i32 284, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SCC1Ev", i32 221, i32 {{[0-9]+}}}
+
+#endif
diff --git a/test/OpenMP/target_parallel_for_codegen_registration_naming.cpp b/test/OpenMP/target_parallel_for_codegen_registration_naming.cpp
new file mode 100644
index 000000000000..b42b5b55a505
--- /dev/null
+++ b/test/OpenMP/target_parallel_for_codegen_registration_naming.cpp
@@ -0,0 +1,68 @@
+// Test host codegen.
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+
+// Test target parallel for codegen - host bc file has to be created first.
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm-bc %s -o %t-ppc-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s -check-prefix=TCHECK
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s -check-prefix=TCHECK
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm-bc %s -o %t-x86-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s -check-prefix=TCHECK
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s -check-prefix=TCHECK
+
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+// CHECK: [[CA:%.+]] = type { i32* }
+
+// CHECK: define {{.*}}i32 @[[NNAME:.+]](i32 {{.*}}%{{.+}})
+int nested(int a){
+ // CHECK: call void @__omp_offloading_[[FILEID:[0-9a-f]+_[0-9a-f]+]]_[[NNAME]]_l[[T1L:[0-9]+]](
+ #pragma omp target parallel for
+ for (int i = 0; i < 10; ++i)
+ ++a;
+
+ // CHECK: call void @"[[LNAME:.+]]"([[CA]]*
+ auto F = [&](){
+ #pragma omp parallel
+ {
+ #pragma omp target parallel for
+ for (int i = 0; i < 10; ++i)
+ ++a;
+ }
+ };
+
+ F();
+
+ return a;
+}
+
+// CHECK: define {{.*}}void @__omp_offloading_[[FILEID]]_[[NNAME]]_l[[T1L]](
+// TCHECK: define {{.*}}void @__omp_offloading_[[FILEID:[0-9a-f]+_[0-9a-f]+]]_[[NNAME:.+]]_l[[T1L:[0-9]+]](
+
+// CHECK: define {{.*}}void @"[[LNAME]]"(
+// CHECK: call void {{.*}}@__kmpc_fork_call{{.+}}[[PNAME:@.+]] to
+
+// CHECK: define {{.*}}void [[PNAME]](
+// CHECK: call void @__omp_offloading_[[FILEID]]_[[NNAME]]_l[[T2L:[0-9]+]](
+
+// CHECK: define {{.*}}void @__omp_offloading_[[FILEID]]_[[NNAME]]_l[[T2L]](
+// TCHECK: define {{.*}}void @__omp_offloading_[[FILEID]]_[[NNAME:.+]]_l[[T2L:[0-9]+]](
+
+
+// Check metadata is properly generated:
+// CHECK: !omp_offload.info = !{!{{[0-9]+}}, !{{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 {{-?[0-9]+}}, i32 {{-?[0-9]+}}, !"[[NNAME]]", i32 [[T1L]], i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 {{-?[0-9]+}}, i32 {{-?[0-9]+}}, !"[[NNAME]]", i32 [[T2L]], i32 {{[0-9]+}}}
+
+// TCHECK: !omp_offload.info = !{!{{[0-9]+}}, !{{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 {{-?[0-9]+}}, i32 {{-?[0-9]+}}, !"[[NNAME]]", i32 [[T1L]], i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 {{-?[0-9]+}}, i32 {{-?[0-9]+}}, !"[[NNAME]]", i32 [[T2L]], i32 {{[0-9]+}}}
+#endif
diff --git a/test/OpenMP/target_parallel_for_debug_codegen.cpp b/test/OpenMP/target_parallel_for_debug_codegen.cpp
new file mode 100644
index 000000000000..0e0bb7e85306
--- /dev/null
+++ b/test/OpenMP/target_parallel_for_debug_codegen.cpp
@@ -0,0 +1,113 @@
+// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc
+// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - -debug-info-kind=limited | FileCheck %s
+// expected-no-diagnostics
+
+int main() {
+ /* int(*b)[a]; */
+ /* int *(**c)[a]; */
+ bool bb;
+ int a;
+ int b[10][10];
+ int c[10][10][10];
+#pragma omp target parallel for firstprivate(a, b) map(tofrom \
+ : c) map(tofrom \
+ : bb) if (a)
+ for (int i = 0; i < 10; ++i) {
+ int &f = c[1][1][1];
+ int &g = a;
+ int &h = b[1][1];
+ int d = 15;
+ a = 5;
+ b[0][a] = 10;
+ c[0][0][a] = 11;
+ b[0][a] = c[0][0][a];
+ bb |= b[0][a];
+ }
+#pragma omp target parallel for firstprivate(a) map(tofrom \
+ : c, b) map(to \
+ : bb)
+ for (int i = 0; i < 10; ++i) {
+ int &f = c[1][1][1];
+ int &g = a;
+ int &h = b[1][1];
+ int d = 15;
+ a = 5;
+ b[0][a] = 10;
+ c[0][0][a] = 11;
+ b[0][a] = c[0][0][a];
+ d = bb;
+ }
+#pragma omp target parallel for map(tofrom \
+ : a, c, b) map(from \
+ : bb)
+ for (int i = 0; i < 10; ++i) {
+ int &f = c[1][1][1];
+ int &g = a;
+ int &h = b[1][1];
+ int d = 15;
+ a = 5;
+ b[0][a] = 10;
+ c[0][0][a] = 11;
+ b[0][a] = c[0][0][a];
+ bb = b[0][a];
+ }
+ return 0;
+}
+
+// CHECK: define internal void @__omp_offloading{{[^(]+}}([10 x [10 x [10 x i32]]] addrspace(1)* {{[^,]+}}, i32 {{[^,]+}}, [10 x [10 x i32]]* {{[^,]+}}, i8 addrspace(1)* noalias{{[^,]+}}, i1 {{[^)]+}})
+// CHECK: addrspacecast [10 x [10 x [10 x i32]]] addrspace(1)* %{{.+}} to [10 x [10 x [10 x i32]]]*
+// CHECK: call void [[NONDEBUG_WRAPPER:.+]](i32* {{[^,]+}}, i32* {{[^,]+}}, [10 x [10 x [10 x i32]]]* {{[^,]+}}, i64 {{[^,]+}}, [10 x [10 x i32]]* {{[^,]+}}, i8* {{[^)]+}})
+
+// CHECK: define internal void [[DEBUG_PARALLEL:@.+]](i32* {{[^,]+}}, i32* {{[^,]+}}, [10 x [10 x [10 x i32]]] addrspace(1)* noalias{{[^,]+}}, i32 {{[^,]+}}, [10 x [10 x i32]]* noalias{{[^,]+}}, i8 addrspace(1)* noalias{{[^)]+}})
+// CHECK: addrspacecast [10 x [10 x [10 x i32]]] addrspace(1)* %{{.+}} to [10 x [10 x [10 x i32]]]*
+
+// CHECK: define internal void [[NONDEBUG_WRAPPER]](i32* {{[^,]+}}, i32* {{[^,]+}}, [10 x [10 x [10 x i32]]]* dereferenceable{{[^,]+}}, i64 {{[^,]+}}, [10 x [10 x i32]]* dereferenceable{{[^,]+}}, i8* dereferenceable{{[^)]+}})
+// CHECK: addrspacecast [10 x [10 x [10 x i32]]]* %{{.+}} to [10 x [10 x [10 x i32]]] addrspace(1)*
+// CHECK: call void [[DEBUG_PARALLEL]](i32* {{[^,]+}}, i32* {{[^,]+}}, [10 x [10 x [10 x i32]]] addrspace(1)* {{[^,]+}}, i32 {{[^,]+}}, [10 x [10 x i32]]* {{[^,]+}}, i8 addrspace(1)* {{[^)]+}})
+
+// CHECK: define void @__omp_offloading_{{[^(]+}}([10 x [10 x [10 x i32]]]* dereferenceable{{[^,]+}}, i64 {{[^,]+}}, [10 x [10 x i32]]* dereferenceable{{[^,]+}}, i8* dereferenceable{{[^)]+}})
+// CHECK: addrspacecast [10 x [10 x [10 x i32]]]* %{{.+}} to [10 x [10 x [10 x i32]]] addrspace(1)*
+// CHECK: call void @__omp_offloading_{{[^(]+}}([10 x [10 x [10 x i32]]] addrspace(1)* {{[^,]+}}, i32 {{[^,]+}}, [10 x [10 x i32]]* {{[^,]+}}, i8 addrspace(1)* {{[^)]+}})
+
+// CHECK: define internal void @__omp_offloading_{{[^(]+}}([10 x [10 x [10 x i32]]] addrspace(1)* noalias{{[^,]+}}, i32 {{[^,]+}}, [10 x [10 x i32]] addrspace(1)* noalias{{[^,]+}}, i8 addrspace(1)* noalias{{[^)]+}})
+// CHECK: addrspacecast [10 x [10 x [10 x i32]]] addrspace(1)* %{{.+}} to [10 x [10 x [10 x i32]]]*
+// CHECK: addrspacecast [10 x [10 x i32]] addrspace(1)* %{{.+}} to [10 x [10 x i32]]*
+// CHECK: call void [[NONDEBUG_WRAPPER:.+]](i32* {{[^,]+}}, i32* {{[^,]+}}, [10 x [10 x [10 x i32]]]* {{[^,]+}}, i64 {{[^,]+}}, [10 x [10 x i32]]* {{[^,]+}}, i8* {{[^)]+}})
+
+// CHECK: define internal void [[DEBUG_PARALLEL:@.+]](i32* {{[^,]+}}, i32* {{[^,]+}}, [10 x [10 x [10 x i32]]] addrspace(1)* noalias{{[^,]+}}, i32 {{[^,]+}}, [10 x [10 x i32]] addrspace(1)* noalias{{[^,]+}}, i8 addrspace(1)* {{[^)]+}})
+// CHECK: addrspacecast [10 x [10 x [10 x i32]]] addrspace(1)* %{{.+}} to [10 x [10 x [10 x i32]]]*
+// CHECK: addrspacecast [10 x [10 x i32]] addrspace(1)* %{{.+}} to [10 x [10 x i32]]*
+
+// CHECK: define internal void [[NONDEBUG_WRAPPER]](i32* {{[^,]+}}, i32* {{[^,]+}}, [10 x [10 x [10 x i32]]]* dereferenceable{{[^,]+}}, i64 {{[^,]+}}, [10 x [10 x i32]]* dereferenceable{{[^,]+}}, i8* dereferenceable{{[^)]+}})
+// CHECK: addrspacecast [10 x [10 x [10 x i32]]]* %{{.+}} to [10 x [10 x [10 x i32]]] addrspace(1)*
+// CHECK: addrspacecast [10 x [10 x i32]]* %{{.+}} to [10 x [10 x i32]] addrspace(1)*
+// CHECK: call void [[DEBUG_PARALLEL]](i32* {{[^,]+}}, i32* {{[^,]+}}, [10 x [10 x [10 x i32]]] addrspace(1)* {{[^,]+}}, i32 {{[^,]+}}, [10 x [10 x i32]] addrspace(1)* {{[^,]+}}, i8 addrspace(1)* {{[^)]+}})
+
+// CHECK: define void @__omp_offloading_{{[^(]+}}([10 x [10 x [10 x i32]]]* dereferenceable{{[^,]+}}, i64 {{[^,]+}}, [10 x [10 x i32]]* dereferenceable{{[^,]+}}, i8* dereferenceable{{[^)]+}})
+// CHECK: addrspacecast [10 x [10 x [10 x i32]]]* %{{.+}} to [10 x [10 x [10 x i32]]] addrspace(1)*
+// CHECK: addrspacecast [10 x [10 x i32]]* %{{.+}} to [10 x [10 x i32]] addrspace(1)*
+// CHECK: call void @__omp_offloading_{{[^(]+}}([10 x [10 x [10 x i32]]] addrspace(1)* {{[^,]+}}, i32 {{[^,]+}}, [10 x [10 x i32]] addrspace(1)* {{[^,]+}}, i8 addrspace(1)* {{[^)]+}})
+
+// CHECK: define internal void @__omp_offloading_{{[^(]+}}([10 x [10 x [10 x i32]]] addrspace(1)* noalias{{[^,]+}}, i32 addrspace(1)* noalias{{[^,]+}}, [10 x [10 x i32]] addrspace(1)* noalias{{[^,]+}}, i8 addrspace(1)* noalias{{[^)]+}})
+// CHECK: addrspacecast [10 x [10 x [10 x i32]]] addrspace(1)* %{{.+}} to [10 x [10 x [10 x i32]]]*
+// CHECK: addrspacecast i32 addrspace(1)* %{{.+}} to i32*
+// CHECK: addrspacecast [10 x [10 x i32]] addrspace(1)* %{{.+}} to [10 x [10 x i32]]*
+// CHECK: call void [[NONDEBUG_WRAPPER:@.+]](i32* {{[^,]+}}, i32* {{[^,]+}}, [10 x [10 x [10 x i32]]]* {{[^,]+}}, i32* {{[^,]+}}, [10 x [10 x i32]]* {{[^,]+}}, i8* {{[^)]+}})
+
+// CHECK: define internal void [[DEBUG_PARALLEL:@.+]](i32* {{[^,]+}}, i32* {{[^,]+}}, [10 x [10 x [10 x i32]]] addrspace(1)* noalias{{[^,]+}}, i32 addrspace(1)* noalias{{[^,]+}}, [10 x [10 x i32]] addrspace(1)* noalias{{[^,]+}}, i8 addrspace(1)* noalias{{[^)]+}})
+// CHECK: addrspacecast [10 x [10 x [10 x i32]]] addrspace(1)* %{{.+}} to [10 x [10 x [10 x i32]]]*
+// CHECK: addrspacecast i32 addrspace(1)* %{{.+}} to i32*
+// CHECK: addrspacecast [10 x [10 x i32]] addrspace(1)* %{{.+}} to [10 x [10 x i32]]*
+
+// CHECK: define internal void [[NONDEBUG_WRAPPER]](i32* {{[^,]+}}, i32* {{[^,]+}}, [10 x [10 x [10 x i32]]]* dereferenceable{{[^,]+}}, i32* dereferenceable{{[^,]+}}, [10 x [10 x i32]]* dereferenceable{{[^,]+}}, i8* dereferenceable{{[^)]+}})
+// CHECK: addrspacecast [10 x [10 x [10 x i32]]]* %{{.+}} to [10 x [10 x [10 x i32]]] addrspace(1)*
+// CHECK: addrspacecast i32* %{{.+}} to i32 addrspace(1)*
+// CHECK: addrspacecast [10 x [10 x i32]]* %{{.+}} to [10 x [10 x i32]] addrspace(1)*
+// CHECK: call void [[DEBUG_PARALLEL]](i32* {{[^,]+}}, i32* {{[^,]+}}, [10 x [10 x [10 x i32]]] addrspace(1)* {{[^,]+}}, i32 addrspace(1)* {{[^,]+}}, [10 x [10 x i32]] addrspace(1)* {{[^,]+}}, i8 addrspace(1)* {{[^)]+}})
+
+// CHECK: define void @__omp_offloading_{{[^(]+}}([10 x [10 x [10 x i32]]]* dereferenceable{{[^,]+}}, i32* dereferenceable{{[^,]+}}, [10 x [10 x i32]]* dereferenceable{{[^,]+}}, i8* dereferenceable{{[^)]+}})
+// CHECK: addrspacecast [10 x [10 x [10 x i32]]]* %{{.+}} to [10 x [10 x [10 x i32]]] addrspace(1)*
+// CHECK: addrspacecast i32* %{{.+}} to i32 addrspace(1)*
+// CHECK: addrspacecast [10 x [10 x i32]]* %{{.+}} to [10 x [10 x i32]] addrspace(1)*
+// CHECK: call void @__omp_offloading_{{[^(]+}}([10 x [10 x [10 x i32]]] addrspace(1)* {{[^,]+}}, i32 addrspace(1)* {{[^,]+}}, [10 x [10 x i32]] addrspace(1)* {{[^,]+}}, i8 addrspace(1)* {{[^)]+}})
+
diff --git a/test/OpenMP/target_parallel_for_depend_messages.cpp b/test/OpenMP/target_parallel_for_depend_messages.cpp
index cf17d7a5def2..19872566161a 100644
--- a/test/OpenMP/target_parallel_for_depend_messages.cpp
+++ b/test/OpenMP/target_parallel_for_depend_messages.cpp
@@ -37,21 +37,21 @@ int main(int argc, char **argv, char *env[]) {
for (i = 0; i < argc; ++i) foo();
#pragma omp target parallel for depend (out: ) // expected-error {{expected expression}}
for (i = 0; i < argc; ++i) foo();
- #pragma omp target parallel for depend (inout : foobool(argc)), depend (in, argc) // expected-error {{expected variable name, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}}
+ #pragma omp target parallel for depend (inout : foobool(argc)), depend (in, argc) // expected-error {{expected addressable lvalue expression, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}}
for (i = 0; i < argc; ++i) foo();
#pragma omp target parallel for depend (out :S1) // expected-error {{'S1' does not refer to a value}}
for (i = 0; i < argc; ++i) foo();
- #pragma omp target parallel for depend(in : argv[1][1] = '2') // expected-error {{expected variable name, array element or array section}}
+ #pragma omp target parallel for depend(in : argv[1][1] = '2')
for (i = 0; i < argc; ++i) foo();
- #pragma omp target parallel for depend (in : vec[1]) // expected-error {{expected variable name, array element or array section}}
+ #pragma omp target parallel for depend (in : vec[1]) // expected-error {{expected addressable lvalue expression, array element or array section}}
for (i = 0; i < argc; ++i) foo();
#pragma omp target parallel for depend (in : argv[0])
for (i = 0; i < argc; ++i) foo();
#pragma omp target parallel for depend (in : ) // expected-error {{expected expression}}
for (i = 0; i < argc; ++i) foo();
- #pragma omp target parallel for depend (in : main) // expected-error {{expected variable name, array element or array section}}
+ #pragma omp target parallel for depend (in : main)
for (i = 0; i < argc; ++i) foo();
- #pragma omp target parallel for depend(in : a[0]) // expected-error{{expected variable name, array element or array section}}
+ #pragma omp target parallel for depend(in : a[0]) // expected-error{{expected addressable lvalue expression, array element or array section}}
for (i = 0; i < argc; ++i) foo();
#pragma omp target parallel for depend (in : vec[1:2]) // expected-error {{ value is not an array or pointer}}
for (i = 0; i < argc; ++i) foo();
diff --git a/test/OpenMP/target_parallel_for_lastprivate_messages.cpp b/test/OpenMP/target_parallel_for_lastprivate_messages.cpp
index c001b7f0d168..ee703a1ce32e 100644
--- a/test/OpenMP/target_parallel_for_lastprivate_messages.cpp
+++ b/test/OpenMP/target_parallel_for_lastprivate_messages.cpp
@@ -18,9 +18,9 @@ public:
S2 &operator=(const S2 &);
const S2 &operator=(const S2 &) const;
static float S2s; // expected-note {{static data member is predetermined as shared}}
- static const float S2sc;
+ static const float S2sc; // expected-note {{static data member is predetermined as shared}}
};
-const float S2::S2sc = 0; // expected-note {{static data member is predetermined as shared}}
+const float S2::S2sc = 0;
const S2 b;
const S2 ba[5];
class S3 {
diff --git a/test/OpenMP/target_parallel_for_map_messages.cpp b/test/OpenMP/target_parallel_for_map_messages.cpp
index f0019f94f493..f3e1c616b406 100644
--- a/test/OpenMP/target_parallel_for_map_messages.cpp
+++ b/test/OpenMP/target_parallel_for_map_messages.cpp
@@ -14,8 +14,8 @@ class S2 {
public:
S2():a(0) { }
S2(S2 &s2):a(s2.a) { }
- static float S2s; // expected-note 4 {{mappable type cannot contain static members}}
- static const float S2sc; // expected-note 4 {{mappable type cannot contain static members}}
+ static float S2s;
+ static const float S2sc;
};
const float S2::S2sc = 0;
const S2 b;
@@ -116,9 +116,9 @@ T tmain(T argc) {
for (i = 0; i < argc; ++i) foo();
#pragma omp target parallel for map(S1) // expected-error {{'S1' does not refer to a value}}
for (i = 0; i < argc; ++i) foo();
-#pragma omp target parallel for map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} expected-error 2 {{type 'S2' is not mappable to target}}
+#pragma omp target parallel for map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}}
for (i = 0; i < argc; ++i) foo();
-#pragma omp target parallel for map(ba) // expected-error 2 {{type 'S2' is not mappable to target}}
+#pragma omp target parallel for map(ba)
for (i = 0; i < argc; ++i) foo();
#pragma omp target parallel for map(ca)
for (i = 0; i < argc; ++i) foo();
@@ -222,11 +222,11 @@ int main(int argc, char **argv) {
for (i = 0; i < argc; ++i) foo();
#pragma omp target parallel for map(S1) // expected-error {{'S1' does not refer to a value}}
for (i = 0; i < argc; ++i) foo();
-#pragma omp target parallel for map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} expected-error 2 {{type 'S2' is not mappable to target}}
+#pragma omp target parallel for map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}}
for (i = 0; i < argc; ++i) foo();
#pragma omp target parallel for map(argv[1])
for (i = 0; i < argc; ++i) foo();
-#pragma omp target parallel for map(ba) // expected-error 2 {{type 'S2' is not mappable to target}}
+#pragma omp target parallel for map(ba)
for (i = 0; i < argc; ++i) foo();
#pragma omp target parallel for map(ca)
for (i = 0; i < argc; ++i) foo();
diff --git a/test/OpenMP/target_parallel_for_reduction_messages.cpp b/test/OpenMP/target_parallel_for_reduction_messages.cpp
index 234b71aec218..9f1f68f25f83 100644
--- a/test/OpenMP/target_parallel_for_reduction_messages.cpp
+++ b/test/OpenMP/target_parallel_for_reduction_messages.cpp
@@ -25,9 +25,9 @@ public:
S2() : a(0) {}
S2(S2 &s2) : a(s2.a) {}
static float S2s; // expected-note 2 {{static data member is predetermined as shared}}
- static const float S2sc;
+ static const float S2sc; // expected-note 2 {{'S2sc' declared here}}
};
-const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}}
+const float S2::S2sc = 0;
S2 b; // expected-note 3 {{'b' defined here}}
const S2 ba[5]; // expected-note 2 {{'ba' defined here}}
class S3 {
diff --git a/test/OpenMP/target_parallel_for_simd_ast_print.cpp b/test/OpenMP/target_parallel_for_simd_ast_print.cpp
index 82d72c3b1a4b..8f0ed97d5cd9 100644
--- a/test/OpenMP/target_parallel_for_simd_ast_print.cpp
+++ b/test/OpenMP/target_parallel_for_simd_ast_print.cpp
@@ -77,14 +77,14 @@ T tmain(T argc, T *argv) {
a = 2;
// CHECK-NEXT: for (T i = 0; i < 2; ++i)
// CHECK-NEXT: a = 2;
-#pragma omp target parallel for simd private(argc, b), firstprivate(c, d), lastprivate(d, f) collapse(N) schedule(static, N) ordered(N) if (parallel :argc) num_threads(N) default(shared) shared(e) reduction(+ : h)
+#pragma omp target parallel for simd private(argc, b), firstprivate(c, d), lastprivate(d, f) collapse(N) schedule(static, N) ordered if (parallel :argc) num_threads(N) default(shared) shared(e) reduction(+ : h)
for (int i = 0; i < 2; ++i)
for (int j = 0; j < 2; ++j)
for (int j = 0; j < 2; ++j)
for (int j = 0; j < 2; ++j)
for (int j = 0; j < 2; ++j)
foo();
- // CHECK-NEXT: #pragma omp target parallel for simd private(argc,b) firstprivate(c,d) lastprivate(d,f) collapse(N) schedule(static, N) ordered(N) if(parallel: argc) num_threads(N) default(shared) shared(e) reduction(+: h)
+ // CHECK-NEXT: #pragma omp target parallel for simd private(argc,b) firstprivate(c,d) lastprivate(d,f) collapse(N) schedule(static, N) ordered if(parallel: argc) num_threads(N) default(shared) shared(e) reduction(+: h)
// CHECK-NEXT: for (int i = 0; i < 2; ++i)
// CHECK-NEXT: for (int j = 0; j < 2; ++j)
// CHECK-NEXT: for (int j = 0; j < 2; ++j)
diff --git a/test/OpenMP/target_parallel_for_simd_codegen.cpp b/test/OpenMP/target_parallel_for_simd_codegen.cpp
new file mode 100644
index 000000000000..d168214df35f
--- /dev/null
+++ b/test/OpenMP/target_parallel_for_simd_codegen.cpp
@@ -0,0 +1,812 @@
+// Test host codegen.
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+
+// Test target codegen - host bc file has to be created first.
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm-bc %s -o %t-ppc-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-64
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-64
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm-bc %s -o %t-x86-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-32
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-32
+
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+// CHECK-DAG: %ident_t = type { i32, i32, i32, i32, i8* }
+// CHECK-DAG: [[STR:@.+]] = private unnamed_addr constant [23 x i8] c";unknown;unknown;0;0;;\00"
+// CHECK-DAG: [[DEF_LOC:@.+]] = private unnamed_addr constant %ident_t { i32 0, i32 2, i32 0, i32 0, i8* getelementptr inbounds ([23 x i8], [23 x i8]* [[STR]], i32 0, i32 0) }
+
+// CHECK-DAG: [[TT:%.+]] = type { i64, i8 }
+// CHECK-DAG: [[S1:%.+]] = type { double }
+// CHECK-DAG: [[ENTTY:%.+]] = type { i8*, i8*, i[[SZ:32|64]], i32, i32 }
+// CHECK-DAG: [[DEVTY:%.+]] = type { i8*, i8*, [[ENTTY]]*, [[ENTTY]]* }
+// CHECK-DAG: [[DSCTY:%.+]] = type { i32, [[DEVTY]]*, [[ENTTY]]*, [[ENTTY]]* }
+
+// TCHECK: [[ENTTY:%.+]] = type { i8*, i8*, i{{32|64}}, i32, i32 }
+
+// CHECK-DAG: $[[REGFN:\.omp_offloading\..+]] = comdat
+
+// We have 8 target regions, but only 7 that actually will generate offloading
+// code, only 6 will have mapped arguments, and only 4 have all-constant map
+// sizes.
+
+// CHECK-DAG: [[SIZET2:@.+]] = private unnamed_addr constant [3 x i[[SZ]]] [i[[SZ]] 2, i[[SZ]] 4, i[[SZ]] 4]
+// CHECK-DAG: [[MAPT2:@.+]] = private unnamed_addr constant [3 x i64] [i64 288, i64 288, i64 288]
+// CHECK-DAG: [[SIZET3:@.+]] = private unnamed_addr constant [2 x i[[SZ]]] [i[[SZ]] 4, i[[SZ]] 2]
+// CHECK-DAG: [[MAPT3:@.+]] = private unnamed_addr constant [2 x i64] [i64 288, i64 288]
+// CHECK-DAG: [[MAPT4:@.+]] = private unnamed_addr constant [10 x i64] [i64 288, i64 547, i64 288, i64 547, i64 547, i64 288, i64 288, i64 547, i64 547, i64 288]
+// CHECK-DAG: [[SIZET5:@.+]] = private unnamed_addr constant [3 x i[[SZ]]] [i[[SZ]] 4, i[[SZ]] 2, i[[SZ]] 40]
+// CHECK-DAG: [[MAPT5:@.+]] = private unnamed_addr constant [3 x i64] [i64 288, i64 288, i64 547]
+// CHECK-DAG: [[SIZET6:@.+]] = private unnamed_addr constant [4 x i[[SZ]]] [i[[SZ]] 4, i[[SZ]] 2, i[[SZ]] 1, i[[SZ]] 40]
+// CHECK-DAG: [[MAPT6:@.+]] = private unnamed_addr constant [4 x i64] [i64 288, i64 288, i64 288, i64 547]
+// CHECK-DAG: [[MAPT7:@.+]] = private unnamed_addr constant [5 x i64] [i64 547, i64 288, i64 288, i64 288, i64 547]
+// CHECK-DAG: @{{.*}} = private constant i8 0
+// CHECK-DAG: @{{.*}} = private constant i8 0
+// CHECK-DAG: @{{.*}} = private constant i8 0
+// CHECK-DAG: @{{.*}} = private constant i8 0
+// CHECK-DAG: @{{.*}} = private constant i8 0
+// CHECK-DAG: @{{.*}} = private constant i8 0
+// CHECK-DAG: @{{.*}} = private constant i8 0
+
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+// TCHECK-NOT: @{{.+}} = constant [[ENTTY]]
+
+// Check if offloading descriptor is created.
+// CHECK: [[ENTBEGIN:@.+]] = external constant [[ENTTY]]
+// CHECK: [[ENTEND:@.+]] = external constant [[ENTTY]]
+// CHECK: [[DEVBEGIN:@.+]] = external constant i8
+// CHECK: [[DEVEND:@.+]] = external constant i8
+// CHECK: [[IMAGES:@.+]] = internal unnamed_addr constant [1 x [[DEVTY]]] [{{.+}} { i8* [[DEVBEGIN]], i8* [[DEVEND]], [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }], comdat($[[REGFN]])
+// CHECK: [[DESC:@.+]] = internal constant [[DSCTY]] { i32 1, [[DEVTY]]* getelementptr inbounds ([1 x [[DEVTY]]], [1 x [[DEVTY]]]* [[IMAGES]], i32 0, i32 0), [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }, comdat($[[REGFN]])
+
+// Check target registration is registered as a Ctor.
+// CHECK: appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 0, void ()* bitcast (void (i8*)* @[[REGFN]] to void ()*), i8* bitcast (void (i8*)* @[[REGFN]] to i8*) }]
+
+
+template<typename tx, typename ty>
+struct TT{
+ tx X;
+ ty Y;
+};
+
+// CHECK-LABEL: get_val
+long long get_val() { return 0; }
+
+// CHECK: define {{.*}}[[FOO:@.+]](
+int foo(int n) {
+ int a = 0;
+ short aa = 0;
+ float b[10];
+ float bn[n];
+ double c[5][10];
+ double cn[5][n];
+ TT<long long, char> d;
+
+ // CHECK: [[RET:%.+]] = call i32 @__tgt_target_teams_nowait(i64 -1, i8* @{{[^,]+}}, i32 0, i8** null, i8** null, i[[SZ]]* null, i64* null, i32 1, i32 0)
+ // CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
+ // CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:[^,]+]], label %[[END:[^,]+]]
+ // CHECK: [[FAIL]]
+ // CHECK: call void [[HVT0:@.+]]()
+ // CHECK-NEXT: br label %[[END]]
+ // CHECK: [[END]]
+ #pragma omp target parallel for simd nowait
+ for (int i = 3; i < 32; i += 5) {
+ }
+
+ // CHECK: call void [[HVT1:@.+]](i[[SZ]] {{[^,]+}}, i{{32|64}}{{[*]*}} {{[^)]+}})
+ long long k = get_val();
+ #pragma omp target parallel for simd if(target: 0) linear(k : 3) schedule(dynamic)
+ for (int i = 10; i > 1; i--) {
+ a += 1;
+ }
+
+ // CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 3, i8** [[BP:%[^,]+]], i8** [[P:%[^,]+]], i[[SZ]]* getelementptr inbounds ([3 x i[[SZ]]], [3 x i[[SZ]]]* [[SIZET2]], i32 0, i32 0), i64* getelementptr inbounds ([3 x i64], [3 x i64]* [[MAPT2]], i32 0, i32 0), i32 1, i32 0)
+ // CHECK-DAG: [[BP]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BPR:%[^,]+]], i32 0, i32 0
+ // CHECK-DAG: [[P]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[PR:%[^,]+]], i32 0, i32 0
+ // CHECK-DAG: [[BPADDR0:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BPR]], i32 0, i32 0
+ // CHECK-DAG: [[PADDR0:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[PR]], i32 0, i32 0
+ // CHECK-DAG: [[CBPADDR0:%.+]] = bitcast i8** [[BPADDR0]] to i[[SZ]]*
+ // CHECK-DAG: [[CPADDR0:%.+]] = bitcast i8** [[PADDR0]] to i[[SZ]]*
+ // CHECK-DAG: store i[[SZ]] [[VAL0:%.+]], i[[SZ]]* [[CBPADDR0]],
+ // CHECK-DAG: store i[[SZ]] [[VAL0]], i[[SZ]]* [[CPADDR0]],
+ // CHECK-DAG: [[BPADDR1:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BPR]], i32 0, i32 1
+ // CHECK-DAG: [[PADDR1:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[PR]], i32 0, i32 1
+ // CHECK-DAG: [[CBPADDR1:%.+]] = bitcast i8** [[BPADDR1]] to i[[SZ]]*
+ // CHECK-DAG: [[CPADDR1:%.+]] = bitcast i8** [[PADDR1]] to i[[SZ]]*
+ // CHECK-DAG: store i[[SZ]] [[VAL1:%.+]], i[[SZ]]* [[CBPADDR1]],
+ // CHECK-DAG: store i[[SZ]] [[VAL1]], i[[SZ]]* [[CPADDR1]],
+ // CHECK-DAG: [[BPADDR2:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BPR]], i32 0, i32 1
+ // CHECK-DAG: [[PADDR2:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[PR]], i32 0, i32 1
+ // CHECK-DAG: [[CBPADDR2:%.+]] = bitcast i8** [[BPADDR2]] to i[[SZ]]*
+ // CHECK-DAG: [[CPADDR2:%.+]] = bitcast i8** [[PADDR2]] to i[[SZ]]*
+ // CHECK-DAG: store i[[SZ]] [[VAL2:%.+]], i[[SZ]]* [[CBPADDR2]],
+ // CHECK-DAG: store i[[SZ]] [[VAL2]], i[[SZ]]* [[CPADDR2]],
+
+ // CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
+ // CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:[^,]+]], label %[[END:[^,]+]]
+ // CHECK: [[FAIL]]
+ // CHECK: call void [[HVT2:@.+]](i[[SZ]] {{[^,]+}}, i[[SZ]] {{[^)]+}})
+ // CHECK-NEXT: br label %[[END]]
+ // CHECK: [[END]]
+ int lin = 12;
+ #pragma omp target parallel for simd if(target: 1) linear(lin, a : get_val())
+ for (unsigned long long it = 2000; it >= 600; it-=400) {
+ aa += 1;
+ }
+
+ // CHECK: [[IF:%.+]] = icmp sgt i32 {{[^,]+}}, 10
+ // CHECK: br i1 [[IF]], label %[[IFTHEN:[^,]+]], label %[[IFELSE:[^,]+]]
+ // CHECK: [[IFTHEN]]
+ // CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 2, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* getelementptr inbounds ([2 x i[[SZ]]], [2 x i[[SZ]]]* [[SIZET3]], i32 0, i32 0), i64* getelementptr inbounds ([2 x i64], [2 x i64]* [[MAPT3]], i32 0, i32 0), i32 1, i32 0)
+ // CHECK-DAG: [[BPR]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[BP:%[^,]+]], i32 0, i32 0
+ // CHECK-DAG: [[PR]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[P:%[^,]+]], i32 0, i32 0
+
+ // CHECK-DAG: [[BPADDR0:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[BP]], i32 0, i32 0
+ // CHECK-DAG: [[PADDR0:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[P]], i32 0, i32 0
+ // CHECK-DAG: [[CBPADDR0:%.+]] = bitcast i8** [[BPADDR0]] to i[[SZ]]*
+ // CHECK-DAG: [[CPADDR0:%.+]] = bitcast i8** [[PADDR0]] to i[[SZ]]*
+ // CHECK-DAG: store i[[SZ]] [[VAL0:%.+]], i[[SZ]]* [[CBPADDR0]],
+ // CHECK-DAG: store i[[SZ]] [[VAL0]], i[[SZ]]* [[CPADDR0]],
+
+ // CHECK-DAG: [[BPADDR1:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[BP]], i32 0, i32 1
+ // CHECK-DAG: [[PADDR1:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[P]], i32 0, i32 1
+ // CHECK-DAG: [[CBPADDR1:%.+]] = bitcast i8** [[BPADDR1]] to i[[SZ]]*
+ // CHECK-DAG: [[CPADDR1:%.+]] = bitcast i8** [[PADDR1]] to i[[SZ]]*
+ // CHECK-DAG: store i[[SZ]] [[VAL1:%.+]], i[[SZ]]* [[CBPADDR1]],
+ // CHECK-DAG: store i[[SZ]] [[VAL1]], i[[SZ]]* [[CPADDR1]],
+ // CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
+ // CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
+ // CHECK: [[FAIL]]
+ // CHECK: call void [[HVT3:@.+]]({{[^,]+}}, {{[^,]+}})
+ // CHECK-NEXT: br label %[[END]]
+ // CHECK: [[END]]
+ // CHECK-NEXT: br label %[[IFEND:.+]]
+ // CHECK: [[IFELSE]]
+ // CHECK: call void [[HVT3]]({{[^,]+}}, {{[^,]+}})
+ // CHECK-NEXT: br label %[[IFEND]]
+ // CHECK: [[IFEND]]
+
+ #pragma omp target parallel for simd if(target: n>10)
+ for (short it = 6; it <= 20; it-=-4) {
+ a += 1;
+ aa += 1;
+ }
+
+ // We capture 3 VLA sizes in this target region
+ // CHECK: [[A_VAL:%.+]] = load i32, i32* %{{.+}},
+ // CHECK: store i32 [[A_VAL]], i32* [[A_CADDR:%.+]],
+ // CHECK-64: [[A_VAL:%.+]] = load i32, i32* %{{.+}},
+ // CHECK-64: [[A_ADDR:%.+]] = bitcast i[[SZ]]* [[A_CADDR:%.+]] to i32*
+ // CHECK-64: store i32 [[A_VAL]], i32* [[A_ADDR]],
+ // CHECK-64: [[A_CVAL:%.+]] = load i[[SZ]], i[[SZ]]* [[A_CADDR]],
+
+ // CHECK-32: [[A_VAL:%.+]] = load i32, i32* %{{.+}},
+ // CHECK-32: store i32 [[A_VAL]], i32* [[A_CADDR:%.+]],
+ // CHECK-32: [[A_CVAL:%.+]] = load i[[SZ]], i[[SZ]]* [[A_CADDR]],
+
+ // CHECK: [[BNSIZE:%.+]] = mul nuw i[[SZ]] [[VLA0:%.+]], 4
+ // CHECK: [[CNELEMSIZE2:%.+]] = mul nuw i[[SZ]] 5, [[VLA1:%.+]]
+ // CHECK: [[CNSIZE:%.+]] = mul nuw i[[SZ]] [[CNELEMSIZE2]], 8
+
+ // CHECK: [[IF:%.+]] = icmp sgt i32 {{[^,]+}}, 20
+ // CHECK: br i1 [[IF]], label %[[TRY:[^,]+]], label %[[FAIL:[^,]+]]
+ // CHECK: [[TRY]]
+ // CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 10, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* [[SR:%[^,]+]], i64* getelementptr inbounds ([10 x i64], [10 x i64]* [[MAPT4]], i32 0, i32 0), i32 1, i32 0)
+ // CHECK-DAG: [[BPR]] = getelementptr inbounds [10 x i8*], [10 x i8*]* [[BP:%[^,]+]], i32 0, i32 0
+ // CHECK-DAG: [[PR]] = getelementptr inbounds [10 x i8*], [10 x i8*]* [[P:%[^,]+]], i32 0, i32 0
+ // CHECK-DAG: [[SR]] = getelementptr inbounds [10 x i[[SZ]]], [10 x i[[SZ]]]* [[S:%[^,]+]], i32 0, i32 0
+
+ // CHECK-DAG: [[SADDR0:%.+]] = getelementptr inbounds [10 x i[[SZ]]], [10 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX0:[0-9]+]]
+ // CHECK-DAG: [[BPADDR0:%.+]] = getelementptr inbounds [10 x i8*], [10 x i8*]* [[BP]], i32 0, i32 [[IDX0]]
+ // CHECK-DAG: [[PADDR0:%.+]] = getelementptr inbounds [10 x i8*], [10 x i8*]* [[P]], i32 0, i32 [[IDX0]]
+ // CHECK-DAG: [[SADDR1:%.+]] = getelementptr inbounds [10 x i[[SZ]]], [10 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX1:[0-9]+]]
+ // CHECK-DAG: [[BPADDR1:%.+]] = getelementptr inbounds [10 x i8*], [10 x i8*]* [[BP]], i32 0, i32 [[IDX1]]
+ // CHECK-DAG: [[PADDR1:%.+]] = getelementptr inbounds [10 x i8*], [10 x i8*]* [[P]], i32 0, i32 [[IDX1]]
+ // CHECK-DAG: [[SADDR2:%.+]] = getelementptr inbounds [10 x i[[SZ]]], [10 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX2:[0-9]+]]
+ // CHECK-DAG: [[BPADDR2:%.+]] = getelementptr inbounds [10 x i8*], [10 x i8*]* [[BP]], i32 0, i32 [[IDX2]]
+ // CHECK-DAG: [[PADDR2:%.+]] = getelementptr inbounds [10 x i8*], [10 x i8*]* [[P]], i32 0, i32 [[IDX2]]
+ // CHECK-DAG: [[SADDR3:%.+]] = getelementptr inbounds [10 x i[[SZ]]], [10 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX3:[0-9]+]]
+ // CHECK-DAG: [[BPADDR3:%.+]] = getelementptr inbounds [10 x i8*], [10 x i8*]* [[BP]], i32 0, i32 [[IDX3]]
+ // CHECK-DAG: [[PADDR3:%.+]] = getelementptr inbounds [10 x i8*], [10 x i8*]* [[P]], i32 0, i32 [[IDX3]]
+ // CHECK-DAG: [[SADDR4:%.+]] = getelementptr inbounds [10 x i[[SZ]]], [10 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX4:[0-9]+]]
+ // CHECK-DAG: [[BPADDR4:%.+]] = getelementptr inbounds [10 x i8*], [10 x i8*]* [[BP]], i32 0, i32 [[IDX4]]
+ // CHECK-DAG: [[PADDR4:%.+]] = getelementptr inbounds [10 x i8*], [10 x i8*]* [[P]], i32 0, i32 [[IDX4]]
+ // CHECK-DAG: [[SADDR5:%.+]] = getelementptr inbounds [10 x i[[SZ]]], [10 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX5:[0-9]+]]
+ // CHECK-DAG: [[BPADDR5:%.+]] = getelementptr inbounds [10 x i8*], [10 x i8*]* [[BP]], i32 0, i32 [[IDX5]]
+ // CHECK-DAG: [[PADDR5:%.+]] = getelementptr inbounds [10 x i8*], [10 x i8*]* [[P]], i32 0, i32 [[IDX5]]
+ // CHECK-DAG: [[SADDR6:%.+]] = getelementptr inbounds [10 x i[[SZ]]], [10 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX6:[0-9]+]]
+ // CHECK-DAG: [[BPADDR6:%.+]] = getelementptr inbounds [10 x i8*], [10 x i8*]* [[BP]], i32 0, i32 [[IDX6]]
+ // CHECK-DAG: [[PADDR6:%.+]] = getelementptr inbounds [10 x i8*], [10 x i8*]* [[P]], i32 0, i32 [[IDX6]]
+ // CHECK-DAG: [[SADDR7:%.+]] = getelementptr inbounds [10 x i[[SZ]]], [10 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX7:[0-9]+]]
+ // CHECK-DAG: [[BPADDR7:%.+]] = getelementptr inbounds [10 x i8*], [10 x i8*]* [[BP]], i32 0, i32 [[IDX7]]
+ // CHECK-DAG: [[PADDR7:%.+]] = getelementptr inbounds [10 x i8*], [10 x i8*]* [[P]], i32 0, i32 [[IDX7]]
+ // CHECK-DAG: [[SADDR8:%.+]] = getelementptr inbounds [10 x i[[SZ]]], [10 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX8:[0-9]+]]
+ // CHECK-DAG: [[BPADDR8:%.+]] = getelementptr inbounds [10 x i8*], [10 x i8*]* [[BP]], i32 0, i32 [[IDX8]]
+ // CHECK-DAG: [[PADDR8:%.+]] = getelementptr inbounds [10 x i8*], [10 x i8*]* [[P]], i32 0, i32 [[IDX8]]
+
+ // The names below are not necessarily consistent with the names used for the
+ // addresses above as some are repeated.
+ // CHECK-DAG: store i[[SZ]] [[VLA0]], i[[SZ]]* [[CBPADDR0:%.+]],
+ // CHECK-DAG: store i[[SZ]] [[VLA0]], i[[SZ]]* [[CPADDR0:%.+]],
+ // CHECK-DAG: [[CBPADDR0]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+ // CHECK-DAG: [[CPADDR0]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+ // CHECK-DAG: store i[[SZ]] {{4|8}}, i[[SZ]]* {{%[^,]+}}
+
+ // CHECK-DAG: store i[[SZ]] [[VLA1]], i[[SZ]]* [[CBPADDR1:%.+]],
+ // CHECK-DAG: store i[[SZ]] [[VLA1]], i[[SZ]]* [[CPADDR1:%.+]],
+ // CHECK-DAG: [[CBPADDR1]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+ // CHECK-DAG: [[CPADDR1]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+ // CHECK-DAG: store i[[SZ]] {{4|8}}, i[[SZ]]* {{%[^,]+}}
+
+ // CHECK-DAG: store i[[SZ]] 5, i[[SZ]]* [[CBPADDR2:%.+]],
+ // CHECK-DAG: store i[[SZ]] 5, i[[SZ]]* [[CPADDR2:%.+]],
+ // CHECK-DAG: [[CBPADDR2]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+ // CHECK-DAG: [[CPADDR2]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+ // CHECK-DAG: store i[[SZ]] {{4|8}}, i[[SZ]]* {{%[^,]+}}
+
+ // CHECK-DAG: store i[[SZ]] [[A_CVAL]], i[[SZ]]* [[CBPADDR3:%.+]],
+ // CHECK-DAG: store i[[SZ]] [[A_CVAL]], i[[SZ]]* [[CPADDR3:%.+]],
+ // CHECK-DAG: [[CBPADDR3]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+ // CHECK-DAG: [[CPADDR3]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+ // CHECK-DAG: store i[[SZ]] 4, i[[SZ]]* {{%[^,]+}}
+
+ // CHECK-DAG: store [10 x float]* %{{.+}}, [10 x float]** [[CBPADDR4:%.+]],
+ // CHECK-DAG: store [10 x float]* %{{.+}}, [10 x float]** [[CPADDR4:%.+]],
+ // CHECK-DAG: [[CBPADDR4]] = bitcast i8** {{%[^,]+}} to [10 x float]**
+ // CHECK-DAG: [[CPADDR4]] = bitcast i8** {{%[^,]+}} to [10 x float]**
+ // CHECK-DAG: store i[[SZ]] 40, i[[SZ]]* {{%[^,]+}}
+
+ // CHECK-DAG: store float* %{{.+}}, float** [[CBPADDR5:%.+]],
+ // CHECK-DAG: store float* %{{.+}}, float** [[CPADDR5:%.+]],
+ // CHECK-DAG: [[CBPADDR5]] = bitcast i8** {{%[^,]+}} to float**
+ // CHECK-DAG: [[CPADDR5]] = bitcast i8** {{%[^,]+}} to float**
+ // CHECK-DAG: store i[[SZ]] [[BNSIZE]], i[[SZ]]* {{%[^,]+}}
+
+ // CHECK-DAG: store [5 x [10 x double]]* %{{.+}}, [5 x [10 x double]]** [[CBPADDR6:%.+]],
+ // CHECK-DAG: store [5 x [10 x double]]* %{{.+}}, [5 x [10 x double]]** [[CPADDR6:%.+]],
+ // CHECK-DAG: [[CBPADDR6]] = bitcast i8** {{%[^,]+}} to [5 x [10 x double]]**
+ // CHECK-DAG: [[CPADDR6]] = bitcast i8** {{%[^,]+}} to [5 x [10 x double]]**
+ // CHECK-DAG: store i[[SZ]] 400, i[[SZ]]* {{%[^,]+}}
+
+ // CHECK-DAG: store double* %{{.+}}, double** [[CBPADDR7:%.+]],
+ // CHECK-DAG: store double* %{{.+}}, double** [[CPADDR7:%.+]],
+ // CHECK-DAG: [[CBPADDR7]] = bitcast i8** {{%[^,]+}} to double**
+ // CHECK-DAG: [[CPADDR7]] = bitcast i8** {{%[^,]+}} to double**
+ // CHECK-DAG: store i[[SZ]] [[CNSIZE]], i[[SZ]]* {{%[^,]+}}
+
+ // CHECK-DAG: store [[TT]]* %{{.+}}, [[TT]]** [[CBPADDR8:%.+]],
+ // CHECK-DAG: store [[TT]]* %{{.+}}, [[TT]]** [[CPADDR8:%.+]],
+ // CHECK-DAG: [[CBPADDR8]] = bitcast i8** {{%[^,]+}} to [[TT]]**
+ // CHECK-DAG: [[CPADDR8]] = bitcast i8** {{%[^,]+}} to [[TT]]**
+ // CHECK-DAG: store i[[SZ]] {{12|16}}, i[[SZ]]* {{%[^,]+}}
+
+ // CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
+ // CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:[^,]+]], label %[[END:[^,]+]]
+
+ // CHECK: [[FAIL]]
+ // CHECK: call void [[HVT4:@.+]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^)]+}})
+ // CHECK-NEXT: br label %[[END]]
+ // CHECK: [[END]]
+ #pragma omp target parallel for simd if(target: n>20) schedule(static, a)
+ for (unsigned char it = 'z'; it >= 'a'; it+=-1) {
+ a += 1;
+ b[2] += 1.0;
+ bn[3] += 1.0;
+ c[1][2] += 1.0;
+ cn[1][3] += 1.0;
+ d.X += 1;
+ d.Y += 1;
+ }
+
+ return a;
+}
+
+// Check that the offloading functions are emitted and that the arguments are
+// correct and loaded correctly for the target regions in foo().
+
+// CHECK: define internal void [[HVT0]]()
+// CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* [[DEF_LOC]], i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* [[OMP_OUTLINED:@.+]] to void (i32*, i32*, ...)*))
+//
+//
+// CHECK: define internal {{.*}}void [[OMP_OUTLINED]](i32* noalias %.global_tid., i32* noalias %.bound_tid.)
+// CHECK: !llvm.loop
+// CHECK: ret void
+// CHECK-NEXT: }
+
+
+// CHECK: define internal void [[HVT1]](i[[SZ]] %{{.+}}, i{{32|64}}{{[*]*.*}} %{{.+}})
+// Create stack storage and store argument in there.
+// CHECK: [[AA_ADDR:%.+]] = alloca i[[SZ]], align
+// CHECK: alloca i{{32|64}}{{[*]*}}, align
+// CHECK: [[AA_CASTED:%.+]] = alloca i[[SZ]], align
+// CHECK: store i[[SZ]] %{{.+}}, i[[SZ]]* [[AA_ADDR]], align
+// CHECK-64: [[AA_CADDR:%.+]] = bitcast i[[SZ]]* [[AA_ADDR]] to i32*
+// CHECK-64: [[AA:%.+]] = load i32, i32* [[AA_CADDR]], align
+// CHECK-32: [[AA:%.+]] = load i32, i32* [[AA_ADDR]], align
+// CHECK-64: [[AA_C:%.+]] = bitcast i[[SZ]]* [[AA_CASTED]] to i32*
+// CHECK-64: store i32 [[AA]], i32* [[AA_C]], align
+// CHECK-32: store i32 [[AA]], i32* [[AA_CASTED]], align
+// CHECK: [[PARAM:%.+]] = load i[[SZ]], i[[SZ]]* [[AA_CASTED]], align
+// CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* [[DEF_LOC]], i32 2, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i[[SZ]], i{{32|64}}{{[*]*}})* [[OMP_OUTLINED1:@.+]] to void (i32*, i32*, ...)*), i[[SZ]] [[PARAM]], i{{32|64}}{{[*]*}} %{{.+}})
+//
+//
+// CHECK: define internal {{.*}}void [[OMP_OUTLINED1]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i[[SZ]] %{{.+}})
+// CHECK: [[AA_ADDR:%.+]] = alloca i[[SZ]], align
+// CHECK: store i[[SZ]] %{{.+}}, i[[SZ]]* [[AA_ADDR]], align
+// CHECK-64: [[AA_CADDR:%.+]] = bitcast i[[SZ]]* [[AA_ADDR]] to i32*
+// CHECK-64: [[AA:%.+]] = load i32, i32* [[AA_CADDR]], align
+// CHECK-32: [[AA:%.+]] = load i32, i32* [[AA_ADDR]], align
+// CHECK: !llvm.mem.parallel_loop_access
+// CHECK: !llvm.loop
+// CHECK: ret void
+// CHECK-NEXT: }
+
+// CHECK: define internal void [[HVT2]](i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}})
+// Create stack storage and store argument in there.
+// CHECK: [[AA_ADDR:%.+]] = alloca i[[SZ]], align
+// CHECK: alloca i[[SZ]], align
+// CHECK: alloca i[[SZ]], align
+// CHECK: [[AA_CASTED:%.+]] = alloca i[[SZ]], align
+// CHECK: store i[[SZ]] %{{.+}}, i[[SZ]]* [[AA_ADDR]], align
+// CHECK: [[AA_CADDR:%.+]] = bitcast i[[SZ]]* [[AA_ADDR]] to i16*
+// CHECK: [[AA:%.+]] = load i16, i16* [[AA_CADDR]], align
+// CHECK: [[AA_C:%.+]] = bitcast i[[SZ]]* [[AA_CASTED]] to i16*
+// CHECK: store i16 [[AA]], i16* [[AA_C]], align
+// CHECK: [[PARAM:%.+]] = load i[[SZ]], i[[SZ]]* [[AA_CASTED]], align
+// CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* [[DEF_LOC]], i32 3, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i[[SZ]], i[[SZ]], i[[SZ]])* [[OMP_OUTLINED2:@.+]] to void (i32*, i32*, ...)*), i[[SZ]] [[PARAM]], i[[SZ]] {{.+}}, i[[SZ]] {{.+}})
+//
+//
+// CHECK: define internal {{.*}}void [[OMP_OUTLINED2]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}})
+// CHECK: [[AA_ADDR:%.+]] = alloca i[[SZ]], align
+// CHECK: store i[[SZ]] %{{.+}}, i[[SZ]]* [[AA_ADDR]], align
+// CHECK: [[AA_CADDR:%.+]] = bitcast i[[SZ]]* [[AA_ADDR]] to i16*
+// CHECK: [[AA:%.+]] = load i16, i16* [[AA_CADDR]], align
+// CHECK: !llvm.loop
+// CHECK: ret void
+// CHECK-NEXT: }
+
+// CHECK: define internal void [[HVT3]]
+// Create stack storage and store argument in there.
+// CHECK: [[A_ADDR:%.+]] = alloca i[[SZ]], align
+// CHECK: [[AA_ADDR:%.+]] = alloca i[[SZ]], align
+// CHECK: [[A_CASTED:%.+]] = alloca i[[SZ]], align
+// CHECK: [[AA_CASTED:%.+]] = alloca i[[SZ]], align
+// CHECK-DAG: store i[[SZ]] %{{.+}}, i[[SZ]]* [[A_ADDR]], align
+// CHECK-DAG: store i[[SZ]] %{{.+}}, i[[SZ]]* [[AA_ADDR]], align
+// CHECK-64-DAG:[[A_CADDR:%.+]] = bitcast i[[SZ]]* [[A_ADDR]] to i32*
+// CHECK-DAG: [[AA_CADDR:%.+]] = bitcast i[[SZ]]* [[AA_ADDR]] to i16*
+// CHECK-64-DAG:[[A:%.+]] = load i32, i32* [[A_CADDR]], align
+// CHECK-32-DAG:[[A:%.+]] = load i32, i32* [[A_ADDR]], align
+// CHECK-64-DAG:[[A_C:%.+]] = bitcast i[[SZ]]* [[A_CASTED]] to i32*
+// CHECK-64-DAG:store i32 [[A]], i32* [[A_C]], align
+// CHECK-32-DAG:store i32 [[A]], i32* [[A_CASTED]], align
+// CHECK-DAG: [[AA:%.+]] = load i16, i16* [[AA_CADDR]], align
+// CHECK-DAG: [[AA_C:%.+]] = bitcast i[[SZ]]* [[AA_CASTED]] to i16*
+// CHECK-DAG: store i16 [[AA]], i16* [[AA_C]], align
+// CHECK-DAG: [[PARAM1:%.+]] = load i[[SZ]], i[[SZ]]* [[A_CASTED]], align
+// CHECK-DAG: [[PARAM2:%.+]] = load i[[SZ]], i[[SZ]]* [[AA_CASTED]], align
+// CHECK-DAG: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* [[DEF_LOC]], i32 2, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i[[SZ]], i[[SZ]])* [[OMP_OUTLINED3:@.+]] to void (i32*, i32*, ...)*), i[[SZ]] [[PARAM1]], i[[SZ]] [[PARAM2]])
+//
+//
+// CHECK: define internal {{.*}}void [[OMP_OUTLINED3]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}})
+// CHECK: [[A_ADDR:%.+]] = alloca i[[SZ]], align
+// CHECK: [[AA_ADDR:%.+]] = alloca i[[SZ]], align
+// CHECK-DAG: store i[[SZ]] %{{.+}}, i[[SZ]]* [[A_ADDR]], align
+// CHECK-DAG: store i[[SZ]] %{{.+}}, i[[SZ]]* [[AA_ADDR]], align
+// CHECK-64-DAG:[[A_CADDR:%.+]] = bitcast i[[SZ]]* [[A_ADDR]] to i32*
+// CHECK-DAG: [[AA_CADDR:%.+]] = bitcast i[[SZ]]* [[AA_ADDR]] to i16*
+// CHECK: !llvm.loop
+// CHECK: ret void
+// CHECK-NEXT: }
+
+// CHECK: define internal void [[HVT4]]
+// Create local storage for each capture.
+// CHECK: [[LOCAL_A:%.+]] = alloca i[[SZ]]
+// CHECK: [[LOCAL_B:%.+]] = alloca [10 x float]*
+// CHECK: [[LOCAL_VLA1:%.+]] = alloca i[[SZ]]
+// CHECK: [[LOCAL_BN:%.+]] = alloca float*
+// CHECK: [[LOCAL_C:%.+]] = alloca [5 x [10 x double]]*
+// CHECK: [[LOCAL_VLA2:%.+]] = alloca i[[SZ]]
+// CHECK: [[LOCAL_VLA3:%.+]] = alloca i[[SZ]]
+// CHECK: [[LOCAL_CN:%.+]] = alloca double*
+// CHECK: [[LOCAL_D:%.+]] = alloca [[TT]]*
+// CHECK: alloca i[[SZ]]
+// CHECK: [[LOCAL_A_CASTED:%.+]] = alloca i[[SZ]]
+// CHECK-DAG: store i[[SZ]] [[ARG_A:%.+]], i[[SZ]]* [[LOCAL_A]]
+// CHECK-DAG: store [10 x float]* [[ARG_B:%.+]], [10 x float]** [[LOCAL_B]]
+// CHECK-DAG: store i[[SZ]] [[ARG_VLA1:%.+]], i[[SZ]]* [[LOCAL_VLA1]]
+// CHECK-DAG: store float* [[ARG_BN:%.+]], float** [[LOCAL_BN]]
+// CHECK-DAG: store [5 x [10 x double]]* [[ARG_C:%.+]], [5 x [10 x double]]** [[LOCAL_C]]
+// CHECK-DAG: store i[[SZ]] [[ARG_VLA2:%.+]], i[[SZ]]* [[LOCAL_VLA2]]
+// CHECK-DAG: store i[[SZ]] [[ARG_VLA3:%.+]], i[[SZ]]* [[LOCAL_VLA3]]
+// CHECK-DAG: store double* [[ARG_CN:%.+]], double** [[LOCAL_CN]]
+// CHECK-DAG: store [[TT]]* [[ARG_D:%.+]], [[TT]]** [[LOCAL_D]]
+
+// CHECK-64-DAG:[[CONV_AP:%.+]] = bitcast i[[SZ]]* [[LOCAL_A]] to i32*
+// CHECK-DAG: [[REF_B:%.+]] = load [10 x float]*, [10 x float]** [[LOCAL_B]],
+// CHECK-DAG: [[VAL_VLA1:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_VLA1]],
+// CHECK-DAG: [[REF_BN:%.+]] = load float*, float** [[LOCAL_BN]],
+// CHECK-DAG: [[REF_C:%.+]] = load [5 x [10 x double]]*, [5 x [10 x double]]** [[LOCAL_C]],
+// CHECK-DAG: [[VAL_VLA2:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_VLA2]],
+// CHECK-DAG: [[VAL_VLA3:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_VLA3]],
+// CHECK-DAG: [[REF_CN:%.+]] = load double*, double** [[LOCAL_CN]],
+// CHECK-DAG: [[REF_D:%.+]] = load [[TT]]*, [[TT]]** [[LOCAL_D]],
+
+// CHECK-64-DAG:[[CONV_A:%.+]] = load i32, i32* [[CONV_AP]]
+// CHECK-64-DAG:[[CONV:%.+]] = bitcast i[[SZ]]* [[LOCAL_A_CASTED]] to i32*
+// CHECK-64-DAG:store i32 [[CONV_A]], i32* [[CONV]], align
+// CHECK-32-DAG:[[LOCAL_AV:%.+]] = load i32, i32* [[LOCAL_A]]
+// CHECK-32-DAG:store i32 [[LOCAL_AV]], i32* [[LOCAL_A_CASTED]], align
+// CHECK-DAG: [[REF_A:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_A_CASTED]],
+
+// CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* [[DEF_LOC]], i32 10, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i[[SZ]], [10 x float]*, i[[SZ]], float*, [5 x [10 x double]]*, i[[SZ]], i[[SZ]], double*, [[TT]]*, i[[SZ]])* [[OMP_OUTLINED4:@.+]] to void (i32*, i32*, ...)*), i[[SZ]] [[REF_A]], [10 x float]* [[REF_B]], i[[SZ]] [[VAL_VLA1]], float* [[REF_BN]], [5 x [10 x double]]* [[REF_C]], i[[SZ]] [[VAL_VLA2]], i[[SZ]] [[VAL_VLA3]], double* [[REF_CN]], [[TT]]* [[REF_D]], i[[SZ]] %{{.+}})
+//
+//
+// CHECK: define internal {{.*}}void [[OMP_OUTLINED4]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i[[SZ]] %{{.+}}, [10 x float]* {{.+}}, i[[SZ]] %{{.+}}, float* {{.+}}, [5 x [10 x double]]* {{.+}}, i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, double* {{.+}}, [[TT]]* {{.+}})
+// To reduce complexity, we're only going as far as validating the signature of the outlined parallel function.
+
+template<typename tx>
+tx ftemplate(int n) {
+ tx a = 0;
+ short aa = 0;
+ tx b[10];
+
+ #pragma omp target parallel for simd if(target: n>40)
+ for (long long i = -10; i < 10; i += 3) {
+ a += 1;
+ aa += 1;
+ b[2] += 1;
+ }
+
+ return a;
+}
+
+static
+int fstatic(int n) {
+ int a = 0;
+ short aa = 0;
+ char aaa = 0;
+ int b[10];
+
+ #pragma omp target parallel for simd if(target: n>50)
+ for (unsigned i=100; i<10; i+=10) {
+ a += 1;
+ aa += 1;
+ aaa += 1;
+ b[2] += 1;
+ }
+
+ return a;
+}
+
+struct S1 {
+ double a;
+
+ int r1(int n){
+ int b = n+1;
+ short int c[2][n];
+
+ #pragma omp target parallel for simd if(target: n>60)
+ for (unsigned long long it = 2000; it >= 600; it -= 400) {
+ this->a = (double)b + 1.5;
+ c[1][1] = ++a;
+ }
+
+ return c[1][1] + (int)b;
+ }
+};
+
+// CHECK: define {{.*}}@{{.*}}bar{{.*}}
+int bar(int n){
+ int a = 0;
+
+ // CHECK: call {{.*}}i32 [[FOO]](i32 {{.*}})
+ a += foo(n);
+
+ S1 S;
+ // CHECK: call {{.*}}i32 [[FS1:@.+]]([[S1]]* {{.*}}, i32 {{.*}})
+ a += S.r1(n);
+
+ // CHECK: call {{.*}}i32 [[FSTATIC:@.+]](i32 {{.*}})
+ a += fstatic(n);
+
+ // CHECK: call {{.*}}i32 [[FTEMPLATE:@.+]](i32 {{.*}})
+ a += ftemplate<int>(n);
+
+ return a;
+}
+
+//
+// CHECK: define {{.*}}[[FS1]]
+//
+// CHECK: i8* @llvm.stacksave()
+// CHECK-64: [[B_ADDR:%.+]] = bitcast i[[SZ]]* [[B_CADDR:%.+]] to i32*
+// CHECK-64: store i32 %{{.+}}, i32* [[B_ADDR]],
+// CHECK-64: [[B_CVAL:%.+]] = load i[[SZ]], i[[SZ]]* [[B_CADDR]],
+
+// CHECK-32: store i32 %{{.+}}, i32* [[B_ADDR:%.+]],
+// CHECK-32: [[B_CVAL:%.+]] = load i[[SZ]], i[[SZ]]* [[B_ADDR]],
+
+// We capture 2 VLA sizes in this target region
+// CHECK: [[CELEMSIZE2:%.+]] = mul nuw i[[SZ]] 2, [[VLA0:%.+]]
+// CHECK: [[CSIZE:%.+]] = mul nuw i[[SZ]] [[CELEMSIZE2]], 2
+
+// CHECK: [[IF:%.+]] = icmp sgt i32 {{[^,]+}}, 60
+// CHECK: br i1 [[IF]], label %[[TRY:[^,]+]], label %[[FAIL:[^,]+]]
+// CHECK: [[TRY]]
+// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 5, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* [[SR:%[^,]+]], i64* getelementptr inbounds ([5 x i64], [5 x i64]* [[MAPT7]], i32 0, i32 0), i32 1, i32 0)
+// CHECK-DAG: [[BPR]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[BP:%.+]], i32 0, i32 0
+// CHECK-DAG: [[PR]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[P:%.+]], i32 0, i32 0
+// CHECK-DAG: [[SR]] = getelementptr inbounds [5 x i[[SZ]]], [5 x i[[SZ]]]* [[S:%.+]], i32 0, i32 0
+// CHECK-DAG: [[SADDR0:%.+]] = getelementptr inbounds [5 x i[[SZ]]], [5 x i[[SZ]]]* [[S]], i32 [[IDX0:[0-9]+]]
+// CHECK-DAG: [[BPADDR0:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[BP]], i32 [[IDX0]]
+// CHECK-DAG: [[PADDR0:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[P]], i32 [[IDX0]]
+// CHECK-DAG: [[SADDR1:%.+]] = getelementptr inbounds [5 x i[[SZ]]], [5 x i[[SZ]]]* [[S]], i32 [[IDX1:[0-9]+]]
+// CHECK-DAG: [[BPADDR1:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[BP]], i32 [[IDX1]]
+// CHECK-DAG: [[PADDR1:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[P]], i32 [[IDX1]]
+// CHECK-DAG: [[SADDR2:%.+]] = getelementptr inbounds [5 x i[[SZ]]], [5 x i[[SZ]]]* [[S]], i32 [[IDX2:[0-9]+]]
+// CHECK-DAG: [[BPADDR2:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[BP]], i32 [[IDX2]]
+// CHECK-DAG: [[PADDR2:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[P]], i32 [[IDX2]]
+// CHECK-DAG: [[SADDR3:%.+]] = getelementptr inbounds [5 x i[[SZ]]], [5 x i[[SZ]]]* [[S]], i32 [[IDX3:[0-9]+]]
+// CHECK-DAG: [[BPADDR3:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[BP]], i32 [[IDX3]]
+// CHECK-DAG: [[PADDR3:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[P]], i32 [[IDX3]]
+
+// The names below are not necessarily consistent with the names used for the
+// addresses above as some are repeated.
+// CHECK-DAG: store i[[SZ]] [[VLA0]], i[[SZ]]* [[CBPADDR0:%.+]],
+// CHECK-DAG: store i[[SZ]] [[VLA0]], i[[SZ]]* [[CPADDR0:%.+]],
+// CHECK-DAG: [[CBPADDR0]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+// CHECK-DAG: [[CPADDR0]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+// CHECK-DAG: store i[[SZ]] {{4|8}}, i[[SZ]]* {{%[^,]+}}
+
+// CHECK-DAG: store i[[SZ]] 2, i[[SZ]]* [[CBPADDR1:%.+]],
+// CHECK-DAG: store i[[SZ]] 2, i[[SZ]]* [[CPADDR1:%.+]],
+// CHECK-DAG: [[CBPADDR1]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+// CHECK-DAG: [[CPADDR1]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+// CHECK-DAG: store i[[SZ]] {{4|8}}, i[[SZ]]* {{%[^,]+}}
+
+// CHECK-DAG: store i[[SZ]] [[B_CVAL]], i[[SZ]]* [[CBPADDR2:%.+]],
+// CHECK-DAG: store i[[SZ]] [[B_CVAL]], i[[SZ]]* [[CPADDR2:%.+]],
+// CHECK-DAG: [[CBPADDR2]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+// CHECK-DAG: [[CPADDR2]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+// CHECK-DAG: store i[[SZ]] 4, i[[SZ]]* {{%[^,]+}}
+
+// CHECK-DAG: store [[S1]]* %{{.+}}, [[S1]]** [[CBPADDR3:%.+]],
+// CHECK-DAG: store [[S1]]* %{{.+}}, [[S1]]** [[CPADDR3:%.+]],
+// CHECK-DAG: [[CBPADDR3]] = bitcast i8** {{%[^,]+}} to [[S1]]**
+// CHECK-DAG: [[CPADDR3]] = bitcast i8** {{%[^,]+}} to [[S1]]**
+// CHECK-DAG: store i[[SZ]] 8, i[[SZ]]* {{%[^,]+}}
+
+// CHECK-DAG: store i16* %{{.+}}, i16** [[CBPADDR4:%.+]],
+// CHECK-DAG: store i16* %{{.+}}, i16** [[CPADDR4:%.+]],
+// CHECK-DAG: [[CBPADDR4]] = bitcast i8** {{%[^,]+}} to i16**
+// CHECK-DAG: [[CPADDR4]] = bitcast i8** {{%[^,]+}} to i16**
+// CHECK-DAG: store i[[SZ]] [[CSIZE]], i[[SZ]]* {{%[^,]+}}
+
+// CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
+// CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:[^,]+]], label %[[END:[^,]+]]
+
+// CHECK: [[FAIL]]
+// CHECK: call void [[HVT7:@.+]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}})
+// CHECK-NEXT: br label %[[END]]
+// CHECK: [[END]]
+
+//
+// CHECK: define {{.*}}[[FSTATIC]]
+//
+// CHECK: [[IF:%.+]] = icmp sgt i32 {{[^,]+}}, 50
+// CHECK: br i1 [[IF]], label %[[IFTHEN:[^,]+]], label %[[IFELSE:[^,]+]]
+// CHECK: [[IFTHEN]]
+// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 4, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* getelementptr inbounds ([4 x i[[SZ]]], [4 x i[[SZ]]]* [[SIZET6]], i32 0, i32 0), i64* getelementptr inbounds ([4 x i64], [4 x i64]* [[MAPT6]], i32 0, i32 0), i32 1, i32 0)
+// CHECK-DAG: [[BPR]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[BP:%.+]], i32 0, i32 0
+// CHECK-DAG: [[PR]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[P:%.+]], i32 0, i32 0
+
+// CHECK-DAG: [[BPADDR0:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[BP]], i32 0, i32 0
+// CHECK-DAG: [[PADDR0:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[P]], i32 0, i32 0
+// CHECK-DAG: [[CBPADDR0:%.+]] = bitcast i8** [[BPADDR0]] to i[[SZ]]*
+// CHECK-DAG: [[CPADDR0:%.+]] = bitcast i8** [[PADDR0]] to i[[SZ]]*
+// CHECK-DAG: store i[[SZ]] [[VAL0:%.+]], i[[SZ]]* [[CBPADDR0]],
+// CHECK-DAG: store i[[SZ]] [[VAL0]], i[[SZ]]* [[CPADDR0]],
+
+// CHECK-DAG: [[BPADDR1:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[BP]], i32 0, i32 1
+// CHECK-DAG: [[PADDR1:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[P]], i32 0, i32 1
+// CHECK-DAG: [[CBPADDR1:%.+]] = bitcast i8** [[BPADDR1]] to i[[SZ]]*
+// CHECK-DAG: [[CPADDR1:%.+]] = bitcast i8** [[PADDR1]] to i[[SZ]]*
+// CHECK-DAG: store i[[SZ]] [[VAL1:%.+]], i[[SZ]]* [[CBPADDR1]],
+// CHECK-DAG: store i[[SZ]] [[VAL1]], i[[SZ]]* [[CPADDR1]],
+
+// CHECK-DAG: [[BPADDR2:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[BP]], i32 0, i32 2
+// CHECK-DAG: [[PADDR2:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[P]], i32 0, i32 2
+// CHECK-DAG: [[CBPADDR2:%.+]] = bitcast i8** [[BPADDR2]] to i[[SZ]]*
+// CHECK-DAG: [[CPADDR2:%.+]] = bitcast i8** [[PADDR2]] to i[[SZ]]*
+// CHECK-DAG: store i[[SZ]] [[VAL2:%.+]], i[[SZ]]* [[CBPADDR2]],
+// CHECK-DAG: store i[[SZ]] [[VAL2]], i[[SZ]]* [[CPADDR2]],
+
+// CHECK-DAG: [[BPADDR3:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[BP]], i32 0, i32 3
+// CHECK-DAG: [[PADDR3:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[P]], i32 0, i32 3
+// CHECK-DAG: [[CBPADDR3:%.+]] = bitcast i8** [[BPADDR3]] to [10 x i32]**
+// CHECK-DAG: [[CPADDR3:%.+]] = bitcast i8** [[PADDR3]] to [10 x i32]**
+// CHECK-DAG: store [10 x i32]* [[VAL3:%.+]], [10 x i32]** [[CBPADDR3]],
+// CHECK-DAG: store [10 x i32]* [[VAL3]], [10 x i32]** [[CPADDR3]],
+
+// CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
+// CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
+// CHECK: [[FAIL]]
+// CHECK: call void [[HVT6:@.+]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}})
+// CHECK-NEXT: br label %[[END]]
+// CHECK: [[END]]
+// CHECK-NEXT: br label %[[IFEND:.+]]
+// CHECK: [[IFELSE]]
+// CHECK: call void [[HVT6]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}})
+// CHECK-NEXT: br label %[[IFEND]]
+// CHECK: [[IFEND]]
+
+//
+// CHECK: define {{.*}}[[FTEMPLATE]]
+//
+// CHECK: [[IF:%.+]] = icmp sgt i32 {{[^,]+}}, 40
+// CHECK: br i1 [[IF]], label %[[IFTHEN:[^,]+]], label %[[IFELSE:[^,]+]]
+// CHECK: [[IFTHEN]]
+// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 3, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* getelementptr inbounds ([3 x i[[SZ]]], [3 x i[[SZ]]]* [[SIZET5]], i32 0, i32 0), i64* getelementptr inbounds ([3 x i64], [3 x i64]* [[MAPT5]], i32 0, i32 0), i32 1, i32 0)
+// CHECK-DAG: [[BPR]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BP:%.+]], i32 0, i32 0
+// CHECK-DAG: [[PR]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[P:%.+]], i32 0, i32 0
+
+// CHECK-DAG: [[BPADDR0:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BP]], i32 0, i32 0
+// CHECK-DAG: [[PADDR0:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[P]], i32 0, i32 0
+// CHECK-DAG: [[CBPADDR0:%.+]] = bitcast i8** [[BPADDR0]] to i[[SZ]]*
+// CHECK-DAG: [[CPADDR0:%.+]] = bitcast i8** [[PADDR0]] to i[[SZ]]*
+// CHECK-DAG: store i[[SZ]] [[VAL0:%.+]], i[[SZ]]* [[CBPADDR0]],
+// CHECK-DAG: store i[[SZ]] [[VAL0]], i[[SZ]]* [[CPADDR0]],
+
+// CHECK-DAG: [[BPADDR1:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BP]], i32 0, i32 1
+// CHECK-DAG: [[PADDR1:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[P]], i32 0, i32 1
+// CHECK-DAG: [[CBPADDR1:%.+]] = bitcast i8** [[BPADDR1]] to i[[SZ]]*
+// CHECK-DAG: [[CPADDR1:%.+]] = bitcast i8** [[PADDR1]] to i[[SZ]]*
+// CHECK-DAG: store i[[SZ]] [[VAL1:%.+]], i[[SZ]]* [[CBPADDR1]],
+// CHECK-DAG: store i[[SZ]] [[VAL1]], i[[SZ]]* [[CPADDR1]],
+
+// CHECK-DAG: [[BPADDR2:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BP]], i32 0, i32 2
+// CHECK-DAG: [[PADDR2:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[P]], i32 0, i32 2
+// CHECK-DAG: [[CBPADDR2:%.+]] = bitcast i8** [[BPADDR2]] to [10 x i32]**
+// CHECK-DAG: [[CPADDR2:%.+]] = bitcast i8** [[PADDR2]] to [10 x i32]**
+// CHECK-DAG: store [10 x i32]* [[VAL2:%.+]], [10 x i32]** [[CBPADDR2]],
+// CHECK-DAG: store [10 x i32]* [[VAL2]], [10 x i32]** [[CPADDR2]],
+
+// CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
+// CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
+// CHECK: [[FAIL]]
+// CHECK: call void [[HVT5:@.+]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}})
+// CHECK-NEXT: br label %[[END]]
+// CHECK: [[END]]
+// CHECK-NEXT: br label %[[IFEND:.+]]
+// CHECK: [[IFELSE]]
+// CHECK: call void [[HVT:@.+]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}})
+// CHECK-NEXT: br label %[[IFEND]]
+// CHECK: [[IFEND]]
+
+// Check that the offloading functions are emitted and that the arguments are
+// correct and loaded correctly for the target regions of the callees of bar().
+
+// CHECK: define internal void [[HVT7]]
+// Create local storage for each capture.
+// CHECK: [[LOCAL_THIS:%.+]] = alloca [[S1]]*
+// CHECK: [[LOCAL_B:%.+]] = alloca i[[SZ]]
+// CHECK: [[LOCAL_VLA1:%.+]] = alloca i[[SZ]]
+// CHECK: [[LOCAL_VLA2:%.+]] = alloca i[[SZ]]
+// CHECK: [[LOCAL_C:%.+]] = alloca i16*
+// CHECK: [[LOCAL_B_CASTED:%.+]] = alloca i[[SZ]]
+// CHECK-DAG: store [[S1]]* [[ARG_THIS:%.+]], [[S1]]** [[LOCAL_THIS]]
+// CHECK-DAG: store i[[SZ]] [[ARG_B:%.+]], i[[SZ]]* [[LOCAL_B]]
+// CHECK-DAG: store i[[SZ]] [[ARG_VLA1:%.+]], i[[SZ]]* [[LOCAL_VLA1]]
+// CHECK-DAG: store i[[SZ]] [[ARG_VLA2:%.+]], i[[SZ]]* [[LOCAL_VLA2]]
+// CHECK-DAG: store i16* [[ARG_C:%.+]], i16** [[LOCAL_C]]
+// Store captures in the context.
+// CHECK-DAG: [[REF_THIS:%.+]] = load [[S1]]*, [[S1]]** [[LOCAL_THIS]],
+// CHECK-64-DAG:[[CONV_BP:%.+]] = bitcast i[[SZ]]* [[LOCAL_B]] to i32*
+// CHECK-DAG: [[VAL_VLA1:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_VLA1]],
+// CHECK-DAG: [[VAL_VLA2:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_VLA2]],
+// CHECK-DAG: [[REF_C:%.+]] = load i16*, i16** [[LOCAL_C]],
+
+// CHECK-64-DAG:[[CONV_B:%.+]] = load i32, i32* [[CONV_BP]]
+// CHECK-64-DAG:[[CONV:%.+]] = bitcast i[[SZ]]* [[LOCAL_B_CASTED]] to i32*
+// CHECK-64-DAG:store i32 [[CONV_B]], i32* [[CONV]], align
+// CHECK-32-DAG:[[LOCAL_BV:%.+]] = load i32, i32* [[LOCAL_B]]
+// CHECK-32-DAG:store i32 [[LOCAL_BV]], i32* [[LOCAL_B_CASTED]], align
+// CHECK-DAG: [[REF_B:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_B_CASTED]],
+
+// CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* [[DEF_LOC]], i32 5, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, [[S1]]*, i[[SZ]], i[[SZ]], i[[SZ]], i16*)* [[OMP_OUTLINED5:@.+]] to void (i32*, i32*, ...)*), [[S1]]* [[REF_THIS]], i[[SZ]] [[REF_B]], i[[SZ]] [[VAL_VLA1]], i[[SZ]] [[VAL_VLA2]], i16* [[REF_C]])
+//
+//
+// CHECK: define internal {{.*}}void [[OMP_OUTLINED5]](i32* noalias %.global_tid., i32* noalias %.bound_tid., [[S1]]* %{{.+}}, i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, i16* {{.+}})
+// To reduce complexity, we're only going as far as validating the signature of the outlined parallel function.
+
+
+// CHECK: define internal void [[HVT6]]
+// Create local storage for each capture.
+// CHECK: [[LOCAL_A:%.+]] = alloca i[[SZ]]
+// CHECK: [[LOCAL_AA:%.+]] = alloca i[[SZ]]
+// CHECK: [[LOCAL_AAA:%.+]] = alloca i[[SZ]]
+// CHECK: [[LOCAL_B:%.+]] = alloca [10 x i32]*
+// CHECK: [[LOCAL_A_CASTED:%.+]] = alloca i[[SZ]]
+// CHECK: [[LOCAL_AA_CASTED:%.+]] = alloca i[[SZ]]
+// CHECK: [[LOCAL_AAA_CASTED:%.+]] = alloca i[[SZ]]
+// CHECK-DAG: store i[[SZ]] [[ARG_A:%.+]], i[[SZ]]* [[LOCAL_A]]
+// CHECK-DAG: store i[[SZ]] [[ARG_AA:%.+]], i[[SZ]]* [[LOCAL_AA]]
+// CHECK-DAG: store i[[SZ]] [[ARG_AAA:%.+]], i[[SZ]]* [[LOCAL_AAA]]
+// CHECK-DAG: store [10 x i32]* [[ARG_B:%.+]], [10 x i32]** [[LOCAL_B]]
+// Store captures in the context.
+// CHECK-64-DAG:[[CONV_AP:%.+]] = bitcast i[[SZ]]* [[LOCAL_A]] to i32*
+// CHECK-DAG: [[CONV_AAP:%.+]] = bitcast i[[SZ]]* [[LOCAL_AA]] to i16*
+// CHECK-DAG: [[CONV_AAAP:%.+]] = bitcast i[[SZ]]* [[LOCAL_AAA]] to i8*
+// CHECK-DAG: [[REF_B:%.+]] = load [10 x i32]*, [10 x i32]** [[LOCAL_B]],
+
+// CHECK-64-DAG:[[CONV_A:%.+]] = load i32, i32* [[CONV_AP]]
+// CHECK-64-DAG:[[CONV:%.+]] = bitcast i[[SZ]]* [[LOCAL_A_CASTED]] to i32*
+// CHECK-64-DAG:store i32 [[CONV_A]], i32* [[CONV]], align
+// CHECK-32-DAG:[[LOCAL_AV:%.+]] = load i32, i32* [[LOCAL_A]]
+// CHECK-32-DAG:store i32 [[LOCAL_AV]], i32* [[LOCAL_A_CASTED]], align
+// CHECK-DAG: [[REF_A:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_A_CASTED]],
+
+// CHECK-DAG: [[CONV_AA:%.+]] = load i16, i16* [[CONV_AAP]]
+// CHECK-DAG: [[CONV:%.+]] = bitcast i[[SZ]]* [[LOCAL_AA_CASTED]] to i16*
+// CHECK-DAG: store i16 [[CONV_AA]], i16* [[CONV]], align
+// CHECK-DAG: [[REF_AA:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_AA_CASTED]],
+
+// CHECK-DAG: [[CONV_AAA:%.+]] = load i8, i8* [[CONV_AAAP]]
+// CHECK-DAG: [[CONV:%.+]] = bitcast i[[SZ]]* [[LOCAL_AAA_CASTED]] to i8*
+// CHECK-DAG: store i8 [[CONV_AAA]], i8* [[CONV]], align
+// CHECK-DAG: [[REF_AAA:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_AAA_CASTED]],
+
+// CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* [[DEF_LOC]], i32 4, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i[[SZ]], i[[SZ]], i[[SZ]], [10 x i32]*)* [[OMP_OUTLINED6:@.+]] to void (i32*, i32*, ...)*), i[[SZ]] [[REF_A]], i[[SZ]] [[REF_AA]], i[[SZ]] [[REF_AAA]], [10 x i32]* [[REF_B]])
+//
+//
+// CHECK: define internal {{.*}}void [[OMP_OUTLINED6]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, [10 x i32]* {{.+}})
+// To reduce complexity, we're only going as far as validating the signature of the outlined parallel function.
+
+// CHECK: define internal void [[HVT5]]
+// Create local storage for each capture.
+// CHECK: [[LOCAL_A:%.+]] = alloca i[[SZ]]
+// CHECK: [[LOCAL_AA:%.+]] = alloca i[[SZ]]
+// CHECK: [[LOCAL_B:%.+]] = alloca [10 x i32]*
+// CHECK: [[LOCAL_A_CASTED:%.+]] = alloca i[[SZ]]
+// CHECK: [[LOCAL_AA_CASTED:%.+]] = alloca i[[SZ]]
+// CHECK-DAG: store i[[SZ]] [[ARG_A:%.+]], i[[SZ]]* [[LOCAL_A]]
+// CHECK-DAG: store i[[SZ]] [[ARG_AA:%.+]], i[[SZ]]* [[LOCAL_AA]]
+// CHECK-DAG: store [10 x i32]* [[ARG_B:%.+]], [10 x i32]** [[LOCAL_B]]
+// Store captures in the context.
+// CHECK-64-DAG:[[CONV_AP:%.+]] = bitcast i[[SZ]]* [[LOCAL_A]] to i32*
+// CHECK-DAG: [[CONV_AAP:%.+]] = bitcast i[[SZ]]* [[LOCAL_AA]] to i16*
+// CHECK-DAG: [[REF_B:%.+]] = load [10 x i32]*, [10 x i32]** [[LOCAL_B]],
+
+// CHECK-64-DAG:[[CONV_A:%.+]] = load i32, i32* [[CONV_AP]]
+// CHECK-64-DAG:[[CONV:%.+]] = bitcast i[[SZ]]* [[LOCAL_A_CASTED]] to i32*
+// CHECK-64-DAG:store i32 [[CONV_A]], i32* [[CONV]], align
+// CHECK-32-DAG:[[LOCAL_AV:%.+]] = load i32, i32* [[LOCAL_A]]
+// CHECK-32-DAG:store i32 [[LOCAL_AV]], i32* [[LOCAL_A_CASTED]], align
+// CHECK-DAG: [[REF_A:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_A_CASTED]],
+
+// CHECK-DAG: [[CONV_AA:%.+]] = load i16, i16* [[CONV_AAP]]
+// CHECK-DAG: [[CONV:%.+]] = bitcast i[[SZ]]* [[LOCAL_AA_CASTED]] to i16*
+// CHECK-DAG: store i16 [[CONV_AA]], i16* [[CONV]], align
+// CHECK-DAG: [[REF_AA:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_AA_CASTED]],
+
+// CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* [[DEF_LOC]], i32 3, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i[[SZ]], i[[SZ]], [10 x i32]*)* [[OMP_OUTLINED7:@.+]] to void (i32*, i32*, ...)*), i[[SZ]] [[REF_A]], i[[SZ]] [[REF_AA]], [10 x i32]* [[REF_B]])
+//
+//
+// CHECK: define internal {{.*}}void [[OMP_OUTLINED7]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, [10 x i32]* {{.+}})
+// To reduce complexity, we're only going as far as validating the signature of the outlined parallel function.
+
+#endif
diff --git a/test/OpenMP/target_parallel_for_simd_codegen_registration.cpp b/test/OpenMP/target_parallel_for_simd_codegen_registration.cpp
new file mode 100644
index 000000000000..5cc9d7015cbd
--- /dev/null
+++ b/test/OpenMP/target_parallel_for_simd_codegen_registration.cpp
@@ -0,0 +1,451 @@
+// Test host codegen.
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+
+// Test target parallel for simd codegen - host bc file has to be created first.
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm-bc %s -o %t-ppc-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s -check-prefix=TCHECK
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s -check-prefix=TCHECK
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm-bc %s -o %t-x86-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s -check-prefix=TCHECK
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s -check-prefix=TCHECK
+
+// Check that no target code is emmitted if no omptests flag was provided.
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s -check-prefix=CHECK-NTARGET
+
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+// CHECK-DAG: [[SA:%.+]] = type { [4 x i32] }
+// CHECK-DAG: [[SB:%.+]] = type { [8 x i32] }
+// CHECK-DAG: [[SC:%.+]] = type { [16 x i32] }
+// CHECK-DAG: [[SD:%.+]] = type { [32 x i32] }
+// CHECK-DAG: [[SE:%.+]] = type { [64 x i32] }
+// CHECK-DAG: [[ST1:%.+]] = type { [228 x i32] }
+// CHECK-DAG: [[ST2:%.+]] = type { [1128 x i32] }
+// CHECK-DAG: [[ENTTY:%.+]] = type { i8*, i8*, i[[SZ:32|64]], i32, i32 }
+// CHECK-DAG: [[DEVTY:%.+]] = type { i8*, i8*, [[ENTTY]]*, [[ENTTY]]* }
+// CHECK-DAG: [[DSCTY:%.+]] = type { i32, [[DEVTY]]*, [[ENTTY]]*, [[ENTTY]]* }
+
+// TCHECK: [[ENTTY:%.+]] = type { i8*, i8*, i[[SZ:32|64]], i32, i32 }
+
+// CHECK-DAG: $[[REGFN:\.omp_offloading\..+]] = comdat
+
+// CHECK-DAG: [[A1:@.+]] = internal global [[SA]]
+// CHECK-DAG: [[A2:@.+]] = global [[SA]]
+// CHECK-DAG: [[B1:@.+]] = global [[SB]]
+// CHECK-DAG: [[B2:@.+]] = global [[SB]]
+// CHECK-DAG: [[C1:@.+]] = internal global [[SC]]
+// CHECK-DAG: [[D1:@.+]] = global [[SD]]
+// CHECK-DAG: [[E1:@.+]] = global [[SE]]
+// CHECK-DAG: [[T1:@.+]] = global [[ST1]]
+// CHECK-DAG: [[T2:@.+]] = global [[ST2]]
+
+// CHECK-NTARGET-DAG: [[SA:%.+]] = type { [4 x i32] }
+// CHECK-NTARGET-DAG: [[SB:%.+]] = type { [8 x i32] }
+// CHECK-NTARGET-DAG: [[SC:%.+]] = type { [16 x i32] }
+// CHECK-NTARGET-DAG: [[SD:%.+]] = type { [32 x i32] }
+// CHECK-NTARGET-DAG: [[SE:%.+]] = type { [64 x i32] }
+// CHECK-NTARGET-DAG: [[ST1:%.+]] = type { [228 x i32] }
+// CHECK-NTARGET-DAG: [[ST2:%.+]] = type { [1128 x i32] }
+// CHECK-NTARGET-NOT: type { i8*, i8*, %
+// CHECK-NTARGET-NOT: type { i32, %
+
+// We have 7 target regions
+
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// TCHECK-NOT: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
+
+// CHECK-NTARGET-NOT: private constant i8 0
+// CHECK-NTARGET-NOT: private unnamed_addr constant [1 x i
+
+// CHECK-DAG: [[NAMEPTR1:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME1:__omp_offloading_[0-9a-f]+_[0-9a-f]+__Z.+_l[0-9]+]]\00"
+// CHECK-DAG: [[ENTRY1:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR1]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR2:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME2:.+]]\00"
+// CHECK-DAG: [[ENTRY2:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR2]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR3:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME3:.+]]\00"
+// CHECK-DAG: [[ENTRY3:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR3]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR4:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME4:.+]]\00"
+// CHECK-DAG: [[ENTRY4:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR4]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR5:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME5:.+]]\00"
+// CHECK-DAG: [[ENTRY5:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR5]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR6:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME6:.+]]\00"
+// CHECK-DAG: [[ENTRY6:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR6]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR7:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME7:.+]]\00"
+// CHECK-DAG: [[ENTRY7:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR7]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR8:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME8:.+]]\00"
+// CHECK-DAG: [[ENTRY8:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR8]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR9:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME9:.+]]\00"
+// CHECK-DAG: [[ENTRY9:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR9]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR10:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME10:.+]]\00"
+// CHECK-DAG: [[ENTRY10:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR10]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR11:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME11:.+]]\00"
+// CHECK-DAG: [[ENTRY11:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR11]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR12:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME12:.+]]\00"
+// CHECK-DAG: [[ENTRY12:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR12]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+
+// TCHECK-DAG: [[NAMEPTR1:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME1:__omp_offloading_[0-9a-f]+_[0-9a-f]+__Z.+_l[0-9]+]]\00"
+// TCHECK-DAG: [[ENTRY1:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR1]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR2:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME2:.+]]\00"
+// TCHECK-DAG: [[ENTRY2:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR2]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR3:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME3:.+]]\00"
+// TCHECK-DAG: [[ENTRY3:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR3]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR4:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME4:.+]]\00"
+// TCHECK-DAG: [[ENTRY4:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR4]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR5:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME5:.+]]\00"
+// TCHECK-DAG: [[ENTRY5:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR5]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR6:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME6:.+]]\00"
+// TCHECK-DAG: [[ENTRY6:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR6]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR7:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME7:.+]]\00"
+// TCHECK-DAG: [[ENTRY7:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR7]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR8:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME8:.+]]\00"
+// TCHECK-DAG: [[ENTRY8:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR8]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR9:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME9:.+]]\00"
+// TCHECK-DAG: [[ENTRY9:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR9]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR10:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME10:.+]]\00"
+// TCHECK-DAG: [[ENTRY10:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR10]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR11:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME11:.+]]\00"
+// TCHECK-DAG: [[ENTRY11:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR11]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR12:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME12:.+]]\00"
+// TCHECK-DAG: [[ENTRY12:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR12]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+
+// CHECK: [[ENTBEGIN:@.+]] = external constant [[ENTTY]]
+// CHECK: [[ENTEND:@.+]] = external constant [[ENTTY]]
+// CHECK: [[DEVBEGIN:@.+]] = external constant i8
+// CHECK: [[DEVEND:@.+]] = external constant i8
+// CHECK: [[IMAGES:@.+]] = internal unnamed_addr constant [1 x [[DEVTY]]] [{{.+}} { i8* [[DEVBEGIN]], i8* [[DEVEND]], [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }], comdat($[[REGFN]])
+// CHECK: [[DESC:@.+]] = internal constant [[DSCTY]] { i32 1, [[DEVTY]]* getelementptr inbounds ([1 x [[DEVTY]]], [1 x [[DEVTY]]]* [[IMAGES]], i32 0, i32 0), [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }, comdat($[[REGFN]])
+
+// We have 4 initializers, one for the 500 priority, another one for 501, or more for the default priority, and the last one for the offloading registration function.
+// CHECK: @llvm.global_ctors = appending global [4 x { i32, void ()*, i8* }] [
+// CHECK-SAME: { i32, void ()*, i8* } { i32 500, void ()* [[P500:@[^,]+]], i8* null },
+// CHECK-SAME: { i32, void ()*, i8* } { i32 501, void ()* [[P501:@[^,]+]], i8* null },
+// CHECK-SAME: { i32, void ()*, i8* } { i32 65535, void ()* [[PMAX:@[^,]+]], i8* null },
+// CHECK-SAME: { i32, void ()*, i8* } { i32 0, void ()* bitcast (void (i8*)* @[[REGFN]] to void ()*), i8* bitcast (void (i8*)* @[[REGFN]] to i8*) }]
+
+// CHECK-NTARGET: @llvm.global_ctors = appending global [3 x { i32, void ()*, i8* }] [
+
+extern int *R;
+
+struct SA {
+ int arr[4];
+ void foo() {
+ int a = *R;
+ a += 1;
+ *R = a;
+ }
+ SA() {
+ int a = *R;
+ a += 2;
+ *R = a;
+ }
+ ~SA() {
+ int a = *R;
+ a += 3;
+ *R = a;
+ }
+};
+
+struct SB {
+ int arr[8];
+ void foo() {
+ int a = *R;
+ #pragma omp target parallel for simd
+ for (int i = 0; i < 10; ++i)
+ a += 4;
+ *R = a;
+ }
+ SB() {
+ int a = *R;
+ a += 5;
+ *R = a;
+ }
+ ~SB() {
+ int a = *R;
+ a += 6;
+ *R = a;
+ }
+};
+
+struct SC {
+ int arr[16];
+ void foo() {
+ int a = *R;
+ a += 7;
+ *R = a;
+ }
+ SC() {
+ int a = *R;
+ #pragma omp target parallel for simd
+ for (int i = 0; i < 10; ++i)
+ a += 8;
+ *R = a;
+ }
+ ~SC() {
+ int a = *R;
+ a += 9;
+ *R = a;
+ }
+};
+
+struct SD {
+ int arr[32];
+ void foo() {
+ int a = *R;
+ a += 10;
+ *R = a;
+ }
+ SD() {
+ int a = *R;
+ a += 11;
+ *R = a;
+ }
+ ~SD() {
+ int a = *R;
+ #pragma omp target parallel for simd
+ for (int i = 0; i < 10; ++i)
+ a += 12;
+ *R = a;
+ }
+};
+
+struct SE {
+ int arr[64];
+ void foo() {
+ int a = *R;
+ #pragma omp target parallel for simd if(target: 0)
+ for (int i = 0; i < 10; ++i)
+ a += 13;
+ *R = a;
+ }
+ SE() {
+ int a = *R;
+ #pragma omp target parallel for simd
+ for (int i = 0; i < 10; ++i)
+ a += 14;
+ *R = a;
+ }
+ ~SE() {
+ int a = *R;
+ #pragma omp target parallel for simd
+ for (int i = 0; i < 10; ++i)
+ a += 15;
+ *R = a;
+ }
+};
+
+template <int x>
+struct ST {
+ int arr[128 + x];
+ void foo() {
+ int a = *R;
+ #pragma omp target parallel for simd
+ for (int i = 0; i < 10; ++i)
+ a += 16 + x;
+ *R = a;
+ }
+ ST() {
+ int a = *R;
+ #pragma omp target parallel for simd
+ for (int i = 0; i < 10; ++i)
+ a += 17 + x;
+ *R = a;
+ }
+ ~ST() {
+ int a = *R;
+ #pragma omp target parallel for simd
+ for (int i = 0; i < 10; ++i)
+ a += 18 + x;
+ *R = a;
+ }
+};
+
+// We have to make sure we us all the target regions:
+//CHECK-DAG: define internal void @[[NAME1]](
+//CHECK-DAG: call void @[[NAME1]](
+//CHECK-DAG: define internal void @[[NAME2]](
+//CHECK-DAG: call void @[[NAME2]](
+//CHECK-DAG: define internal void @[[NAME3]](
+//CHECK-DAG: call void @[[NAME3]](
+//CHECK-DAG: define internal void @[[NAME4]](
+//CHECK-DAG: call void @[[NAME4]](
+//CHECK-DAG: define internal void @[[NAME5]](
+//CHECK-DAG: call void @[[NAME5]](
+//CHECK-DAG: define internal void @[[NAME6]](
+//CHECK-DAG: call void @[[NAME6]](
+//CHECK-DAG: define internal void @[[NAME7]](
+//CHECK-DAG: call void @[[NAME7]](
+//CHECK-DAG: define internal void @[[NAME8]](
+//CHECK-DAG: call void @[[NAME8]](
+//CHECK-DAG: define internal void @[[NAME9]](
+//CHECK-DAG: call void @[[NAME9]](
+//CHECK-DAG: define internal void @[[NAME10]](
+//CHECK-DAG: call void @[[NAME10]](
+//CHECK-DAG: define internal void @[[NAME11]](
+//CHECK-DAG: call void @[[NAME11]](
+//CHECK-DAG: define internal void @[[NAME12]](
+//CHECK-DAG: call void @[[NAME12]](
+
+//TCHECK-DAG: define void @[[NAME1]](
+//TCHECK-DAG: define void @[[NAME2]](
+//TCHECK-DAG: define void @[[NAME3]](
+//TCHECK-DAG: define void @[[NAME4]](
+//TCHECK-DAG: define void @[[NAME5]](
+//TCHECK-DAG: define void @[[NAME6]](
+//TCHECK-DAG: define void @[[NAME7]](
+//TCHECK-DAG: define void @[[NAME8]](
+//TCHECK-DAG: define void @[[NAME9]](
+//TCHECK-DAG: define void @[[NAME10]](
+//TCHECK-DAG: define void @[[NAME11]](
+//TCHECK-DAG: define void @[[NAME12]](
+
+// CHECK-NTARGET-NOT: __tgt_target
+// CHECK-NTARGET-NOT: __tgt_register_lib
+// CHECK-NTARGET-NOT: __tgt_unregister_lib
+
+// TCHECK-NOT: __tgt_target
+// TCHECK-NOT: __tgt_register_lib
+// TCHECK-NOT: __tgt_unregister_lib
+
+// We have 2 initializers with priority 500
+//CHECK: define internal void [[P500]](
+//CHECK: call void @{{.+}}()
+//CHECK: call void @{{.+}}()
+//CHECK-NOT: call void @{{.+}}()
+//CHECK: ret void
+
+// We have 1 initializers with priority 501
+//CHECK: define internal void [[P501]](
+//CHECK: call void @{{.+}}()
+//CHECK-NOT: call void @{{.+}}()
+//CHECK: ret void
+
+// We have 6 initializers with default priority
+//CHECK: define internal void [[PMAX]](
+//CHECK: call void @{{.+}}()
+//CHECK: call void @{{.+}}()
+//CHECK: call void @{{.+}}()
+//CHECK: call void @{{.+}}()
+//CHECK: call void @{{.+}}()
+//CHECK: call void @{{.+}}()
+//CHECK-NOT: call void @{{.+}}()
+//CHECK: ret void
+
+// Check registration and unregistration
+
+//CHECK: define internal void @[[UNREGFN:.+]](i8*)
+//CHECK-SAME: comdat($[[REGFN]]) {
+//CHECK: call i32 @__tgt_unregister_lib([[DSCTY]]* [[DESC]])
+//CHECK: ret void
+//CHECK: declare i32 @__tgt_unregister_lib([[DSCTY]]*)
+
+//CHECK: define linkonce hidden void @[[REGFN]](i8*)
+//CHECK-SAME: comdat {
+//CHECK: call i32 @__tgt_register_lib([[DSCTY]]* [[DESC]])
+//CHECK: call i32 @__cxa_atexit(void (i8*)* @[[UNREGFN]], i8* bitcast ([[DSCTY]]* [[DESC]] to i8*),
+//CHECK: ret void
+//CHECK: declare i32 @__tgt_register_lib([[DSCTY]]*)
+
+static __attribute__((init_priority(500))) SA a1;
+SA a2;
+SB __attribute__((init_priority(500))) b1;
+SB __attribute__((init_priority(501))) b2;
+static SC c1;
+SD d1;
+SE e1;
+ST<100> t1;
+ST<1000> t2;
+
+
+int bar(int a){
+ int r = a;
+
+ a1.foo();
+ a2.foo();
+ b1.foo();
+ b2.foo();
+ c1.foo();
+ d1.foo();
+ e1.foo();
+ t1.foo();
+ t2.foo();
+
+ #pragma omp target parallel for simd
+ for (int i = 0; i < 10; ++i)
+ ++r;
+
+ return r + *R;
+}
+
+// Check metadata is properly generated:
+// CHECK: !omp_offload.info = !{!{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID:-?[0-9]+]], i32 [[FILEID:-?[0-9]+]], !"_ZN2SB3fooEv", i32 195, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SDD1Ev", i32 247, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SEC1Ev", i32 265, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SED1Ev", i32 272, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EE3fooEv", i32 284, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EEC1Ev", i32 291, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_Z3bari", i32 415, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EED1Ev", i32 298, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EEC1Ev", i32 291, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EED1Ev", i32 298, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EE3fooEv", i32 284, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SCC1Ev", i32 221, i32 {{[0-9]+}}}
+
+// TCHECK: !omp_offload.info = !{!{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID:-?[0-9]+]], i32 [[FILEID:-?[0-9]+]], !"_ZN2SB3fooEv", i32 195, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SDD1Ev", i32 247, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SEC1Ev", i32 265, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SED1Ev", i32 272, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EE3fooEv", i32 284, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EEC1Ev", i32 291, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_Z3bari", i32 415, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EED1Ev", i32 298, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EEC1Ev", i32 291, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EED1Ev", i32 298, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EE3fooEv", i32 284, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SCC1Ev", i32 221, i32 {{[0-9]+}}}
+
+#endif
diff --git a/test/OpenMP/target_parallel_for_simd_codegen_registration_naming.cpp b/test/OpenMP/target_parallel_for_simd_codegen_registration_naming.cpp
new file mode 100644
index 000000000000..bdfa38669859
--- /dev/null
+++ b/test/OpenMP/target_parallel_for_simd_codegen_registration_naming.cpp
@@ -0,0 +1,68 @@
+// Test host codegen.
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+
+// Test target parallel for simd codegen - host bc file has to be created first.
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm-bc %s -o %t-ppc-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s -check-prefix=TCHECK
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s -check-prefix=TCHECK
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm-bc %s -o %t-x86-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s -check-prefix=TCHECK
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s -check-prefix=TCHECK
+
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+// CHECK: [[CA:%.+]] = type { i32* }
+
+// CHECK: define {{.*}}i32 @[[NNAME:.+]](i32 {{.*}}%{{.+}})
+int nested(int a){
+ // CHECK: call void @__omp_offloading_[[FILEID:[0-9a-f]+_[0-9a-f]+]]_[[NNAME]]_l[[T1L:[0-9]+]](
+ #pragma omp target parallel for simd
+ for (int i = 0; i < 10; ++i)
+ ++a;
+
+ // CHECK: call void @"[[LNAME:.+]]"([[CA]]*
+ auto F = [&](){
+ #pragma omp parallel
+ {
+ #pragma omp target parallel for simd
+ for (int i = 0; i < 10; ++i)
+ ++a;
+ }
+ };
+
+ F();
+
+ return a;
+}
+
+// CHECK: define {{.*}}void @__omp_offloading_[[FILEID]]_[[NNAME]]_l[[T1L]](
+// TCHECK: define {{.*}}void @__omp_offloading_[[FILEID:[0-9a-f]+_[0-9a-f]+]]_[[NNAME:.+]]_l[[T1L:[0-9]+]](
+
+// CHECK: define {{.*}}void @"[[LNAME]]"(
+// CHECK: call void {{.*}}@__kmpc_fork_call{{.+}}[[PNAME:@.+]] to
+
+// CHECK: define {{.*}}void [[PNAME]](
+// CHECK: call void @__omp_offloading_[[FILEID]]_[[NNAME]]_l[[T2L:[0-9]+]](
+
+// CHECK: define {{.*}}void @__omp_offloading_[[FILEID]]_[[NNAME]]_l[[T2L]](
+// TCHECK: define {{.*}}void @__omp_offloading_[[FILEID]]_[[NNAME:.+]]_l[[T2L:[0-9]+]](
+
+
+// Check metadata is properly generated:
+// CHECK: !omp_offload.info = !{!{{[0-9]+}}, !{{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 {{-?[0-9]+}}, i32 {{-?[0-9]+}}, !"[[NNAME]]", i32 [[T1L]], i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 {{-?[0-9]+}}, i32 {{-?[0-9]+}}, !"[[NNAME]]", i32 [[T2L]], i32 {{[0-9]+}}}
+
+// TCHECK: !omp_offload.info = !{!{{[0-9]+}}, !{{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 {{-?[0-9]+}}, i32 {{-?[0-9]+}}, !"[[NNAME]]", i32 [[T1L]], i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 {{-?[0-9]+}}, i32 {{-?[0-9]+}}, !"[[NNAME]]", i32 [[T2L]], i32 {{[0-9]+}}}
+#endif
diff --git a/test/OpenMP/target_parallel_for_simd_depend_messages.cpp b/test/OpenMP/target_parallel_for_simd_depend_messages.cpp
index a8b4de7ff755..4375941036cf 100644
--- a/test/OpenMP/target_parallel_for_simd_depend_messages.cpp
+++ b/test/OpenMP/target_parallel_for_simd_depend_messages.cpp
@@ -37,21 +37,21 @@ int main(int argc, char **argv, char *env[]) {
for (i = 0; i < argc; ++i) foo();
#pragma omp target parallel for simd depend (out: ) // expected-error {{expected expression}}
for (i = 0; i < argc; ++i) foo();
- #pragma omp target parallel for simd depend (inout : foobool(argc)), depend (in, argc) // expected-error {{expected variable name, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}}
+ #pragma omp target parallel for simd depend (inout : foobool(argc)), depend (in, argc) // expected-error {{expected addressable lvalue expression, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}}
for (i = 0; i < argc; ++i) foo();
#pragma omp target parallel for simd depend (out :S1) // expected-error {{'S1' does not refer to a value}}
for (i = 0; i < argc; ++i) foo();
- #pragma omp target parallel for simd depend(in : argv[1][1] = '2') // expected-error {{expected variable name, array element or array section}}
+ #pragma omp target parallel for simd depend(in : argv[1][1] = '2')
for (i = 0; i < argc; ++i) foo();
- #pragma omp target parallel for simd depend (in : vec[1]) // expected-error {{expected variable name, array element or array section}}
+ #pragma omp target parallel for simd depend (in : vec[1]) // expected-error {{expected addressable lvalue expression, array element or array section}}
for (i = 0; i < argc; ++i) foo();
#pragma omp target parallel for simd depend (in : argv[0])
for (i = 0; i < argc; ++i) foo();
#pragma omp target parallel for simd depend (in : ) // expected-error {{expected expression}}
for (i = 0; i < argc; ++i) foo();
- #pragma omp target parallel for simd depend (in : main) // expected-error {{expected variable name, array element or array section}}
+ #pragma omp target parallel for simd depend (in : main)
for (i = 0; i < argc; ++i) foo();
- #pragma omp target parallel for simd depend(in : a[0]) // expected-error{{expected variable name, array element or array section}}
+ #pragma omp target parallel for simd depend(in : a[0]) // expected-error{{expected addressable lvalue expression, array element or array section}}
for (i = 0; i < argc; ++i) foo();
#pragma omp target parallel for simd depend (in : vec[1:2]) // expected-error {{ value is not an array or pointer}}
for (i = 0; i < argc; ++i) foo();
diff --git a/test/OpenMP/target_parallel_for_simd_firstprivate_messages.cpp b/test/OpenMP/target_parallel_for_simd_firstprivate_messages.cpp
index 9397314d87cc..9ad255f033e4 100644
--- a/test/OpenMP/target_parallel_for_simd_firstprivate_messages.cpp
+++ b/test/OpenMP/target_parallel_for_simd_firstprivate_messages.cpp
@@ -125,11 +125,11 @@ int foomain(int argc, char **argv) {
foo();
#pragma omp parallel private(i)
#pragma omp target parallel for simd firstprivate(i) // expected-note {{defined as firstprivate}}
- for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp target parallel for simd' directive may not be firstprivate, predetermined as private}}
+ for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp target parallel for simd' directive may not be firstprivate, predetermined as linear}}
foo();
#pragma omp parallel reduction(+ : i)
#pragma omp target parallel for simd firstprivate(i) // expected-note {{defined as firstprivate}}
- for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp target parallel for simd' directive may not be firstprivate, predetermined as private}}
+ for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp target parallel for simd' directive may not be firstprivate, predetermined as linear}}
foo();
return 0;
}
@@ -219,7 +219,7 @@ int main(int argc, char **argv) {
for (i = 0; i < argc; ++i)
foo();
#pragma omp target parallel for simd firstprivate(i) // expected-note {{defined as firstprivate}}
- for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp target parallel for simd' directive may not be firstprivate, predetermined as private}}
+ for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp target parallel for simd' directive may not be firstprivate, predetermined as linear}}
foo();
#pragma omp parallel shared(xa)
#pragma omp target parallel for simd firstprivate(xa) // OK: may be firstprivate
@@ -246,11 +246,11 @@ int main(int argc, char **argv) {
}
#pragma omp parallel private(i)
#pragma omp target parallel for simd firstprivate(i) // expected-note {{defined as firstprivate}}
- for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp target parallel for simd' directive may not be firstprivate, predetermined as private}}
+ for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp target parallel for simd' directive may not be firstprivate, predetermined as linear}}
foo();
#pragma omp parallel reduction(+ : i)
#pragma omp target parallel for simd firstprivate(i) // expected-note {{defined as firstprivate}}
- for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp target parallel for simd' directive may not be firstprivate, predetermined as private}}
+ for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp target parallel for simd' directive may not be firstprivate, predetermined as linear}}
foo();
static int si;
#pragma omp target parallel for simd firstprivate(si) // OK
diff --git a/test/OpenMP/target_parallel_for_simd_lastprivate_messages.cpp b/test/OpenMP/target_parallel_for_simd_lastprivate_messages.cpp
index 51fc72464c9a..313192dbb5f6 100644
--- a/test/OpenMP/target_parallel_for_simd_lastprivate_messages.cpp
+++ b/test/OpenMP/target_parallel_for_simd_lastprivate_messages.cpp
@@ -18,9 +18,9 @@ public:
S2 &operator=(const S2 &);
const S2 &operator=(const S2 &) const;
static float S2s; // expected-note {{static data member is predetermined as shared}}
- static const float S2sc;
+ static const float S2sc; // expected-note {{static data member is predetermined as shared}}
};
-const float S2::S2sc = 0; // expected-note {{static data member is predetermined as shared}}
+const float S2::S2sc = 0;
const S2 b;
const S2 ba[5];
class S3 {
@@ -209,6 +209,8 @@ int main(int argc, char **argv) {
#pragma omp target parallel for simd private(xa), lastprivate(xa) // expected-error {{private variable cannot be lastprivate}} expected-note {{defined as private}}
for (i = 0; i < argc; ++i)
foo();
+// expected-note@+2 {{defined as lastprivate}}
+// expected-error@+2 {{loop iteration variable in the associated loop of 'omp target parallel for simd' directive may not be lastprivate, predetermined as linear}}
#pragma omp target parallel for simd lastprivate(i)
for (i = 0; i < argc; ++i)
foo();
diff --git a/test/OpenMP/target_parallel_for_simd_loop_messages.cpp b/test/OpenMP/target_parallel_for_simd_loop_messages.cpp
index ed184a5e4124..f07f19e2a690 100644
--- a/test/OpenMP/target_parallel_for_simd_loop_messages.cpp
+++ b/test/OpenMP/target_parallel_for_simd_loop_messages.cpp
@@ -238,27 +238,29 @@ int test_iteration_spaces() {
c[ii] = a[ii];
// expected-note@+2 {{defined as firstprivate}}
-// expected-error@+2 {{loop iteration variable in the associated loop of 'omp target parallel for simd' directive may not be firstprivate, predetermined as private}}
+// expected-error@+2 {{loop iteration variable in the associated loop of 'omp target parallel for simd' directive may not be firstprivate, predetermined as linear}}
#pragma omp target parallel for simd firstprivate(ii)
for (ii = 0; ii < 10; ii++)
c[ii] = a[ii];
-// expected-note@+2 {{defined as linear}}
-// expected-error@+2 {{loop iteration variable in the associated loop of 'omp target parallel for simd' directive may not be linear, predetermined as private}}
#pragma omp target parallel for simd linear(ii)
for (ii = 0; ii < 10; ii++)
c[ii] = a[ii];
+// expected-note@+2 {{defined as private}}
+// expected-error@+2 {{loop iteration variable in the associated loop of 'omp target parallel for simd' directive may not be private, predetermined as linear}}
#pragma omp target parallel for simd private(ii)
for (ii = 0; ii < 10; ii++)
c[ii] = a[ii];
+// expected-note@+2 {{defined as lastprivate}}
+// expected-error@+2 {{loop iteration variable in the associated loop of 'omp target parallel for simd' directive may not be lastprivate, predetermined as linear}}
#pragma omp target parallel for simd lastprivate(ii)
for (ii = 0; ii < 10; ii++)
c[ii] = a[ii];
{
-// expected-error@+2 {{loop iteration variable in the associated loop of 'omp target parallel for simd' directive may not be threadprivate or thread local, predetermined as private}}
+// expected-error@+2 {{loop iteration variable in the associated loop of 'omp target parallel for simd' directive may not be threadprivate or thread local, predetermined as linear}}
#pragma omp target parallel for simd
for (sii = 0; sii < 10; sii += 1)
c[sii] = a[sii];
@@ -585,15 +587,15 @@ void test_loop_eh() {
#pragma omp target parallel for simd
for (int i = 0; i < 10; i++) {
c[i] = a[i] + b[i];
- try {
+ try { // expected-error {{'try' statement cannot be used in OpenMP simd region}}
for (int j = 0; j < 10; ++j) {
if (a[i] > b[j])
- throw a[i];
+ throw a[i]; // expected-error {{'throw' statement cannot be used in OpenMP simd region}}
}
- throw a[i];
+ throw a[i]; // expected-error {{'throw' statement cannot be used in OpenMP simd region}}
} catch (float f) {
if (f > 0.1)
- throw a[i];
+ throw a[i]; // expected-error {{'throw' statement cannot be used in OpenMP simd region}}
return; // expected-error {{cannot return from OpenMP region}}
}
switch (i) {
@@ -605,7 +607,7 @@ void test_loop_eh() {
}
for (int j = 0; j < 10; j++) {
if (c[i] > 10)
- throw c[i];
+ throw c[i]; // expected-error {{'throw' statement cannot be used in OpenMP simd region}}
}
}
if (c[9] > 10)
diff --git a/test/OpenMP/target_parallel_for_simd_map_messages.cpp b/test/OpenMP/target_parallel_for_simd_map_messages.cpp
index 195b39c595c3..7e95e10ae5ca 100644
--- a/test/OpenMP/target_parallel_for_simd_map_messages.cpp
+++ b/test/OpenMP/target_parallel_for_simd_map_messages.cpp
@@ -14,8 +14,8 @@ class S2 {
public:
S2():a(0) { }
S2(S2 &s2):a(s2.a) { }
- static float S2s; // expected-note 4 {{mappable type cannot contain static members}}
- static const float S2sc; // expected-note 4 {{mappable type cannot contain static members}}
+ static float S2s;
+ static const float S2sc;
};
const float S2::S2sc = 0;
const S2 b;
@@ -116,9 +116,9 @@ T tmain(T argc) {
for (i = 0; i < argc; ++i) foo();
#pragma omp target parallel for simd map(S1) // expected-error {{'S1' does not refer to a value}}
for (i = 0; i < argc; ++i) foo();
-#pragma omp target parallel for simd map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} expected-error 2 {{type 'S2' is not mappable to target}}
+#pragma omp target parallel for simd map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}}
for (i = 0; i < argc; ++i) foo();
-#pragma omp target parallel for simd map(ba) // expected-error 2 {{type 'S2' is not mappable to target}}
+#pragma omp target parallel for simd map(ba)
for (i = 0; i < argc; ++i) foo();
#pragma omp target parallel for simd map(ca)
for (i = 0; i < argc; ++i) foo();
@@ -222,11 +222,11 @@ int main(int argc, char **argv) {
for (i = 0; i < argc; ++i) foo();
#pragma omp target parallel for simd map(S1) // expected-error {{'S1' does not refer to a value}}
for (i = 0; i < argc; ++i) foo();
-#pragma omp target parallel for simd map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} expected-error 2 {{type 'S2' is not mappable to target}}
+#pragma omp target parallel for simd map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}}
for (i = 0; i < argc; ++i) foo();
#pragma omp target parallel for simd map(argv[1])
for (i = 0; i < argc; ++i) foo();
-#pragma omp target parallel for simd map(ba) // expected-error 2 {{type 'S2' is not mappable to target}}
+#pragma omp target parallel for simd map(ba)
for (i = 0; i < argc; ++i) foo();
#pragma omp target parallel for simd map(ca)
for (i = 0; i < argc; ++i) foo();
diff --git a/test/OpenMP/target_parallel_for_simd_misc_messages.c b/test/OpenMP/target_parallel_for_simd_misc_messages.c
index 2adc6f85116e..f2574a35472d 100644
--- a/test/OpenMP/target_parallel_for_simd_misc_messages.c
+++ b/test/OpenMP/target_parallel_for_simd_misc_messages.c
@@ -166,7 +166,7 @@ void test_collapse() {
// expected-note@+1 {{variable with automatic storage duration is predetermined as private; perhaps you forget to enclose 'omp for' directive into a parallel or another task region?}}
for (int j = 0; j < 16; ++j)
// expected-error@+2 2 {{reduction variable must be shared}}
-// expected-error@+1 {{region cannot be closely nested inside 'target parallel for simd' region; perhaps you forget to enclose 'omp for' directive into a parallel region?}}
+// expected-error@+1 {{OpenMP constructs may not be nested inside a simd region}}
#pragma omp for reduction(+ : i, j)
for (int k = 0; k < 16; ++k)
i += j;
diff --git a/test/OpenMP/target_parallel_for_simd_ordered_messages.cpp b/test/OpenMP/target_parallel_for_simd_ordered_messages.cpp
index 70a3b4ef6245..065d81517f83 100644
--- a/test/OpenMP/target_parallel_for_simd_ordered_messages.cpp
+++ b/test/OpenMP/target_parallel_for_simd_ordered_messages.cpp
@@ -6,7 +6,7 @@ void foo() {
}
#if __cplusplus >= 201103L
- // expected-note@+2 4 {{declared here}}
+ // expected-note@+2 2 {{declared here}}
#endif
bool foobool(int argc) {
return argc;
@@ -15,7 +15,7 @@ bool foobool(int argc) {
struct S1; // expected-note {{declared here}}
template <class T, typename S, int N, int ST> // expected-note {{declared here}}
-T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
+T tmain(T argc, S **argv) {
int j; // expected-note {{declared here}}
#pragma omp target parallel for simd ordered
for (int i = ST; i < N; i++)
@@ -26,28 +26,26 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}
#pragma omp target parallel for simd ordered() // expected-error {{expected expression}}
for (int i = ST; i < N; i++)
argv[0][i] = argv[0][i] - argv[0][i - ST];
-// expected-error@+3 {{expected ')'}} expected-note@+3 {{to match this '('}}
-// expected-error@+2 2 {{expression is not an integral constant expression}}
-// expected-note@+1 2 {{read of non-const variable 'argc' is not allowed in a constant expression}}
+// expected-error@+2 {{'ordered' clause with a parameter can not be specified in '#pragma omp target parallel for simd' directive}}
+// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
#pragma omp target parallel for simd ordered(argc
for (int i = ST; i < N; i++)
argv[0][i] = argv[0][i] - argv[0][i - ST];
-// expected-error@+1 2 {{argument to 'ordered' clause must be a strictly positive integer value}}
+// expected-error@+1 {{'ordered' clause with a parameter can not be specified in '#pragma omp target parallel for simd' directive}}
#pragma omp target parallel for simd ordered(ST // expected-error {{expected ')'}} expected-note {{to match this '('}}
for (int i = ST; i < N; i++)
argv[0][i] = argv[0][i] - argv[0][i - ST];
+// expected-error@+1 {{'ordered' clause with a parameter can not be specified in '#pragma omp target parallel for simd' directive}}
#pragma omp target parallel for simd ordered(1)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}}
for (int i = ST; i < N; i++)
argv[0][i] = argv[0][i] - argv[0][i - ST];
-#pragma omp target parallel for simd ordered((ST > 0) ? 1 + ST : 2) // expected-note 2 {{as specified in 'ordered' clause}}
+// expected-error@+1 {{'ordered' clause with a parameter can not be specified in '#pragma omp target parallel for simd' directive}}
+#pragma omp target parallel for simd ordered((ST > 0) ? 1 + ST : 2)
for (int i = ST; i < N; i++)
- argv[0][i] = argv[0][i] - argv[0][i - ST]; // expected-error 2 {{expected 2 for loops after '#pragma omp target parallel for simd', but found only 1}}
-#if __cplusplus >= 201103L
- // expected-note@+5 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
-#endif
-// expected-error@+3 2 {{directive '#pragma omp target parallel for simd' cannot contain more than one 'ordered' clause}}
-// expected-error@+2 2 {{argument to 'ordered' clause must be a strictly positive integer value}}
-// expected-error@+1 2 {{expression is not an integral constant expression}}
+ argv[0][i] = argv[0][i] - argv[0][i - ST];
+// expected-error@+3 2 {{argument to 'ordered' clause must be a strictly positive integer value}}
+// expected-error@+2 2 {{directive '#pragma omp target parallel for simd' cannot contain more than one 'ordered' clause}}
+// expected-error@+1 {{'ordered' clause with a parameter can not be specified in '#pragma omp target parallel for simd' directive}}
#pragma omp target parallel for simd ordered(foobool(argc)), ordered(true), ordered(-5)
for (int i = ST; i < N; i++)
argv[0][i] = argv[0][i] - argv[0][i - ST];
@@ -59,14 +57,17 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}
#pragma omp target parallel for simd ordered(j = 2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
for (int i = ST; i < N; i++)
argv[0][i] = argv[0][i] - argv[0][i - ST];
+// expected-error@+1 {{'ordered' clause with a parameter can not be specified in '#pragma omp target parallel for simd' directive}}
#pragma omp target parallel for simd ordered(1)
for (int i = ST; i < N; i++)
argv[0][i] = argv[0][i] - argv[0][i - ST];
-#pragma omp target parallel for simd ordered(N) // expected-error {{argument to 'ordered' clause must be a strictly positive integer value}}
+// expected-error@+1 {{'ordered' clause with a parameter can not be specified in '#pragma omp target parallel for simd' directive}}
+#pragma omp target parallel for simd ordered(N)
for (T i = ST; i < N; i++)
argv[0][i] = argv[0][i] - argv[0][i - ST];
-#pragma omp target parallel for simd ordered(2) // expected-note {{as specified in 'ordered' clause}}
- foo(); // expected-error {{expected 2 for loops after '#pragma omp target parallel for simd'}}
+// expected-error@+1 {{'ordered' clause with a parameter can not be specified in '#pragma omp target parallel for simd' directive}}
+#pragma omp target parallel for simd ordered(2)
+ foo();
return argc;
}
@@ -81,12 +82,14 @@ int main(int argc, char **argv) {
#pragma omp target parallel for simd ordered() // expected-error {{expected expression}}
for (int i = 4; i < 12; i++)
argv[0][i] = argv[0][i] - argv[0][i - 4];
-#pragma omp target parallel for simd ordered(4 // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-note {{as specified in 'ordered' clause}}
+// expected-error@+1 {{'ordered' clause with a parameter can not be specified in '#pragma omp target parallel for simd' directive}}
+#pragma omp target parallel for simd ordered(4 // expected-error {{expected ')'}} expected-note {{to match this '('}}
for (int i = 4; i < 12; i++)
- argv[0][i] = argv[0][i] - argv[0][i - 4]; // expected-error {{expected 4 for loops after '#pragma omp target parallel for simd', but found only 1}}
-#pragma omp target parallel for simd ordered(2 + 2)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}} expected-note {{as specified in 'ordered' clause}}
+ argv[0][i] = argv[0][i] - argv[0][i - 4];
+// expected-error@+1 {{'ordered' clause with a parameter can not be specified in '#pragma omp target parallel for simd' directive}}
+#pragma omp target parallel for simd ordered(2 + 2)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}}
for (int i = 4; i < 12; i++)
- argv[0][i] = argv[0][i] - argv[0][i - 4]; // expected-error {{expected 4 for loops after '#pragma omp target parallel for simd', but found only 1}}
+ argv[0][i] = argv[0][i] - argv[0][i - 4];
#if __cplusplus >= 201103L
// expected-note@+2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
#endif
@@ -110,13 +113,12 @@ int main(int argc, char **argv) {
#pragma omp target parallel for simd ordered(j = 2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
for (int i = 4; i < 12; i++)
argv[0][i] = argv[0][i] - argv[0][i - 4];
-// expected-error@+3 {{statement after '#pragma omp target parallel for simd' must be a for loop}}
-// expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, -1, -2>' requested here}}
+// expected-error@+2 {{statement after '#pragma omp target parallel for simd' must be a for loop}}
#pragma omp target parallel for simd ordered(ordered(tmain < int, char, -1, -2 > (argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}}
foo();
-#pragma omp target parallel for simd ordered(2) // expected-note {{as specified in 'ordered' clause}}
- foo(); // expected-error {{expected 2 for loops after '#pragma omp target parallel for simd'}}
- // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, 1, 0>' requested here}}
+// expected-error@+1 {{'ordered' clause with a parameter can not be specified in '#pragma omp target parallel for simd' directive}}
+#pragma omp target parallel for simd ordered(2)
+ foo();
return tmain<int, char, 1, 0>(argc, argv);
}
diff --git a/test/OpenMP/target_parallel_for_simd_reduction_messages.cpp b/test/OpenMP/target_parallel_for_simd_reduction_messages.cpp
index 289b5b2641b6..72e2130f3df4 100644
--- a/test/OpenMP/target_parallel_for_simd_reduction_messages.cpp
+++ b/test/OpenMP/target_parallel_for_simd_reduction_messages.cpp
@@ -25,9 +25,9 @@ public:
S2() : a(0) {}
S2(S2 &s2) : a(s2.a) {}
static float S2s; // expected-note 2 {{static data member is predetermined as shared}}
- static const float S2sc;
+ static const float S2sc; // expected-note 2 {{'S2sc' declared here}}
};
-const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}}
+const float S2::S2sc = 0;
S2 b; // expected-note 3 {{'b' defined here}}
const S2 ba[5]; // expected-note 2 {{'ba' defined here}}
class S3 {
diff --git a/test/OpenMP/target_parallel_if_codegen.cpp b/test/OpenMP/target_parallel_if_codegen.cpp
index 0aebcc218fbb..c155bf7c051a 100644
--- a/test/OpenMP/target_parallel_if_codegen.cpp
+++ b/test/OpenMP/target_parallel_if_codegen.cpp
@@ -130,8 +130,6 @@ int bar(int n){
return a;
}
-
-
//
// CHECK: define {{.*}}[[FS1]]([[S1]]* {{%.+}}, i32 {{[^%]*}}[[PARM:%.+]])
//
@@ -147,10 +145,8 @@ int bar(int n){
// CHECK: store i8 [[FB]], i8* [[CONV]], align
// CHECK: [[ARG:%.+]] = load i[[SZ]], i[[SZ]]* [[CAPEC_ADDR]], align
//
-// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 3, {{.*}}, i32 1, i32 0)
-// CHECK: store i32 [[RET]], i32* [[RHV:%.+]], align
-// CHECK: [[RET2:%.+]] = load i32, i32* [[RHV]], align
-// CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 3, {{.*}}, i32 1, i32 0)
+// CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
// CHECK: br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
//
// CHECK: [[FAIL]]
@@ -175,28 +171,18 @@ int bar(int n){
// CHECK: br i1 [[CMP]], label {{%?}}[[IF_THEN:.+]], label {{%?}}[[IF_ELSE:.+]]
//
// CHECK: [[IF_THEN]]
-// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 2, {{.*}}, i32 1, i32 0)
-// CHECK: store i32 [[RET]], i32* [[RHV:%.+]], align
-// CHECK: br label {{%?}}[[END:.+]]
-//
-// CHECK: [[IF_ELSE]]
-// CHECK: store i32 -1, i32* [[RHV]], align
-// CHECK: br label {{%?}}[[END]]
-//
-// CHECK: [[END]]
-// CHECK: [[RET2:%.+]] = load i32, i32* [[RHV]], align
-// CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
-// CHECK: br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
-//
+// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 2, {{.*}}, i32 1, i32 0)
+// CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
+// CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
// CHECK: [[FAIL]]
// CHECK: call void [[HVT2:@.+]]([[S1]]* {{%.+}}, i[[SZ]] [[ARG]])
-// CHECK: br label {{%?}}[[END]]
+// CHECK-NEXT: br label %[[END]]
// CHECK: [[END]]
-
-
-
-
-
+// CHECK-NEXT: br label %[[IFEND:.+]]
+// CHECK: [[IF_ELSE]]
+// CHECK: call void [[HVT2]]([[S1]]* {{%.+}}, i[[SZ]] [[ARG]])
+// CHECK-NEXT: br label %[[IFEND]]
+// CHECK: [[IFEND]]
//
// CHECK: define {{.*}}[[FSTATIC]](i32 {{[^%]*}}[[PARM:%.+]])
@@ -217,23 +203,18 @@ int bar(int n){
// CHECK: br i1 [[TB]], label {{%?}}[[IF_THEN:.+]], label {{%?}}[[IF_ELSE:.+]]
//
// CHECK: [[IF_THEN]]
-// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 1, {{.*}}, i32 1, i32 0)
-// CHECK: store i32 [[RET]], i32* [[RHV:%.+]], align
-// CHECK: br label {{%?}}[[END:.+]]
-//
-// CHECK: [[IF_ELSE]]
-// CHECK: store i32 -1, i32* [[RHV]], align
-// CHECK: br label {{%?}}[[END]]
-//
-// CHECK: [[END]]
-// CHECK: [[RET2:%.+]] = load i32, i32* [[RHV]], align
-// CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
-// CHECK: br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
-//
+// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 1, {{.*}}, i32 1, i32 0)
+// CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
+// CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
// CHECK: [[FAIL]]
// CHECK: call void [[HVT3:@.+]](i[[SZ]] [[ARG]])
-// CHECK: br label {{%?}}[[END]]
+// CHECK-NEXT: br label %[[END]]
// CHECK: [[END]]
+// CHECK-NEXT: br label %[[IFEND:.+]]
+// CHECK: [[IF_ELSE]]
+// CHECK: call void [[HVT3]](i[[SZ]] [[ARG]])
+// CHECK-NEXT: br label %[[IFEND]]
+// CHECK: [[IFEND]]
//
//
//
@@ -243,23 +224,18 @@ int bar(int n){
// CHECK: br i1 [[CMP]], label {{%?}}[[IF_THEN:.+]], label {{%?}}[[IF_ELSE:.+]]
//
// CHECK: [[IF_THEN]]
-// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 0, {{.*}}, i32 1, i32 0)
-// CHECK: store i32 [[RET]], i32* [[RHV:%.+]], align
-// CHECK: br label {{%?}}[[END:.+]]
-//
-// CHECK: [[IF_ELSE]]
-// CHECK: store i32 -1, i32* [[RHV]], align
-// CHECK: br label {{%?}}[[END]]
-//
-// CHECK: [[END]]
-// CHECK: [[RET2:%.+]] = load i32, i32* [[RHV]], align
-// CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
-// CHECK: br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
-//
+// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 0, {{.*}}, i32 1, i32 0)
+// CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
+// CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
// CHECK: [[FAIL]]
// CHECK: call void [[HVT4:@.+]]()
-// CHECK: br label {{%?}}[[END]]
+// CHECK-NEXT: br label %[[END]]
// CHECK: [[END]]
+// CHECK-NEXT: br label %[[IFEND:.+]]
+// CHECK: [[IF_ELSE]]
+// CHECK: call void [[HVT4]]()
+// CHECK-NEXT: br label %[[IFEND]]
+// CHECK: [[IFEND]]
@@ -269,10 +245,8 @@ int bar(int n){
//
// CHECK: define {{.*}}[[FTEMPLATE]]
//
-// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 1, {{.*}}, i32 1, i32 0)
-// CHECK-NEXT: store i32 [[RET]], i32* [[RHV:%.+]], align
-// CHECK-NEXT: [[RET2:%.+]] = load i32, i32* [[RHV]], align
-// CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 1, {{.*}}, i32 1, i32 0)
+// CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
// CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
//
// CHECK: [[FAIL]]
@@ -283,10 +257,8 @@ int bar(int n){
//
//
//
-// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 2, {{.*}}, i32 1, i32 0)
-// CHECK-NEXT: store i32 [[RET]], i32* [[RHV:%.+]], align
-// CHECK-NEXT: [[RET2:%.+]] = load i32, i32* [[RHV]], align
-// CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 2, {{.*}}, i32 1, i32 0)
+// CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
// CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
//
// CHECK: [[FAIL]]
diff --git a/test/OpenMP/target_parallel_map_messages.cpp b/test/OpenMP/target_parallel_map_messages.cpp
index ca794cecf4c5..d3cc742decd5 100644
--- a/test/OpenMP/target_parallel_map_messages.cpp
+++ b/test/OpenMP/target_parallel_map_messages.cpp
@@ -14,8 +14,8 @@ class S2 {
public:
S2():a(0) { }
S2(S2 &s2):a(s2.a) { }
- static float S2s; // expected-note 4 {{mappable type cannot contain static members}}
- static const float S2sc; // expected-note 4 {{mappable type cannot contain static members}}
+ static float S2s;
+ static const float S2sc;
};
const float S2::S2sc = 0;
const S2 b;
@@ -116,9 +116,9 @@ T tmain(T argc) {
foo();
#pragma omp target parallel map(S1) // expected-error {{'S1' does not refer to a value}}
foo();
-#pragma omp target parallel map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} expected-error 2 {{type 'S2' is not mappable to target}}
+#pragma omp target parallel map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}}
foo();
-#pragma omp target parallel map(ba) // expected-error 2 {{type 'S2' is not mappable to target}}
+#pragma omp target parallel map(ba)
foo();
#pragma omp target parallel map(ca)
foo();
@@ -221,11 +221,11 @@ int main(int argc, char **argv) {
foo();
#pragma omp target parallel map(S1) // expected-error {{'S1' does not refer to a value}}
foo();
-#pragma omp target parallel map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} expected-error 2 {{type 'S2' is not mappable to target}}
+#pragma omp target parallel map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}}
foo();
#pragma omp target parallel map(argv[1])
foo();
-#pragma omp target parallel map(ba) // expected-error 2 {{type 'S2' is not mappable to target}}
+#pragma omp target parallel map(ba)
foo();
#pragma omp target parallel map(ca)
foo();
diff --git a/test/OpenMP/target_parallel_no_exceptions.cpp b/test/OpenMP/target_parallel_no_exceptions.cpp
new file mode 100644
index 000000000000..95189a3ade2b
--- /dev/null
+++ b/test/OpenMP/target_parallel_no_exceptions.cpp
@@ -0,0 +1,18 @@
+/// Make sure no exception messages are inclided in the llvm output.
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix CHK-EXCEPTION
+
+void test_increment() {
+#pragma omp target
+ {
+ []() { return; }();
+ }
+}
+
+int main() {
+ test_increment();
+ return 0;
+}
+
+//CHK-EXCEPTION-NOT: invoke
+
diff --git a/test/OpenMP/target_parallel_num_threads_codegen.cpp b/test/OpenMP/target_parallel_num_threads_codegen.cpp
index 225c2dd1d06a..836a92d9a5db 100644
--- a/test/OpenMP/target_parallel_num_threads_codegen.cpp
+++ b/test/OpenMP/target_parallel_num_threads_codegen.cpp
@@ -147,10 +147,8 @@ int bar(int n){
// CHECK: [[ARG:%.+]] = load i[[SZ]], i[[SZ]]* [[CAPEC_ADDR]], align
// CHECK: [[THREADS:%.+]] = load i32, i32* [[CAPE_ADDR]], align
//
-// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 3, {{.*}}, i32 1, i32 [[THREADS]])
-// CHECK: store i32 [[RET]], i32* [[RHV:%.+]], align
-// CHECK: [[RET2:%.+]] = load i32, i32* [[RHV]], align
-// CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 3, {{.*}}, i32 1, i32 [[THREADS]])
+// CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
// CHECK: br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
//
// CHECK: [[FAIL]]
@@ -160,10 +158,8 @@ int bar(int n){
//
//
//
-// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 1, {{.+}}, i32 1, i32 1024)
-// CHECK: store i32 [[RET]], i32* [[RHV:%.+]], align
-// CHECK: [[RET2:%.+]] = load i32, i32* [[RHV]], align
-// CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 1, {{.+}}, i32 1, i32 1024)
+// CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
// CHECK: br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
//
// CHECK: [[FAIL]]
@@ -190,10 +186,8 @@ int bar(int n){
// CHECK: [[ARG:%.+]] = load i[[SZ]], i[[SZ]]* [[CAPEC_ADDR]], align
// CHECK: [[THREADS:%.+]] = load i32, i32* [[CAPE_ADDR]], align
//
-// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 1, {{.*}}, i32 1, i32 [[THREADS]])
-// CHECK: store i32 [[RET]], i32* [[RHV:%.+]], align
-// CHECK: [[RET2:%.+]] = load i32, i32* [[RHV]], align
-// CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 1, {{.*}}, i32 1, i32 [[THREADS]])
+// CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
// CHECK: br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
//
// CHECK: [[FAIL]]
@@ -213,10 +207,8 @@ int bar(int n){
// CHECK: [[ARG:%.+]] = load i[[SZ]], i[[SZ]]* [[CAPEC_ADDR]], align
// CHECK: [[THREADS:%.+]] = load i32, i32* [[CAPE_ADDR]], align
//
-// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 1, {{.*}}, i32 1, i32 [[THREADS]])
-// CHECK: store i32 [[RET]], i32* [[RHV:%.+]], align
-// CHECK: [[RET2:%.+]] = load i32, i32* [[RHV]], align
-// CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 1, {{.*}}, i32 1, i32 [[THREADS]])
+// CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
// CHECK: br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
//
// CHECK: [[FAIL]]
@@ -233,10 +225,8 @@ int bar(int n){
//
// CHECK: define {{.*}}[[FTEMPLATE]]
//
-// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 0, {{.*}}, i32 1, i32 20)
-// CHECK-NEXT: store i32 [[RET]], i32* [[RHV:%.+]], align
-// CHECK-NEXT: [[RET2:%.+]] = load i32, i32* [[RHV]], align
-// CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 0, {{.*}}, i32 1, i32 20)
+// CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
// CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
//
// CHECK: [[FAIL]]
@@ -257,10 +247,8 @@ int bar(int n){
// CHECK: [[T:%.+]] = load i16, i16* [[CAPE_ADDR]], align
// CHECK: [[THREADS:%.+]] = sext i16 [[T]] to i32
//
-// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 3, {{.*}}, i32 1, i32 [[THREADS]])
-// CHECK: store i32 [[RET]], i32* [[RHV:%.+]], align
-// CHECK: [[RET2:%.+]] = load i32, i32* [[RHV]], align
-// CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 3, {{.*}}, i32 1, i32 [[THREADS]])
+// CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
// CHECK: br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
//
// CHECK: [[FAIL]]
diff --git a/test/OpenMP/target_parallel_reduction_messages.cpp b/test/OpenMP/target_parallel_reduction_messages.cpp
index 52338ee71cbe..038f099c5a6c 100644
--- a/test/OpenMP/target_parallel_reduction_messages.cpp
+++ b/test/OpenMP/target_parallel_reduction_messages.cpp
@@ -24,9 +24,9 @@ public:
S2() : a(0) {}
S2(S2 &s2) : a(s2.a) {}
static float S2s; // expected-note 2 {{static data member is predetermined as shared}}
- static const float S2sc;
+ static const float S2sc; // expected-note 2 {{'S2sc' declared here}}
};
-const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}}
+const float S2::S2sc = 0;
S2 b; // expected-note 3 {{'b' defined here}}
const S2 ba[5]; // expected-note 2 {{'ba' defined here}}
class S3 {
diff --git a/test/OpenMP/target_reduction_codegen.cpp b/test/OpenMP/target_reduction_codegen.cpp
new file mode 100644
index 000000000000..f86719b55fa1
--- /dev/null
+++ b/test/OpenMP/target_reduction_codegen.cpp
@@ -0,0 +1,215 @@
+// Only test codegen on target side, as private clause does not require any action on the host side
+// Test target codegen - host bc file has to be created first.
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm-bc %s -o %t-ppc-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-64
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-64
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm-bc %s -o %t-x86-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-32
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-32
+
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+template<typename tx, typename ty>
+struct TT{
+ tx X;
+ ty Y;
+ TT<tx, ty> operator*(const TT<tx, ty> &) { return *this; }
+};
+
+// TCHECK: [[S1:%.+]] = type { double }
+
+int foo(int n) {
+ int a = 0;
+ short aa = 0;
+ float b[10];
+ float bn[n];
+ double c[5][10];
+ double cn[5][n];
+ TT<long long, char> d;
+
+ #pragma omp target reduction(*:a)
+ {
+ }
+
+ // TCHECK: define void @__omp_offloading_{{.+}}(i32*{{.+}} %{{.+}})
+ // TCHECK: [[A:%.+]] = alloca i{{[0-9]+}}*,
+ // TCHECK: store {{.+}}, {{.+}} [[A]],
+ // TCHECK: load i32*, i32** [[A]],
+ // TCHECK: ret void
+
+#pragma omp target reduction(+:a)
+ {
+ a = 1;
+ }
+
+ // TCHECK: define void @__omp_offloading_{{.+}}(i32*{{.+}} %{{.+}})
+ // TCHECK: [[A:%.+]] = alloca i{{[0-9]+}}*,
+ // TCHECK: store {{.+}}, {{.+}} [[A]],
+ // TCHECK: [[REF:%.+]] = load i32*, i32** [[A]],
+ // TCHECK: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[REF]],
+ // TCHECK: ret void
+
+ #pragma omp target reduction(-:a, aa)
+ {
+ a = 1;
+ aa = 1;
+ }
+
+ // TCHECK: define void @__omp_offloading_{{.+}}(i32*{{.+}} [[A:%.+]], i16*{{.+}} [[AA:%.+]])
+ // TCHECK: [[A:%.+]] = alloca i{{[0-9]+}}*,
+ // TCHECK: [[AA:%.+]] = alloca i{{[0-9]+}}*,
+ // TCHECK: store {{.+}}, {{.+}} [[A]],
+ // TCHECK: store {{.+}}, {{.+}} [[AA]],
+ // TCHECK: [[A_REF:%.+]] = load i32*, i32** [[A]],
+ // TCHECK: [[AA_REF:%.+]] = load i16*, i16** [[AA]],
+ // TCHECK: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[A_REF]],
+ // TCHECK: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[AA_REF]],
+ // TCHECK: ret void
+
+ return a;
+}
+
+
+template<typename tx>
+tx ftemplate(int n) {
+ tx a = 0;
+ short aa = 0;
+ tx b[10];
+
+#pragma omp target reduction(+:a,aa,b)
+ {
+ a = 1;
+ aa = 1;
+ b[2] = 1;
+ }
+
+ return a;
+}
+
+static
+int fstatic(int n) {
+ int a = 0;
+ short aa = 0;
+ char aaa = 0;
+ int b[10];
+
+#pragma omp target reduction(-:a,aa,aaa,b)
+ {
+ a = 1;
+ aa = 1;
+ aaa = 1;
+ b[2] = 1;
+ }
+
+ return a;
+}
+
+// TCHECK: define void @__omp_offloading_{{.+}}(i32*{{.+}}, i16*{{.+}}, i8*{{.+}}, [10 x i32]*{{.+}})
+// TCHECK: [[A:%.+]] = alloca i{{[0-9]+}}*,
+// TCHECK: [[A2:%.+]] = alloca i{{[0-9]+}}*,
+// TCHECK: [[A3:%.+]] = alloca i{{[0-9]+}}*,
+// TCHECK: [[B:%.+]] = alloca [10 x i{{[0-9]+}}]*,
+// TCHECK: store {{.+}}, {{.+}} [[A]],
+// TCHECK: store {{.+}}, {{.+}} [[A2]],
+// TCHECK: store {{.+}}, {{.+}} [[A3]],
+// TCHECK: store {{.+}}, {{.+}} [[B]],
+// TCHECK: [[A_REF:%.+]] = load i32*, i32** [[A]],
+// TCHECK: [[AA_REF:%.+]] = load i16*, i16** [[AA]],
+// TCHECK: [[A3_REF:%.+]] = load i8*, i8** [[A3]],
+// TCHECK: [[B_REF:%.+]] = load {{.+}}*, {{.+}}** [[B]],
+// TCHECK: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[A_REF]],
+// TCHECK: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[AA_REF]],
+// TCHECK: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[A3_REF]],
+// TCHECK: [[B_GEP:%.+]] = getelementptr inbounds [10 x i{{[0-9]+}}], [10 x i{{[0-9]+}}]* [[B_REF]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+// TCHECK: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[B_GEP]],
+// TCHECK: ret void
+
+struct S1 {
+ double a;
+
+ int r1(int n){
+ int b = n+1;
+ short int c[2][n];
+
+#pragma omp target reduction(max:b,c)
+ {
+ this->a = (double)b + 1.5;
+ c[1][1] = ++a;
+ }
+
+ return c[1][1] + (int)b;
+ }
+
+ // TCHECK: define void @__omp_offloading_{{.+}}([[S1]]* [[TH:%.+]], i32*{{.+}}, i{{[0-9]+}} [[VLA:%.+]], i{{[0-9]+}} [[VLA1:%.+]], i16*{{.+}})
+ // TCHECK: [[TH_ADDR:%.+]] = alloca [[S1]]*,
+ // TCHECK: [[B_ADDR:%.+]] = alloca i{{[0-9]+}}*,
+ // TCHECK: [[VLA_ADDR:%.+]] = alloca i{{[0-9]+}},
+ // TCHECK: [[VLA_ADDR2:%.+]] = alloca i{{[0-9]+}},
+ // TCHECK: [[C_ADDR:%.+]] = alloca i{{[0-9]+}}*,
+ // TCHECK: store [[S1]]* [[TH]], [[S1]]** [[TH_ADDR]],
+ // TCHECK: store i{{[0-9]+}}* {{.+}}, i{{[0-9]+}}** [[B_ADDR]],
+ // TCHECK: store i{{[0-9]+}} [[VLA]], i{{[0-9]+}}* [[VLA_ADDR]],
+ // TCHECK: store i{{[0-9]+}} [[VLA1]], i{{[0-9]+}}* [[VLA_ADDR2]],
+ // TCHECK: store i{{[0-9]+}}* {{.+}}, i{{[0-9]+}}** [[C_ADDR]],
+ // TCHECK: [[TH_ADDR_REF:%.+]] = load [[S1]]*, [[S1]]** [[TH_ADDR]],
+ // TCHECK: [[B_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[B_ADDR]],
+ // TCHECK: [[VLA_ADDR_REF:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[VLA_ADDR]],
+ // TCHECK: [[VLA_ADDR_REF2:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[VLA_ADDR2]],
+ // TCHECK: [[C_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[C_ADDR]],
+
+ // this->a = (double)b + 1.5;
+ // TCHECK: [[B_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[B_REF]],
+ // TCHECK: [[B_CONV:%.+]] = sitofp i{{[0-9]+}} [[B_VAL]] to double
+ // TCHECK: [[NEW_A_VAL:%.+]] = fadd double [[B_CONV]], 1.5{{.+}}+00
+ // TCHECK: [[A_FIELD:%.+]] = getelementptr inbounds [[S1]], [[S1]]* [[TH_ADDR_REF]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // TCHECK: store double [[NEW_A_VAL]], double* [[A_FIELD]],
+
+ // c[1][1] = ++a;
+ // TCHECK: [[A_FIELD4:%.+]] = getelementptr inbounds [[S1]], [[S1]]* [[TH_ADDR_REF]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // TCHECK: [[A_FIELD4_VAL:%.+]] = load double, double* [[A_FIELD4]],
+ // TCHECK: [[A_FIELD_INC:%.+]] = fadd double [[A_FIELD4_VAL]], 1.0{{.+}}+00
+ // TCHECK: store double [[A_FIELD_INC]], double* [[A_FIELD4]],
+ // TCHECK: [[A_FIELD_INC_CONV:%.+]] = fptosi double [[A_FIELD_INC]] to i{{[0-9]+}}
+ // TCHECK: [[C_IND:%.+]] = mul{{.+}} i{{[0-9]+}} 1, [[VLA_ADDR_REF2]]
+ // TCHECK: [[C_1_REF:%.+]] = getelementptr inbounds i{{[0-9]+}}, i{{[0-9]+}}* [[C_REF]], i{{[0-9]+}} [[C_IND]]
+ // TCHECK: [[C_1_1_REF:%.+]] = getelementptr inbounds i{{[0-9]+}}, i{{[0-9]+}}* [[C_1_REF]], i{{[0-9]+}} 1
+ // TCHECK: store i{{[0-9]+}} [[A_FIELD_INC_CONV]], i{{[0-9]+}}* [[C_1_1_REF]],
+
+ // finish
+ // TCHECK: ret void
+};
+
+
+int bar(int n){
+ int a = 0;
+ a += foo(n);
+ S1 S;
+ a += S.r1(n);
+ a += fstatic(n);
+ a += ftemplate<int>(n);
+
+ return a;
+}
+
+// template
+// TCHECK: define void @__omp_offloading_{{.+}}(i{{[0-9]+}}*{{.+}}, i{{[0-9]+}}*{{.+}}, [10 x i32]*{{.+}})
+// TCHECK: [[A:%.+]] = alloca i{{[0-9]+}}*,
+// TCHECK: [[A2:%.+]] = alloca i{{[0-9]+}}*,
+// TCHECK: [[B:%.+]] = alloca [10 x i{{[0-9]+}}]*,
+// TCHECK: store {{.+}}, {{.+}} [[A]],
+// TCHECK: store {{.+}}, {{.+}} [[A2]],
+// TCHECK: store {{.+}}, {{.+}} [[B]],
+// TCHECK: [[A_REF:%.+]] = load i32*, i32** [[A]],
+// TCHECK: [[AA_REF:%.+]] = load i16*, i16** [[AA]],
+// TCHECK: [[B_REF:%.+]] = load {{.+}}*, {{.+}}** [[B]],
+// TCHECK: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[A_REF]],
+// TCHECK: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[AA_REF]],
+// TCHECK: [[B_GEP:%.+]] = getelementptr inbounds [10 x i{{[0-9]+}}], [10 x i{{[0-9]+}}]* [[B_REF]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+// TCHECK: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[B_GEP]],
+// TCHECK: ret void
+
+#endif
diff --git a/test/OpenMP/target_reduction_messages.cpp b/test/OpenMP/target_reduction_messages.cpp
new file mode 100644
index 000000000000..8cf79f9a5d99
--- /dev/null
+++ b/test/OpenMP/target_reduction_messages.cpp
@@ -0,0 +1,262 @@
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 150 -o - %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++98 -ferror-limit 150 -o - %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 -ferror-limit 150 -o - %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+void foobar(int &ref) {
+#pragma omp target reduction(+:ref)
+ foo();
+}
+
+struct S1; // expected-note {{declared here}} expected-note 4 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+ mutable int a;
+ S2 &operator+(const S2 &arg) { return (*this); } // expected-note 3 {{implicitly declared private here}}
+
+public:
+ S2() : a(0) {}
+ S2(S2 &s2) : a(s2.a) {}
+ static float S2s; // expected-note 2 {{static data member is predetermined as shared}}
+ static const float S2sc; // expected-note 2 {{'S2sc' declared here}}
+};
+const float S2::S2sc = 0;
+S2 b; // expected-note 3 {{'b' defined here}}
+const S2 ba[5]; // expected-note 2 {{'ba' defined here}}
+class S3 {
+ int a;
+
+public:
+ int b;
+ S3() : a(0) {}
+ S3(const S3 &s3) : a(s3.a) {}
+ S3 operator+(const S3 &arg1) { return arg1; }
+};
+int operator+(const S3 &arg1, const S3 &arg2) { return 5; }
+S3 c; // expected-note 3 {{'c' defined here}}
+const S3 ca[5]; // expected-note 2 {{'ca' defined here}}
+extern const int f; // expected-note 4 {{'f' declared here}}
+class S4 {
+ int a;
+ S4(); // expected-note {{implicitly declared private here}}
+ S4(const S4 &s4);
+ S4 &operator+(const S4 &arg) { return (*this); }
+
+public:
+ S4(int v) : a(v) {}
+};
+S4 &operator&=(S4 &arg1, S4 &arg2) { return arg1; }
+class S5 {
+ int a;
+ S5() : a(0) {} // expected-note {{implicitly declared private here}}
+ S5(const S5 &s5) : a(s5.a) {}
+ S5 &operator+(const S5 &arg);
+
+public:
+ S5(int v) : a(v) {}
+};
+class S6 { // expected-note 3 {{candidate function (the implicit copy assignment operator) not viable: no known conversion from 'int' to 'const S6' for 1st argument}}
+#if __cplusplus >= 201103L // C++11 or later
+// expected-note@-2 3 {{candidate function (the implicit move assignment operator) not viable}}
+#endif
+ int a;
+
+public:
+ S6() : a(6) {}
+ operator int() { return 6; }
+} o;
+
+S3 h, k;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class T> // expected-note {{declared here}}
+T tmain(T argc) {
+ const T d = T(); // expected-note 4 {{'d' defined here}}
+ const T da[5] = {T()}; // expected-note 2 {{'da' defined here}}
+ T qa[5] = {T()};
+ T i;
+ T &j = i; // expected-note 4 {{'j' defined here}}
+ S3 &p = k; // expected-note 2 {{'p' defined here}}
+ const T &r = da[(int)i]; // expected-note 2 {{'r' defined here}}
+ T &q = qa[(int)i]; // expected-note 2 {{'q' defined here}}
+ T fl;
+#pragma omp target reduction // expected-error {{expected '(' after 'reduction'}}
+ foo();
+#pragma omp target reduction + // expected-error {{expected '(' after 'reduction'}} expected-warning {{extra tokens at the end of '#pragma omp target' are ignored}}
+ foo();
+#pragma omp target reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+#pragma omp target reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+#pragma omp target reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+ foo();
+#pragma omp target reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}}
+ foo();
+#pragma omp target reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+ foo();
+#pragma omp target reduction(& : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{invalid operands to binary expression ('float' and 'float')}}
+ foo();
+#pragma omp target reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{invalid operands to binary expression ('float' and 'float')}}
+ foo();
+#pragma omp target reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name, array element or array section}}
+ foo();
+#pragma omp target reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}}
+ foo();
+#pragma omp target reduction(&& : argc)
+ foo();
+#pragma omp target reduction(^ : T) // expected-error {{'T' does not refer to a value}}
+ foo();
+#pragma omp target reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
+ foo();
+#pragma omp target reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}}
+ foo();
+#pragma omp target reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
+ foo();
+#pragma omp target reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+ foo();
+#pragma omp target reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+ foo();
+#pragma omp target reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}}
+ foo();
+#pragma omp target reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
+ foo();
+#pragma omp target reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
+ foo();
+#pragma omp target reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+ foo();
+#pragma omp target reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}}
+ foo();
+#pragma omp target reduction(+ : o) // expected-error 2 {{no viable overloaded '='}}
+ foo();
+#pragma omp parallel private(i), reduction(+ : j), reduction(+ : q) // expected-error 4 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+ foo();
+#pragma omp parallel private(k)
+#pragma omp target reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+ foo();
+#pragma omp target reduction(+ : p), reduction(+ : p) // expected-error 2 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 2 {{previously referenced here}}
+ foo();
+#pragma omp target reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}}
+ foo();
+#pragma omp parallel shared(i)
+#pragma omp target reduction(min : i)
+#pragma omp parallel reduction(max : j) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+ foo();
+#pragma omp parallel
+#pragma omp for private(fl)
+ for (int i = 0; i < 10; ++i)
+#pragma omp target reduction(+ : fl)
+ foo();
+#pragma omp parallel
+#pragma omp for reduction(- : fl)
+ for (int i = 0; i < 10; ++i)
+#pragma omp target reduction(+ : fl)
+ foo();
+
+ return T();
+}
+
+namespace A {
+double x;
+#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}}
+}
+namespace B {
+using A::x;
+}
+
+int main(int argc, char **argv) {
+ const int d = 5; // expected-note 2 {{'d' defined here}}
+ const int da[5] = {0}; // expected-note {{'da' defined here}}
+ int qa[5] = {0};
+ S4 e(4);
+ S5 g(5);
+ int i;
+ int &j = i; // expected-note 2 {{'j' defined here}}
+ S3 &p = k; // expected-note 2 {{'p' defined here}}
+ const int &r = da[i]; // expected-note {{'r' defined here}}
+ int &q = qa[i]; // expected-note {{'q' defined here}}
+ float fl;
+#pragma omp target reduction // expected-error {{expected '(' after 'reduction'}}
+ foo();
+#pragma omp target reduction + // expected-error {{expected '(' after 'reduction'}} expected-warning {{extra tokens at the end of '#pragma omp target' are ignored}}
+ foo();
+#pragma omp target reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+#pragma omp target reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+#pragma omp target reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+ foo();
+#pragma omp target reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}}
+ foo();
+#pragma omp target reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+ foo();
+#pragma omp target reduction(foo : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}}
+ foo();
+#pragma omp target reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+#pragma omp target reduction(|| : argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name, array element or array section}}
+ foo();
+#pragma omp target reduction(~ : argc) // expected-error {{expected unqualified-id}}
+ foo();
+#pragma omp target reduction(&& : argc)
+ foo();
+#pragma omp target reduction(^ : S1) // expected-error {{'S1' does not refer to a value}}
+ foo();
+#pragma omp target reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified list item cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}}
+ foo();
+#pragma omp target reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified list item cannot be reduction}}
+ foo();
+#pragma omp target reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
+ foo();
+#pragma omp target reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+ foo();
+#pragma omp target reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+ foo();
+#pragma omp target reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}}
+ foo();
+#pragma omp target reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
+ foo();
+#pragma omp target reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
+ foo();
+#pragma omp target reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+ foo();
+#pragma omp target reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{nvalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
+ foo();
+#pragma omp target reduction(+ : h, k, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be reduction}}
+ foo();
+#pragma omp target reduction(+ : o) // expected-error {{no viable overloaded '='}}
+ foo();
+#pragma omp parallel private(i), reduction(+ : j), reduction(+ : q) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+ foo();
+#pragma omp parallel private(k)
+#pragma omp target reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+ foo();
+#pragma omp target reduction(+ : p), reduction(+ : p) // expected-error {{variable can appear only once in OpenMP 'reduction' clause}} expected-note {{previously referenced here}}
+ foo();
+#pragma omp target reduction(+ : r) // expected-error {{const-qualified list item cannot be reduction}}
+ foo();
+#pragma omp parallel shared(i)
+#pragma omp target reduction(min : i)
+#pragma omp parallel reduction(max : j) // expected-error {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+ foo();
+#pragma omp parallel
+#pragma omp for private(fl)
+ for (int i = 0; i < 10; ++i)
+#pragma omp target reduction(+ : fl)
+ foo();
+#pragma omp parallel
+#pragma omp for reduction(- : fl)
+ for (int i = 0; i < 10; ++i)
+#pragma omp target reduction(+ : fl)
+ foo();
+ static int m;
+#pragma omp target reduction(+ : m) // OK
+ m++;
+
+ return tmain(argc) + tmain(fl); // expected-note {{in instantiation of function template specialization 'tmain<int>' requested here}} expected-note {{in instantiation of function template specialization 'tmain<float>' requested here}}
+}
diff --git a/test/OpenMP/target_simd_codegen.cpp b/test/OpenMP/target_simd_codegen.cpp
new file mode 100644
index 000000000000..d57e3818559a
--- /dev/null
+++ b/test/OpenMP/target_simd_codegen.cpp
@@ -0,0 +1,675 @@
+// Test host codegen.
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+
+// Test target codegen - host bc file has to be created first.
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm-bc %s -o %t-ppc-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-64
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-64
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm-bc %s -o %t-x86-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-32
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-32
+
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+// CHECK-DAG: [[TT:%.+]] = type { i64, i8 }
+// CHECK-DAG: [[S1:%.+]] = type { double }
+// CHECK-DAG: [[ENTTY:%.+]] = type { i8*, i8*, i[[SZ:32|64]], i32, i32 }
+// CHECK-DAG: [[DEVTY:%.+]] = type { i8*, i8*, [[ENTTY]]*, [[ENTTY]]* }
+// CHECK-DAG: [[DSCTY:%.+]] = type { i32, [[DEVTY]]*, [[ENTTY]]*, [[ENTTY]]* }
+
+// TCHECK: [[ENTTY:%.+]] = type { i8*, i8*, i{{32|64}}, i32, i32 }
+
+// CHECK-DAG: $[[REGFN:\.omp_offloading\..+]] = comdat
+
+// We have 8 target regions, but only 7 that actually will generate offloading
+// code, only 6 will have mapped arguments, and only 4 have all-constant map
+// sizes.
+
+// CHECK-DAG: [[SIZET2:@.+]] = private unnamed_addr constant [3 x i[[SZ]]] [i[[SZ]] 2, i[[SZ]] 4, i[[SZ]] 4]
+// CHECK-DAG: [[MAPT2:@.+]] = private unnamed_addr constant [3 x i64] [i64 288, i64 288, i64 288]
+// CHECK-DAG: [[SIZET3:@.+]] = private unnamed_addr constant [2 x i[[SZ]]] [i[[SZ]] 4, i[[SZ]] 2]
+// CHECK-DAG: [[MAPT3:@.+]] = private unnamed_addr constant [2 x i64] [i64 288, i64 288]
+// CHECK-DAG: [[MAPT4:@.+]] = private unnamed_addr constant [9 x i64] [i64 288, i64 547, i64 288, i64 547, i64 547, i64 288, i64 288, i64 547, i64 547]
+// CHECK-DAG: [[SIZET5:@.+]] = private unnamed_addr constant [3 x i[[SZ]]] [i[[SZ]] 4, i[[SZ]] 2, i[[SZ]] 40]
+// CHECK-DAG: [[MAPT5:@.+]] = private unnamed_addr constant [3 x i64] [i64 288, i64 288, i64 547]
+// CHECK-DAG: [[SIZET6:@.+]] = private unnamed_addr constant [4 x i[[SZ]]] [i[[SZ]] 4, i[[SZ]] 2, i[[SZ]] 1, i[[SZ]] 40]
+// CHECK-DAG: [[MAPT6:@.+]] = private unnamed_addr constant [4 x i64] [i64 288, i64 288, i64 288, i64 547]
+// CHECK-DAG: [[MAPT7:@.+]] = private unnamed_addr constant [5 x i64] [i64 547, i64 288, i64 288, i64 288, i64 547]
+// CHECK-DAG: @{{.*}} = private constant i8 0
+// CHECK-DAG: @{{.*}} = private constant i8 0
+// CHECK-DAG: @{{.*}} = private constant i8 0
+// CHECK-DAG: @{{.*}} = private constant i8 0
+// CHECK-DAG: @{{.*}} = private constant i8 0
+// CHECK-DAG: @{{.*}} = private constant i8 0
+// CHECK-DAG: @{{.*}} = private constant i8 0
+
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+// TCHECK-NOT: @{{.+}} = constant [[ENTTY]]
+
+// Check if offloading descriptor is created.
+// CHECK: [[ENTBEGIN:@.+]] = external constant [[ENTTY]]
+// CHECK: [[ENTEND:@.+]] = external constant [[ENTTY]]
+// CHECK: [[DEVBEGIN:@.+]] = external constant i8
+// CHECK: [[DEVEND:@.+]] = external constant i8
+// CHECK: [[IMAGES:@.+]] = internal unnamed_addr constant [1 x [[DEVTY]]] [{{.+}} { i8* [[DEVBEGIN]], i8* [[DEVEND]], [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }], comdat($[[REGFN]])
+// CHECK: [[DESC:@.+]] = internal constant [[DSCTY]] { i32 1, [[DEVTY]]* getelementptr inbounds ([1 x [[DEVTY]]], [1 x [[DEVTY]]]* [[IMAGES]], i32 0, i32 0), [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }, comdat($[[REGFN]])
+
+// Check target registration is registered as a Ctor.
+// CHECK: appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 0, void ()* bitcast (void (i8*)* @[[REGFN]] to void ()*), i8* bitcast (void (i8*)* @[[REGFN]] to i8*) }]
+
+
+template<typename tx, typename ty>
+struct TT{
+ tx X;
+ ty Y;
+};
+
+// CHECK-LABEL: get_val
+long long get_val() { return 0; }
+
+// CHECK: define {{.*}}[[FOO:@.+]](
+int foo(int n) {
+ int a = 0;
+ short aa = 0;
+ float b[10];
+ float bn[n];
+ double c[5][10];
+ double cn[5][n];
+ TT<long long, char> d;
+
+ // CHECK: [[RET:%.+]] = call i32 @__tgt_target_nowait(i64 -1, i8* @{{[^,]+}}, i32 0, i8** null, i8** null, i[[SZ]]* null, i64* null)
+ // CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
+ // CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:[^,]+]], label %[[END:[^,]+]]
+ // CHECK: [[FAIL]]
+ // CHECK: call void [[HVT0:@.+]]()
+ // CHECK-NEXT: br label %[[END]]
+ // CHECK: [[END]]
+ #pragma omp target simd nowait
+ for (int i = 3; i < 32; i += 5) {
+ }
+
+ // CHECK: call void [[HVT1:@.+]](i[[SZ]] {{[^,]+}}, i{{32|64}}{{[*]*}} {{[^)]+}})
+ long long k = get_val();
+ #pragma omp target simd if(target: 0) linear(k : 3)
+ for (int i = 10; i > 1; i--) {
+ a += 1;
+ }
+
+ // CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target(i64 -1, i8* @{{[^,]+}}, i32 3, i8** [[BP:%[^,]+]], i8** [[P:%[^,]+]], i[[SZ]]* getelementptr inbounds ([3 x i[[SZ]]], [3 x i[[SZ]]]* [[SIZET2]], i32 0, i32 0), i64* getelementptr inbounds ([3 x i64], [3 x i64]* [[MAPT2]], i32 0, i32 0))
+ // CHECK-DAG: [[BP]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BPR:%[^,]+]], i32 0, i32 0
+ // CHECK-DAG: [[P]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[PR:%[^,]+]], i32 0, i32 0
+ // CHECK-DAG: [[BPADDR0:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BPR]], i32 0, i32 0
+ // CHECK-DAG: [[PADDR0:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[PR]], i32 0, i32 0
+ // CHECK-DAG: [[CBPADDR0:%.+]] = bitcast i8** [[BPADDR0]] to i[[SZ]]*
+ // CHECK-DAG: [[CPADDR0:%.+]] = bitcast i8** [[PADDR0]] to i[[SZ]]*
+ // CHECK-DAG: store i[[SZ]] [[VAL0:%.+]], i[[SZ]]* [[CBPADDR0]],
+ // CHECK-DAG: store i[[SZ]] [[VAL0]], i[[SZ]]* [[CPADDR0]],
+ // CHECK-DAG: [[BPADDR1:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BPR]], i32 0, i32 1
+ // CHECK-DAG: [[PADDR1:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[PR]], i32 0, i32 1
+ // CHECK-DAG: [[CBPADDR1:%.+]] = bitcast i8** [[BPADDR1]] to i[[SZ]]*
+ // CHECK-DAG: [[CPADDR1:%.+]] = bitcast i8** [[PADDR1]] to i[[SZ]]*
+ // CHECK-DAG: store i[[SZ]] [[VAL1:%.+]], i[[SZ]]* [[CBPADDR1]],
+ // CHECK-DAG: store i[[SZ]] [[VAL1]], i[[SZ]]* [[CPADDR1]],
+ // CHECK-DAG: [[BPADDR2:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BPR]], i32 0, i32 1
+ // CHECK-DAG: [[PADDR2:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[PR]], i32 0, i32 1
+ // CHECK-DAG: [[CBPADDR2:%.+]] = bitcast i8** [[BPADDR2]] to i[[SZ]]*
+ // CHECK-DAG: [[CPADDR2:%.+]] = bitcast i8** [[PADDR2]] to i[[SZ]]*
+ // CHECK-DAG: store i[[SZ]] [[VAL2:%.+]], i[[SZ]]* [[CBPADDR2]],
+ // CHECK-DAG: store i[[SZ]] [[VAL2]], i[[SZ]]* [[CPADDR2]],
+
+ // CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
+ // CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:[^,]+]], label %[[END:[^,]+]]
+ // CHECK: [[FAIL]]
+ // CHECK: call void [[HVT2:@.+]](i[[SZ]] {{[^,]+}}, i[[SZ]] {{[^)]+}})
+ // CHECK-NEXT: br label %[[END]]
+ // CHECK: [[END]]
+ int lin = 12;
+ #pragma omp target simd if(target: 1) linear(lin, a : get_val())
+ for (unsigned long long it = 2000; it >= 600; it-=400) {
+ aa += 1;
+ }
+
+ // CHECK: [[IF:%.+]] = icmp sgt i32 {{[^,]+}}, 10
+ // CHECK: br i1 [[IF]], label %[[IFTHEN:[^,]+]], label %[[IFELSE:[^,]+]]
+ // CHECK: [[IFTHEN]]
+ // CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target(i64 -1, i8* @{{[^,]+}}, i32 2, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* getelementptr inbounds ([2 x i[[SZ]]], [2 x i[[SZ]]]* [[SIZET3]], i32 0, i32 0), i64* getelementptr inbounds ([2 x i64], [2 x i64]* [[MAPT3]], i32 0, i32 0))
+ // CHECK-DAG: [[BPR]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[BP:%[^,]+]], i32 0, i32 0
+ // CHECK-DAG: [[PR]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[P:%[^,]+]], i32 0, i32 0
+
+ // CHECK-DAG: [[BPADDR0:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[BP]], i32 0, i32 0
+ // CHECK-DAG: [[PADDR0:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[P]], i32 0, i32 0
+ // CHECK-DAG: [[CBPADDR0:%.+]] = bitcast i8** [[BPADDR0]] to i[[SZ]]*
+ // CHECK-DAG: [[CPADDR0:%.+]] = bitcast i8** [[PADDR0]] to i[[SZ]]*
+ // CHECK-DAG: store i[[SZ]] [[VAL0:%.+]], i[[SZ]]* [[CBPADDR0]],
+ // CHECK-DAG: store i[[SZ]] [[VAL0]], i[[SZ]]* [[CPADDR0]],
+
+ // CHECK-DAG: [[BPADDR1:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[BP]], i32 0, i32 1
+ // CHECK-DAG: [[PADDR1:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[P]], i32 0, i32 1
+ // CHECK-DAG: [[CBPADDR1:%.+]] = bitcast i8** [[BPADDR1]] to i[[SZ]]*
+ // CHECK-DAG: [[CPADDR1:%.+]] = bitcast i8** [[PADDR1]] to i[[SZ]]*
+ // CHECK-DAG: store i[[SZ]] [[VAL1:%.+]], i[[SZ]]* [[CBPADDR1]],
+ // CHECK-DAG: store i[[SZ]] [[VAL1]], i[[SZ]]* [[CPADDR1]],
+ // CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
+ // CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
+ // CHECK: [[FAIL]]
+ // CHECK: call void [[HVT3:@.+]]({{[^,]+}}, {{[^,]+}})
+ // CHECK-NEXT: br label %[[END]]
+ // CHECK: [[END]]
+ // CHECK-NEXT: br label %[[IFEND:.+]]
+ // CHECK: [[IFELSE]]
+ // CHECK: call void [[HVT3]]({{[^,]+}}, {{[^,]+}})
+ // CHECK-NEXT: br label %[[IFEND]]
+ // CHECK: [[IFEND]]
+
+ #pragma omp target simd if(target: n>10)
+ for (short it = 6; it <= 20; it-=-4) {
+ a += 1;
+ aa += 1;
+ }
+
+ // We capture 3 VLA sizes in this target region
+ // CHECK-64: [[A_VAL:%.+]] = load i32, i32* %{{.+}},
+ // CHECK-64: [[A_ADDR:%.+]] = bitcast i[[SZ]]* [[A_CADDR:%.+]] to i32*
+ // CHECK-64: store i32 [[A_VAL]], i32* [[A_ADDR]],
+ // CHECK-64: [[A_CVAL:%.+]] = load i[[SZ]], i[[SZ]]* [[A_CADDR]],
+
+ // CHECK-32: [[A_VAL:%.+]] = load i32, i32* %{{.+}},
+ // CHECK-32: store i32 [[A_VAL]], i32* [[A_CADDR:%.+]],
+ // CHECK-32: [[A_CVAL:%.+]] = load i[[SZ]], i[[SZ]]* [[A_CADDR]],
+
+ // CHECK: [[BNSIZE:%.+]] = mul nuw i[[SZ]] [[VLA0:%.+]], 4
+ // CHECK: [[CNELEMSIZE2:%.+]] = mul nuw i[[SZ]] 5, [[VLA1:%.+]]
+ // CHECK: [[CNSIZE:%.+]] = mul nuw i[[SZ]] [[CNELEMSIZE2]], 8
+
+ // CHECK: [[IF:%.+]] = icmp sgt i32 {{[^,]+}}, 20
+ // CHECK: br i1 [[IF]], label %[[TRY:[^,]+]], label %[[FAIL:[^,]+]]
+ // CHECK: [[TRY]]
+ // CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target(i64 -1, i8* @{{[^,]+}}, i32 9, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* [[SR:%[^,]+]], i64* getelementptr inbounds ([9 x i64], [9 x i64]* [[MAPT4]], i32 0, i32 0))
+ // CHECK-DAG: [[BPR]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP:%[^,]+]], i32 0, i32 0
+ // CHECK-DAG: [[PR]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P:%[^,]+]], i32 0, i32 0
+ // CHECK-DAG: [[SR]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S:%[^,]+]], i32 0, i32 0
+
+ // CHECK-DAG: [[SADDR0:%.+]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX0:[0-9]+]]
+ // CHECK-DAG: [[BPADDR0:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP]], i32 0, i32 [[IDX0]]
+ // CHECK-DAG: [[PADDR0:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P]], i32 0, i32 [[IDX0]]
+ // CHECK-DAG: [[SADDR1:%.+]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX1:[0-9]+]]
+ // CHECK-DAG: [[BPADDR1:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP]], i32 0, i32 [[IDX1]]
+ // CHECK-DAG: [[PADDR1:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P]], i32 0, i32 [[IDX1]]
+ // CHECK-DAG: [[SADDR2:%.+]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX2:[0-9]+]]
+ // CHECK-DAG: [[BPADDR2:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP]], i32 0, i32 [[IDX2]]
+ // CHECK-DAG: [[PADDR2:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P]], i32 0, i32 [[IDX2]]
+ // CHECK-DAG: [[SADDR3:%.+]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX3:[0-9]+]]
+ // CHECK-DAG: [[BPADDR3:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP]], i32 0, i32 [[IDX3]]
+ // CHECK-DAG: [[PADDR3:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P]], i32 0, i32 [[IDX3]]
+ // CHECK-DAG: [[SADDR4:%.+]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX4:[0-9]+]]
+ // CHECK-DAG: [[BPADDR4:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP]], i32 0, i32 [[IDX4]]
+ // CHECK-DAG: [[PADDR4:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P]], i32 0, i32 [[IDX4]]
+ // CHECK-DAG: [[SADDR5:%.+]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX5:[0-9]+]]
+ // CHECK-DAG: [[BPADDR5:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP]], i32 0, i32 [[IDX5]]
+ // CHECK-DAG: [[PADDR5:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P]], i32 0, i32 [[IDX5]]
+ // CHECK-DAG: [[SADDR6:%.+]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX6:[0-9]+]]
+ // CHECK-DAG: [[BPADDR6:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP]], i32 0, i32 [[IDX6]]
+ // CHECK-DAG: [[PADDR6:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P]], i32 0, i32 [[IDX6]]
+ // CHECK-DAG: [[SADDR7:%.+]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX7:[0-9]+]]
+ // CHECK-DAG: [[BPADDR7:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP]], i32 0, i32 [[IDX7]]
+ // CHECK-DAG: [[PADDR7:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P]], i32 0, i32 [[IDX7]]
+ // CHECK-DAG: [[SADDR8:%.+]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX8:[0-9]+]]
+ // CHECK-DAG: [[BPADDR8:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP]], i32 0, i32 [[IDX8]]
+ // CHECK-DAG: [[PADDR8:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P]], i32 0, i32 [[IDX8]]
+
+ // The names below are not necessarily consistent with the names used for the
+ // addresses above as some are repeated.
+ // CHECK-DAG: store i[[SZ]] [[VLA0]], i[[SZ]]* [[CBPADDR0:%.+]],
+ // CHECK-DAG: store i[[SZ]] [[VLA0]], i[[SZ]]* [[CPADDR0:%.+]],
+ // CHECK-DAG: [[CBPADDR0]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+ // CHECK-DAG: [[CPADDR0]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+ // CHECK-DAG: store i[[SZ]] {{4|8}}, i[[SZ]]* {{%[^,]+}}
+
+ // CHECK-DAG: store i[[SZ]] [[VLA1]], i[[SZ]]* [[CBPADDR1:%.+]],
+ // CHECK-DAG: store i[[SZ]] [[VLA1]], i[[SZ]]* [[CPADDR1:%.+]],
+ // CHECK-DAG: [[CBPADDR1]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+ // CHECK-DAG: [[CPADDR1]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+ // CHECK-DAG: store i[[SZ]] {{4|8}}, i[[SZ]]* {{%[^,]+}}
+
+ // CHECK-DAG: store i[[SZ]] 5, i[[SZ]]* [[CBPADDR2:%.+]],
+ // CHECK-DAG: store i[[SZ]] 5, i[[SZ]]* [[CPADDR2:%.+]],
+ // CHECK-DAG: [[CBPADDR2]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+ // CHECK-DAG: [[CPADDR2]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+ // CHECK-DAG: store i[[SZ]] {{4|8}}, i[[SZ]]* {{%[^,]+}}
+
+ // CHECK-DAG: store i[[SZ]] [[A_CVAL]], i[[SZ]]* [[CBPADDR3:%.+]],
+ // CHECK-DAG: store i[[SZ]] [[A_CVAL]], i[[SZ]]* [[CPADDR3:%.+]],
+ // CHECK-DAG: [[CBPADDR3]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+ // CHECK-DAG: [[CPADDR3]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+ // CHECK-DAG: store i[[SZ]] 4, i[[SZ]]* {{%[^,]+}}
+
+ // CHECK-DAG: store [10 x float]* %{{.+}}, [10 x float]** [[CBPADDR4:%.+]],
+ // CHECK-DAG: store [10 x float]* %{{.+}}, [10 x float]** [[CPADDR4:%.+]],
+ // CHECK-DAG: [[CBPADDR4]] = bitcast i8** {{%[^,]+}} to [10 x float]**
+ // CHECK-DAG: [[CPADDR4]] = bitcast i8** {{%[^,]+}} to [10 x float]**
+ // CHECK-DAG: store i[[SZ]] 40, i[[SZ]]* {{%[^,]+}}
+
+ // CHECK-DAG: store float* %{{.+}}, float** [[CBPADDR5:%.+]],
+ // CHECK-DAG: store float* %{{.+}}, float** [[CPADDR5:%.+]],
+ // CHECK-DAG: [[CBPADDR5]] = bitcast i8** {{%[^,]+}} to float**
+ // CHECK-DAG: [[CPADDR5]] = bitcast i8** {{%[^,]+}} to float**
+ // CHECK-DAG: store i[[SZ]] [[BNSIZE]], i[[SZ]]* {{%[^,]+}}
+
+ // CHECK-DAG: store [5 x [10 x double]]* %{{.+}}, [5 x [10 x double]]** [[CBPADDR6:%.+]],
+ // CHECK-DAG: store [5 x [10 x double]]* %{{.+}}, [5 x [10 x double]]** [[CPADDR6:%.+]],
+ // CHECK-DAG: [[CBPADDR6]] = bitcast i8** {{%[^,]+}} to [5 x [10 x double]]**
+ // CHECK-DAG: [[CPADDR6]] = bitcast i8** {{%[^,]+}} to [5 x [10 x double]]**
+ // CHECK-DAG: store i[[SZ]] 400, i[[SZ]]* {{%[^,]+}}
+
+ // CHECK-DAG: store double* %{{.+}}, double** [[CBPADDR7:%.+]],
+ // CHECK-DAG: store double* %{{.+}}, double** [[CPADDR7:%.+]],
+ // CHECK-DAG: [[CBPADDR7]] = bitcast i8** {{%[^,]+}} to double**
+ // CHECK-DAG: [[CPADDR7]] = bitcast i8** {{%[^,]+}} to double**
+ // CHECK-DAG: store i[[SZ]] [[CNSIZE]], i[[SZ]]* {{%[^,]+}}
+
+ // CHECK-DAG: store [[TT]]* %{{.+}}, [[TT]]** [[CBPADDR8:%.+]],
+ // CHECK-DAG: store [[TT]]* %{{.+}}, [[TT]]** [[CPADDR8:%.+]],
+ // CHECK-DAG: [[CBPADDR8]] = bitcast i8** {{%[^,]+}} to [[TT]]**
+ // CHECK-DAG: [[CPADDR8]] = bitcast i8** {{%[^,]+}} to [[TT]]**
+ // CHECK-DAG: store i[[SZ]] {{12|16}}, i[[SZ]]* {{%[^,]+}}
+
+ // CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
+ // CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:[^,]+]], label %[[END:[^,]+]]
+
+ // CHECK: [[FAIL]]
+ // CHECK: call void [[HVT4:@.+]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}})
+ // CHECK-NEXT: br label %[[END]]
+ // CHECK: [[END]]
+ #pragma omp target simd if(target: n>20)
+ for (unsigned char it = 'z'; it >= 'a'; it+=-1) {
+ a += 1;
+ b[2] += 1.0;
+ bn[3] += 1.0;
+ c[1][2] += 1.0;
+ cn[1][3] += 1.0;
+ d.X += 1;
+ d.Y += 1;
+ }
+
+ return a;
+}
+
+// Check that the offloading functions are emitted and that the arguments are
+// correct and loaded correctly for the target regions in foo().
+
+// CHECK: define internal void [[HVT0]]()
+// CHECK: !llvm.loop
+// CHECK: ret void
+// CHECK-NEXT: }
+
+
+// CHECK: define internal void [[HVT1]](i[[SZ]] %{{.+}}, i{{32|64}}{{[*]*.*}} %{{.+}})
+// CHECK: [[AA_ADDR:%.+]] = alloca i[[SZ]], align
+// CHECK: store i[[SZ]] %{{.+}}, i[[SZ]]* [[AA_ADDR]], align
+// CHECK-64: [[AA_CADDR:%.+]] = bitcast i[[SZ]]* [[AA_ADDR]] to i32*
+// CHECK-64: [[AA:%.+]] = load i32, i32* [[AA_CADDR]], align
+// CHECK-32: [[AA:%.+]] = load i32, i32* [[AA_ADDR]], align
+// CHECK: !llvm.mem.parallel_loop_access
+// CHECK: !llvm.loop
+// CHECK: ret void
+// CHECK-NEXT: }
+
+// CHECK: define internal void [[HVT2]](i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}})
+// CHECK: [[AA_ADDR:%.+]] = alloca i[[SZ]], align
+// CHECK: store i[[SZ]] %{{.+}}, i[[SZ]]* [[AA_ADDR]], align
+// CHECK: [[AA_CADDR:%.+]] = bitcast i[[SZ]]* [[AA_ADDR]] to i16*
+// CHECK: [[AA:%.+]] = load i16, i16* [[AA_CADDR]], align
+// CHECK: !llvm.loop
+// CHECK: ret void
+// CHECK-NEXT: }
+
+// CHECK: define internal void [[HVT3]]
+// CHECK: [[A_ADDR:%.+]] = alloca i[[SZ]], align
+// CHECK: [[AA_ADDR:%.+]] = alloca i[[SZ]], align
+// CHECK-DAG: store i[[SZ]] %{{.+}}, i[[SZ]]* [[A_ADDR]], align
+// CHECK-DAG: store i[[SZ]] %{{.+}}, i[[SZ]]* [[AA_ADDR]], align
+// CHECK-64-DAG:[[A_CADDR:%.+]] = bitcast i[[SZ]]* [[A_ADDR]] to i32*
+// CHECK-DAG: [[AA_CADDR:%.+]] = bitcast i[[SZ]]* [[AA_ADDR]] to i16*
+// CHECK: !llvm.loop
+// CHECK: ret void
+// CHECK-NEXT: }
+
+// CHECK: define internal void [[HVT4]]
+// Create local storage for each capture.
+// CHECK: [[LOCAL_A:%.+]] = alloca i[[SZ]]
+// CHECK: [[LOCAL_B:%.+]] = alloca [10 x float]*
+// CHECK: [[LOCAL_VLA1:%.+]] = alloca i[[SZ]]
+// CHECK: [[LOCAL_BN:%.+]] = alloca float*
+// CHECK: [[LOCAL_C:%.+]] = alloca [5 x [10 x double]]*
+// CHECK: [[LOCAL_VLA2:%.+]] = alloca i[[SZ]]
+// CHECK: [[LOCAL_VLA3:%.+]] = alloca i[[SZ]]
+// CHECK: [[LOCAL_CN:%.+]] = alloca double*
+// CHECK: [[LOCAL_D:%.+]] = alloca [[TT]]*
+// CHECK-DAG: store i[[SZ]] [[ARG_A:%.+]], i[[SZ]]* [[LOCAL_A]]
+// CHECK-DAG: store [10 x float]* [[ARG_B:%.+]], [10 x float]** [[LOCAL_B]]
+// CHECK-DAG: store i[[SZ]] [[ARG_VLA1:%.+]], i[[SZ]]* [[LOCAL_VLA1]]
+// CHECK-DAG: store float* [[ARG_BN:%.+]], float** [[LOCAL_BN]]
+// CHECK-DAG: store [5 x [10 x double]]* [[ARG_C:%.+]], [5 x [10 x double]]** [[LOCAL_C]]
+// CHECK-DAG: store i[[SZ]] [[ARG_VLA2:%.+]], i[[SZ]]* [[LOCAL_VLA2]]
+// CHECK-DAG: store i[[SZ]] [[ARG_VLA3:%.+]], i[[SZ]]* [[LOCAL_VLA3]]
+// CHECK-DAG: store double* [[ARG_CN:%.+]], double** [[LOCAL_CN]]
+// CHECK-DAG: store [[TT]]* [[ARG_D:%.+]], [[TT]]** [[LOCAL_D]]
+
+// CHECK-64-DAG:[[CONV_AP:%.+]] = bitcast i[[SZ]]* [[LOCAL_A]] to i32*
+// CHECK-DAG: [[REF_B:%.+]] = load [10 x float]*, [10 x float]** [[LOCAL_B]],
+// CHECK-DAG: [[VAL_VLA1:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_VLA1]],
+// CHECK-DAG: [[REF_BN:%.+]] = load float*, float** [[LOCAL_BN]],
+// CHECK-DAG: [[REF_C:%.+]] = load [5 x [10 x double]]*, [5 x [10 x double]]** [[LOCAL_C]],
+// CHECK-DAG: [[VAL_VLA2:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_VLA2]],
+// CHECK-DAG: [[VAL_VLA3:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_VLA3]],
+// CHECK-DAG: [[REF_CN:%.+]] = load double*, double** [[LOCAL_CN]],
+// CHECK-DAG: [[REF_D:%.+]] = load [[TT]]*, [[TT]]** [[LOCAL_D]],
+
+
+template<typename tx>
+tx ftemplate(int n) {
+ tx a = 0;
+ short aa = 0;
+ tx b[10];
+
+ #pragma omp target simd if(target: n>40)
+ for (long long i = -10; i < 10; i += 3) {
+ a += 1;
+ aa += 1;
+ b[2] += 1;
+ }
+
+ return a;
+}
+
+static
+int fstatic(int n) {
+ int a = 0;
+ short aa = 0;
+ char aaa = 0;
+ int b[10];
+
+ #pragma omp target simd if(target: n>50)
+ for (unsigned i=100; i<10; i+=10) {
+ a += 1;
+ aa += 1;
+ aaa += 1;
+ b[2] += 1;
+ }
+
+ return a;
+}
+
+struct S1 {
+ double a;
+
+ int r1(int n){
+ int b = n+1;
+ short int c[2][n];
+
+ #pragma omp target simd if(target: n>60)
+ for (unsigned long long it = 2000; it >= 600; it -= 400) {
+ this->a = (double)b + 1.5;
+ c[1][1] = ++a;
+ }
+
+ return c[1][1] + (int)b;
+ }
+};
+
+// CHECK: define {{.*}}@{{.*}}bar{{.*}}
+int bar(int n){
+ int a = 0;
+
+ // CHECK: call {{.*}}i32 [[FOO]](i32 {{.*}})
+ a += foo(n);
+
+ S1 S;
+ // CHECK: call {{.*}}i32 [[FS1:@.+]]([[S1]]* {{.*}}, i32 {{.*}})
+ a += S.r1(n);
+
+ // CHECK: call {{.*}}i32 [[FSTATIC:@.+]](i32 {{.*}})
+ a += fstatic(n);
+
+ // CHECK: call {{.*}}i32 [[FTEMPLATE:@.+]](i32 {{.*}})
+ a += ftemplate<int>(n);
+
+ return a;
+}
+
+//
+// CHECK: define {{.*}}[[FS1]]
+//
+// CHECK: i8* @llvm.stacksave()
+// CHECK-64: [[B_ADDR:%.+]] = bitcast i[[SZ]]* [[B_CADDR:%.+]] to i32*
+// CHECK-64: store i32 %{{.+}}, i32* [[B_ADDR]],
+// CHECK-64: [[B_CVAL:%.+]] = load i[[SZ]], i[[SZ]]* [[B_CADDR]],
+
+// CHECK-32: store i32 %{{.+}}, i32* [[B_ADDR:%.+]],
+// CHECK-32: [[B_CVAL:%.+]] = load i[[SZ]], i[[SZ]]* [[B_ADDR]],
+
+// We capture 2 VLA sizes in this target region
+// CHECK: [[CELEMSIZE2:%.+]] = mul nuw i[[SZ]] 2, [[VLA0:%.+]]
+// CHECK: [[CSIZE:%.+]] = mul nuw i[[SZ]] [[CELEMSIZE2]], 2
+
+// CHECK: [[IF:%.+]] = icmp sgt i32 {{[^,]+}}, 60
+// CHECK: br i1 [[IF]], label %[[TRY:[^,]+]], label %[[FAIL:[^,]+]]
+// CHECK: [[TRY]]
+// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target(i64 -1, i8* @{{[^,]+}}, i32 5, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* [[SR:%[^,]+]], i64* getelementptr inbounds ([5 x i64], [5 x i64]* [[MAPT7]], i32 0, i32 0))
+// CHECK-DAG: [[BPR]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[BP:%.+]], i32 0, i32 0
+// CHECK-DAG: [[PR]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[P:%.+]], i32 0, i32 0
+// CHECK-DAG: [[SR]] = getelementptr inbounds [5 x i[[SZ]]], [5 x i[[SZ]]]* [[S:%.+]], i32 0, i32 0
+// CHECK-DAG: [[SADDR0:%.+]] = getelementptr inbounds [5 x i[[SZ]]], [5 x i[[SZ]]]* [[S]], i32 [[IDX0:[0-9]+]]
+// CHECK-DAG: [[BPADDR0:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[BP]], i32 [[IDX0]]
+// CHECK-DAG: [[PADDR0:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[P]], i32 [[IDX0]]
+// CHECK-DAG: [[SADDR1:%.+]] = getelementptr inbounds [5 x i[[SZ]]], [5 x i[[SZ]]]* [[S]], i32 [[IDX1:[0-9]+]]
+// CHECK-DAG: [[BPADDR1:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[BP]], i32 [[IDX1]]
+// CHECK-DAG: [[PADDR1:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[P]], i32 [[IDX1]]
+// CHECK-DAG: [[SADDR2:%.+]] = getelementptr inbounds [5 x i[[SZ]]], [5 x i[[SZ]]]* [[S]], i32 [[IDX2:[0-9]+]]
+// CHECK-DAG: [[BPADDR2:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[BP]], i32 [[IDX2]]
+// CHECK-DAG: [[PADDR2:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[P]], i32 [[IDX2]]
+// CHECK-DAG: [[SADDR3:%.+]] = getelementptr inbounds [5 x i[[SZ]]], [5 x i[[SZ]]]* [[S]], i32 [[IDX3:[0-9]+]]
+// CHECK-DAG: [[BPADDR3:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[BP]], i32 [[IDX3]]
+// CHECK-DAG: [[PADDR3:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[P]], i32 [[IDX3]]
+
+// The names below are not necessarily consistent with the names used for the
+// addresses above as some are repeated.
+// CHECK-DAG: store i[[SZ]] [[VLA0]], i[[SZ]]* [[CBPADDR0:%.+]],
+// CHECK-DAG: store i[[SZ]] [[VLA0]], i[[SZ]]* [[CPADDR0:%.+]],
+// CHECK-DAG: [[CBPADDR0]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+// CHECK-DAG: [[CPADDR0]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+// CHECK-DAG: store i[[SZ]] {{4|8}}, i[[SZ]]* {{%[^,]+}}
+
+// CHECK-DAG: store i[[SZ]] 2, i[[SZ]]* [[CBPADDR1:%.+]],
+// CHECK-DAG: store i[[SZ]] 2, i[[SZ]]* [[CPADDR1:%.+]],
+// CHECK-DAG: [[CBPADDR1]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+// CHECK-DAG: [[CPADDR1]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+// CHECK-DAG: store i[[SZ]] {{4|8}}, i[[SZ]]* {{%[^,]+}}
+
+// CHECK-DAG: store i[[SZ]] [[B_CVAL]], i[[SZ]]* [[CBPADDR2:%.+]],
+// CHECK-DAG: store i[[SZ]] [[B_CVAL]], i[[SZ]]* [[CPADDR2:%.+]],
+// CHECK-DAG: [[CBPADDR2]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+// CHECK-DAG: [[CPADDR2]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+// CHECK-DAG: store i[[SZ]] 4, i[[SZ]]* {{%[^,]+}}
+
+// CHECK-DAG: store [[S1]]* %{{.+}}, [[S1]]** [[CBPADDR3:%.+]],
+// CHECK-DAG: store [[S1]]* %{{.+}}, [[S1]]** [[CPADDR3:%.+]],
+// CHECK-DAG: [[CBPADDR3]] = bitcast i8** {{%[^,]+}} to [[S1]]**
+// CHECK-DAG: [[CPADDR3]] = bitcast i8** {{%[^,]+}} to [[S1]]**
+// CHECK-DAG: store i[[SZ]] 8, i[[SZ]]* {{%[^,]+}}
+
+// CHECK-DAG: store i16* %{{.+}}, i16** [[CBPADDR4:%.+]],
+// CHECK-DAG: store i16* %{{.+}}, i16** [[CPADDR4:%.+]],
+// CHECK-DAG: [[CBPADDR4]] = bitcast i8** {{%[^,]+}} to i16**
+// CHECK-DAG: [[CPADDR4]] = bitcast i8** {{%[^,]+}} to i16**
+// CHECK-DAG: store i[[SZ]] [[CSIZE]], i[[SZ]]* {{%[^,]+}}
+
+// CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
+// CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:[^,]+]], label %[[END:[^,]+]]
+
+// CHECK: [[FAIL]]
+// CHECK: call void [[HVT7:@.+]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}})
+// CHECK-NEXT: br label %[[END]]
+// CHECK: [[END]]
+
+//
+// CHECK: define {{.*}}[[FSTATIC]]
+//
+// CHECK: [[IF:%.+]] = icmp sgt i32 {{[^,]+}}, 50
+// CHECK: br i1 [[IF]], label %[[IFTHEN:[^,]+]], label %[[IFELSE:[^,]+]]
+// CHECK: [[IFTHEN]]
+// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target(i64 -1, i8* @{{[^,]+}}, i32 4, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* getelementptr inbounds ([4 x i[[SZ]]], [4 x i[[SZ]]]* [[SIZET6]], i32 0, i32 0), i64* getelementptr inbounds ([4 x i64], [4 x i64]* [[MAPT6]], i32 0, i32 0))
+// CHECK-DAG: [[BPR]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[BP:%.+]], i32 0, i32 0
+// CHECK-DAG: [[PR]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[P:%.+]], i32 0, i32 0
+
+// CHECK-DAG: [[BPADDR0:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[BP]], i32 0, i32 0
+// CHECK-DAG: [[PADDR0:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[P]], i32 0, i32 0
+// CHECK-DAG: [[CBPADDR0:%.+]] = bitcast i8** [[BPADDR0]] to i[[SZ]]*
+// CHECK-DAG: [[CPADDR0:%.+]] = bitcast i8** [[PADDR0]] to i[[SZ]]*
+// CHECK-DAG: store i[[SZ]] [[VAL0:%.+]], i[[SZ]]* [[CBPADDR0]],
+// CHECK-DAG: store i[[SZ]] [[VAL0]], i[[SZ]]* [[CPADDR0]],
+
+// CHECK-DAG: [[BPADDR1:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[BP]], i32 0, i32 1
+// CHECK-DAG: [[PADDR1:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[P]], i32 0, i32 1
+// CHECK-DAG: [[CBPADDR1:%.+]] = bitcast i8** [[BPADDR1]] to i[[SZ]]*
+// CHECK-DAG: [[CPADDR1:%.+]] = bitcast i8** [[PADDR1]] to i[[SZ]]*
+// CHECK-DAG: store i[[SZ]] [[VAL1:%.+]], i[[SZ]]* [[CBPADDR1]],
+// CHECK-DAG: store i[[SZ]] [[VAL1]], i[[SZ]]* [[CPADDR1]],
+
+// CHECK-DAG: [[BPADDR2:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[BP]], i32 0, i32 2
+// CHECK-DAG: [[PADDR2:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[P]], i32 0, i32 2
+// CHECK-DAG: [[CBPADDR2:%.+]] = bitcast i8** [[BPADDR2]] to i[[SZ]]*
+// CHECK-DAG: [[CPADDR2:%.+]] = bitcast i8** [[PADDR2]] to i[[SZ]]*
+// CHECK-DAG: store i[[SZ]] [[VAL2:%.+]], i[[SZ]]* [[CBPADDR2]],
+// CHECK-DAG: store i[[SZ]] [[VAL2]], i[[SZ]]* [[CPADDR2]],
+
+// CHECK-DAG: [[BPADDR3:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[BP]], i32 0, i32 3
+// CHECK-DAG: [[PADDR3:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[P]], i32 0, i32 3
+// CHECK-DAG: [[CBPADDR3:%.+]] = bitcast i8** [[BPADDR3]] to [10 x i32]**
+// CHECK-DAG: [[CPADDR3:%.+]] = bitcast i8** [[PADDR3]] to [10 x i32]**
+// CHECK-DAG: store [10 x i32]* [[VAL3:%.+]], [10 x i32]** [[CBPADDR3]],
+// CHECK-DAG: store [10 x i32]* [[VAL3]], [10 x i32]** [[CPADDR3]],
+
+// CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
+// CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
+// CHECK: [[FAIL]]
+// CHECK: call void [[HVT6:@.+]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}})
+// CHECK-NEXT: br label %[[END]]
+// CHECK: [[END]]
+// CHECK-NEXT: br label %[[IFEND:.+]]
+// CHECK: [[IFELSE]]
+// CHECK: call void [[HVT6]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}})
+// CHECK-NEXT: br label %[[IFEND]]
+// CHECK: [[IFEND]]
+
+//
+// CHECK: define {{.*}}[[FTEMPLATE]]
+//
+// CHECK: [[IF:%.+]] = icmp sgt i32 {{[^,]+}}, 40
+// CHECK: br i1 [[IF]], label %[[IFTHEN:[^,]+]], label %[[IFELSE:[^,]+]]
+// CHECK: [[IFTHEN]]
+// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target(i64 -1, i8* @{{[^,]+}}, i32 3, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* getelementptr inbounds ([3 x i[[SZ]]], [3 x i[[SZ]]]* [[SIZET5]], i32 0, i32 0), i64* getelementptr inbounds ([3 x i64], [3 x i64]* [[MAPT5]], i32 0, i32 0))
+// CHECK-DAG: [[BPR]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BP:%.+]], i32 0, i32 0
+// CHECK-DAG: [[PR]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[P:%.+]], i32 0, i32 0
+
+// CHECK-DAG: [[BPADDR0:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BP]], i32 0, i32 0
+// CHECK-DAG: [[PADDR0:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[P]], i32 0, i32 0
+// CHECK-DAG: [[CBPADDR0:%.+]] = bitcast i8** [[BPADDR0]] to i[[SZ]]*
+// CHECK-DAG: [[CPADDR0:%.+]] = bitcast i8** [[PADDR0]] to i[[SZ]]*
+// CHECK-DAG: store i[[SZ]] [[VAL0:%.+]], i[[SZ]]* [[CBPADDR0]],
+// CHECK-DAG: store i[[SZ]] [[VAL0]], i[[SZ]]* [[CPADDR0]],
+
+// CHECK-DAG: [[BPADDR1:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BP]], i32 0, i32 1
+// CHECK-DAG: [[PADDR1:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[P]], i32 0, i32 1
+// CHECK-DAG: [[CBPADDR1:%.+]] = bitcast i8** [[BPADDR1]] to i[[SZ]]*
+// CHECK-DAG: [[CPADDR1:%.+]] = bitcast i8** [[PADDR1]] to i[[SZ]]*
+// CHECK-DAG: store i[[SZ]] [[VAL1:%.+]], i[[SZ]]* [[CBPADDR1]],
+// CHECK-DAG: store i[[SZ]] [[VAL1]], i[[SZ]]* [[CPADDR1]],
+
+// CHECK-DAG: [[BPADDR2:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BP]], i32 0, i32 2
+// CHECK-DAG: [[PADDR2:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[P]], i32 0, i32 2
+// CHECK-DAG: [[CBPADDR2:%.+]] = bitcast i8** [[BPADDR2]] to [10 x i32]**
+// CHECK-DAG: [[CPADDR2:%.+]] = bitcast i8** [[PADDR2]] to [10 x i32]**
+// CHECK-DAG: store [10 x i32]* [[VAL2:%.+]], [10 x i32]** [[CBPADDR2]],
+// CHECK-DAG: store [10 x i32]* [[VAL2]], [10 x i32]** [[CPADDR2]],
+
+// CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
+// CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
+// CHECK: [[FAIL]]
+// CHECK: call void [[HVT5:@.+]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}})
+// CHECK-NEXT: br label %[[END]]
+// CHECK: [[END]]
+// CHECK-NEXT: br label %[[IFEND:.+]]
+// CHECK: [[IFELSE]]
+// CHECK: call void [[HVT:@.+]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}})
+// CHECK-NEXT: br label %[[IFEND]]
+// CHECK: [[IFEND]]
+
+// Check that the offloading functions are emitted and that the arguments are
+// correct and loaded correctly for the target regions of the callees of bar().
+
+// CHECK: define internal void [[HVT7]]
+// Create local storage for each capture.
+// CHECK: [[LOCAL_THIS:%.+]] = alloca [[S1]]*
+// CHECK: [[LOCAL_B:%.+]] = alloca i[[SZ]]
+// CHECK: [[LOCAL_VLA1:%.+]] = alloca i[[SZ]]
+// CHECK: [[LOCAL_VLA2:%.+]] = alloca i[[SZ]]
+// CHECK: [[LOCAL_C:%.+]] = alloca i16*
+// CHECK-DAG: store [[S1]]* [[ARG_THIS:%.+]], [[S1]]** [[LOCAL_THIS]]
+// CHECK-DAG: store i[[SZ]] [[ARG_B:%.+]], i[[SZ]]* [[LOCAL_B]]
+// CHECK-DAG: store i[[SZ]] [[ARG_VLA1:%.+]], i[[SZ]]* [[LOCAL_VLA1]]
+// CHECK-DAG: store i[[SZ]] [[ARG_VLA2:%.+]], i[[SZ]]* [[LOCAL_VLA2]]
+// CHECK-DAG: store i16* [[ARG_C:%.+]], i16** [[LOCAL_C]]
+// Store captures in the context.
+// CHECK-DAG: [[REF_THIS:%.+]] = load [[S1]]*, [[S1]]** [[LOCAL_THIS]],
+// CHECK-64-DAG:[[CONV_BP:%.+]] = bitcast i[[SZ]]* [[LOCAL_B]] to i32*
+// CHECK-DAG: [[VAL_VLA1:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_VLA1]],
+// CHECK-DAG: [[VAL_VLA2:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_VLA2]],
+// CHECK-DAG: [[REF_C:%.+]] = load i16*, i16** [[LOCAL_C]],
+
+
+// CHECK: define internal void [[HVT6]]
+// Create local storage for each capture.
+// CHECK: [[LOCAL_A:%.+]] = alloca i[[SZ]]
+// CHECK: [[LOCAL_AA:%.+]] = alloca i[[SZ]]
+// CHECK: [[LOCAL_AAA:%.+]] = alloca i[[SZ]]
+// CHECK: [[LOCAL_B:%.+]] = alloca [10 x i32]*
+// CHECK-DAG: store i[[SZ]] [[ARG_A:%.+]], i[[SZ]]* [[LOCAL_A]]
+// CHECK-DAG: store i[[SZ]] [[ARG_AA:%.+]], i[[SZ]]* [[LOCAL_AA]]
+// CHECK-DAG: store i[[SZ]] [[ARG_AAA:%.+]], i[[SZ]]* [[LOCAL_AAA]]
+// CHECK-DAG: store [10 x i32]* [[ARG_B:%.+]], [10 x i32]** [[LOCAL_B]]
+// Store captures in the context.
+// CHECK-64-DAG:[[CONV_AP:%.+]] = bitcast i[[SZ]]* [[LOCAL_A]] to i32*
+// CHECK-DAG: [[CONV_AAP:%.+]] = bitcast i[[SZ]]* [[LOCAL_AA]] to i16*
+// CHECK-DAG: [[CONV_AAAP:%.+]] = bitcast i[[SZ]]* [[LOCAL_AAA]] to i8*
+// CHECK-DAG: [[REF_B:%.+]] = load [10 x i32]*, [10 x i32]** [[LOCAL_B]],
+
+// CHECK: define internal void [[HVT5]]
+// Create local storage for each capture.
+// CHECK: [[LOCAL_A:%.+]] = alloca i[[SZ]]
+// CHECK: [[LOCAL_AA:%.+]] = alloca i[[SZ]]
+// CHECK: [[LOCAL_B:%.+]] = alloca [10 x i32]*
+// CHECK-DAG: store i[[SZ]] [[ARG_A:%.+]], i[[SZ]]* [[LOCAL_A]]
+// CHECK-DAG: store i[[SZ]] [[ARG_AA:%.+]], i[[SZ]]* [[LOCAL_AA]]
+// CHECK-DAG: store [10 x i32]* [[ARG_B:%.+]], [10 x i32]** [[LOCAL_B]]
+// Store captures in the context.
+// CHECK-64-DAG:[[CONV_AP:%.+]] = bitcast i[[SZ]]* [[LOCAL_A]] to i32*
+// CHECK-DAG: [[CONV_AAP:%.+]] = bitcast i[[SZ]]* [[LOCAL_AA]] to i16*
+// CHECK-DAG: [[REF_B:%.+]] = load [10 x i32]*, [10 x i32]** [[LOCAL_B]],
+
+#endif
diff --git a/test/OpenMP/target_simd_codegen_registration.cpp b/test/OpenMP/target_simd_codegen_registration.cpp
new file mode 100644
index 000000000000..a6e6e9b38565
--- /dev/null
+++ b/test/OpenMP/target_simd_codegen_registration.cpp
@@ -0,0 +1,451 @@
+// Test host codegen.
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+
+// Test target simd codegen - host bc file has to be created first.
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm-bc %s -o %t-ppc-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s -check-prefix=TCHECK
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s -check-prefix=TCHECK
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm-bc %s -o %t-x86-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s -check-prefix=TCHECK
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s -check-prefix=TCHECK
+
+// Check that no target code is emmitted if no omptests flag was provided.
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s -check-prefix=CHECK-NTARGET
+
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+// CHECK-DAG: [[SA:%.+]] = type { [4 x i32] }
+// CHECK-DAG: [[SB:%.+]] = type { [8 x i32] }
+// CHECK-DAG: [[SC:%.+]] = type { [16 x i32] }
+// CHECK-DAG: [[SD:%.+]] = type { [32 x i32] }
+// CHECK-DAG: [[SE:%.+]] = type { [64 x i32] }
+// CHECK-DAG: [[ST1:%.+]] = type { [228 x i32] }
+// CHECK-DAG: [[ST2:%.+]] = type { [1128 x i32] }
+// CHECK-DAG: [[ENTTY:%.+]] = type { i8*, i8*, i[[SZ:32|64]], i32, i32 }
+// CHECK-DAG: [[DEVTY:%.+]] = type { i8*, i8*, [[ENTTY]]*, [[ENTTY]]* }
+// CHECK-DAG: [[DSCTY:%.+]] = type { i32, [[DEVTY]]*, [[ENTTY]]*, [[ENTTY]]* }
+
+// TCHECK: [[ENTTY:%.+]] = type { i8*, i8*, i[[SZ:32|64]], i32, i32 }
+
+// CHECK-DAG: $[[REGFN:\.omp_offloading\..+]] = comdat
+
+// CHECK-DAG: [[A1:@.+]] = internal global [[SA]]
+// CHECK-DAG: [[A2:@.+]] = global [[SA]]
+// CHECK-DAG: [[B1:@.+]] = global [[SB]]
+// CHECK-DAG: [[B2:@.+]] = global [[SB]]
+// CHECK-DAG: [[C1:@.+]] = internal global [[SC]]
+// CHECK-DAG: [[D1:@.+]] = global [[SD]]
+// CHECK-DAG: [[E1:@.+]] = global [[SE]]
+// CHECK-DAG: [[T1:@.+]] = global [[ST1]]
+// CHECK-DAG: [[T2:@.+]] = global [[ST2]]
+
+// CHECK-NTARGET-DAG: [[SA:%.+]] = type { [4 x i32] }
+// CHECK-NTARGET-DAG: [[SB:%.+]] = type { [8 x i32] }
+// CHECK-NTARGET-DAG: [[SC:%.+]] = type { [16 x i32] }
+// CHECK-NTARGET-DAG: [[SD:%.+]] = type { [32 x i32] }
+// CHECK-NTARGET-DAG: [[SE:%.+]] = type { [64 x i32] }
+// CHECK-NTARGET-DAG: [[ST1:%.+]] = type { [228 x i32] }
+// CHECK-NTARGET-DAG: [[ST2:%.+]] = type { [1128 x i32] }
+// CHECK-NTARGET-NOT: type { i8*, i8*, %
+// CHECK-NTARGET-NOT: type { i32, %
+
+// We have 7 target regions
+
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// TCHECK-NOT: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
+
+// CHECK-NTARGET-NOT: private constant i8 0
+// CHECK-NTARGET-NOT: private unnamed_addr constant [1 x i
+
+// CHECK-DAG: [[NAMEPTR1:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME1:__omp_offloading_[0-9a-f]+_[0-9a-f]+__Z.+_l[0-9]+]]\00"
+// CHECK-DAG: [[ENTRY1:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR1]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR2:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME2:.+]]\00"
+// CHECK-DAG: [[ENTRY2:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR2]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR3:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME3:.+]]\00"
+// CHECK-DAG: [[ENTRY3:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR3]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR4:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME4:.+]]\00"
+// CHECK-DAG: [[ENTRY4:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR4]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR5:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME5:.+]]\00"
+// CHECK-DAG: [[ENTRY5:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR5]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR6:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME6:.+]]\00"
+// CHECK-DAG: [[ENTRY6:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR6]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR7:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME7:.+]]\00"
+// CHECK-DAG: [[ENTRY7:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR7]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR8:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME8:.+]]\00"
+// CHECK-DAG: [[ENTRY8:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR8]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR9:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME9:.+]]\00"
+// CHECK-DAG: [[ENTRY9:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR9]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR10:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME10:.+]]\00"
+// CHECK-DAG: [[ENTRY10:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR10]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR11:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME11:.+]]\00"
+// CHECK-DAG: [[ENTRY11:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR11]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR12:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME12:.+]]\00"
+// CHECK-DAG: [[ENTRY12:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR12]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+
+// TCHECK-DAG: [[NAMEPTR1:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME1:__omp_offloading_[0-9a-f]+_[0-9a-f]+__Z.+_l[0-9]+]]\00"
+// TCHECK-DAG: [[ENTRY1:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR1]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR2:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME2:.+]]\00"
+// TCHECK-DAG: [[ENTRY2:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR2]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR3:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME3:.+]]\00"
+// TCHECK-DAG: [[ENTRY3:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR3]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR4:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME4:.+]]\00"
+// TCHECK-DAG: [[ENTRY4:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR4]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR5:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME5:.+]]\00"
+// TCHECK-DAG: [[ENTRY5:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR5]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR6:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME6:.+]]\00"
+// TCHECK-DAG: [[ENTRY6:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR6]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR7:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME7:.+]]\00"
+// TCHECK-DAG: [[ENTRY7:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR7]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR8:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME8:.+]]\00"
+// TCHECK-DAG: [[ENTRY8:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR8]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR9:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME9:.+]]\00"
+// TCHECK-DAG: [[ENTRY9:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR9]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR10:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME10:.+]]\00"
+// TCHECK-DAG: [[ENTRY10:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR10]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR11:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME11:.+]]\00"
+// TCHECK-DAG: [[ENTRY11:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR11]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR12:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME12:.+]]\00"
+// TCHECK-DAG: [[ENTRY12:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR12]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+
+// CHECK: [[ENTBEGIN:@.+]] = external constant [[ENTTY]]
+// CHECK: [[ENTEND:@.+]] = external constant [[ENTTY]]
+// CHECK: [[DEVBEGIN:@.+]] = external constant i8
+// CHECK: [[DEVEND:@.+]] = external constant i8
+// CHECK: [[IMAGES:@.+]] = internal unnamed_addr constant [1 x [[DEVTY]]] [{{.+}} { i8* [[DEVBEGIN]], i8* [[DEVEND]], [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }], comdat($[[REGFN]])
+// CHECK: [[DESC:@.+]] = internal constant [[DSCTY]] { i32 1, [[DEVTY]]* getelementptr inbounds ([1 x [[DEVTY]]], [1 x [[DEVTY]]]* [[IMAGES]], i32 0, i32 0), [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }, comdat($[[REGFN]])
+
+// We have 4 initializers, one for the 500 priority, another one for 501, or more for the default priority, and the last one for the offloading registration function.
+// CHECK: @llvm.global_ctors = appending global [4 x { i32, void ()*, i8* }] [
+// CHECK-SAME: { i32, void ()*, i8* } { i32 500, void ()* [[P500:@[^,]+]], i8* null },
+// CHECK-SAME: { i32, void ()*, i8* } { i32 501, void ()* [[P501:@[^,]+]], i8* null },
+// CHECK-SAME: { i32, void ()*, i8* } { i32 65535, void ()* [[PMAX:@[^,]+]], i8* null },
+// CHECK-SAME: { i32, void ()*, i8* } { i32 0, void ()* bitcast (void (i8*)* @[[REGFN]] to void ()*), i8* bitcast (void (i8*)* @[[REGFN]] to i8*) }]
+
+// CHECK-NTARGET: @llvm.global_ctors = appending global [3 x { i32, void ()*, i8* }] [
+
+extern int *R;
+
+struct SA {
+ int arr[4];
+ void foo() {
+ int a = *R;
+ a += 1;
+ *R = a;
+ }
+ SA() {
+ int a = *R;
+ a += 2;
+ *R = a;
+ }
+ ~SA() {
+ int a = *R;
+ a += 3;
+ *R = a;
+ }
+};
+
+struct SB {
+ int arr[8];
+ void foo() {
+ int a = *R;
+ #pragma omp target simd
+ for (int i = 0; i < 10; ++i)
+ a += 4;
+ *R = a;
+ }
+ SB() {
+ int a = *R;
+ a += 5;
+ *R = a;
+ }
+ ~SB() {
+ int a = *R;
+ a += 6;
+ *R = a;
+ }
+};
+
+struct SC {
+ int arr[16];
+ void foo() {
+ int a = *R;
+ a += 7;
+ *R = a;
+ }
+ SC() {
+ int a = *R;
+ #pragma omp target simd
+ for (int i = 0; i < 10; ++i)
+ a += 8;
+ *R = a;
+ }
+ ~SC() {
+ int a = *R;
+ a += 9;
+ *R = a;
+ }
+};
+
+struct SD {
+ int arr[32];
+ void foo() {
+ int a = *R;
+ a += 10;
+ *R = a;
+ }
+ SD() {
+ int a = *R;
+ a += 11;
+ *R = a;
+ }
+ ~SD() {
+ int a = *R;
+ #pragma omp target simd
+ for (int i = 0; i < 10; ++i)
+ a += 12;
+ *R = a;
+ }
+};
+
+struct SE {
+ int arr[64];
+ void foo() {
+ int a = *R;
+ #pragma omp target simd if(target: 0)
+ for (int i = 0; i < 10; ++i)
+ a += 13;
+ *R = a;
+ }
+ SE() {
+ int a = *R;
+ #pragma omp target simd
+ for (int i = 0; i < 10; ++i)
+ a += 14;
+ *R = a;
+ }
+ ~SE() {
+ int a = *R;
+ #pragma omp target simd
+ for (int i = 0; i < 10; ++i)
+ a += 15;
+ *R = a;
+ }
+};
+
+template <int x>
+struct ST {
+ int arr[128 + x];
+ void foo() {
+ int a = *R;
+ #pragma omp target simd
+ for (int i = 0; i < 10; ++i)
+ a += 16 + x;
+ *R = a;
+ }
+ ST() {
+ int a = *R;
+ #pragma omp target simd
+ for (int i = 0; i < 10; ++i)
+ a += 17 + x;
+ *R = a;
+ }
+ ~ST() {
+ int a = *R;
+ #pragma omp target simd
+ for (int i = 0; i < 10; ++i)
+ a += 18 + x;
+ *R = a;
+ }
+};
+
+// We have to make sure we us all the target regions:
+//CHECK-DAG: define internal void @[[NAME1]](
+//CHECK-DAG: call void @[[NAME1]](
+//CHECK-DAG: define internal void @[[NAME2]](
+//CHECK-DAG: call void @[[NAME2]](
+//CHECK-DAG: define internal void @[[NAME3]](
+//CHECK-DAG: call void @[[NAME3]](
+//CHECK-DAG: define internal void @[[NAME4]](
+//CHECK-DAG: call void @[[NAME4]](
+//CHECK-DAG: define internal void @[[NAME5]](
+//CHECK-DAG: call void @[[NAME5]](
+//CHECK-DAG: define internal void @[[NAME6]](
+//CHECK-DAG: call void @[[NAME6]](
+//CHECK-DAG: define internal void @[[NAME7]](
+//CHECK-DAG: call void @[[NAME7]](
+//CHECK-DAG: define internal void @[[NAME8]](
+//CHECK-DAG: call void @[[NAME8]](
+//CHECK-DAG: define internal void @[[NAME9]](
+//CHECK-DAG: call void @[[NAME9]](
+//CHECK-DAG: define internal void @[[NAME10]](
+//CHECK-DAG: call void @[[NAME10]](
+//CHECK-DAG: define internal void @[[NAME11]](
+//CHECK-DAG: call void @[[NAME11]](
+//CHECK-DAG: define internal void @[[NAME12]](
+//CHECK-DAG: call void @[[NAME12]](
+
+//TCHECK-DAG: define void @[[NAME1]](
+//TCHECK-DAG: define void @[[NAME2]](
+//TCHECK-DAG: define void @[[NAME3]](
+//TCHECK-DAG: define void @[[NAME4]](
+//TCHECK-DAG: define void @[[NAME5]](
+//TCHECK-DAG: define void @[[NAME6]](
+//TCHECK-DAG: define void @[[NAME7]](
+//TCHECK-DAG: define void @[[NAME8]](
+//TCHECK-DAG: define void @[[NAME9]](
+//TCHECK-DAG: define void @[[NAME10]](
+//TCHECK-DAG: define void @[[NAME11]](
+//TCHECK-DAG: define void @[[NAME12]](
+
+// CHECK-NTARGET-NOT: __tgt_target
+// CHECK-NTARGET-NOT: __tgt_register_lib
+// CHECK-NTARGET-NOT: __tgt_unregister_lib
+
+// TCHECK-NOT: __tgt_target
+// TCHECK-NOT: __tgt_register_lib
+// TCHECK-NOT: __tgt_unregister_lib
+
+// We have 2 initializers with priority 500
+//CHECK: define internal void [[P500]](
+//CHECK: call void @{{.+}}()
+//CHECK: call void @{{.+}}()
+//CHECK-NOT: call void @{{.+}}()
+//CHECK: ret void
+
+// We have 1 initializers with priority 501
+//CHECK: define internal void [[P501]](
+//CHECK: call void @{{.+}}()
+//CHECK-NOT: call void @{{.+}}()
+//CHECK: ret void
+
+// We have 6 initializers with default priority
+//CHECK: define internal void [[PMAX]](
+//CHECK: call void @{{.+}}()
+//CHECK: call void @{{.+}}()
+//CHECK: call void @{{.+}}()
+//CHECK: call void @{{.+}}()
+//CHECK: call void @{{.+}}()
+//CHECK: call void @{{.+}}()
+//CHECK-NOT: call void @{{.+}}()
+//CHECK: ret void
+
+// Check registration and unregistration
+
+//CHECK: define internal void @[[UNREGFN:.+]](i8*)
+//CHECK-SAME: comdat($[[REGFN]]) {
+//CHECK: call i32 @__tgt_unregister_lib([[DSCTY]]* [[DESC]])
+//CHECK: ret void
+//CHECK: declare i32 @__tgt_unregister_lib([[DSCTY]]*)
+
+//CHECK: define linkonce hidden void @[[REGFN]](i8*)
+//CHECK-SAME: comdat {
+//CHECK: call i32 @__tgt_register_lib([[DSCTY]]* [[DESC]])
+//CHECK: call i32 @__cxa_atexit(void (i8*)* @[[UNREGFN]], i8* bitcast ([[DSCTY]]* [[DESC]] to i8*),
+//CHECK: ret void
+//CHECK: declare i32 @__tgt_register_lib([[DSCTY]]*)
+
+static __attribute__((init_priority(500))) SA a1;
+SA a2;
+SB __attribute__((init_priority(500))) b1;
+SB __attribute__((init_priority(501))) b2;
+static SC c1;
+SD d1;
+SE e1;
+ST<100> t1;
+ST<1000> t2;
+
+
+int bar(int a){
+ int r = a;
+
+ a1.foo();
+ a2.foo();
+ b1.foo();
+ b2.foo();
+ c1.foo();
+ d1.foo();
+ e1.foo();
+ t1.foo();
+ t2.foo();
+
+ #pragma omp target simd
+ for (int i = 0; i < 10; ++i)
+ ++r;
+
+ return r + *R;
+}
+
+// Check metadata is properly generated:
+// CHECK: !omp_offload.info = !{!{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID:-?[0-9]+]], i32 [[FILEID:-?[0-9]+]], !"_ZN2SB3fooEv", i32 195, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SDD1Ev", i32 247, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SEC1Ev", i32 265, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SED1Ev", i32 272, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EE3fooEv", i32 284, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EEC1Ev", i32 291, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_Z3bari", i32 415, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EED1Ev", i32 298, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EEC1Ev", i32 291, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EED1Ev", i32 298, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EE3fooEv", i32 284, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SCC1Ev", i32 221, i32 {{[0-9]+}}}
+
+// TCHECK: !omp_offload.info = !{!{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID:-?[0-9]+]], i32 [[FILEID:-?[0-9]+]], !"_ZN2SB3fooEv", i32 195, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SDD1Ev", i32 247, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SEC1Ev", i32 265, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SED1Ev", i32 272, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EE3fooEv", i32 284, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EEC1Ev", i32 291, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_Z3bari", i32 415, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EED1Ev", i32 298, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EEC1Ev", i32 291, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EED1Ev", i32 298, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EE3fooEv", i32 284, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SCC1Ev", i32 221, i32 {{[0-9]+}}}
+
+#endif
diff --git a/test/OpenMP/target_simd_codegen_registration_naming.cpp b/test/OpenMP/target_simd_codegen_registration_naming.cpp
new file mode 100644
index 000000000000..2ed74da4f05b
--- /dev/null
+++ b/test/OpenMP/target_simd_codegen_registration_naming.cpp
@@ -0,0 +1,68 @@
+// Test host codegen.
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+
+// Test target simd codegen - host bc file has to be created first.
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm-bc %s -o %t-ppc-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s -check-prefix=TCHECK
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s -check-prefix=TCHECK
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm-bc %s -o %t-x86-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s -check-prefix=TCHECK
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s -check-prefix=TCHECK
+
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+// CHECK: [[CA:%.+]] = type { i32* }
+
+// CHECK: define {{.*}}i32 @[[NNAME:.+]](i32 {{.*}}%{{.+}})
+int nested(int a){
+ // CHECK: call void @__omp_offloading_[[FILEID:[0-9a-f]+_[0-9a-f]+]]_[[NNAME]]_l[[T1L:[0-9]+]](
+ #pragma omp target simd
+ for (int i = 0; i < 10; ++i)
+ ++a;
+
+ // CHECK: call void @"[[LNAME:.+]]"([[CA]]*
+ auto F = [&](){
+ #pragma omp parallel
+ {
+ #pragma omp target simd
+ for (int i = 0; i < 10; ++i)
+ ++a;
+ }
+ };
+
+ F();
+
+ return a;
+}
+
+// CHECK: define {{.*}}void @__omp_offloading_[[FILEID]]_[[NNAME]]_l[[T1L]](
+// TCHECK: define {{.*}}void @__omp_offloading_[[FILEID:[0-9a-f]+_[0-9a-f]+]]_[[NNAME:.+]]_l[[T1L:[0-9]+]](
+
+// CHECK: define {{.*}}void @"[[LNAME]]"(
+// CHECK: call void {{.*}}@__kmpc_fork_call{{.+}}[[PNAME:@.+]] to
+
+// CHECK: define {{.*}}void [[PNAME]](
+// CHECK: call void @__omp_offloading_[[FILEID]]_[[NNAME]]_l[[T2L:[0-9]+]](
+
+// CHECK: define {{.*}}void @__omp_offloading_[[FILEID]]_[[NNAME]]_l[[T2L]](
+// TCHECK: define {{.*}}void @__omp_offloading_[[FILEID]]_[[NNAME:.+]]_l[[T2L:[0-9]+]](
+
+
+// Check metadata is properly generated:
+// CHECK: !omp_offload.info = !{!{{[0-9]+}}, !{{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 {{-?[0-9]+}}, i32 {{-?[0-9]+}}, !"[[NNAME]]", i32 [[T1L]], i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 {{-?[0-9]+}}, i32 {{-?[0-9]+}}, !"[[NNAME]]", i32 [[T2L]], i32 {{[0-9]+}}}
+
+// TCHECK: !omp_offload.info = !{!{{[0-9]+}}, !{{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 {{-?[0-9]+}}, i32 {{-?[0-9]+}}, !"[[NNAME]]", i32 [[T1L]], i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 {{-?[0-9]+}}, i32 {{-?[0-9]+}}, !"[[NNAME]]", i32 [[T2L]], i32 {{[0-9]+}}}
+#endif
diff --git a/test/OpenMP/target_simd_depend_messages.cpp b/test/OpenMP/target_simd_depend_messages.cpp
index 3fc46f4c0848..89184f25d7a1 100644
--- a/test/OpenMP/target_simd_depend_messages.cpp
+++ b/test/OpenMP/target_simd_depend_messages.cpp
@@ -37,21 +37,21 @@ int main(int argc, char **argv, char *env[]) {
for (i = 0; i < argc; ++i) foo();
#pragma omp target simd depend (out: ) // expected-error {{expected expression}}
for (i = 0; i < argc; ++i) foo();
- #pragma omp target simd depend (inout : foobool(argc)), depend (in, argc) // expected-error {{expected variable name, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}}
+ #pragma omp target simd depend (inout : foobool(argc)), depend (in, argc) // expected-error {{expected addressable lvalue expression, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}}
for (i = 0; i < argc; ++i) foo();
#pragma omp target simd depend (out :S1) // expected-error {{'S1' does not refer to a value}}
for (i = 0; i < argc; ++i) foo();
- #pragma omp target simd depend(in : argv[1][1] = '2') // expected-error {{expected variable name, array element or array section}}
+ #pragma omp target simd depend(in : argv[1][1] = '2')
for (i = 0; i < argc; ++i) foo();
- #pragma omp target simd depend (in : vec[1]) // expected-error {{expected variable name, array element or array section}}
+ #pragma omp target simd depend (in : vec[1]) // expected-error {{expected addressable lvalue expression, array element or array section}}
for (i = 0; i < argc; ++i) foo();
#pragma omp target simd depend (in : argv[0])
for (i = 0; i < argc; ++i) foo();
#pragma omp target simd depend (in : ) // expected-error {{expected expression}}
for (i = 0; i < argc; ++i) foo();
- #pragma omp target simd depend (in : main) // expected-error {{expected variable name, array element or array section}}
+ #pragma omp target simd depend (in : main)
for (i = 0; i < argc; ++i) foo();
- #pragma omp target simd depend(in : a[0]) // expected-error{{expected variable name, array element or array section}}
+ #pragma omp target simd depend(in : a[0]) // expected-error{{expected addressable lvalue expression, array element or array section}}
for (i = 0; i < argc; ++i) foo();
#pragma omp target simd depend (in : vec[1:2]) // expected-error {{ value is not an array or pointer}}
for (i = 0; i < argc; ++i) foo();
diff --git a/test/OpenMP/target_simd_lastprivate_messages.cpp b/test/OpenMP/target_simd_lastprivate_messages.cpp
index afb38d9c9222..9a6eb241728b 100644
--- a/test/OpenMP/target_simd_lastprivate_messages.cpp
+++ b/test/OpenMP/target_simd_lastprivate_messages.cpp
@@ -18,9 +18,9 @@ public:
S2 &operator=(const S2 &);
const S2 &operator=(const S2 &) const;
static float S2s; // expected-note {{static data member is predetermined as shared}}
- static const float S2sc;
+ static const float S2sc; // expected-note {{static data member is predetermined as shared}}
};
-const float S2::S2sc = 0; // expected-note {{static data member is predetermined as shared}}
+const float S2::S2sc = 0;
const S2 b;
const S2 ba[5];
class S3 {
diff --git a/test/OpenMP/target_simd_map_messages.cpp b/test/OpenMP/target_simd_map_messages.cpp
index 63bbdde77255..2473bbb49bea 100644
--- a/test/OpenMP/target_simd_map_messages.cpp
+++ b/test/OpenMP/target_simd_map_messages.cpp
@@ -14,8 +14,8 @@ class S2 {
public:
S2():a(0) { }
S2(S2 &s2):a(s2.a) { }
- static float S2s; // expected-note 4 {{mappable type cannot contain static members}}
- static const float S2sc; // expected-note 4 {{mappable type cannot contain static members}}
+ static float S2s;
+ static const float S2sc;
};
const float S2::S2sc = 0;
const S2 b;
@@ -112,9 +112,9 @@ T tmain(T argc) {
for (i = 0; i < argc; ++i) foo();
#pragma omp target simd map(S1) // expected-error {{'S1' does not refer to a value}}
for (i = 0; i < argc; ++i) foo();
-#pragma omp target simd map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} expected-error 2 {{type 'S2' is not mappable to target}}
+#pragma omp target simd map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}}
for (i = 0; i < argc; ++i) foo();
-#pragma omp target simd map(ba) // expected-error 2 {{type 'S2' is not mappable to target}}
+#pragma omp target simd map(ba)
for (i = 0; i < argc; ++i) foo();
#pragma omp target simd map(ca)
for (i = 0; i < argc; ++i) foo();
@@ -214,11 +214,11 @@ int main(int argc, char **argv) {
for (i = 0; i < argc; ++i) foo();
#pragma omp target simd map(S1) // expected-error {{'S1' does not refer to a value}}
for (i = 0; i < argc; ++i) foo();
-#pragma omp target simd map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} expected-error 2 {{type 'S2' is not mappable to target}}
+#pragma omp target simd map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}}
for (i = 0; i < argc; ++i) foo();
#pragma omp target simd map(argv[1])
for (i = 0; i < argc; ++i) foo();
-#pragma omp target simd map(ba) // expected-error 2 {{type 'S2' is not mappable to target}}
+#pragma omp target simd map(ba)
for (i = 0; i < argc; ++i) foo();
#pragma omp target simd map(ca)
for (i = 0; i < argc; ++i) foo();
diff --git a/test/OpenMP/target_simd_reduction_messages.cpp b/test/OpenMP/target_simd_reduction_messages.cpp
index ca14acb2293f..9e1bb0521d71 100644
--- a/test/OpenMP/target_simd_reduction_messages.cpp
+++ b/test/OpenMP/target_simd_reduction_messages.cpp
@@ -25,9 +25,9 @@ public:
S2() : a(0) {}
S2(S2 &s2) : a(s2.a) {}
static float S2s; // expected-note 2 {{static data member is predetermined as shared}}
- static const float S2sc;
+ static const float S2sc; // expected-note 2 {{'S2sc' declared here}}
};
-const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}}
+const float S2::S2sc = 0;
S2 b; // expected-note 3 {{'b' defined here}}
const S2 ba[5]; // expected-note 2 {{'ba' defined here}}
class S3 {
diff --git a/test/OpenMP/target_teams_codegen.cpp b/test/OpenMP/target_teams_codegen.cpp
index 208cda6bb350..e6c250178d06 100644
--- a/test/OpenMP/target_teams_codegen.cpp
+++ b/test/OpenMP/target_teams_codegen.cpp
@@ -38,16 +38,18 @@
// code, only 6 will have mapped arguments, and only 4 have all-constant map
// sizes.
-// CHECK-DAG: [[SIZET2:@.+]] = private unnamed_addr constant [1 x i{{32|64}}] [i[[SZ:32|64]] 2]
-// CHECK-DAG: [[MAPT2:@.+]] = private unnamed_addr constant [1 x i32] [i32 288]
+// CHECK-DAG: [[SIZET:@.+]] = private unnamed_addr constant [3 x i[[SZ]]] [i[[SZ]] 2, i[[SZ]] 4, i[[SZ]] 4]
+// CHECK-DAG: [[MAPT:@.+]] = private unnamed_addr constant [3 x i64] [i64 288, i64 288, i64 288]
+// CHECK-DAG: [[SIZET2:@.+]] = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 2]
+// CHECK-DAG: [[MAPT2:@.+]] = private unnamed_addr constant [1 x i64] [i64 288]
// CHECK-DAG: [[SIZET3:@.+]] = private unnamed_addr constant [2 x i[[SZ]]] [i[[SZ]] 4, i[[SZ]] 2]
-// CHECK-DAG: [[MAPT3:@.+]] = private unnamed_addr constant [2 x i32] [i32 288, i32 288]
-// CHECK-DAG: [[MAPT4:@.+]] = private unnamed_addr constant [9 x i32] [i32 288, i32 35, i32 288, i32 35, i32 35, i32 288, i32 288, i32 35, i32 35]
+// CHECK-DAG: [[MAPT3:@.+]] = private unnamed_addr constant [2 x i64] [i64 288, i64 288]
+// CHECK-DAG: [[MAPT4:@.+]] = private unnamed_addr constant [9 x i64] [i64 288, i64 547, i64 288, i64 547, i64 547, i64 288, i64 288, i64 547, i64 547]
// CHECK-DAG: [[SIZET5:@.+]] = private unnamed_addr constant [3 x i[[SZ]]] [i[[SZ]] 4, i[[SZ]] 2, i[[SZ]] 40]
-// CHECK-DAG: [[MAPT5:@.+]] = private unnamed_addr constant [3 x i32] [i32 288, i32 288, i32 35]
+// CHECK-DAG: [[MAPT5:@.+]] = private unnamed_addr constant [3 x i64] [i64 288, i64 288, i64 547]
// CHECK-DAG: [[SIZET6:@.+]] = private unnamed_addr constant [4 x i[[SZ]]] [i[[SZ]] 4, i[[SZ]] 2, i[[SZ]] 1, i[[SZ]] 40]
-// CHECK-DAG: [[MAPT6:@.+]] = private unnamed_addr constant [4 x i32] [i32 288, i32 288, i32 288, i32 35]
-// CHECK-DAG: [[MAPT7:@.+]] = private unnamed_addr constant [5 x i32] [i32 35, i32 288, i32 288, i32 288, i32 35]
+// CHECK-DAG: [[MAPT6:@.+]] = private unnamed_addr constant [4 x i64] [i64 288, i64 288, i64 288, i64 547]
+// CHECK-DAG: [[MAPT7:@.+]] = private unnamed_addr constant [5 x i64] [i64 547, i64 288, i64 288, i64 288, i64 547]
// CHECK-DAG: @{{.*}} = private constant i8 0
// CHECK-DAG: @{{.*}} = private constant i8 0
// CHECK-DAG: @{{.*}} = private constant i8 0
@@ -83,6 +85,8 @@ struct TT{
ty Y;
};
+int global;
+
// CHECK: define {{.*}}[[FOO:@.+]](
int foo(int n) {
int a = 0;
@@ -93,30 +97,44 @@ int foo(int n) {
double cn[5][n];
TT<long long, char> d;
- // CHECK: [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 0, i8** null, i8** null, i[[SZ]]* null, i32* null, i32 0, i32 0)
- // CHECK: store i32 [[RET]], i32* [[RHV:%.+]], align 4
- // CHECK: [[RET2:%.+]] = load i32, i32* [[RHV]], align 4
- // CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+ // CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams_nowait(i64 -1, i8* @{{[^,]+}}, i32 3, i8** [[BP:%[^,]+]], i8** [[P:%[^,]+]], i[[SZ]]* getelementptr inbounds ([3 x i[[SZ]]], [3 x i[[SZ]]]* [[SIZET]], i32 0, i32 0), i64* getelementptr inbounds ([3 x i64], [3 x i64]* [[MAPT]], i32 0, i32 0), i32 {{[^,]+}}, i32 {{[^)]+}})
+ // CHECK-DAG: [[BP]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BPR:%[^,]+]], i32 0, i32 0
+ // CHECK-DAG: [[P]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[PR:%[^,]+]], i32 0, i32 0
+ // CHECK-DAG: [[BPADDR0:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BPR]], i32 0, i32 [[IDX0:[0-9]+]]
+ // CHECK-DAG: [[PADDR0:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[PR]], i32 0, i32 [[IDX0]]
+ // CHECK-DAG: [[CBPADDR0:%.+]] = bitcast i8** [[BPADDR0]] to i[[SZ]]*
+ // CHECK-DAG: [[CPADDR0:%.+]] = bitcast i8** [[PADDR0]] to i[[SZ]]*
+ // CHECK-DAG: store i[[SZ]] %{{.+}}, i[[SZ]]* [[CBPADDR0]]
+ // CHECK-DAG: store i[[SZ]] %{{.+}}, i[[SZ]]* [[CPADDR0]]
+ // CHECK-DAG: [[BPADDR1:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BPR]], i32 0, i32 [[IDX1:[0-9]+]]
+ // CHECK-DAG: [[PADDR1:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[PR]], i32 0, i32 [[IDX1]]
+ // CHECK-DAG: [[CBPADDR1:%.+]] = bitcast i8** [[BPADDR1]] to i[[SZ]]*
+ // CHECK-DAG: [[CPADDR1:%.+]] = bitcast i8** [[PADDR1]] to i[[SZ]]*
+ // CHECK-DAG: store i[[SZ]] %{{.+}}, i[[SZ]]* [[CBPADDR1]]
+ // CHECK-DAG: store i[[SZ]] %{{.+}}, i[[SZ]]* [[CPADDR1]]
+ // CHECK-DAG: [[BPADDR2:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BPR]], i32 0, i32 [[IDX1:[0-9]+]]
+ // CHECK-DAG: [[PADDR2:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[PR]], i32 0, i32 [[IDX1]]
+ // CHECK-DAG: [[CBPADDR2:%.+]] = bitcast i8** [[BPADDR2]] to i[[SZ]]*
+ // CHECK-DAG: [[CPADDR2:%.+]] = bitcast i8** [[PADDR2]] to i[[SZ]]*
+ // CHECK-DAG: store i[[SZ]] %{{.+}}, i[[SZ]]* [[CBPADDR2]]
+ // CHECK-DAG: store i[[SZ]] %{{.+}}, i[[SZ]]* [[CPADDR2]]
+ // CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
// CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:[^,]+]], label %[[END:[^,]+]]
// CHECK: [[FAIL]]
- // CHECK: call void [[HVT0:@.+]]()
+ // CHECK: call void [[HVT0:@.+]](i[[SZ]] {{[^,]+}}, i[[SZ]] {{[^,]+}}, i[[SZ]] {{[^)]+}})
// CHECK-NEXT: br label %[[END]]
// CHECK: [[END]]
- #pragma omp target teams
+ #pragma omp target teams num_teams(a) thread_limit(a) firstprivate(aa) nowait
{
}
- // CHECK: store i32 0, i32* [[RHV:%.+]], align 4
- // CHECK: store i32 -1, i32* [[RHV]], align 4
- // CHECK: [[RET2:%.+]] = load i32, i32* [[RHV]], align 4
- // CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
// CHECK: call void [[HVT1:@.+]](i[[SZ]] {{[^,]+}})
#pragma omp target teams if(target: 0)
{
a += 1;
}
- // CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 1, i8** [[BP:%[^,]+]], i8** [[P:%[^,]+]], i[[SZ]]* getelementptr inbounds ([1 x i[[SZ]]], [1 x i[[SZ]]]* [[SIZET2]], i32 0, i32 0), i32* getelementptr inbounds ([1 x i32], [1 x i32]* [[MAPT2]], i32 0, i32 0), i32 0, i32 0)
+ // CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 1, i8** [[BP:%[^,]+]], i8** [[P:%[^,]+]], i[[SZ]]* getelementptr inbounds ([1 x i[[SZ]]], [1 x i[[SZ]]]* [[SIZET2]], i32 0, i32 0), i64* getelementptr inbounds ([1 x i64], [1 x i64]* [[MAPT2]], i32 0, i32 0), i32 0, i32 0)
// CHECK-DAG: [[BP]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[BPR:%[^,]+]], i32 0, i32 0
// CHECK-DAG: [[P]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[PR:%[^,]+]], i32 0, i32 0
// CHECK-DAG: [[BPADDR0:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[BPR]], i32 0, i32 [[IDX0:[0-9]+]]
@@ -126,9 +144,7 @@ int foo(int n) {
// CHECK-DAG: store i[[SZ]] %{{.+}}, i[[SZ]]* [[CBPADDR0]]
// CHECK-DAG: store i[[SZ]] %{{.+}}, i[[SZ]]* [[CPADDR0]]
- // CHECK: store i32 [[RET]], i32* [[RHV:%.+]], align 4
- // CHECK: [[RET2:%.+]] = load i32, i32* [[RHV]], align 4
- // CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+ // CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
// CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:[^,]+]], label %[[END:[^,]+]]
// CHECK: [[FAIL]]
// CHECK: call void [[HVT2:@.+]](i[[SZ]] {{[^,]+}})
@@ -142,7 +158,7 @@ int foo(int n) {
// CHECK: [[IF:%.+]] = icmp sgt i32 {{[^,]+}}, 10
// CHECK: br i1 [[IF]], label %[[IFTHEN:[^,]+]], label %[[IFELSE:[^,]+]]
// CHECK: [[IFTHEN]]
- // CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 2, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* getelementptr inbounds ([2 x i[[SZ]]], [2 x i[[SZ]]]* [[SIZET3]], i32 0, i32 0), i32* getelementptr inbounds ([2 x i32], [2 x i32]* [[MAPT3]], i32 0, i32 0), i32 0, i32 0)
+ // CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 2, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* getelementptr inbounds ([2 x i[[SZ]]], [2 x i[[SZ]]]* [[SIZET3]], i32 0, i32 0), i64* getelementptr inbounds ([2 x i64], [2 x i64]* [[MAPT3]], i32 0, i32 0), i32 0, i32 0)
// CHECK-DAG: [[BPR]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[BP:%[^,]+]], i32 0, i32 0
// CHECK-DAG: [[PR]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[P:%[^,]+]], i32 0, i32 0
@@ -159,21 +175,17 @@ int foo(int n) {
// CHECK-DAG: [[CPADDR1:%.+]] = bitcast i8** [[PADDR1]] to i[[SZ]]*
// CHECK-DAG: store i[[SZ]] %{{.+}}, i[[SZ]]* [[CBPADDR1]]
// CHECK-DAG: store i[[SZ]] %{{.+}}, i[[SZ]]* [[CPADDR1]]
- // CHECK: store i32 [[RET]], i32* [[RHV:%.+]], align 4
- // CHECK-NEXT: br label %[[IFEND:.+]]
-
- // CHECK: [[IFELSE]]
- // CHECK: store i32 -1, i32* [[RHV]], align 4
- // CHECK-NEXT: br label %[[IFEND:.+]]
-
- // CHECK: [[IFEND]]
- // CHECK: [[RET2:%.+]] = load i32, i32* [[RHV]], align 4
- // CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+ // CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
// CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
// CHECK: [[FAIL]]
// CHECK: call void [[HVT3:@.+]]({{[^,]+}}, {{[^,]+}})
// CHECK-NEXT: br label %[[END]]
// CHECK: [[END]]
+ // CHECK-NEXT: br label %[[IFEND:.+]]
+ // CHECK: [[IFELSE]]
+ // CHECK: call void [[HVT3]]({{[^,]+}}, {{[^,]+}})
+ // CHECK-NEXT: br label %[[IFEND]]
+ // CHECK: [[IFEND]]
#pragma omp target teams if(target: n>10)
{
a += 1;
@@ -197,7 +209,7 @@ int foo(int n) {
// CHECK: [[IF:%.+]] = icmp sgt i32 {{[^,]+}}, 20
// CHECK: br i1 [[IF]], label %[[TRY:[^,]+]], label %[[FAIL:[^,]+]]
// CHECK: [[TRY]]
- // CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 9, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* [[SR:%[^,]+]], i32* getelementptr inbounds ([9 x i32], [9 x i32]* [[MAPT4]], i32 0, i32 0), i32 0, i32 0)
+ // CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 9, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* [[SR:%[^,]+]], i64* getelementptr inbounds ([9 x i64], [9 x i64]* [[MAPT4]], i32 0, i32 0), i32 0, i32 0)
// CHECK-DAG: [[BPR]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP:%[^,]+]], i32 0, i32 0
// CHECK-DAG: [[PR]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P:%[^,]+]], i32 0, i32 0
// CHECK-DAG: [[SR]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S:%[^,]+]], i32 0, i32 0
@@ -286,9 +298,7 @@ int foo(int n) {
// CHECK-DAG: [[CPADDR8]] = bitcast i8** {{%[^,]+}} to [[TT]]**
// CHECK-DAG: store i[[SZ]] {{12|16}}, i[[SZ]]* {{%[^,]+}}
- // CHECK: store i32 [[RET]], i32* [[RHV:%.+]], align 4
- // CHECK: [[RET2:%.+]] = load i32, i32* [[RHV]], align 4
- // CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+ // CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
// CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:[^,]+]], label %[[END:[^,]+]]
// CHECK: [[FAIL]]
@@ -312,11 +322,12 @@ int foo(int n) {
// Check that the offloading functions are emitted and that the arguments are
// correct and loaded correctly for the target regions in foo().
-// CHECK: define internal void [[HVT0]]()
-// CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams(%ident_t* [[DEF_LOC]], i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* [[OMP_OUTLINED:@.+]] to void (i32*, i32*, ...)*))
+// CHECK: define internal void [[HVT0]](i[[SZ]] {{[^,]+}}, i[[SZ]] {{[^,]+}}, i[[SZ]] {{[^)]+}})
+// CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams(%ident_t* [[DEF_LOC]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i[[SZ]])* [[OMP_OUTLINED:@.+]] to void (i32*, i32*, ...)*), i[[SZ]] {{[^)]+}})
//
//
-// CHECK: define internal {{.*}}void [[OMP_OUTLINED]](i32* noalias %.global_tid., i32* noalias %.bound_tid.)
+// CHECK: define internal {{.*}}void [[OMP_OUTLINED]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i[[SZ]] {{[^)]+}})
+// CHECK: alloca i16,
// CHECK: ret void
// CHECK-NEXT: }
@@ -441,7 +452,7 @@ int foo(int n) {
// CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams(%ident_t* [[DEF_LOC]], i32 9, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i[[SZ]], [10 x float]*, i[[SZ]], float*, [5 x [10 x double]]*, i[[SZ]], i[[SZ]], double*, [[TT]]*)* [[OMP_OUTLINED4:@.+]] to void (i32*, i32*, ...)*), i[[SZ]] [[REF_A]], [10 x float]* [[REF_B]], i[[SZ]] [[VAL_VLA1]], float* [[REF_BN]], [5 x [10 x double]]* [[REF_C]], i[[SZ]] [[VAL_VLA2]], i[[SZ]] [[VAL_VLA3]], double* [[REF_CN]], [[TT]]* [[REF_D]])
//
//
-// CHECK: define internal {{.*}}void [[OMP_OUTLINED4]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i[[SZ]] %{{.+}}, [10 x float]* {{.+}}, i[[SZ]] %{{.+}}, float* %{{.+}}, [5 x [10 x double]]* {{.+}}, i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, double* %{{.+}}, [[TT]]* {{.+}})
+// CHECK: define internal {{.*}}void [[OMP_OUTLINED4]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i[[SZ]] %{{.+}}, [10 x float]* {{.+}}, i[[SZ]] %{{.+}}, float* {{.+}}, [5 x [10 x double]]* {{.+}}, i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, double* {{.+}}, [[TT]]* {{.+}})
// To reduce complexity, we're only going as far as validating the signature of the outlined parallel function.
template<typename tx>
@@ -533,7 +544,7 @@ int bar(int n){
// CHECK: [[IF:%.+]] = icmp sgt i32 {{[^,]+}}, 60
// CHECK: br i1 [[IF]], label %[[TRY:[^,]+]], label %[[FAIL:[^,]+]]
// CHECK: [[TRY]]
-// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 5, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* [[SR:%[^,]+]], i32* getelementptr inbounds ([5 x i32], [5 x i32]* [[MAPT7]], i32 0, i32 0), i32 0, i32 0)
+// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 5, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* [[SR:%[^,]+]], i64* getelementptr inbounds ([5 x i64], [5 x i64]* [[MAPT7]], i32 0, i32 0), i32 0, i32 0)
// CHECK-DAG: [[BPR]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[BP:%.+]], i32 0, i32 0
// CHECK-DAG: [[PR]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[P:%.+]], i32 0, i32 0
// CHECK-DAG: [[SR]] = getelementptr inbounds [5 x i[[SZ]]], [5 x i[[SZ]]]* [[S:%.+]], i32 0, i32 0
@@ -582,9 +593,7 @@ int bar(int n){
// CHECK-DAG: [[CPADDR4]] = bitcast i8** {{%[^,]+}} to i16**
// CHECK-DAG: store i[[SZ]] [[CSIZE]], i[[SZ]]* {{%[^,]+}}
-// CHECK: store i32 [[RET]], i32* [[RHV:%.+]], align 4
-// CHECK: [[RET2:%.+]] = load i32, i32* [[RHV]], align 4
-// CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+// CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
// CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:[^,]+]], label %[[END:[^,]+]]
// CHECK: [[FAIL]]
@@ -598,7 +607,7 @@ int bar(int n){
// CHECK: [[IF:%.+]] = icmp sgt i32 {{[^,]+}}, 50
// CHECK: br i1 [[IF]], label %[[IFTHEN:[^,]+]], label %[[IFELSE:[^,]+]]
// CHECK: [[IFTHEN]]
-// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 4, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* getelementptr inbounds ([4 x i[[SZ]]], [4 x i[[SZ]]]* [[SIZET6]], i32 0, i32 0), i32* getelementptr inbounds ([4 x i32], [4 x i32]* [[MAPT6]], i32 0, i32 0), i32 0, i32 0)
+// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 4, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* getelementptr inbounds ([4 x i[[SZ]]], [4 x i[[SZ]]]* [[SIZET6]], i32 0, i32 0), i64* getelementptr inbounds ([4 x i64], [4 x i64]* [[MAPT6]], i32 0, i32 0), i32 0, i32 0)
// CHECK-DAG: [[BPR]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[BP:%.+]], i32 0, i32 0
// CHECK-DAG: [[PR]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[P:%.+]], i32 0, i32 0
@@ -630,21 +639,17 @@ int bar(int n){
// CHECK-DAG: [[CBPADDR3]] = bitcast i8** {{%[^,]+}} to [10 x i32]**
// CHECK-DAG: [[CPADDR3]] = bitcast i8** {{%[^,]+}} to [10 x i32]**
-// CHECK: store i32 [[RET]], i32* [[RHV:%.+]], align 4
-// CHECK-NEXT: br label %[[IFEND:.+]]
-
-// CHECK: [[IFELSE]]
-// CHECK: store i32 -1, i32* [[RHV]], align 4
-// CHECK-NEXT: br label %[[IFEND:.+]]
-
-// CHECK: [[IFEND]]
-// CHECK: [[RET2:%.+]] = load i32, i32* [[RHV]], align 4
-// CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+// CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
// CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
// CHECK: [[FAIL]]
// CHECK: call void [[HVT6:@.+]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}})
// CHECK-NEXT: br label %[[END]]
// CHECK: [[END]]
+// CHECK-NEXT: br label %[[IFEND:.+]]
+// CHECK: [[IFELSE]]
+// CHECK: call void [[HVT6]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}})
+// CHECK-NEXT: br label %[[IFEND]]
+// CHECK: [[IFEND]]
//
// CHECK: define {{.*}}[[FTEMPLATE]]
@@ -652,7 +657,7 @@ int bar(int n){
// CHECK: [[IF:%.+]] = icmp sgt i32 {{[^,]+}}, 40
// CHECK: br i1 [[IF]], label %[[IFTHEN:[^,]+]], label %[[IFELSE:[^,]+]]
// CHECK: [[IFTHEN]]
-// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 3, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* getelementptr inbounds ([3 x i[[SZ]]], [3 x i[[SZ]]]* [[SIZET5]], i32 0, i32 0), i32* getelementptr inbounds ([3 x i32], [3 x i32]* [[MAPT5]], i32 0, i32 0), i32 0, i32 0)
+// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 3, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* getelementptr inbounds ([3 x i[[SZ]]], [3 x i[[SZ]]]* [[SIZET5]], i32 0, i32 0), i64* getelementptr inbounds ([3 x i64], [3 x i64]* [[MAPT5]], i32 0, i32 0), i32 0, i32 0)
// CHECK-DAG: [[BPR]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BP:%.+]], i32 0, i32 0
// CHECK-DAG: [[PR]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[P:%.+]], i32 0, i32 0
@@ -677,21 +682,17 @@ int bar(int n){
// CHECK-DAG: [[CBPADDR2]] = bitcast i8** {{%[^,]+}} to [10 x i32]**
// CHECK-DAG: [[CPADDR2]] = bitcast i8** {{%[^,]+}} to [10 x i32]**
-// CHECK: store i32 [[RET]], i32* [[RHV:%.+]], align 4
-// CHECK-NEXT: br label %[[IFEND:.+]]
-
-// CHECK: [[IFELSE]]
-// CHECK: store i32 -1, i32* [[RHV]], align 4
-// CHECK-NEXT: br label %[[IFEND:.+]]
-
-// CHECK: [[IFEND]]
-// CHECK: [[RET2:%.+]] = load i32, i32* [[RHV]], align 4
-// CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+// CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
// CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
// CHECK: [[FAIL]]
// CHECK: call void [[HVT5:@.+]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}})
// CHECK-NEXT: br label %[[END]]
// CHECK: [[END]]
+// CHECK-NEXT: br label %[[IFEND:.+]]
+// CHECK: [[IFELSE]]
+// CHECK: call void [[HVT5]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}})
+// CHECK-NEXT: br label %[[IFEND]]
+// CHECK: [[IFEND]]
@@ -728,7 +729,7 @@ int bar(int n){
// CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams(%ident_t* [[DEF_LOC]], i32 5, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, [[S1]]*, i[[SZ]], i[[SZ]], i[[SZ]], i16*)* [[OMP_OUTLINED5:@.+]] to void (i32*, i32*, ...)*), [[S1]]* [[REF_THIS]], i[[SZ]] [[REF_B]], i[[SZ]] [[VAL_VLA1]], i[[SZ]] [[VAL_VLA2]], i16* [[REF_C]])
//
//
-// CHECK: define internal {{.*}}void [[OMP_OUTLINED5]](i32* noalias %.global_tid., i32* noalias %.bound_tid., [[S1]]* %{{.+}}, i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, i16* %{{.+}})
+// CHECK: define internal {{.*}}void [[OMP_OUTLINED5]](i32* noalias %.global_tid., i32* noalias %.bound_tid., [[S1]]* %{{.+}}, i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, i16* {{.+}})
// To reduce complexity, we're only going as far as validating the signature of the outlined parallel function.
diff --git a/test/OpenMP/target_teams_codegen_registration.cpp b/test/OpenMP/target_teams_codegen_registration.cpp
index b8154538df04..38668a46b161 100644
--- a/test/OpenMP/target_teams_codegen_registration.cpp
+++ b/test/OpenMP/target_teams_codegen_registration.cpp
@@ -63,40 +63,40 @@
// CHECK-DAG: {{@.+}} = private constant i8 0
// TCHECK-NOT: {{@.+}} = private constant i8 0
// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
-// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
// CHECK-DAG: {{@.+}} = private constant i8 0
// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
-// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
// CHECK-DAG: {{@.+}} = private constant i8 0
// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
-// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
// CHECK-DAG: {{@.+}} = private constant i8 0
// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
-// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
// CHECK-DAG: {{@.+}} = private constant i8 0
// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
-// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
// CHECK-DAG: {{@.+}} = private constant i8 0
// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
-// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
// CHECK-DAG: {{@.+}} = private constant i8 0
// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
-// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
// CHECK-DAG: {{@.+}} = private constant i8 0
// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
-// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
// CHECK-DAG: {{@.+}} = private constant i8 0
// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
-// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
// CHECK-DAG: {{@.+}} = private constant i8 0
// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
-// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
// CHECK-DAG: {{@.+}} = private constant i8 0
// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
-// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
// CHECK-DAG: {{@.+}} = private constant i8 0
// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
-// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
// CHECK-NTARGET-NOT: private constant i8 0
// CHECK-NTARGET-NOT: private unnamed_addr constant [1 x i
diff --git a/test/OpenMP/target_teams_depend_messages.cpp b/test/OpenMP/target_teams_depend_messages.cpp
index 9308e8972872..57983eec8882 100644
--- a/test/OpenMP/target_teams_depend_messages.cpp
+++ b/test/OpenMP/target_teams_depend_messages.cpp
@@ -36,21 +36,21 @@ int main(int argc, char **argv, char *env[]) {
foo();
#pragma omp target teams depend (out: ) // expected-error {{expected expression}}
foo();
-#pragma omp target teams depend (inout : foobool(argc)), depend (in, argc) // expected-error {{expected variable name, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}}
+#pragma omp target teams depend (inout : foobool(argc)), depend (in, argc) // expected-error {{expected addressable lvalue expression, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}}
foo();
#pragma omp target teams depend (out :S1) // expected-error {{'S1' does not refer to a value}}
foo();
-#pragma omp target teams depend(in : argv[1][1] = '2') // expected-error {{expected variable name, array element or array section}}
+#pragma omp target teams depend(in : argv[1][1] = '2')
foo();
-#pragma omp target teams depend (in : vec[1]) // expected-error {{expected variable name, array element or array section}}
+#pragma omp target teams depend (in : vec[1]) // expected-error {{expected addressable lvalue expression, array element or array section}}
foo();
#pragma omp target teams depend (in : argv[0])
foo();
#pragma omp target teams depend (in : ) // expected-error {{expected expression}}
foo();
-#pragma omp target teams depend (in : main) // expected-error {{expected variable name, array element or array section}}
+#pragma omp target teams depend (in : main)
foo();
-#pragma omp target teams depend(in : a[0]) // expected-error{{expected variable name, array element or array section}}
+#pragma omp target teams depend(in : a[0]) // expected-error{{expected addressable lvalue expression, array element or array section}}
foo();
#pragma omp target teams depend (in : vec[1:2]) // expected-error {{ value is not an array or pointer}}
foo();
diff --git a/test/OpenMP/target_teams_distribute_codegen.cpp b/test/OpenMP/target_teams_distribute_codegen.cpp
new file mode 100644
index 000000000000..17baa603d12b
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_codegen.cpp
@@ -0,0 +1,820 @@
+// Test host codegen.
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+
+// Test target codegen - host bc file has to be created first.
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm-bc %s -o %t-ppc-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-64
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-64
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm-bc %s -o %t-x86-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-32
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-32
+
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+// CHECK-DAG: %ident_t = type { i32, i32, i32, i32, i8* }
+// CHECK-DAG: [[STR:@.+]] = private unnamed_addr constant [23 x i8] c";unknown;unknown;0;0;;\00"
+// CHECK-DAG: [[DEF_LOC:@.+]] = private unnamed_addr constant %ident_t { i32 0, i32 2, i32 0, i32 0, i8* getelementptr inbounds ([23 x i8], [23 x i8]* [[STR]], i32 0, i32 0) }
+
+// CHECK-DAG: [[TT:%.+]] = type { i64, i8 }
+// CHECK-DAG: [[S1:%.+]] = type { double }
+// CHECK-DAG: [[ENTTY:%.+]] = type { i8*, i8*, i[[SZ:32|64]], i32, i32 }
+// CHECK-DAG: [[DEVTY:%.+]] = type { i8*, i8*, [[ENTTY]]*, [[ENTTY]]* }
+// CHECK-DAG: [[DSCTY:%.+]] = type { i32, [[DEVTY]]*, [[ENTTY]]*, [[ENTTY]]* }
+
+// TCHECK: [[ENTTY:%.+]] = type { i8*, i8*, i{{32|64}}, i32, i32 }
+
+// CHECK-DAG: $[[REGFN:\.omp_offloading\..+]] = comdat
+
+// We have 8 target regions, but only 7 that actually will generate offloading
+// code, only 6 will have mapped arguments, and only 4 have all-constant map
+// sizes.
+
+// CHECK-DAG: [[SIZET:@.+]] = private unnamed_addr constant [3 x i[[SZ]]] [i[[SZ]] 2, i[[SZ]] 4, i[[SZ]] 4]
+// CHECK-DAG: [[MAPT:@.+]] = private unnamed_addr constant [3 x i64] [i64 288, i64 288, i64 288]
+// CHECK-DAG: [[SIZET2:@.+]] = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 2]
+// CHECK-DAG: [[MAPT2:@.+]] = private unnamed_addr constant [1 x i64] [i64 288]
+// CHECK-DAG: [[SIZET3:@.+]] = private unnamed_addr constant [2 x i[[SZ]]] [i[[SZ]] 4, i[[SZ]] 2]
+// CHECK-DAG: [[MAPT3:@.+]] = private unnamed_addr constant [2 x i64] [i64 288, i64 288]
+// CHECK-DAG: [[MAPT4:@.+]] = private unnamed_addr constant [9 x i64] [i64 288, i64 547, i64 288, i64 547, i64 547, i64 288, i64 288, i64 547, i64 547]
+// CHECK-DAG: [[MAPT5:@.+]] = private unnamed_addr constant [5 x i64] [i64 547, i64 288, i64 288, i64 288, i64 547]
+// CHECK-DAG: [[SIZET6:@.+]] = private unnamed_addr constant [5 x i[[SZ]]] [i[[SZ]] 4, i[[SZ]] 4, i[[SZ]] 2, i[[SZ]] 1, i[[SZ]] 40]
+// CHECK-DAG: [[MAPT6:@.+]] = private unnamed_addr constant [5 x i64] [i64 288, i64 288, i64 288, i64 288, i64 547]
+// CHECK-DAG: [[SIZET7:@.+]] = private unnamed_addr constant [3 x i[[SZ]]] [i[[SZ]] 4, i[[SZ]] 2, i[[SZ]] 40]
+// CHECK-DAG: [[MAPT7:@.+]] = private unnamed_addr constant [3 x i64] [i64 288, i64 288, i64 547]
+// CHECK-DAG: @{{.*}} = private constant i8 0
+// CHECK-DAG: @{{.*}} = private constant i8 0
+// CHECK-DAG: @{{.*}} = private constant i8 0
+// CHECK-DAG: @{{.*}} = private constant i8 0
+// CHECK-DAG: @{{.*}} = private constant i8 0
+// CHECK-DAG: @{{.*}} = private constant i8 0
+// CHECK-DAG: @{{.*}} = private constant i8 0
+
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+// TCHECK-NOT: @{{.+}} = constant [[ENTTY]]
+
+// Check if offloading descriptor is created.
+// CHECK: [[ENTBEGIN:@.+]] = external constant [[ENTTY]]
+// CHECK: [[ENTEND:@.+]] = external constant [[ENTTY]]
+// CHECK: [[DEVBEGIN:@.+]] = external constant i8
+// CHECK: [[DEVEND:@.+]] = external constant i8
+// CHECK: [[IMAGES:@.+]] = internal unnamed_addr constant [1 x [[DEVTY]]] [{{.+}} { i8* [[DEVBEGIN]], i8* [[DEVEND]], [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }], comdat($[[REGFN]])
+// CHECK: [[DESC:@.+]] = internal constant [[DSCTY]] { i32 1, [[DEVTY]]* getelementptr inbounds ([1 x [[DEVTY]]], [1 x [[DEVTY]]]* [[IMAGES]], i32 0, i32 0), [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }, comdat($[[REGFN]])
+
+// Check target registration is registered as a Ctor.
+// CHECK: appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 0, void ()* bitcast (void (i8*)* @[[REGFN]] to void ()*), i8* bitcast (void (i8*)* @[[REGFN]] to i8*) }]
+
+
+template<typename tx, typename ty>
+struct TT{
+ tx X;
+ ty Y;
+};
+
+int global;
+
+// CHECK: define {{.*}}[[FOO:@.+]](
+int foo(int n) {
+ int a = 0;
+ short aa = 0;
+ float b[10];
+ float bn[n];
+ double c[5][10];
+ double cn[5][n];
+ TT<long long, char> d;
+
+ // CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams_nowait(i64 -1, i8* @{{[^,]+}}, i32 3, i8** [[BP:%[^,]+]], i8** [[P:%[^,]+]], i[[SZ]]* getelementptr inbounds ([3 x i[[SZ]]], [3 x i[[SZ]]]* [[SIZET]], i32 0, i32 0), i64* getelementptr inbounds ([3 x i64], [3 x i64]* [[MAPT]], i32 0, i32 0), i32 {{[^,]+}}, i32 {{[^)]+}})
+ // CHECK-DAG: [[BP]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BPR:%[^,]+]], i32 0, i32 0
+ // CHECK-DAG: [[P]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[PR:%[^,]+]], i32 0, i32 0
+ // CHECK-DAG: [[BPADDR0:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BPR]], i32 0, i32 [[IDX0:[0-9]+]]
+ // CHECK-DAG: [[PADDR0:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[PR]], i32 0, i32 [[IDX0]]
+ // CHECK-DAG: [[CBPADDR0:%.+]] = bitcast i8** [[BPADDR0]] to i[[SZ]]*
+ // CHECK-DAG: [[CPADDR0:%.+]] = bitcast i8** [[PADDR0]] to i[[SZ]]*
+ // CHECK-DAG: store i[[SZ]] %{{.+}}, i[[SZ]]* [[CBPADDR0]]
+ // CHECK-DAG: store i[[SZ]] %{{.+}}, i[[SZ]]* [[CPADDR0]]
+ // CHECK-DAG: [[BPADDR1:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BPR]], i32 0, i32 [[IDX1:[0-9]+]]
+ // CHECK-DAG: [[PADDR1:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[PR]], i32 0, i32 [[IDX1]]
+ // CHECK-DAG: [[CBPADDR1:%.+]] = bitcast i8** [[BPADDR1]] to i[[SZ]]*
+ // CHECK-DAG: [[CPADDR1:%.+]] = bitcast i8** [[PADDR1]] to i[[SZ]]*
+ // CHECK-DAG: store i[[SZ]] %{{.+}}, i[[SZ]]* [[CBPADDR1]]
+ // CHECK-DAG: store i[[SZ]] %{{.+}}, i[[SZ]]* [[CPADDR1]]
+ // CHECK-DAG: [[BPADDR2:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BPR]], i32 0, i32 [[IDX1:[0-9]+]]
+ // CHECK-DAG: [[PADDR2:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[PR]], i32 0, i32 [[IDX1]]
+ // CHECK-DAG: [[CBPADDR2:%.+]] = bitcast i8** [[BPADDR2]] to i[[SZ]]*
+ // CHECK-DAG: [[CPADDR2:%.+]] = bitcast i8** [[PADDR2]] to i[[SZ]]*
+ // CHECK-DAG: store i[[SZ]] %{{.+}}, i[[SZ]]* [[CBPADDR2]]
+ // CHECK-DAG: store i[[SZ]] %{{.+}}, i[[SZ]]* [[CPADDR2]]
+ // CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
+ // CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:[^,]+]], label %[[END:[^,]+]]
+ // CHECK: [[FAIL]]
+ // CHECK: call void [[HVT0:@.+]](i[[SZ]] {{[^,]+}}, i[[SZ]] {{[^,]+}}, i[[SZ]] {{[^)]+}})
+ // CHECK-NEXT: br label %[[END]]
+ // CHECK: [[END]]
+ #pragma omp target teams distribute num_teams(a) thread_limit(a) firstprivate(aa) nowait
+ for (int i = 0; i < 10; ++i) {
+ }
+
+ // CHECK: call void [[HVT1:@.+]](i[[SZ]] {{[^,]+}})
+ #pragma omp target teams distribute if(target: 0)
+ for (int i = 0; i < 10; ++i) {
+ a += 1;
+ }
+
+ // CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 1, i8** [[BP:%[^,]+]], i8** [[P:%[^,]+]], i[[SZ]]* getelementptr inbounds ([1 x i[[SZ]]], [1 x i[[SZ]]]* [[SIZET2]], i32 0, i32 0), i64* getelementptr inbounds ([1 x i64], [1 x i64]* [[MAPT2]], i32 0, i32 0), i32 0, i32 0)
+ // CHECK-DAG: [[BP]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[BPR:%[^,]+]], i32 0, i32 0
+ // CHECK-DAG: [[P]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[PR:%[^,]+]], i32 0, i32 0
+ // CHECK-DAG: [[BPADDR0:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[BPR]], i32 0, i32 [[IDX0:[0-9]+]]
+ // CHECK-DAG: [[PADDR0:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[PR]], i32 0, i32 [[IDX0]]
+ // CHECK-DAG: [[CBPADDR0:%.+]] = bitcast i8** [[BPADDR0]] to i[[SZ]]*
+ // CHECK-DAG: [[CPADDR0:%.+]] = bitcast i8** [[PADDR0]] to i[[SZ]]*
+ // CHECK-DAG: store i[[SZ]] %{{.+}}, i[[SZ]]* [[CBPADDR0]]
+ // CHECK-DAG: store i[[SZ]] %{{.+}}, i[[SZ]]* [[CPADDR0]]
+
+ // CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
+ // CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:[^,]+]], label %[[END:[^,]+]]
+ // CHECK: [[FAIL]]
+ // CHECK: call void [[HVT2:@.+]](i[[SZ]] {{[^,]+}})
+ // CHECK-NEXT: br label %[[END]]
+ // CHECK: [[END]]
+ #pragma omp target teams distribute if(target: 1)
+ for (int i = 0; i < 10; ++i) {
+ aa += 1;
+ }
+
+ // CHECK: [[IF:%.+]] = icmp sgt i32 {{[^,]+}}, 10
+ // CHECK: br i1 [[IF]], label %[[IFTHEN:[^,]+]], label %[[IFELSE:[^,]+]]
+ // CHECK: [[IFTHEN]]
+ // CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 2, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* getelementptr inbounds ([2 x i[[SZ]]], [2 x i[[SZ]]]* [[SIZET3]], i32 0, i32 0), i64* getelementptr inbounds ([2 x i64], [2 x i64]* [[MAPT3]], i32 0, i32 0), i32 0, i32 0)
+ // CHECK-DAG: [[BPR]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[BP:%[^,]+]], i32 0, i32 0
+ // CHECK-DAG: [[PR]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[P:%[^,]+]], i32 0, i32 0
+
+ // CHECK-DAG: [[BPADDR0:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[BP]], i32 0, i32 0
+ // CHECK-DAG: [[PADDR0:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[P]], i32 0, i32 0
+ // CHECK-DAG: [[CBPADDR0:%.+]] = bitcast i8** [[BPADDR0]] to i[[SZ]]*
+ // CHECK-DAG: [[CPADDR0:%.+]] = bitcast i8** [[PADDR0]] to i[[SZ]]*
+ // CHECK-DAG: store i[[SZ]] %{{.+}}, i[[SZ]]* [[CBPADDR0]]
+ // CHECK-DAG: store i[[SZ]] %{{.+}}, i[[SZ]]* [[CPADDR0]]
+
+ // CHECK-DAG: [[BPADDR1:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[BP]], i32 0, i32 1
+ // CHECK-DAG: [[PADDR1:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[P]], i32 0, i32 1
+ // CHECK-DAG: [[CBPADDR1:%.+]] = bitcast i8** [[BPADDR1]] to i[[SZ]]*
+ // CHECK-DAG: [[CPADDR1:%.+]] = bitcast i8** [[PADDR1]] to i[[SZ]]*
+ // CHECK-DAG: store i[[SZ]] %{{.+}}, i[[SZ]]* [[CBPADDR1]]
+ // CHECK-DAG: store i[[SZ]] %{{.+}}, i[[SZ]]* [[CPADDR1]]
+ // CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
+ // CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
+ // CHECK: [[FAIL]]
+ // CHECK: call void [[HVT3:@.+]]({{[^,]+}}, {{[^,]+}})
+ // CHECK-NEXT: br label %[[END]]
+ // CHECK: [[END]]
+ // CHECK-NEXT: br label %[[IFEND:.+]]
+ // CHECK: [[IFELSE]]
+ // CHECK: call void [[HVT3]]({{[^,]+}}, {{[^,]+}})
+ // CHECK-NEXT: br label %[[IFEND]]
+ // CHECK: [[IFEND]]
+ #pragma omp target teams distribute if(target: n>10)
+ for (int i = 0; i < 10; ++i) {
+ a += 1;
+ aa += 1;
+ }
+
+ // We capture 3 VLA sizes in this target region
+ // CHECK-64: [[A_VAL:%.+]] = load i32, i32* %{{.+}},
+ // CHECK-64: [[A_ADDR:%.+]] = bitcast i[[SZ]]* [[A_CADDR:%.+]] to i32*
+ // CHECK-64: store i32 [[A_VAL]], i32* [[A_ADDR]],
+ // CHECK-64: [[A_CVAL:%.+]] = load i[[SZ]], i[[SZ]]* [[A_CADDR]],
+
+ // CHECK-32: [[A_VAL:%.+]] = load i32, i32* %{{.+}},
+ // CHECK-32: store i32 [[A_VAL]], i32* [[A_CADDR:%.+]],
+ // CHECK-32: [[A_CVAL:%.+]] = load i[[SZ]], i[[SZ]]* [[A_CADDR]],
+
+ // CHECK: [[BNSIZE:%.+]] = mul nuw i[[SZ]] [[VLA0:%.+]], 4
+ // CHECK: [[CNELEMSIZE2:%.+]] = mul nuw i[[SZ]] 5, [[VLA1:%.+]]
+ // CHECK: [[CNSIZE:%.+]] = mul nuw i[[SZ]] [[CNELEMSIZE2]], 8
+
+ // CHECK: [[IF:%.+]] = icmp sgt i32 {{[^,]+}}, 20
+ // CHECK: br i1 [[IF]], label %[[TRY:[^,]+]], label %[[FAIL:[^,]+]]
+ // CHECK: [[TRY]]
+ // CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 9, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* [[SR:%[^,]+]], i64* getelementptr inbounds ([9 x i64], [9 x i64]* [[MAPT4]], i32 0, i32 0), i32 0, i32 0)
+ // CHECK-DAG: [[BPR]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP:%[^,]+]], i32 0, i32 0
+ // CHECK-DAG: [[PR]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P:%[^,]+]], i32 0, i32 0
+ // CHECK-DAG: [[SR]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S:%[^,]+]], i32 0, i32 0
+
+ // CHECK-DAG: [[SADDR0:%.+]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX0:[0-9]+]]
+ // CHECK-DAG: [[BPADDR0:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP]], i32 0, i32 [[IDX0]]
+ // CHECK-DAG: [[PADDR0:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P]], i32 0, i32 [[IDX0]]
+ // CHECK-DAG: [[SADDR1:%.+]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX1:[0-9]+]]
+ // CHECK-DAG: [[BPADDR1:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP]], i32 0, i32 [[IDX1]]
+ // CHECK-DAG: [[PADDR1:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P]], i32 0, i32 [[IDX1]]
+ // CHECK-DAG: [[SADDR2:%.+]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX2:[0-9]+]]
+ // CHECK-DAG: [[BPADDR2:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP]], i32 0, i32 [[IDX2]]
+ // CHECK-DAG: [[PADDR2:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P]], i32 0, i32 [[IDX2]]
+ // CHECK-DAG: [[SADDR3:%.+]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX3:[0-9]+]]
+ // CHECK-DAG: [[BPADDR3:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP]], i32 0, i32 [[IDX3]]
+ // CHECK-DAG: [[PADDR3:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P]], i32 0, i32 [[IDX3]]
+ // CHECK-DAG: [[SADDR4:%.+]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX4:[0-9]+]]
+ // CHECK-DAG: [[BPADDR4:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP]], i32 0, i32 [[IDX4]]
+ // CHECK-DAG: [[PADDR4:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P]], i32 0, i32 [[IDX4]]
+ // CHECK-DAG: [[SADDR5:%.+]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX5:[0-9]+]]
+ // CHECK-DAG: [[BPADDR5:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP]], i32 0, i32 [[IDX5]]
+ // CHECK-DAG: [[PADDR5:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P]], i32 0, i32 [[IDX5]]
+ // CHECK-DAG: [[SADDR6:%.+]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX6:[0-9]+]]
+ // CHECK-DAG: [[BPADDR6:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP]], i32 0, i32 [[IDX6]]
+ // CHECK-DAG: [[PADDR6:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P]], i32 0, i32 [[IDX6]]
+ // CHECK-DAG: [[SADDR7:%.+]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX7:[0-9]+]]
+ // CHECK-DAG: [[BPADDR7:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP]], i32 0, i32 [[IDX7]]
+ // CHECK-DAG: [[PADDR7:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P]], i32 0, i32 [[IDX7]]
+ // CHECK-DAG: [[SADDR8:%.+]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX8:[0-9]+]]
+ // CHECK-DAG: [[BPADDR8:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP]], i32 0, i32 [[IDX8]]
+ // CHECK-DAG: [[PADDR8:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P]], i32 0, i32 [[IDX8]]
+
+ // The names below are not necessarily consistent with the names used for the
+ // addresses above as some are repeated.
+ // CHECK-DAG: store i[[SZ]] [[VLA0]], i[[SZ]]* [[CBPADDR0:%.+]],
+ // CHECK-DAG: store i[[SZ]] [[VLA0]], i[[SZ]]* [[CPADDR0:%.+]],
+ // CHECK-DAG: [[CBPADDR0]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+ // CHECK-DAG: [[CPADDR0]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+ // CHECK-DAG: store i[[SZ]] {{4|8}}, i[[SZ]]* {{%[^,]+}}
+
+ // CHECK-DAG: store i[[SZ]] [[VLA1]], i[[SZ]]* [[CBPADDR1:%.+]],
+ // CHECK-DAG: store i[[SZ]] [[VLA1]], i[[SZ]]* [[CPADDR1:%.+]],
+ // CHECK-DAG: [[CBPADDR1]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+ // CHECK-DAG: [[CPADDR1]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+ // CHECK-DAG: store i[[SZ]] {{4|8}}, i[[SZ]]* {{%[^,]+}}
+
+ // CHECK-DAG: store i[[SZ]] 5, i[[SZ]]* [[CBPADDR2:%.+]],
+ // CHECK-DAG: store i[[SZ]] 5, i[[SZ]]* [[CPADDR2:%.+]],
+ // CHECK-DAG: [[CBPADDR2]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+ // CHECK-DAG: [[CPADDR2]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+ // CHECK-DAG: store i[[SZ]] {{4|8}}, i[[SZ]]* {{%[^,]+}}
+
+ // CHECK-DAG: store i[[SZ]] [[A_CVAL]], i[[SZ]]* [[CBPADDR3:%.+]],
+ // CHECK-DAG: store i[[SZ]] [[A_CVAL]], i[[SZ]]* [[CPADDR3:%.+]],
+ // CHECK-DAG: [[CBPADDR3]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+ // CHECK-DAG: [[CPADDR3]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+ // CHECK-DAG: store i[[SZ]] 4, i[[SZ]]* {{%[^,]+}}
+
+ // CHECK-DAG: store [10 x float]* %{{.+}}, [10 x float]** [[CBPADDR4:%.+]],
+ // CHECK-DAG: store [10 x float]* %{{.+}}, [10 x float]** [[CPADDR4:%.+]],
+ // CHECK-DAG: [[CBPADDR4]] = bitcast i8** {{%[^,]+}} to [10 x float]**
+ // CHECK-DAG: [[CPADDR4]] = bitcast i8** {{%[^,]+}} to [10 x float]**
+ // CHECK-DAG: store i[[SZ]] 40, i[[SZ]]* {{%[^,]+}}
+
+ // CHECK-DAG: store float* %{{.+}}, float** [[CBPADDR5:%.+]],
+ // CHECK-DAG: store float* %{{.+}}, float** [[CPADDR5:%.+]],
+ // CHECK-DAG: [[CBPADDR5]] = bitcast i8** {{%[^,]+}} to float**
+ // CHECK-DAG: [[CPADDR5]] = bitcast i8** {{%[^,]+}} to float**
+ // CHECK-DAG: store i[[SZ]] [[BNSIZE]], i[[SZ]]* {{%[^,]+}}
+
+ // CHECK-DAG: store [5 x [10 x double]]* %{{.+}}, [5 x [10 x double]]** [[CBPADDR6:%.+]],
+ // CHECK-DAG: store [5 x [10 x double]]* %{{.+}}, [5 x [10 x double]]** [[CPADDR6:%.+]],
+ // CHECK-DAG: [[CBPADDR6]] = bitcast i8** {{%[^,]+}} to [5 x [10 x double]]**
+ // CHECK-DAG: [[CPADDR6]] = bitcast i8** {{%[^,]+}} to [5 x [10 x double]]**
+ // CHECK-DAG: store i[[SZ]] 400, i[[SZ]]* {{%[^,]+}}
+
+ // CHECK-DAG: store double* %{{.+}}, double** [[CBPADDR7:%.+]],
+ // CHECK-DAG: store double* %{{.+}}, double** [[CPADDR7:%.+]],
+ // CHECK-DAG: [[CBPADDR7]] = bitcast i8** {{%[^,]+}} to double**
+ // CHECK-DAG: [[CPADDR7]] = bitcast i8** {{%[^,]+}} to double**
+ // CHECK-DAG: store i[[SZ]] [[CNSIZE]], i[[SZ]]* {{%[^,]+}}
+
+ // CHECK-DAG: store [[TT]]* %{{.+}}, [[TT]]** [[CBPADDR8:%.+]],
+ // CHECK-DAG: store [[TT]]* %{{.+}}, [[TT]]** [[CPADDR8:%.+]],
+ // CHECK-DAG: [[CBPADDR8]] = bitcast i8** {{%[^,]+}} to [[TT]]**
+ // CHECK-DAG: [[CPADDR8]] = bitcast i8** {{%[^,]+}} to [[TT]]**
+ // CHECK-DAG: store i[[SZ]] {{12|16}}, i[[SZ]]* {{%[^,]+}}
+
+ // CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
+ // CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:[^,]+]], label %[[END:[^,]+]]
+
+ // CHECK: [[FAIL]]
+ // CHECK: call void [[HVT4:@.+]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}})
+ // CHECK-NEXT: br label %[[END]]
+ // CHECK: [[END]]
+ #pragma omp target teams distribute if(target: n>20)
+ for (int i = 0; i < 10; ++i) {
+ a += 1;
+ b[2] += 1.0;
+ bn[3] += 1.0;
+ c[1][2] += 1.0;
+ cn[1][3] += 1.0;
+ d.X += 1;
+ d.Y += 1;
+ }
+
+ return a;
+}
+
+// Check that the offloading functions are emitted and that the arguments are
+// correct and loaded correctly for the target regions in foo().
+
+// CHECK: define internal void [[HVT0]](i[[SZ]] {{[^,]+}}, i[[SZ]] {{[^,]+}}, i[[SZ]] {{[^)]+}})
+// CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams(%ident_t* [[DEF_LOC]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i[[SZ]])* [[OMP_OUTLINED:@.+]] to void (i32*, i32*, ...)*), i[[SZ]] {{[^)]+}})
+//
+//
+// CHECK: define internal {{.*}}void [[OMP_OUTLINED]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i[[SZ]] {{[^)]+}})
+// CHECK: alloca i16,
+// CHECK: ret void
+// CHECK-NEXT: }
+
+
+// CHECK: define internal void [[HVT1]](i[[SZ]] %{{.+}})
+// Create stack storage and store argument in there.
+// CHECK: [[AA_ADDR:%.+]] = alloca i[[SZ]], align
+// CHECK: [[AA_CASTED:%.+]] = alloca i[[SZ]], align
+// CHECK: store i[[SZ]] %{{.+}}, i[[SZ]]* [[AA_ADDR]], align
+// CHECK-64: [[AA_CADDR:%.+]] = bitcast i[[SZ]]* [[AA_ADDR]] to i32*
+// CHECK-64: [[AA:%.+]] = load i32, i32* [[AA_CADDR]], align
+// CHECK-32: [[AA:%.+]] = load i32, i32* [[AA_ADDR]], align
+// CHECK-64: [[AA_C:%.+]] = bitcast i[[SZ]]* [[AA_CASTED]] to i32*
+// CHECK-64: store i32 [[AA]], i32* [[AA_C]], align
+// CHECK-32: store i32 [[AA]], i32* [[AA_CASTED]], align
+// CHECK: [[PARAM:%.+]] = load i[[SZ]], i[[SZ]]* [[AA_CASTED]], align
+// CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams(%ident_t* [[DEF_LOC]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i[[SZ]])* [[OMP_OUTLINED1:@.+]] to void (i32*, i32*, ...)*), i[[SZ]] [[PARAM]])
+//
+//
+// CHECK: define internal {{.*}}void [[OMP_OUTLINED1]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i[[SZ]] %{{.+}})
+// CHECK: [[AA_ADDR:%.+]] = alloca i[[SZ]], align
+// CHECK: store i[[SZ]] %{{.+}}, i[[SZ]]* [[AA_ADDR]], align
+// CHECK-64: [[AA_CADDR:%.+]] = bitcast i[[SZ]]* [[AA_ADDR]] to i32*
+// CHECK-64: [[AA:%.+]] = load i32, i32* [[AA_CADDR]], align
+// CHECK-32: [[AA:%.+]] = load i32, i32* [[AA_ADDR]], align
+// CHECK: ret void
+// CHECK-NEXT: }
+
+// CHECK: define internal void [[HVT2]](i[[SZ]] %{{.+}})
+// Create stack storage and store argument in there.
+// CHECK: [[AA_ADDR:%.+]] = alloca i[[SZ]], align
+// CHECK: [[AA_CASTED:%.+]] = alloca i[[SZ]], align
+// CHECK: store i[[SZ]] %{{.+}}, i[[SZ]]* [[AA_ADDR]], align
+// CHECK: [[AA_CADDR:%.+]] = bitcast i[[SZ]]* [[AA_ADDR]] to i16*
+// CHECK: [[AA:%.+]] = load i16, i16* [[AA_CADDR]], align
+// CHECK: [[AA_C:%.+]] = bitcast i[[SZ]]* [[AA_CASTED]] to i16*
+// CHECK: store i16 [[AA]], i16* [[AA_C]], align
+// CHECK: [[PARAM:%.+]] = load i[[SZ]], i[[SZ]]* [[AA_CASTED]], align
+// CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams(%ident_t* [[DEF_LOC]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i[[SZ]])* [[OMP_OUTLINED2:@.+]] to void (i32*, i32*, ...)*), i[[SZ]] [[PARAM]])
+//
+//
+// CHECK: define internal {{.*}}void [[OMP_OUTLINED2]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i[[SZ]] %{{.+}})
+// CHECK: [[AA_ADDR:%.+]] = alloca i[[SZ]], align
+// CHECK: store i[[SZ]] %{{.+}}, i[[SZ]]* [[AA_ADDR]], align
+// CHECK: [[AA_CADDR:%.+]] = bitcast i[[SZ]]* [[AA_ADDR]] to i16*
+// CHECK: [[AA:%.+]] = load i16, i16* [[AA_CADDR]], align
+// CHECK: ret void
+// CHECK-NEXT: }
+
+// CHECK: define internal void [[HVT3]]
+// Create stack storage and store argument in there.
+// CHECK: [[A_ADDR:%.+]] = alloca i[[SZ]], align
+// CHECK: [[AA_ADDR:%.+]] = alloca i[[SZ]], align
+// CHECK: [[A_CASTED:%.+]] = alloca i[[SZ]], align
+// CHECK: [[AA_CASTED:%.+]] = alloca i[[SZ]], align
+// CHECK-DAG: store i[[SZ]] %{{.+}}, i[[SZ]]* [[A_ADDR]], align
+// CHECK-DAG: store i[[SZ]] %{{.+}}, i[[SZ]]* [[AA_ADDR]], align
+// CHECK-64-DAG:[[A_CADDR:%.+]] = bitcast i[[SZ]]* [[A_ADDR]] to i32*
+// CHECK-DAG: [[AA_CADDR:%.+]] = bitcast i[[SZ]]* [[AA_ADDR]] to i16*
+// CHECK-64-DAG:[[A:%.+]] = load i32, i32* [[A_CADDR]], align
+// CHECK-32-DAG:[[A:%.+]] = load i32, i32* [[A_ADDR]], align
+// CHECK-64-DAG:[[A_C:%.+]] = bitcast i[[SZ]]* [[A_CASTED]] to i32*
+// CHECK-64-DAG:store i32 [[A]], i32* [[A_C]], align
+// CHECK-32-DAG:store i32 [[A]], i32* [[A_CASTED]], align
+// CHECK-DAG: [[AA:%.+]] = load i16, i16* [[AA_CADDR]], align
+// CHECK-DAG: [[AA_C:%.+]] = bitcast i[[SZ]]* [[AA_CASTED]] to i16*
+// CHECK-DAG: store i16 [[AA]], i16* [[AA_C]], align
+// CHECK-DAG: [[PARAM1:%.+]] = load i[[SZ]], i[[SZ]]* [[A_CASTED]], align
+// CHECK-DAG: [[PARAM2:%.+]] = load i[[SZ]], i[[SZ]]* [[AA_CASTED]], align
+// CHECK-DAG: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams(%ident_t* [[DEF_LOC]], i32 2, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i[[SZ]], i[[SZ]])* [[OMP_OUTLINED3:@.+]] to void (i32*, i32*, ...)*), i[[SZ]] [[PARAM1]], i[[SZ]] [[PARAM2]])
+//
+//
+// CHECK: define internal {{.*}}void [[OMP_OUTLINED3]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}})
+// CHECK: [[A_ADDR:%.+]] = alloca i[[SZ]], align
+// CHECK: [[AA_ADDR:%.+]] = alloca i[[SZ]], align
+// CHECK-DAG: store i[[SZ]] %{{.+}}, i[[SZ]]* [[A_ADDR]], align
+// CHECK-DAG: store i[[SZ]] %{{.+}}, i[[SZ]]* [[AA_ADDR]], align
+// CHECK-64-DAG:[[A_CADDR:%.+]] = bitcast i[[SZ]]* [[A_ADDR]] to i32*
+// CHECK-DAG: [[AA_CADDR:%.+]] = bitcast i[[SZ]]* [[AA_ADDR]] to i16*
+// CHECK: ret void
+// CHECK-NEXT: }
+
+// CHECK: define internal void [[HVT4]]
+// Create local storage for each capture.
+// CHECK: [[LOCAL_A:%.+]] = alloca i[[SZ]]
+// CHECK: [[LOCAL_B:%.+]] = alloca [10 x float]*
+// CHECK: [[LOCAL_VLA1:%.+]] = alloca i[[SZ]]
+// CHECK: [[LOCAL_BN:%.+]] = alloca float*
+// CHECK: [[LOCAL_C:%.+]] = alloca [5 x [10 x double]]*
+// CHECK: [[LOCAL_VLA2:%.+]] = alloca i[[SZ]]
+// CHECK: [[LOCAL_VLA3:%.+]] = alloca i[[SZ]]
+// CHECK: [[LOCAL_CN:%.+]] = alloca double*
+// CHECK: [[LOCAL_D:%.+]] = alloca [[TT]]*
+// CHECK: [[LOCAL_A_CASTED:%.+]] = alloca i[[SZ]]
+// CHECK-DAG: store i[[SZ]] [[ARG_A:%.+]], i[[SZ]]* [[LOCAL_A]]
+// CHECK-DAG: store [10 x float]* [[ARG_B:%.+]], [10 x float]** [[LOCAL_B]]
+// CHECK-DAG: store i[[SZ]] [[ARG_VLA1:%.+]], i[[SZ]]* [[LOCAL_VLA1]]
+// CHECK-DAG: store float* [[ARG_BN:%.+]], float** [[LOCAL_BN]]
+// CHECK-DAG: store [5 x [10 x double]]* [[ARG_C:%.+]], [5 x [10 x double]]** [[LOCAL_C]]
+// CHECK-DAG: store i[[SZ]] [[ARG_VLA2:%.+]], i[[SZ]]* [[LOCAL_VLA2]]
+// CHECK-DAG: store i[[SZ]] [[ARG_VLA3:%.+]], i[[SZ]]* [[LOCAL_VLA3]]
+// CHECK-DAG: store double* [[ARG_CN:%.+]], double** [[LOCAL_CN]]
+// CHECK-DAG: store [[TT]]* [[ARG_D:%.+]], [[TT]]** [[LOCAL_D]]
+
+// CHECK-64-DAG:[[CONV_AP:%.+]] = bitcast i[[SZ]]* [[LOCAL_A]] to i32*
+// CHECK-DAG: [[REF_B:%.+]] = load [10 x float]*, [10 x float]** [[LOCAL_B]],
+// CHECK-DAG: [[VAL_VLA1:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_VLA1]],
+// CHECK-DAG: [[REF_BN:%.+]] = load float*, float** [[LOCAL_BN]],
+// CHECK-DAG: [[REF_C:%.+]] = load [5 x [10 x double]]*, [5 x [10 x double]]** [[LOCAL_C]],
+// CHECK-DAG: [[VAL_VLA2:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_VLA2]],
+// CHECK-DAG: [[VAL_VLA3:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_VLA3]],
+// CHECK-DAG: [[REF_CN:%.+]] = load double*, double** [[LOCAL_CN]],
+// CHECK-DAG: [[REF_D:%.+]] = load [[TT]]*, [[TT]]** [[LOCAL_D]],
+
+// CHECK-64-DAG:[[CONV_A:%.+]] = load i32, i32* [[CONV_AP]]
+// CHECK-64-DAG:[[CONV:%.+]] = bitcast i[[SZ]]* [[LOCAL_A_CASTED]] to i32*
+// CHECK-64-DAG:store i32 [[CONV_A]], i32* [[CONV]], align
+// CHECK-32-DAG:[[LOCAL_AV:%.+]] = load i32, i32* [[LOCAL_A]]
+// CHECK-32-DAG:store i32 [[LOCAL_AV]], i32* [[LOCAL_A_CASTED]], align
+// CHECK-DAG: [[REF_A:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_A_CASTED]],
+
+// CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams(%ident_t* [[DEF_LOC]], i32 9, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i[[SZ]], [10 x float]*, i[[SZ]], float*, [5 x [10 x double]]*, i[[SZ]], i[[SZ]], double*, [[TT]]*)* [[OMP_OUTLINED4:@.+]] to void (i32*, i32*, ...)*), i[[SZ]] [[REF_A]], [10 x float]* [[REF_B]], i[[SZ]] [[VAL_VLA1]], float* [[REF_BN]], [5 x [10 x double]]* [[REF_C]], i[[SZ]] [[VAL_VLA2]], i[[SZ]] [[VAL_VLA3]], double* [[REF_CN]], [[TT]]* [[REF_D]])
+//
+//
+// CHECK: define internal {{.*}}void [[OMP_OUTLINED4]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i[[SZ]] %{{.+}}, [10 x float]* {{.+}}, i[[SZ]] %{{.+}}, float* {{.+}}, [5 x [10 x double]]* {{.+}}, i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, double* {{.+}}, [[TT]]* {{.+}})
+// To reduce complexity, we're only going as far as validating the signature of the outlined parallel function.
+
+template<typename tx>
+tx ftemplate(int n) {
+ tx a = 0;
+ short aa = 0;
+ tx b[10];
+
+ #pragma omp target teams distribute if(target: n>40)
+ for (int i = 0; i < 10; ++i) {
+ a += 1;
+ aa += 1;
+ b[2] += 1;
+ }
+
+ return a;
+}
+
+static
+int fstatic(int n) {
+ int a = 0;
+ short aa = 0;
+ char aaa = 0;
+ int b[10];
+
+ #pragma omp target teams distribute if(target: n>50)
+ for (int i = a; i < n; ++i) {
+ a += 1;
+ aa += 1;
+ aaa += 1;
+ b[2] += 1;
+ }
+
+ return a;
+}
+
+struct S1 {
+ double a;
+
+ int r1(int n){
+ int b = n+1;
+ short int c[2][n];
+
+ #pragma omp target teams distribute if(target: n>60)
+ for (int i = 0; i < 10; ++i) {
+ this->a = (double)b + 1.5;
+ c[1][1] = ++a;
+ }
+
+ return c[1][1] + (int)b;
+ }
+};
+
+// CHECK: define {{.*}}@{{.*}}bar{{.*}}
+int bar(int n){
+ int a = 0;
+
+ // CHECK: call {{.*}}i32 [[FOO]](i32 {{.*}})
+ a += foo(n);
+
+ S1 S;
+ // CHECK: call {{.*}}i32 [[FS1:@.+]]([[S1]]* {{.*}}, i32 {{.*}})
+ a += S.r1(n);
+
+ // CHECK: call {{.*}}i32 [[FSTATIC:@.+]](i32 {{.*}})
+ a += fstatic(n);
+
+ // CHECK: call {{.*}}i32 [[FTEMPLATE:@.+]](i32 {{.*}})
+ a += ftemplate<int>(n);
+
+ return a;
+}
+
+//
+// CHECK: define {{.*}}[[FS1]]
+//
+// CHECK: i8* @llvm.stacksave()
+// CHECK-64: [[B_ADDR:%.+]] = bitcast i[[SZ]]* [[B_CADDR:%.+]] to i32*
+// CHECK-64: store i32 %{{.+}}, i32* [[B_ADDR]],
+// CHECK-64: [[B_CVAL:%.+]] = load i[[SZ]], i[[SZ]]* [[B_CADDR]],
+
+// CHECK-32: store i32 %{{.+}}, i32* [[B_ADDR:%.+]],
+// CHECK-32: [[B_CVAL:%.+]] = load i[[SZ]], i[[SZ]]* [[B_ADDR]],
+
+// We capture 2 VLA sizes in this target region
+// CHECK: [[CELEMSIZE2:%.+]] = mul nuw i[[SZ]] 2, [[VLA0:%.+]]
+// CHECK: [[CSIZE:%.+]] = mul nuw i[[SZ]] [[CELEMSIZE2]], 2
+
+// CHECK: [[IF:%.+]] = icmp sgt i32 {{[^,]+}}, 60
+// CHECK: br i1 [[IF]], label %[[TRY:[^,]+]], label %[[FAIL:[^,]+]]
+// CHECK: [[TRY]]
+// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 5, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* [[SR:%[^,]+]], i64* getelementptr inbounds ([5 x i64], [5 x i64]* [[MAPT5]], i32 0, i32 0), i32 0, i32 0)
+// CHECK-DAG: [[BPR]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[BP:%.+]], i32 0, i32 0
+// CHECK-DAG: [[PR]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[P:%.+]], i32 0, i32 0
+// CHECK-DAG: [[SR]] = getelementptr inbounds [5 x i[[SZ]]], [5 x i[[SZ]]]* [[S:%.+]], i32 0, i32 0
+// CHECK-DAG: [[SADDR0:%.+]] = getelementptr inbounds [5 x i[[SZ]]], [5 x i[[SZ]]]* [[S]], i32 [[IDX0:[0-9]+]]
+// CHECK-DAG: [[BPADDR0:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[BP]], i32 [[IDX0]]
+// CHECK-DAG: [[PADDR0:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[P]], i32 [[IDX0]]
+// CHECK-DAG: [[SADDR1:%.+]] = getelementptr inbounds [5 x i[[SZ]]], [5 x i[[SZ]]]* [[S]], i32 [[IDX1:[0-9]+]]
+// CHECK-DAG: [[BPADDR1:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[BP]], i32 [[IDX1]]
+// CHECK-DAG: [[PADDR1:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[P]], i32 [[IDX1]]
+// CHECK-DAG: [[SADDR2:%.+]] = getelementptr inbounds [5 x i[[SZ]]], [5 x i[[SZ]]]* [[S]], i32 [[IDX2:[0-9]+]]
+// CHECK-DAG: [[BPADDR2:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[BP]], i32 [[IDX2]]
+// CHECK-DAG: [[PADDR2:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[P]], i32 [[IDX2]]
+// CHECK-DAG: [[SADDR3:%.+]] = getelementptr inbounds [5 x i[[SZ]]], [5 x i[[SZ]]]* [[S]], i32 [[IDX3:[0-9]+]]
+// CHECK-DAG: [[BPADDR3:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[BP]], i32 [[IDX3]]
+// CHECK-DAG: [[PADDR3:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[P]], i32 [[IDX3]]
+
+// The names below are not necessarily consistent with the names used for the
+// addresses above as some are repeated.
+// CHECK-DAG: store i[[SZ]] [[VLA0]], i[[SZ]]* [[CBPADDR0:%.+]],
+// CHECK-DAG: store i[[SZ]] [[VLA0]], i[[SZ]]* [[CPADDR0:%.+]],
+// CHECK-DAG: [[CBPADDR0]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+// CHECK-DAG: [[CPADDR0]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+// CHECK-DAG: store i[[SZ]] {{4|8}}, i[[SZ]]* {{%[^,]+}}
+
+// CHECK-DAG: store i[[SZ]] 2, i[[SZ]]* [[CBPADDR1:%.+]],
+// CHECK-DAG: store i[[SZ]] 2, i[[SZ]]* [[CPADDR1:%.+]],
+// CHECK-DAG: [[CBPADDR1]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+// CHECK-DAG: [[CPADDR1]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+// CHECK-DAG: store i[[SZ]] {{4|8}}, i[[SZ]]* {{%[^,]+}}
+
+// CHECK-DAG: store i[[SZ]] [[B_CVAL]], i[[SZ]]* [[CBPADDR2:%.+]],
+// CHECK-DAG: store i[[SZ]] [[B_CVAL]], i[[SZ]]* [[CPADDR2:%.+]],
+// CHECK-DAG: [[CBPADDR2]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+// CHECK-DAG: [[CPADDR2]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+// CHECK-DAG: store i[[SZ]] 4, i[[SZ]]* {{%[^,]+}}
+
+// CHECK-DAG: store [[S1]]* %{{.+}}, [[S1]]** [[CBPADDR3:%.+]],
+// CHECK-DAG: store [[S1]]* %{{.+}}, [[S1]]** [[CPADDR3:%.+]],
+// CHECK-DAG: [[CBPADDR3]] = bitcast i8** {{%[^,]+}} to [[S1]]**
+// CHECK-DAG: [[CPADDR3]] = bitcast i8** {{%[^,]+}} to [[S1]]**
+// CHECK-DAG: store i[[SZ]] 8, i[[SZ]]* {{%[^,]+}}
+
+// CHECK-DAG: store i16* %{{.+}}, i16** [[CBPADDR4:%.+]],
+// CHECK-DAG: store i16* %{{.+}}, i16** [[CPADDR4:%.+]],
+// CHECK-DAG: [[CBPADDR4]] = bitcast i8** {{%[^,]+}} to i16**
+// CHECK-DAG: [[CPADDR4]] = bitcast i8** {{%[^,]+}} to i16**
+// CHECK-DAG: store i[[SZ]] [[CSIZE]], i[[SZ]]* {{%[^,]+}}
+
+// CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
+// CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:[^,]+]], label %[[END:[^,]+]]
+
+// CHECK: [[FAIL]]
+// CHECK: call void [[HVT7:@.+]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}})
+// CHECK-NEXT: br label %[[END]]
+// CHECK: [[END]]
+
+//
+// CHECK: define {{.*}}[[FSTATIC]]
+//
+// CHECK: [[IF:%.+]] = icmp sgt i32 {{[^,]+}}, 50
+// CHECK: br i1 [[IF]], label %[[IFTHEN:[^,]+]], label %[[IFELSE:[^,]+]]
+// CHECK: [[IFTHEN]]
+// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 5, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* getelementptr inbounds ([5 x i[[SZ]]], [5 x i[[SZ]]]* [[SIZET6]], i32 0, i32 0), i64* getelementptr inbounds ([5 x i64], [5 x i64]* [[MAPT6]], i32 0, i32 0), i32 0, i32 0)
+// CHECK-DAG: [[BPR]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[BP:%.+]], i32 0, i32 0
+// CHECK-DAG: [[PR]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[P:%.+]], i32 0, i32 0
+
+// CHECK-DAG: [[BPADDR0:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[BP]], i32 0, i32 0
+// CHECK-DAG: [[PADDR0:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[P]], i32 0, i32 0
+// CHECK-DAG: store i[[SZ]] [[VAL0:%.+]], i[[SZ]]* [[CBPADDR0:%.+]],
+// CHECK-DAG: store i[[SZ]] [[VAL0]], i[[SZ]]* [[CPADDR0:%.+]],
+// CHECK-DAG: [[CBPADDR0]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+// CHECK-DAG: [[CPADDR0]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+
+// CHECK-DAG: [[BPADDR1:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[BP]], i32 0, i32 1
+// CHECK-DAG: [[PADDR1:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[P]], i32 0, i32 1
+// CHECK-DAG: store i[[SZ]] [[VAL1:%.+]], i[[SZ]]* [[CBPADDR1:%.+]],
+// CHECK-DAG: store i[[SZ]] [[VAL1]], i[[SZ]]* [[CPADDR1:%.+]],
+// CHECK-DAG: [[CBPADDR1]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+// CHECK-DAG: [[CPADDR1]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+
+// CHECK-DAG: [[BPADDR2:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[BP]], i32 0, i32 2
+// CHECK-DAG: [[PADDR2:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[P]], i32 0, i32 2
+// CHECK-DAG: store i[[SZ]] [[VAL2:%.+]], i[[SZ]]* [[CBPADDR2:%.+]],
+// CHECK-DAG: store i[[SZ]] [[VAL2]], i[[SZ]]* [[CPADDR2:%.+]],
+// CHECK-DAG: [[CBPADDR2]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+// CHECK-DAG: [[CPADDR2]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+
+// CHECK-DAG: [[BPADDR3:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[BP]], i32 0, i32 3
+// CHECK-DAG: [[PADDR3:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[P]], i32 0, i32 3
+// CHECK-DAG: store i[[SZ]] [[VAL3:%.+]], i[[SZ]]* [[CBPADDR3:%.+]],
+// CHECK-DAG: store i[[SZ]] [[VAL3]], i[[SZ]]* [[CPADDR3:%.+]],
+// CHECK-DAG: [[CBPADDR3]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+// CHECK-DAG: [[CPADDR3]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+
+// CHECK-DAG: [[BPADDR4:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[BP]], i32 0, i32 4
+// CHECK-DAG: [[PADDR4:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[P]], i32 0, i32 4
+// CHECK-DAG: store [10 x i32]* %{{.+}}, [10 x i32]** [[CBPADDR4:%.+]],
+// CHECK-DAG: store [10 x i32]* %{{.+}}, [10 x i32]** [[CPADDR4:%.+]],
+// CHECK-DAG: [[CBPADDR4]] = bitcast i8** {{%[^,]+}} to [10 x i32]**
+// CHECK-DAG: [[CPADDR4]] = bitcast i8** {{%[^,]+}} to [10 x i32]**
+
+// CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
+// CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
+// CHECK: [[FAIL]]
+// CHECK: call void [[HVT6:@.+]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}})
+// CHECK-NEXT: br label %[[END]]
+// CHECK: [[END]]
+// CHECK-NEXT: br label %[[IFEND:.+]]
+// CHECK: [[IFELSE]]
+// CHECK: call void [[HVT6]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}})
+// CHECK-NEXT: br label %[[IFEND]]
+// CHECK: [[IFEND]]
+
+//
+// CHECK: define {{.*}}[[FTEMPLATE]]
+//
+// CHECK: [[IF:%.+]] = icmp sgt i32 {{[^,]+}}, 40
+// CHECK: br i1 [[IF]], label %[[IFTHEN:[^,]+]], label %[[IFELSE:[^,]+]]
+// CHECK: [[IFTHEN]]
+// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 3, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* getelementptr inbounds ([3 x i[[SZ]]], [3 x i[[SZ]]]* [[SIZET7]], i32 0, i32 0), i64* getelementptr inbounds ([3 x i64], [3 x i64]* [[MAPT7]], i32 0, i32 0), i32 0, i32 0)
+// CHECK-DAG: [[BPR]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BP:%.+]], i32 0, i32 0
+// CHECK-DAG: [[PR]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[P:%.+]], i32 0, i32 0
+
+// CHECK-DAG: [[BPADDR0:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BP]], i32 0, i32 0
+// CHECK-DAG: [[PADDR0:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[P]], i32 0, i32 0
+// CHECK-DAG: store i[[SZ]] [[VAL0:%.+]], i[[SZ]]* [[CBPADDR0:%.+]],
+// CHECK-DAG: store i[[SZ]] [[VAL0]], i[[SZ]]* [[CPADDR0:%.+]],
+// CHECK-DAG: [[CBPADDR0]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+// CHECK-DAG: [[CPADDR0]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+
+// CHECK-DAG: [[BPADDR1:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BP]], i32 0, i32 1
+// CHECK-DAG: [[PADDR1:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[P]], i32 0, i32 1
+// CHECK-DAG: store i[[SZ]] [[VAL1:%.+]], i[[SZ]]* [[CBPADDR1:%.+]],
+// CHECK-DAG: store i[[SZ]] [[VAL1]], i[[SZ]]* [[CPADDR1:%.+]],
+// CHECK-DAG: [[CBPADDR1]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+// CHECK-DAG: [[CPADDR1]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+
+// CHECK-DAG: [[BPADDR2:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BP]], i32 0, i32 2
+// CHECK-DAG: [[PADDR2:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[P]], i32 0, i32 2
+// CHECK-DAG: store i[[SZ]] [[VAL2:%.+]], i[[SZ]]* [[CBPADDR2:%.+]],
+// CHECK-DAG: store i[[SZ]] [[VAL2]], i[[SZ]]* [[CPADDR2:%.+]],
+// CHECK-DAG: [[CBPADDR2]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+// CHECK-DAG: [[CPADDR2]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+
+// CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
+// CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
+// CHECK: [[FAIL]]
+// CHECK: call void [[HVT5:@.+]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}})
+// CHECK-NEXT: br label %[[END]]
+// CHECK: [[END]]
+// CHECK-NEXT: br label %[[IFEND:.+]]
+// CHECK: [[IFELSE]]
+// CHECK: call void [[HVT5]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}})
+// CHECK-NEXT: br label %[[IFEND]]
+// CHECK: [[IFEND]]
+
+
+
+// Check that the offloading functions are emitted and that the arguments are
+// correct and loaded correctly for the target regions of the callees of bar().
+
+// CHECK: define internal void [[HVT7]]
+// Create local storage for each capture.
+// CHECK: [[LOCAL_THIS:%.+]] = alloca [[S1]]*
+// CHECK: [[LOCAL_B:%.+]] = alloca i[[SZ]]
+// CHECK: [[LOCAL_VLA1:%.+]] = alloca i[[SZ]]
+// CHECK: [[LOCAL_VLA2:%.+]] = alloca i[[SZ]]
+// CHECK: [[LOCAL_C:%.+]] = alloca i16*
+// CHECK: [[LOCAL_B_CASTED:%.+]] = alloca i[[SZ]]
+// CHECK-DAG: store [[S1]]* [[ARG_THIS:%.+]], [[S1]]** [[LOCAL_THIS]]
+// CHECK-DAG: store i[[SZ]] [[ARG_B:%.+]], i[[SZ]]* [[LOCAL_B]]
+// CHECK-DAG: store i[[SZ]] [[ARG_VLA1:%.+]], i[[SZ]]* [[LOCAL_VLA1]]
+// CHECK-DAG: store i[[SZ]] [[ARG_VLA2:%.+]], i[[SZ]]* [[LOCAL_VLA2]]
+// CHECK-DAG: store i16* [[ARG_C:%.+]], i16** [[LOCAL_C]]
+// Store captures in the context.
+// CHECK-DAG: [[REF_THIS:%.+]] = load [[S1]]*, [[S1]]** [[LOCAL_THIS]],
+// CHECK-64-DAG:[[CONV_BP:%.+]] = bitcast i[[SZ]]* [[LOCAL_B]] to i32*
+// CHECK-DAG: [[VAL_VLA1:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_VLA1]],
+// CHECK-DAG: [[VAL_VLA2:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_VLA2]],
+// CHECK-DAG: [[REF_C:%.+]] = load i16*, i16** [[LOCAL_C]],
+
+// CHECK-64-DAG:[[CONV_B:%.+]] = load i32, i32* [[CONV_BP]]
+// CHECK-64-DAG:[[CONV:%.+]] = bitcast i[[SZ]]* [[LOCAL_B_CASTED]] to i32*
+// CHECK-64-DAG:store i32 [[CONV_B]], i32* [[CONV]], align
+// CHECK-32-DAG:[[LOCAL_BV:%.+]] = load i32, i32* [[LOCAL_B]]
+// CHECK-32-DAG:store i32 [[LOCAL_BV]], i32* [[LOCAL_B_CASTED]], align
+// CHECK-DAG: [[REF_B:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_B_CASTED]],
+
+// CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams(%ident_t* [[DEF_LOC]], i32 5, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, [[S1]]*, i[[SZ]], i[[SZ]], i[[SZ]], i16*)* [[OMP_OUTLINED5:@.+]] to void (i32*, i32*, ...)*), [[S1]]* [[REF_THIS]], i[[SZ]] [[REF_B]], i[[SZ]] [[VAL_VLA1]], i[[SZ]] [[VAL_VLA2]], i16* [[REF_C]])
+//
+//
+// CHECK: define internal {{.*}}void [[OMP_OUTLINED5]](i32* noalias %.global_tid., i32* noalias %.bound_tid., [[S1]]* %{{.+}}, i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, i16* {{.+}})
+// To reduce complexity, we're only going as far as validating the signature of the outlined parallel function.
+
+
+// CHECK: define internal void [[HVT6]]
+// Create local storage for each capture.
+// CHECK: [[LOCAL_A:%.+]] = alloca i[[SZ]]
+// CHECK: alloca i[[SZ]],
+// CHECK: [[LOCAL_AA:%.+]] = alloca i[[SZ]]
+// CHECK: [[LOCAL_AAA:%.+]] = alloca i[[SZ]]
+// CHECK: [[LOCAL_B:%.+]] = alloca [10 x i32]*
+// CHECK: [[LOCAL_A_CASTED:%.+]] = alloca i[[SZ]]
+// CHECK: alloca i[[SZ]],
+// CHECK: [[LOCAL_AA_CASTED:%.+]] = alloca i[[SZ]]
+// CHECK: [[LOCAL_AAA_CASTED:%.+]] = alloca i[[SZ]]
+// CHECK-DAG: store i[[SZ]] [[ARG_A:%.+]], i[[SZ]]* [[LOCAL_A]]
+// CHECK-DAG: store i[[SZ]] [[ARG_AA:%.+]], i[[SZ]]* [[LOCAL_AA]]
+// CHECK-DAG: store i[[SZ]] [[ARG_AAA:%.+]], i[[SZ]]* [[LOCAL_AAA]]
+// CHECK-DAG: store [10 x i32]* [[ARG_B:%.+]], [10 x i32]** [[LOCAL_B]]
+// Store captures in the context.
+// CHECK-64-DAG:[[CONV_AP:%.+]] = bitcast i[[SZ]]* [[LOCAL_A]] to i32*
+// CHECK-DAG: [[CONV_AAP:%.+]] = bitcast i[[SZ]]* [[LOCAL_AA]] to i16*
+// CHECK-DAG: [[CONV_AAAP:%.+]] = bitcast i[[SZ]]* [[LOCAL_AAA]] to i8*
+// CHECK-DAG: [[REF_B:%.+]] = load [10 x i32]*, [10 x i32]** [[LOCAL_B]],
+
+// CHECK-64-DAG:[[CONV_A:%.+]] = load i32, i32* [[CONV_AP]]
+// CHECK-64-DAG:[[CONV:%.+]] = bitcast i[[SZ]]* [[LOCAL_A_CASTED]] to i32*
+// CHECK-64-DAG:store i32 [[CONV_A]], i32* [[CONV]], align
+// CHECK-32-DAG:[[LOCAL_AV:%.+]] = load i32, i32* [[LOCAL_A]]
+// CHECK-32-DAG:store i32 [[LOCAL_AV]], i32* [[LOCAL_A_CASTED]], align
+// CHECK-DAG: [[REF_A:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_A_CASTED]],
+
+// CHECK-DAG: [[CONV_AA:%.+]] = load i16, i16* [[CONV_AAP]]
+// CHECK-DAG: [[CONV:%.+]] = bitcast i[[SZ]]* [[LOCAL_AA_CASTED]] to i16*
+// CHECK-DAG: store i16 [[CONV_AA]], i16* [[CONV]], align
+// CHECK-DAG: [[REF_AA:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_AA_CASTED]],
+
+// CHECK-DAG: [[CONV_AAA:%.+]] = load i8, i8* [[CONV_AAAP]]
+// CHECK-DAG: [[CONV:%.+]] = bitcast i[[SZ]]* [[LOCAL_AAA_CASTED]] to i8*
+// CHECK-DAG: store i8 [[CONV_AAA]], i8* [[CONV]], align
+// CHECK-DAG: [[REF_AAA:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_AAA_CASTED]],
+
+// CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams(%ident_t* [[DEF_LOC]], i32 5, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i[[SZ]], i[[SZ]], i[[SZ]], i[[SZ]], [10 x i32]*)* [[OMP_OUTLINED6:@.+]] to void (i32*, i32*, ...)*), i[[SZ]] [[REF_A]], i[[SZ]] {{.+}}, i[[SZ]] [[REF_AA]], i[[SZ]] [[REF_AAA]], [10 x i32]* [[REF_B]])
+//
+//
+// CHECK: define internal {{.*}}void [[OMP_OUTLINED6]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, [10 x i32]* {{.+}})
+// To reduce complexity, we're only going as far as validating the signature of the outlined parallel function.
+
+// CHECK: define internal void [[HVT5]]
+// Create local storage for each capture.
+// CHECK: [[LOCAL_A:%.+]] = alloca i[[SZ]]
+// CHECK: [[LOCAL_AA:%.+]] = alloca i[[SZ]]
+// CHECK: [[LOCAL_B:%.+]] = alloca [10 x i32]*
+// CHECK: [[LOCAL_A_CASTED:%.+]] = alloca i[[SZ]]
+// CHECK: [[LOCAL_AA_CASTED:%.+]] = alloca i[[SZ]]
+// CHECK-DAG: store i[[SZ]] [[ARG_A:%.+]], i[[SZ]]* [[LOCAL_A]]
+// CHECK-DAG: store i[[SZ]] [[ARG_AA:%.+]], i[[SZ]]* [[LOCAL_AA]]
+// CHECK-DAG: store [10 x i32]* [[ARG_B:%.+]], [10 x i32]** [[LOCAL_B]]
+// Store captures in the context.
+// CHECK-64-DAG:[[CONV_AP:%.+]] = bitcast i[[SZ]]* [[LOCAL_A]] to i32*
+// CHECK-DAG: [[CONV_AAP:%.+]] = bitcast i[[SZ]]* [[LOCAL_AA]] to i16*
+// CHECK-DAG: [[REF_B:%.+]] = load [10 x i32]*, [10 x i32]** [[LOCAL_B]],
+
+// CHECK-64-DAG:[[CONV_A:%.+]] = load i32, i32* [[CONV_AP]]
+// CHECK-64-DAG:[[CONV:%.+]] = bitcast i[[SZ]]* [[LOCAL_A_CASTED]] to i32*
+// CHECK-64-DAG:store i32 [[CONV_A]], i32* [[CONV]], align
+// CHECK-32-DAG:[[LOCAL_AV:%.+]] = load i32, i32* [[LOCAL_A]]
+// CHECK-32-DAG:store i32 [[LOCAL_AV]], i32* [[LOCAL_A_CASTED]], align
+// CHECK-DAG: [[REF_A:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_A_CASTED]],
+
+// CHECK-DAG: [[CONV_AA:%.+]] = load i16, i16* [[CONV_AAP]]
+// CHECK-DAG: [[CONV:%.+]] = bitcast i[[SZ]]* [[LOCAL_AA_CASTED]] to i16*
+// CHECK-DAG: store i16 [[CONV_AA]], i16* [[CONV]], align
+// CHECK-DAG: [[REF_AA:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_AA_CASTED]],
+
+// CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams(%ident_t* [[DEF_LOC]], i32 3, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i[[SZ]], i[[SZ]], [10 x i32]*)* [[OMP_OUTLINED7:@.+]] to void (i32*, i32*, ...)*), i[[SZ]] [[REF_A]], i[[SZ]] [[REF_AA]], [10 x i32]* [[REF_B]])
+//
+//
+// CHECK: define internal {{.*}}void [[OMP_OUTLINED7]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, [10 x i32]* {{.+}})
+// To reduce complexity, we're only going as far as validating the signature of the outlined parallel function.
+
+#endif
diff --git a/test/OpenMP/target_teams_distribute_codegen_registration.cpp b/test/OpenMP/target_teams_distribute_codegen_registration.cpp
new file mode 100644
index 000000000000..c031731c8065
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_codegen_registration.cpp
@@ -0,0 +1,451 @@
+// Test host codegen.
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+
+// Test target teams distribute codegen - host bc file has to be created first.
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm-bc %s -o %t-ppc-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s -check-prefix=TCHECK
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s -check-prefix=TCHECK
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm-bc %s -o %t-x86-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s -check-prefix=TCHECK
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s -check-prefix=TCHECK
+
+// Check that no target code is emmitted if no omptests flag was provided.
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s -check-prefix=CHECK-NTARGET
+
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+// CHECK-DAG: [[SA:%.+]] = type { [4 x i32] }
+// CHECK-DAG: [[SB:%.+]] = type { [8 x i32] }
+// CHECK-DAG: [[SC:%.+]] = type { [16 x i32] }
+// CHECK-DAG: [[SD:%.+]] = type { [32 x i32] }
+// CHECK-DAG: [[SE:%.+]] = type { [64 x i32] }
+// CHECK-DAG: [[ST1:%.+]] = type { [228 x i32] }
+// CHECK-DAG: [[ST2:%.+]] = type { [1128 x i32] }
+// CHECK-DAG: [[ENTTY:%.+]] = type { i8*, i8*, i[[SZ:32|64]], i32, i32 }
+// CHECK-DAG: [[DEVTY:%.+]] = type { i8*, i8*, [[ENTTY]]*, [[ENTTY]]* }
+// CHECK-DAG: [[DSCTY:%.+]] = type { i32, [[DEVTY]]*, [[ENTTY]]*, [[ENTTY]]* }
+
+// TCHECK: [[ENTTY:%.+]] = type { i8*, i8*, i[[SZ:32|64]], i32, i32 }
+
+// CHECK-DAG: $[[REGFN:\.omp_offloading\..+]] = comdat
+
+// CHECK-DAG: [[A1:@.+]] = internal global [[SA]]
+// CHECK-DAG: [[A2:@.+]] = global [[SA]]
+// CHECK-DAG: [[B1:@.+]] = global [[SB]]
+// CHECK-DAG: [[B2:@.+]] = global [[SB]]
+// CHECK-DAG: [[C1:@.+]] = internal global [[SC]]
+// CHECK-DAG: [[D1:@.+]] = global [[SD]]
+// CHECK-DAG: [[E1:@.+]] = global [[SE]]
+// CHECK-DAG: [[T1:@.+]] = global [[ST1]]
+// CHECK-DAG: [[T2:@.+]] = global [[ST2]]
+
+// CHECK-NTARGET-DAG: [[SA:%.+]] = type { [4 x i32] }
+// CHECK-NTARGET-DAG: [[SB:%.+]] = type { [8 x i32] }
+// CHECK-NTARGET-DAG: [[SC:%.+]] = type { [16 x i32] }
+// CHECK-NTARGET-DAG: [[SD:%.+]] = type { [32 x i32] }
+// CHECK-NTARGET-DAG: [[SE:%.+]] = type { [64 x i32] }
+// CHECK-NTARGET-DAG: [[ST1:%.+]] = type { [228 x i32] }
+// CHECK-NTARGET-DAG: [[ST2:%.+]] = type { [1128 x i32] }
+// CHECK-NTARGET-NOT: type { i8*, i8*, %
+// CHECK-NTARGET-NOT: type { i32, %
+
+// We have 7 target regions
+
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// TCHECK-NOT: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
+
+// CHECK-NTARGET-NOT: private constant i8 0
+// CHECK-NTARGET-NOT: private unnamed_addr constant [1 x i
+
+// CHECK-DAG: [[NAMEPTR1:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME1:__omp_offloading_[0-9a-f]+_[0-9a-f]+__Z.+_l[0-9]+]]\00"
+// CHECK-DAG: [[ENTRY1:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR1]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR2:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME2:.+]]\00"
+// CHECK-DAG: [[ENTRY2:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR2]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR3:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME3:.+]]\00"
+// CHECK-DAG: [[ENTRY3:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR3]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR4:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME4:.+]]\00"
+// CHECK-DAG: [[ENTRY4:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR4]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR5:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME5:.+]]\00"
+// CHECK-DAG: [[ENTRY5:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR5]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR6:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME6:.+]]\00"
+// CHECK-DAG: [[ENTRY6:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR6]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR7:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME7:.+]]\00"
+// CHECK-DAG: [[ENTRY7:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR7]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR8:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME8:.+]]\00"
+// CHECK-DAG: [[ENTRY8:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR8]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR9:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME9:.+]]\00"
+// CHECK-DAG: [[ENTRY9:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR9]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR10:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME10:.+]]\00"
+// CHECK-DAG: [[ENTRY10:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR10]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR11:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME11:.+]]\00"
+// CHECK-DAG: [[ENTRY11:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR11]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR12:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME12:.+]]\00"
+// CHECK-DAG: [[ENTRY12:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR12]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+
+// TCHECK-DAG: [[NAMEPTR1:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME1:__omp_offloading_[0-9a-f]+_[0-9a-f]+__Z.+_l[0-9]+]]\00"
+// TCHECK-DAG: [[ENTRY1:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR1]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR2:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME2:.+]]\00"
+// TCHECK-DAG: [[ENTRY2:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR2]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR3:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME3:.+]]\00"
+// TCHECK-DAG: [[ENTRY3:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR3]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR4:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME4:.+]]\00"
+// TCHECK-DAG: [[ENTRY4:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR4]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR5:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME5:.+]]\00"
+// TCHECK-DAG: [[ENTRY5:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR5]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR6:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME6:.+]]\00"
+// TCHECK-DAG: [[ENTRY6:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR6]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR7:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME7:.+]]\00"
+// TCHECK-DAG: [[ENTRY7:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR7]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR8:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME8:.+]]\00"
+// TCHECK-DAG: [[ENTRY8:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR8]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR9:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME9:.+]]\00"
+// TCHECK-DAG: [[ENTRY9:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR9]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR10:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME10:.+]]\00"
+// TCHECK-DAG: [[ENTRY10:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR10]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR11:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME11:.+]]\00"
+// TCHECK-DAG: [[ENTRY11:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR11]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR12:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME12:.+]]\00"
+// TCHECK-DAG: [[ENTRY12:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR12]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+
+// CHECK: [[ENTBEGIN:@.+]] = external constant [[ENTTY]]
+// CHECK: [[ENTEND:@.+]] = external constant [[ENTTY]]
+// CHECK: [[DEVBEGIN:@.+]] = external constant i8
+// CHECK: [[DEVEND:@.+]] = external constant i8
+// CHECK: [[IMAGES:@.+]] = internal unnamed_addr constant [1 x [[DEVTY]]] [{{.+}} { i8* [[DEVBEGIN]], i8* [[DEVEND]], [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }], comdat($[[REGFN]])
+// CHECK: [[DESC:@.+]] = internal constant [[DSCTY]] { i32 1, [[DEVTY]]* getelementptr inbounds ([1 x [[DEVTY]]], [1 x [[DEVTY]]]* [[IMAGES]], i32 0, i32 0), [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }, comdat($[[REGFN]])
+
+// We have 4 initializers, one for the 500 priority, another one for 501, or more for the default priority, and the last one for the offloading registration function.
+// CHECK: @llvm.global_ctors = appending global [4 x { i32, void ()*, i8* }] [
+// CHECK-SAME: { i32, void ()*, i8* } { i32 500, void ()* [[P500:@[^,]+]], i8* null },
+// CHECK-SAME: { i32, void ()*, i8* } { i32 501, void ()* [[P501:@[^,]+]], i8* null },
+// CHECK-SAME: { i32, void ()*, i8* } { i32 65535, void ()* [[PMAX:@[^,]+]], i8* null },
+// CHECK-SAME: { i32, void ()*, i8* } { i32 0, void ()* bitcast (void (i8*)* @[[REGFN]] to void ()*), i8* bitcast (void (i8*)* @[[REGFN]] to i8*) }]
+
+// CHECK-NTARGET: @llvm.global_ctors = appending global [3 x { i32, void ()*, i8* }] [
+
+extern int *R;
+
+struct SA {
+ int arr[4];
+ void foo() {
+ int a = *R;
+ a += 1;
+ *R = a;
+ }
+ SA() {
+ int a = *R;
+ a += 2;
+ *R = a;
+ }
+ ~SA() {
+ int a = *R;
+ a += 3;
+ *R = a;
+ }
+};
+
+struct SB {
+ int arr[8];
+ void foo() {
+ int a = *R;
+ #pragma omp target teams distribute
+ for (int i = 0; i < 10; ++i)
+ a += 4;
+ *R = a;
+ }
+ SB() {
+ int a = *R;
+ a += 5;
+ *R = a;
+ }
+ ~SB() {
+ int a = *R;
+ a += 6;
+ *R = a;
+ }
+};
+
+struct SC {
+ int arr[16];
+ void foo() {
+ int a = *R;
+ a += 7;
+ *R = a;
+ }
+ SC() {
+ int a = *R;
+ #pragma omp target teams distribute
+ for (int i = 0; i < 10; ++i)
+ a += 8;
+ *R = a;
+ }
+ ~SC() {
+ int a = *R;
+ a += 9;
+ *R = a;
+ }
+};
+
+struct SD {
+ int arr[32];
+ void foo() {
+ int a = *R;
+ a += 10;
+ *R = a;
+ }
+ SD() {
+ int a = *R;
+ a += 11;
+ *R = a;
+ }
+ ~SD() {
+ int a = *R;
+ #pragma omp target teams distribute
+ for (int i = 0; i < 10; ++i)
+ a += 12;
+ *R = a;
+ }
+};
+
+struct SE {
+ int arr[64];
+ void foo() {
+ int a = *R;
+ #pragma omp target teams distribute if(target: 0)
+ for (int i = 0; i < 10; ++i)
+ a += 13;
+ *R = a;
+ }
+ SE() {
+ int a = *R;
+ #pragma omp target teams distribute
+ for (int i = 0; i < 10; ++i)
+ a += 14;
+ *R = a;
+ }
+ ~SE() {
+ int a = *R;
+ #pragma omp target teams distribute
+ for (int i = 0; i < 10; ++i)
+ a += 15;
+ *R = a;
+ }
+};
+
+template <int x>
+struct ST {
+ int arr[128 + x];
+ void foo() {
+ int a = *R;
+ #pragma omp target teams distribute
+ for (int i = 0; i < 10; ++i)
+ a += 16 + x;
+ *R = a;
+ }
+ ST() {
+ int a = *R;
+ #pragma omp target teams distribute
+ for (int i = 0; i < 10; ++i)
+ a += 17 + x;
+ *R = a;
+ }
+ ~ST() {
+ int a = *R;
+ #pragma omp target teams distribute
+ for (int i = 0; i < 10; ++i)
+ a += 18 + x;
+ *R = a;
+ }
+};
+
+// We have to make sure we us all the target regions:
+//CHECK-DAG: define internal void @[[NAME1]](
+//CHECK-DAG: call void @[[NAME1]](
+//CHECK-DAG: define internal void @[[NAME2]](
+//CHECK-DAG: call void @[[NAME2]](
+//CHECK-DAG: define internal void @[[NAME3]](
+//CHECK-DAG: call void @[[NAME3]](
+//CHECK-DAG: define internal void @[[NAME4]](
+//CHECK-DAG: call void @[[NAME4]](
+//CHECK-DAG: define internal void @[[NAME5]](
+//CHECK-DAG: call void @[[NAME5]](
+//CHECK-DAG: define internal void @[[NAME6]](
+//CHECK-DAG: call void @[[NAME6]](
+//CHECK-DAG: define internal void @[[NAME7]](
+//CHECK-DAG: call void @[[NAME7]](
+//CHECK-DAG: define internal void @[[NAME8]](
+//CHECK-DAG: call void @[[NAME8]](
+//CHECK-DAG: define internal void @[[NAME9]](
+//CHECK-DAG: call void @[[NAME9]](
+//CHECK-DAG: define internal void @[[NAME10]](
+//CHECK-DAG: call void @[[NAME10]](
+//CHECK-DAG: define internal void @[[NAME11]](
+//CHECK-DAG: call void @[[NAME11]](
+//CHECK-DAG: define internal void @[[NAME12]](
+//CHECK-DAG: call void @[[NAME12]](
+
+//TCHECK-DAG: define void @[[NAME1]](
+//TCHECK-DAG: define void @[[NAME2]](
+//TCHECK-DAG: define void @[[NAME3]](
+//TCHECK-DAG: define void @[[NAME4]](
+//TCHECK-DAG: define void @[[NAME5]](
+//TCHECK-DAG: define void @[[NAME6]](
+//TCHECK-DAG: define void @[[NAME7]](
+//TCHECK-DAG: define void @[[NAME8]](
+//TCHECK-DAG: define void @[[NAME9]](
+//TCHECK-DAG: define void @[[NAME10]](
+//TCHECK-DAG: define void @[[NAME11]](
+//TCHECK-DAG: define void @[[NAME12]](
+
+// CHECK-NTARGET-NOT: __tgt_target
+// CHECK-NTARGET-NOT: __tgt_register_lib
+// CHECK-NTARGET-NOT: __tgt_unregister_lib
+
+// TCHECK-NOT: __tgt_target
+// TCHECK-NOT: __tgt_register_lib
+// TCHECK-NOT: __tgt_unregister_lib
+
+// We have 2 initializers with priority 500
+//CHECK: define internal void [[P500]](
+//CHECK: call void @{{.+}}()
+//CHECK: call void @{{.+}}()
+//CHECK-NOT: call void @{{.+}}()
+//CHECK: ret void
+
+// We have 1 initializers with priority 501
+//CHECK: define internal void [[P501]](
+//CHECK: call void @{{.+}}()
+//CHECK-NOT: call void @{{.+}}()
+//CHECK: ret void
+
+// We have 6 initializers with default priority
+//CHECK: define internal void [[PMAX]](
+//CHECK: call void @{{.+}}()
+//CHECK: call void @{{.+}}()
+//CHECK: call void @{{.+}}()
+//CHECK: call void @{{.+}}()
+//CHECK: call void @{{.+}}()
+//CHECK: call void @{{.+}}()
+//CHECK-NOT: call void @{{.+}}()
+//CHECK: ret void
+
+// Check registration and unregistration
+
+//CHECK: define internal void @[[UNREGFN:.+]](i8*)
+//CHECK-SAME: comdat($[[REGFN]]) {
+//CHECK: call i32 @__tgt_unregister_lib([[DSCTY]]* [[DESC]])
+//CHECK: ret void
+//CHECK: declare i32 @__tgt_unregister_lib([[DSCTY]]*)
+
+//CHECK: define linkonce hidden void @[[REGFN]](i8*)
+//CHECK-SAME: comdat {
+//CHECK: call i32 @__tgt_register_lib([[DSCTY]]* [[DESC]])
+//CHECK: call i32 @__cxa_atexit(void (i8*)* @[[UNREGFN]], i8* bitcast ([[DSCTY]]* [[DESC]] to i8*),
+//CHECK: ret void
+//CHECK: declare i32 @__tgt_register_lib([[DSCTY]]*)
+
+static __attribute__((init_priority(500))) SA a1;
+SA a2;
+SB __attribute__((init_priority(500))) b1;
+SB __attribute__((init_priority(501))) b2;
+static SC c1;
+SD d1;
+SE e1;
+ST<100> t1;
+ST<1000> t2;
+
+
+int bar(int a){
+ int r = a;
+
+ a1.foo();
+ a2.foo();
+ b1.foo();
+ b2.foo();
+ c1.foo();
+ d1.foo();
+ e1.foo();
+ t1.foo();
+ t2.foo();
+
+ #pragma omp target teams distribute
+ for (int i = 0; i < 10; ++i)
+ ++r;
+
+ return r + *R;
+}
+
+// Check metadata is properly generated:
+// CHECK: !omp_offload.info = !{!{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID:-?[0-9]+]], i32 [[FILEID:-?[0-9]+]], !"_ZN2SB3fooEv", i32 195, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SDD1Ev", i32 247, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SEC1Ev", i32 265, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SED1Ev", i32 272, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EE3fooEv", i32 284, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EEC1Ev", i32 291, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_Z3bari", i32 415, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EED1Ev", i32 298, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EEC1Ev", i32 291, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EED1Ev", i32 298, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EE3fooEv", i32 284, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SCC1Ev", i32 221, i32 {{[0-9]+}}}
+
+// TCHECK: !omp_offload.info = !{!{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID:-?[0-9]+]], i32 [[FILEID:-?[0-9]+]], !"_ZN2SB3fooEv", i32 195, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SDD1Ev", i32 247, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SEC1Ev", i32 265, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SED1Ev", i32 272, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EE3fooEv", i32 284, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EEC1Ev", i32 291, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_Z3bari", i32 415, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EED1Ev", i32 298, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EEC1Ev", i32 291, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EED1Ev", i32 298, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EE3fooEv", i32 284, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SCC1Ev", i32 221, i32 {{[0-9]+}}}
+
+#endif
diff --git a/test/OpenMP/target_teams_distribute_codegen_registration_naming.cpp b/test/OpenMP/target_teams_distribute_codegen_registration_naming.cpp
new file mode 100644
index 000000000000..c03466a52646
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_codegen_registration_naming.cpp
@@ -0,0 +1,68 @@
+// Test host codegen.
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+
+// Test target teams distribute codegen - host bc file has to be created first.
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm-bc %s -o %t-ppc-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s -check-prefix=TCHECK
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s -check-prefix=TCHECK
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm-bc %s -o %t-x86-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s -check-prefix=TCHECK
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s -check-prefix=TCHECK
+
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+// CHECK: [[CA:%.+]] = type { i32* }
+
+// CHECK: define {{.*}}i32 @[[NNAME:.+]](i32 {{.*}}%{{.+}})
+int nested(int a){
+ // CHECK: call void @__omp_offloading_[[FILEID:[0-9a-f]+_[0-9a-f]+]]_[[NNAME]]_l[[T1L:[0-9]+]](
+ #pragma omp target teams distribute
+ for (int i = 0; i < 10; ++i)
+ ++a;
+
+ // CHECK: call void @"[[LNAME:.+]]"([[CA]]*
+ auto F = [&](){
+ #pragma omp parallel
+ {
+ #pragma omp target teams distribute
+ for (int i = 0; i < 10; ++i)
+ ++a;
+ }
+ };
+
+ F();
+
+ return a;
+}
+
+// CHECK: define {{.*}}void @__omp_offloading_[[FILEID]]_[[NNAME]]_l[[T1L]](
+// TCHECK: define {{.*}}void @__omp_offloading_[[FILEID:[0-9a-f]+_[0-9a-f]+]]_[[NNAME:.+]]_l[[T1L:[0-9]+]](
+
+// CHECK: define {{.*}}void @"[[LNAME]]"(
+// CHECK: call void {{.*}}@__kmpc_fork_call{{.+}}[[PNAME:@.+]] to
+
+// CHECK: define {{.*}}void [[PNAME]](
+// CHECK: call void @__omp_offloading_[[FILEID]]_[[NNAME]]_l[[T2L:[0-9]+]](
+
+// CHECK: define {{.*}}void @__omp_offloading_[[FILEID]]_[[NNAME]]_l[[T2L]](
+// TCHECK: define {{.*}}void @__omp_offloading_[[FILEID]]_[[NNAME:.+]]_l[[T2L:[0-9]+]](
+
+
+// Check metadata is properly generated:
+// CHECK: !omp_offload.info = !{!{{[0-9]+}}, !{{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 {{-?[0-9]+}}, i32 {{-?[0-9]+}}, !"[[NNAME]]", i32 [[T1L]], i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 {{-?[0-9]+}}, i32 {{-?[0-9]+}}, !"[[NNAME]]", i32 [[T2L]], i32 {{[0-9]+}}}
+
+// TCHECK: !omp_offload.info = !{!{{[0-9]+}}, !{{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 {{-?[0-9]+}}, i32 {{-?[0-9]+}}, !"[[NNAME]]", i32 [[T1L]], i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 {{-?[0-9]+}}, i32 {{-?[0-9]+}}, !"[[NNAME]]", i32 [[T2L]], i32 {{[0-9]+}}}
+#endif
diff --git a/test/OpenMP/target_teams_distribute_collapse_codegen.cpp b/test/OpenMP/target_teams_distribute_collapse_codegen.cpp
new file mode 100644
index 000000000000..be99186e4681
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_collapse_codegen.cpp
@@ -0,0 +1,125 @@
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+// Test host codegen.
+// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64
+// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32
+#ifdef CK1
+
+template <typename T, int X, long long Y>
+struct SS{
+ T a[X][Y];
+
+ // CK1: define {{.*}}i32 @{{.+}}foo{{.+}}(
+ int foo(void) {
+
+ // CK1: call i32 @__tgt_target_teams(
+ // CK1: call void @[[OFFL1:.+]](
+ #pragma omp target teams distribute collapse(2)
+ for(int i = 0; i < X; i++) {
+ for(int j = 0; j < Y; j++) {
+ a[i][j] = (T)0;
+ }
+ }
+ // CK1: define internal void @[[OFFL1]](
+ // CK1: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTL1:.+]] to {{.+}},
+ // CK1: ret void
+
+ // CK1: define internal void @[[OUTL1]]({{.+}})
+ // discard loop variables not needed here
+ // CK1: = alloca i32,
+ // CK1: = alloca i32,
+ // CK1: = alloca i32,
+ // CK1: = alloca i32,
+ // CK1: [[OMP_UB:%.+]] = alloca i32,
+ // CK1: store i32 56087, i32* [[OMP_UB]],
+ // CK1: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 92, {{.+}}, {{.+}}, i32* [[OMP_UB]],
+ // CK1: call void @__kmpc_for_static_fini(
+ // CK1: ret void
+
+ return a[0][0];
+ }
+};
+
+int teams_template_struct(void) {
+ SS<int, 123, 456> V;
+ return V.foo();
+
+}
+#endif // CK1
+
+// Test host codegen.
+// RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64
+// RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32
+#ifdef CK2
+
+template <typename T, int n, int m>
+int tmain(T argc) {
+ T a[n][m];
+ #pragma omp target teams distribute collapse(2)
+ for(int i = 0; i < n; i++) {
+ for(int j = 0; j < m; j++) {
+ a[i][j] = (T)0;
+ }
+ }
+ return 0;
+}
+
+int main (int argc, char **argv) {
+ int n = 100;
+ int m = 2;
+ int a[n][m];
+ #pragma omp target teams distribute collapse(2)
+ for(int i = 0; i < n; i++) {
+ for(int j = 0; j < m; j++) {
+ a[i][j] = 0;
+ }
+ }
+ return tmain<int, 10, 2>(argc);
+}
+
+// CK2: define {{.*}}i32 @{{[^,]+}}(i{{.+}}{{.+}} %[[ARGC:.+]], {{.+}})
+// CK2: call i32 @__tgt_target_teams(
+// CK2: call void @[[OFFL1:.+]]({{.+}})
+// CK2: {{%.+}} = call{{.*}} i32 @[[TMAIN:.+]]({{.+}})
+// CK2: ret
+
+// CK2: define {{.*}}void @[[OFFL1]]({{.+}})
+// CK2: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 5, {{.+}} @[[OUTL1:.+]] to {{.+}},
+// CK2: ret void
+
+// CK2: define internal void @[[OUTL1]]({{.+}})
+// CK2: [[OMP_UB:%.omp.ub]] = alloca i64,
+// CK2: store i64 {{.+}}, i64* [[OMP_UB]],
+// CK2: call void @__kmpc_for_static_init_8({{.+}}, {{.+}}, i32 92, {{.+}}, {{.+}}, i64* [[OMP_UB]],
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+// CK2: define {{.*}}i32 @[[TMAIN]]({{.+}})
+// CK2: call i32 @__tgt_target_teams(
+// CK2: call void @[[OFFLT1:.+]]({{.+}})
+// CK2: ret
+// CK2-NEXT: }
+
+// CK2: define {{.*}}void @[[OFFLT1]]({{.+}})
+// CK2: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTLT1:.+]] to {{.+}},
+// CK2: ret void
+
+// CK2: define internal void @[[OUTLT1]]({{.+}})
+// discard loop variables not needed here
+// CK2: [[OMP_UB:%.omp.ub]] = alloca i32,
+// CK2: store i32 {{.+}}, i32* [[OMP_UB]],
+// CK2: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 92, {{.+}}, {{.+}}, i32* [[OMP_UB]],
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+#endif // CK2
+#endif // #ifndef HEADER
diff --git a/test/OpenMP/target_teams_distribute_depend_messages.cpp b/test/OpenMP/target_teams_distribute_depend_messages.cpp
index b3e733141070..fbdd49590f87 100644
--- a/test/OpenMP/target_teams_distribute_depend_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_depend_messages.cpp
@@ -37,21 +37,21 @@ int main(int argc, char **argv, char *env[]) {
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute depend (out: ) // expected-error {{expected expression}}
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute depend (inout : foobool(argc)), depend (in, argc) // expected-error {{expected variable name, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}}
+#pragma omp target teams distribute depend (inout : foobool(argc)), depend (in, argc) // expected-error {{expected addressable lvalue expression, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}}
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute depend (out :S1) // expected-error {{'S1' does not refer to a value}}
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute depend(in : argv[1][1] = '2') // expected-error {{expected variable name, array element or array section}}
+#pragma omp target teams distribute depend(in : argv[1][1] = '2')
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute depend (in : vec[1]) // expected-error {{expected variable name, array element or array section}}
+#pragma omp target teams distribute depend (in : vec[1]) // expected-error {{expected addressable lvalue expression, array element or array section}}
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute depend (in : argv[0])
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute depend (in : ) // expected-error {{expected expression}}
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute depend (in : main) // expected-error {{expected variable name, array element or array section}}
+#pragma omp target teams distribute depend (in : main)
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute depend(in : a[0]) // expected-error{{expected variable name, array element or array section}}
+#pragma omp target teams distribute depend(in : a[0]) // expected-error{{expected addressable lvalue expression, array element or array section}}
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute depend (in : vec[1:2]) // expected-error {{ value is not an array or pointer}}
for (i = 0; i < argc; ++i) foo();
diff --git a/test/OpenMP/target_teams_distribute_dist_schedule_codegen.cpp b/test/OpenMP/target_teams_distribute_dist_schedule_codegen.cpp
new file mode 100644
index 000000000000..0c9b2387debf
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_dist_schedule_codegen.cpp
@@ -0,0 +1,197 @@
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+// Test host codegen.
+// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64
+// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32
+#ifdef CK1
+
+template <typename T, int X, long long Y>
+struct SS{
+ T a[X];
+ float b;
+ // CK1: define {{.*}}i32 @{{.+}}foo{{.+}}(
+ int foo(void) {
+
+ // CK1: call i32 @__tgt_target_teams(
+ // CK1: call void @[[OFFL1:.+]](
+ #pragma omp target teams distribute
+ for(int i = 0; i < X; i++) {
+ a[i] = (T)0;
+ }
+ // CK1: call i32 @__tgt_target_teams(
+ // CK1: call void @[[OFFL2:.+]](
+ #pragma omp target teams distribute dist_schedule(static)
+ for(int i = 0; i < X; i++) {
+ a[i] = (T)0;
+ }
+ // CK1: call i32 @__tgt_target_teams(
+ // CK1: call void @[[OFFL3:.+]](
+ #pragma omp target teams distribute dist_schedule(static, X/2)
+ for(int i = 0; i < X; i++) {
+ a[i] = (T)0;
+ }
+ // CK1: define internal void @[[OFFL1]](
+ // CK1: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTL1:.+]] to {{.+}},
+ // CK1: ret void
+
+ // CK1: define internal void @[[OUTL1]]({{.+}})
+ // CK1: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 92
+ // CK1: call void @__kmpc_for_static_fini(
+ // CK1: ret void
+
+ // CK1: define internal void @[[OFFL2]](
+ // CK1: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTL2:.+]] to {{.+}},
+ // CK1: ret void
+
+ // CK1: define internal void @[[OUTL2]]({{.+}})
+ // CK1: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 92
+ // CK1: call void @__kmpc_for_static_fini(
+ // CK1: ret void
+
+ // CK1: define internal void @[[OFFL3]](
+ // CK1: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTL3:.+]] to {{.+}},
+ // CK1: ret void
+
+ // CK1: define internal void @[[OUTL3]]({{.+}})
+ // CK1: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 91
+ // CK1: call void @__kmpc_for_static_fini(
+ // CK1: ret void
+
+ return a[0];
+ }
+};
+
+int teams_template_struct(void) {
+ SS<int, 123, 456> V;
+ return V.foo();
+
+}
+#endif // CK1
+
+// Test host codegen.
+// RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64
+// RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32
+#ifdef CK2
+
+template <typename T, int n>
+int tmain(T argc) {
+ T a[n];
+#pragma omp target teams distribute
+ for(int i = 0; i < n; i++) {
+ a[i] = (T)0;
+ }
+#pragma omp target teams distribute dist_schedule(static)
+ for(int i = 0; i < n; i++) {
+ a[i] = (T)0;
+ }
+#pragma omp target teams distribute dist_schedule(static, n)
+ for(int i = 0; i < n; i++) {
+ a[i] = (T)0;
+ }
+ return 0;
+}
+
+int main (int argc, char **argv) {
+ int n = 100;
+ int a[n];
+#pragma omp target teams distribute
+ for(int i = 0; i < n; i++) {
+ a[i] = 0;
+ }
+#pragma omp target teams distribute dist_schedule(static)
+ for(int i = 0; i < n; i++) {
+ a[i] = 0;
+ }
+#pragma omp target teams distribute dist_schedule(static, n)
+ for(int i = 0; i < n; i++) {
+ a[i] = 0;
+ }
+ return tmain<int, 10>(argc);
+}
+
+// CK2: define {{.*}}i32 @{{[^,]+}}(i{{.+}}{{.+}} %[[ARGC:.+]], {{.+}})
+// CK2: call i32 @__tgt_target_teams(
+// CK2: call void @[[OFFL1:.+]]({{.+}})
+// CK2: call i32 @__tgt_target_teams(
+// CK2: call void @[[OFFL2:.+]]({{.+}})
+// CK2: call i32 @__tgt_target_teams(
+// CK2: call void @[[OFFL3:.+]]({{.+}})
+// CK2: {{%.+}} = call{{.*}} i32 @[[TMAIN:.+]]({{.+}})
+// CK2: ret
+
+// CK2: define {{.*}}void @[[OFFL1]]({{.+}})
+// CK2: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 3, {{.+}} @[[OUTL1:.+]] to {{.+}},
+// CK2: ret void
+
+// CK2: define internal void @[[OUTL1]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 92
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define {{.*}}void @[[OFFL2]]({{.+}})
+// CK2: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 3, {{.+}} @[[OUTL2:.+]] to {{.+}},
+// CK2: ret void
+
+// CK2: define internal void @[[OUTL2]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 92
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define {{.*}}void @[[OFFL3]]({{.+}})
+// CK2: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 4, {{.+}} @[[OUTL3:.+]] to {{.+}},
+// CK2: ret void
+
+// CK2: define internal void @[[OUTL3]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 91
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define {{.*}}i32 @[[TMAIN]]({{.+}})
+// CK2: call i32 @__tgt_target_teams(
+// CK2: call void @[[OFFLT1:.+]]({{.+}})
+// CK2: call i32 @__tgt_target_teams(
+// CK2: call void @[[OFFLT2:.+]]({{.+}})
+// CK2: call i32 @__tgt_target_teams(
+// CK2: call void @[[OFFLT3:.+]]({{.+}})
+// CK2: ret
+// CK2-NEXT: }
+
+// CK2: define {{.*}}void @[[OFFLT1]]({{.+}})
+// CK2: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTLT1:.+]] to {{.+}},
+// CK2: ret void
+
+// CK2: define internal void @[[OUTLT1]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 92
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define {{.*}}void @[[OFFLT2]]({{.+}})
+// CK2: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTLT2:.+]] to {{.+}},
+// CK2: ret void
+
+// CK2: define internal void @[[OUTLT2]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 92
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define {{.*}}void @[[OFFLT3]]({{.+}})
+// CK2: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTLT3:.+]] to {{.+}},
+// CK2: ret void
+
+// CK2: define internal void @[[OUTLT3]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 91
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+#endif // CK2
+#endif // #ifndef HEADER
diff --git a/test/OpenMP/target_teams_distribute_firstprivate_codegen.cpp b/test/OpenMP/target_teams_distribute_firstprivate_codegen.cpp
new file mode 100644
index 000000000000..35abffa92600
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_firstprivate_codegen.cpp
@@ -0,0 +1,342 @@
+// RUN: %clang_cc1 -DCHECK -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -DCHECK -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+
+// RUN: %clang_cc1 -DLAMBDA -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+struct St {
+ int a, b;
+ St() : a(0), b(0) {}
+ St(const St &st) : a(st.a + st.b), b(0) {}
+ ~St() {}
+};
+
+volatile int g = 1212;
+volatile int &g1 = g;
+
+template <class T>
+struct S {
+ T f;
+ S(T a) : f(a + g) {}
+ S() : f(g) {}
+ S(const S &s, St t = St()) : f(s.f + t.a) {}
+ operator T() { return T(); }
+ ~S() {}
+};
+
+// CHECK-DAG: [[S_FLOAT_TY:%.+]] = type { float }
+// CHECK-DAG: [[S_INT_TY:%.+]] = type { i{{[0-9]+}} }
+// CHECK-DAG: [[ST_TY:%.+]] = type { i{{[0-9]+}}, i{{[0-9]+}} }
+
+template <typename T>
+T tmain() {
+ S<T> test;
+ T t_var = T();
+ T vec[] = {1, 2};
+ S<T> s_arr[] = {1, 2};
+ S<T> &var = test;
+#pragma omp target teams distribute firstprivate(t_var, vec, s_arr, var)
+ for (int i = 0; i < 2; ++i) {
+ vec[i] = t_var;
+ s_arr[i] = var;
+ }
+ return T();
+}
+
+// CHECK-DAG: [[TEST:@.+]] = global [[S_FLOAT_TY]] zeroinitializer,
+S<float> test;
+// CHECK-DAG: [[T_VAR:@.+]] = global i{{[0-9]+}} 333,
+int t_var = 333;
+// CHECK-DAG: [[VEC:@.+]] = global [2 x i{{[0-9]+}}] [i{{[0-9]+}} 1, i{{[0-9]+}} 2],
+int vec[] = {1, 2};
+// CHECK-DAG: [[S_ARR:@.+]] = global [2 x [[S_FLOAT_TY]]] zeroinitializer,
+S<float> s_arr[] = {1, 2};
+// CHECK-DAG: [[VAR:@.+]] = global [[S_FLOAT_TY]] zeroinitializer,
+S<float> var(3);
+// CHECK-DAG: [[SIVAR:@.+]] = internal global i{{[0-9]+}} 0,
+
+int main() {
+ static int sivar;
+#ifdef LAMBDA
+ // LAMBDA: [[G:@.+]] = global i{{[0-9]+}} 1212,
+ // LAMBDA-LABEL: @main
+ // LAMBDA: call void [[OUTER_LAMBDA:@.+]](
+ [&]() {
+ // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
+ // LAMBDA: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 3, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 0)
+ // LAMBDA: call void @[[LOFFL1:.+]](i{{64|32}} %{{.+}})
+ // LAMBDA: ret
+#pragma omp target teams distribute firstprivate(g, g1, sivar)
+ for (int i = 0; i < 2; ++i) {
+ // LAMBDA: define{{.*}} internal{{.*}} void @[[LOFFL1]](i{{64|32}} {{%.+}}, i{{64|32}} {{%.+}})
+ // LAMBDA: {{%.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: {{%.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: {{%.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: [[G_CAST:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[G1_CAST:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[SIVAR_CAST:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA-DAG: [[G_CAST_VAL:%.+]] = load{{.+}} [[G_CAST]],
+ // LAMBDA-DAG: [[G1_CAST_VAL:%.+]] = load{{.+}} [[G1_CAST]],
+ // LAMBDA-DAG: [[SIVAR_CAST_VAL:%.+]] = load{{.+}} [[SIVAR_CAST]],
+ // LAMBDA: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 3, {{.+}} @[[LOUTL1:.+]] to {{.+}}, {{.+}} [[G_CAST_VAL]], {{.+}} [[G1_CAST_VAL]], {{.+}} [[SIVAR_CAST_VAL]])
+ // LAMBDA: ret void
+
+ // LAMBDA: define internal void @[[LOUTL1]]({{.+}})
+ // Skip global and bound tid vars
+ // LAMBDA: {{.+}} = alloca i32*,
+ // LAMBDA: {{.+}} = alloca i32*,
+ // LAMBDA: [[G_ADDR:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[G1_ADDR:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[SIVAR_ADDR:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: {{%.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: {{%.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: {{%.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: {{%.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: {{%.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: {{%.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: [[G_PRIV_ADDR:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[G1_PRIV_ADDR:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[G1_TMP:%.+]] = alloca i32*,
+ // LAMBDA: [[SIVAR_PRIV_ADDR:%.+]] = alloca i{{[0-9]+}},
+ // skip loop vars
+ // LAMBDA-DAG: store {{.+}}, {{.+}} [[G_ADDR]],
+ // LAMBDA-DAG: store {{.+}}, {{.+}} [[G1_ADDR]],
+ // LAMBDA-DAG: store {{.+}}, {{.+}} [[SIVAR_ADDR]],
+ // LAMBDA-DAG: [[G_CONV:%.+]] = bitcast {{.+}} [[G_ADDR]] to
+ // LAMBDA-DAG: [[G1_CONV:%.+]] = bitcast {{.+}} [[G1_ADDR]] to
+ // LAMBDA-DAG: [[SIVAR_CONV:%.+]] = bitcast {{.+}} [[SIVAR_ADDR]] to
+ // LAMBDA-DAG: store{{.+}} [[G1_PRIV_ADDR]], {{.+}} [[G1_TMP]],
+ g = 1;
+ g1 = 1;
+ sivar = 2;
+ // LAMBDA: call void @__kmpc_for_static_init_4(
+ // LAMBDA-DAG: store{{.+}} 1, {{.+}} [[G_PRIV_ADDR]],
+ // LAMBDA-DAG: [[G1:%.+]] = load{{.+}}, {{.+}}* [[G1_TMP]]
+ // LAMBDA-DAG: store{{.+}} 1, {{.+}} [[G1]],
+ // LAMBDA-DAG: store{{.+}} 2, {{.+}} [[SIVAR_PRIV_ADDR]],
+ // LAMBDA-DAG: [[G1_REF:%.+]] = load{{.+}}, {{.+}} [[G1_TMP]],
+ // LAMBDA-DAG: store{{.+}} 1, {{.+}} [[G1_REF]],
+ // LAMBDA: call void [[INNER_LAMBDA:@.+]](
+ // LAMBDA: call void @__kmpc_for_static_fini(
+ [&]() {
+ // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]])
+ // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]],
+ g = 2;
+ g1 = 2;
+ sivar = 4;
+ // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]]
+
+ // LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // LAMBDA: [[G_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G_PTR_REF]]
+ // LAMBDA: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[G_REF]]
+ // LAMBDA: [[G1_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // LAMBDA: [[G1_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G1_PTR_REF]]
+ // LAMBDA: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[G1_REF]]
+ // LAMBDA: [[SIVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+ // LAMBDA: [[SIVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SIVAR_PTR_REF]]
+ // LAMBDA: store i{{[0-9]+}} 4, i{{[0-9]+}}* [[SIVAR_REF]]
+ }();
+ }
+ }();
+ return 0;
+#else
+#pragma omp target teams distribute firstprivate(t_var, vec, s_arr, var, sivar)
+ for (int i = 0; i < 2; ++i) {
+ vec[i] = t_var;
+ s_arr[i] = var;
+ sivar += i;
+ }
+ return tmain<int>();
+#endif
+}
+
+// CHECK: define {{.*}}i{{[0-9]+}} @main()
+// CHECK: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 5, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 0)
+// CHECK: call void @[[OFFL1:.+]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}})
+// CHECK: {{%.+}} = call{{.*}} i32 @[[TMAIN_INT:.+]]()
+// CHECK: ret
+
+// CHECK: define{{.*}} void @[[OFFL1]]({{.+}})
+// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}]*,
+// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]]*,
+// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]]*,
+// CHECK: [[SIVAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[T_VAR_CAST:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[SIVAR_CAST:%.+]] = alloca i{{[0-9]+}},
+
+// CHECK-DAG: [[VEC_TE_PAR:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** [[VEC_PRIV]],
+// CHECK-DAG: [[T_VAR_TE_PAR:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_CAST]],
+// CHECK-DAG: [[S_ARR_TE_PAR:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[S_ARR_PRIV]],
+// CHECK-DAG: [[VAR_TE_PAR:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[VAR_PRIV]],
+// CHECK-DAG: [[SIVAR_TE_PAR:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR_CAST]],
+
+// CHECK: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 5, {{.+}} @[[OUTL1:.+]] to {{.+}}, [2 x i{{[0-9]+}}]* [[VEC_TE_PAR]], i{{[0-9]+}} [[T_VAR_TE_PAR]], [2 x [[S_FLOAT_TY]]]* [[S_ARR_TE_PAR]], [[S_FLOAT_TY]]* [[VAR_TE_PAR]], i{{[0-9]+}} [[SIVAR_TE_PAR]])
+// CHECK: ret void
+
+// CHECK: define internal void @[[OUTL1]]({{.+}})
+// Skip global and bound tid vars
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: [[VEC_ADDR:%.+]] = alloca [2 x i{{[0-9]+}}]*,
+// CHECK: [[T_VAR_ADDR:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[S_ARR_ADDR:%.+]] = alloca [2 x [[S_FLOAT_TY]]]*,
+// CHECK: [[VAR_ADDR:%.+]] = alloca [[S_FLOAT_TY]]*,
+// CHECK: [[SIVAR_ADDR:%.+]] = alloca i{{[0-9]+}},
+// Skip temp vars for loop
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]],
+// CHECK: [[AGG_TMP1:%.+]] = alloca [[ST_TY]],
+// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]],
+// CHECK: [[AGG_TMP2:%.+]] = alloca [[ST_TY]],
+
+// param copy
+// CHECK: store [2 x i{{[0-9]+}}]* {{.+}}, [2 x i{{[0-9]+}}]** [[VEC_ADDR]],
+// CHECK: store i{{[0-9]+}} {{.+}}, i{{[0-9]+}}* [[T_VAR_ADDR]],
+// CHECK: store [2 x [[S_FLOAT_TY]]]* {{.+}}, [2 x [[S_FLOAT_TY]]]** [[S_ARR_ADDR]],
+// CHECK: store [[S_FLOAT_TY]]* {{.+}}, [[S_FLOAT_TY]]** [[VAR_ADDR]],
+// CHECK: store i{{[0-9]+}} {{.+}}, i{{[0-9]+}}* [[SIVAR_ADDR]],
+
+// T_VAR and SIVAR
+// CHECK-DAG-64: [[CONV_TVAR:%.+]] = bitcast i64* [[T_VAR_ADDR]] to i32*
+// CHECK-DAG-64: [[CONV_SIVAR:%.+]] = bitcast i64* [[SIVAR_ADDR]] to i32*
+
+// preparation vars
+// CHECK-DAG: [[VEC_ADDR_VAL:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** [[VEC_ADDR]],
+// CHECK-DAG: [[S_ARR_ADDR_REF:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[S_ARR_ADDR]],
+// CHECK-DAG: [[VAR_ADDR_REF:%.+]] = load{{.+}} [[VAR_ADDR]],
+
+// firstprivate vec(vec): copy from *_addr into priv1 and then from priv1 into priv2
+// CHECK-DAG: [[VEC_DEST_PRIV:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV]] to i8*
+// CHECK-DAG: [[VEC_SRC:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_ADDR_VAL]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[VEC_DEST_PRIV]], i8* [[VEC_SRC]], {{.+}})
+
+// firstprivate(s_arr)
+// CHECK-DAG: [[S_ARR_PRIV_BGN:%.+]] = getelementptr{{.*}} [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[S_ARR_PRIV]],
+// CHECK-DAG: [[S_ARR_ADDR_BGN:%.+]] = bitcast [2 x [[S_FLOAT_TY]]]* [[S_ARR_ADDR_REF]] to
+// CHECK-DAG: [[S_ARR_FIN:%.+]] = icmp{{.+}} [[S_ARR_PRIV_BGN]],
+// CHECK-DAG: [[S_ARR_SRC_COPY:%.+]] = phi{{.+}} [ [[S_ARR_ADDR_BGN]], {{.+}} ], [ [[S_ARR_SRC:%.+]], {{.+}} ]
+// CHECK-DAG: [[S_ARR_DST_COPY:%.+]] = phi{{.+}} [ [[S_ARR_PRIV_BGN]], {{.+}}], [ [[S_ARR_DST:%.+]], {{.+}} ]
+// CHECK-DAG: call void @{{.+}}({{.+}} [[AGG_TMP1]])
+// CHECK-DAG: call void @{{.+}}({{.+}} [[S_ARR_DST_COPY]], {{.+}} [[S_ARR_SRC_COPY]], {{.+}} [[AGG_TMP1]])
+// CHECK-DAG: call void @{{.+}}({{.+}} [[AGG_TMP1]])
+// CHECK-DAG: [[S_ARR_DST]] = getelementptr {{.+}} [[S_ARR_DST_COPY]],
+// CHECK-DAG: [[S_ARR_SRC]] = getelementptr {{.+}} [[S_ARR_SRC_COPY]],
+
+// firstprivate(var)
+// CHECK-DAG: call void @{{.+}}({{.+}} [[AGG_TMP2]])
+// CHECK-DAG: call void @{{.+}}({{.+}} [[VAR_PRIV]], {{.+}} [[VAR_ADDR_REF]], {{.+}} [[AGG_TMP2]])
+// CHECK-DAG: call void @{{.+}}({{.+}} [[AGG_TMP2]])
+
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK-DAG-32: {{.+}} = {{.+}} [[T_VAR_ADDR]]
+// CHECK-DAG-64: {{.+}} = {{.+}} [[CONV_TVAR]]
+// CHECK-DAG: {{.+}} = {{.+}} [[VEC_PRIV]]
+// CHECK-DAG: {{.+}} = {{.+}} [[S_ARR_PRIV]]
+// CHECK-DAG: {{.+}} = {{.+}} [[VAR_PRIV]]
+// CHECK-DAG-32: {{.+}} = {{.+}} [[SIVAR_ADDR]]
+// CHECK-DAG-64: {{.+}} = {{.+}} [[CONV_SIVAR]]
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: ret void
+
+// CHECK: define{{.*}} i{{[0-9]+}} @[[TMAIN_INT]]()
+// CHECK: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 4, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 0)
+// CHECK: call void @[[TOFFL1:.+]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}})
+// CHECK: ret
+
+// CHECK: define {{.*}}void @[[TOFFL1]]({{.+}})
+// CHECK: [[TVEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}]*,
+// CHECK: [[TT_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[TS_ARR_PRIV:%.+]] = alloca [2 x [[S_INT_TY]]]*,
+// CHECK: [[TVAR_PRIV:%.+]] = alloca [[S_INT_TY]]*,
+// CHECK: [[TT_VAR_CAST:%.+]] = alloca i{{[0-9]+}},
+
+// CHECK-DAG: [[TVEC_TE_PAR:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** [[TVEC_PRIV]],
+// CHECK-DAG: [[TT_VAR_TE_PAR:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[TT_VAR_CAST]],
+// CHECK-DAG: [[TS_ARR_TE_PAR:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** [[TS_ARR_PRIV]],
+// CHECK-DAG: [[TVAR_TE_PAR:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[TVAR_PRIV]],
+
+// CHECK: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 4, {{.+}} @[[TOUTL1:.+]] to {{.+}}, [2 x i{{[0-9]+}}]* [[TVEC_TE_PAR]], i{{[0-9]+}} [[TT_VAR_TE_PAR]], [2 x [[S_INT_TY]]]* [[TS_ARR_TE_PAR]], [[S_INT_TY]]* [[TVAR_TE_PAR]])
+// CHECK: ret void
+
+// CHECK: define internal void @[[TOUTL1]]({{.+}})
+// Skip global and bound tid vars
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: [[VEC_ADDR:%.+]] = alloca [2 x i{{[0-9]+}}]*,
+// CHECK: [[T_VAR_ADDR:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[S_ARR_ADDR:%.+]] = alloca [2 x [[S_INT_TY]]]*,
+// CHECK: [[VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*,
+// Skip temp vars for loop
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_INT_TY]]],
+// CHECK: [[AGG_TMP1:%.+]] = alloca [[ST_TY]],
+// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_INT_TY]],
+// CHECK: [[AGG_TMP2:%.+]] = alloca [[ST_TY]],
+// CHECK: [[TMP:%.+]] = alloca [[S_INT_TY]]*,
+
+// param copy
+// CHECK: store [2 x i{{[0-9]+}}]* {{.+}}, [2 x i{{[0-9]+}}]** [[VEC_ADDR]],
+// CHECK: store i{{[0-9]+}} {{.+}}, i{{[0-9]+}}* [[T_VAR_ADDR]],
+// CHECK: store [2 x [[S_INT_TY]]]* {{.+}}, [2 x [[S_INT_TY]]]** [[S_ARR_ADDR]],
+// CHECK: store [[S_INT_TY]]* {{.+}}, [[S_INT_TY]]** [[VAR_ADDR]],
+
+
+// T_VAR and preparation variables
+// CHECK: [[VEC_ADDR_VAL:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** [[VEC_ADDR]],
+// CHECK-64: [[CONV_TVAR:%.+]] = bitcast i64* [[T_VAR_ADDR]] to i32*
+// CHECK: [[S_ARR_ADDR_REF:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** [[S_ARR_ADDR]],
+
+// firstprivate vec(vec): copy from *_addr into priv1 and then from priv1 into priv2
+// CHECK-DAG: [[VEC_DEST_PRIV:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV]] to i8*
+// CHECK-DAG: [[VEC_SRC:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_ADDR_VAL]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[VEC_DEST_PRIV]], i8* [[VEC_SRC]], {{.+}})
+
+// firstprivate(s_arr)
+// CHECK-DAG: [[S_ARR_PRIV_BGN:%.+]] = getelementptr{{.*}} [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[S_ARR_PRIV]],
+// CHECK-DAG: [[S_ARR_ADDR_BGN:%.+]] = bitcast [2 x [[S_INT_TY]]]* [[S_ARR_ADDR_REF]] to
+// CHECK-DAG: [[S_ARR_FIN:%.+]] = icmp{{.+}} [[S_ARR_PRIV_BGN]],
+// CHECK-DAG: [[S_ARR_SRC_COPY:%.+]] = phi{{.+}} [ [[S_ARR_ADDR_BGN]], {{.+}} ], [ [[S_ARR_SRC:%.+]], {{.+}} ]
+// CHECK-DAG: [[S_ARR_DST_COPY:%.+]] = phi{{.+}} [ [[S_ARR_PRIV_BGN]], {{.+}} ], [ [[S_ARR_DST:%.+]], {{.+}} ]
+// CHECK-DAG: call void @{{.+}}({{.+}} [[AGG_TMP1]])
+// CHECK-DAG: call void @{{.+}}({{.+}} [[S_ARR_DST_COPY]], {{.+}} [[S_ARR_SRC_COPY]], {{.+}} [[AGG_TMP1]])
+// CHECK-DAG: call void @{{.+}}({{.+}} [[AGG_TMP1]])
+// CHECK-DAG: [[S_ARR_DST]] = getelementptr {{.+}} [[S_ARR_DST_COPY]],
+// CHECK-DAG: [[S_ARR_SRC]] = getelementptr {{.+}} [[S_ARR_SRC_COPY]],
+
+// firstprivate(var)
+// CHECK-DAG: [[VAR_ADDR_REF:%.+]] = load{{.+}} [[VAR_ADDR]],
+// CHECK-DAG: call void @{{.+}}({{.+}} [[AGG_TMP2]])
+// CHECK-DAG: call void @{{.+}}({{.+}} [[VAR_PRIV]], {{.+}} [[VAR_ADDR_REF]], {{.+}} [[AGG_TMP2]])
+// CHECK-DAG: call void @{{.+}}({{.+}} [[AGG_TMP2]])
+// CHECK-DAG: store [[S_INT_TY]]* [[VAR_PRIV]], [[S_INT_TY]]** [[TMP]],
+
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK-DAG-32: {{.+}} = {{.+}} [[T_VAR_ADDR]]
+// CHECK-DAG-64: {{.+}} = {{.+}} [[CONV_TVAR]]
+// CHECK-DAG: {{.+}} = {{.+}} [[VEC_PRIV]]
+// CHECK-DAG: {{.+}} = {{.+}} [[TMP]]
+// CHECK-DAG: {{.+}} = {{.+}} [[S_ARR_PRIV]]
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: ret void
+
+#endif
diff --git a/test/OpenMP/target_teams_distribute_firstprivate_messages.cpp b/test/OpenMP/target_teams_distribute_firstprivate_messages.cpp
index 602e039802d1..934149e7c139 100644
--- a/test/OpenMP/target_teams_distribute_firstprivate_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_firstprivate_messages.cpp
@@ -125,7 +125,8 @@ int main(int argc, char **argv) {
#pragma omp target teams distribute firstprivate(j)
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute lastprivate(argc), firstprivate(argc) // OK
+// expected-error@+1 {{lastprivate variable cannot be firstprivate}} expected-note@+1 {{defined as lastprivate}}
+#pragma omp target teams distribute lastprivate(argc), firstprivate(argc)
for (i = 0; i < argc; ++i) foo();
return 0;
diff --git a/test/OpenMP/target_teams_distribute_lastprivate_codegen.cpp b/test/OpenMP/target_teams_distribute_lastprivate_codegen.cpp
new file mode 100644
index 000000000000..b41a6016079b
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_lastprivate_codegen.cpp
@@ -0,0 +1,384 @@
+// RUN: %clang_cc1 -DLAMBDA -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+// RUN: %clang_cc1 -DLAMBDA -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-32
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-32
+
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+template <class T>
+struct S {
+ T f;
+ S(T a) : f(a) {}
+ S() : f() {}
+ operator T() { return T(); }
+ ~S() {}
+};
+
+// CHECK: [[S_FLOAT_TY:%.+]] = type { float }
+// CHECK: [[S_INT_TY:%.+]] = type { i{{[0-9]+}} }
+template <typename T>
+T tmain() {
+ S<T> test;
+ T t_var = T();
+ T vec[] = {1, 2};
+ S<T> s_arr[] = {1, 2};
+ S<T> &var = test;
+ #pragma omp target teams distribute lastprivate(t_var, vec, s_arr, s_arr, var, var)
+ for (int i = 0; i < 2; ++i) {
+ vec[i] = t_var;
+ s_arr[i] = var;
+ }
+ return T();
+}
+
+int main() {
+ static int svar;
+ volatile double g;
+ volatile double &g1 = g;
+
+ #ifdef LAMBDA
+ // LAMBDA-LABEL: @main
+ // LAMBDA: call{{.*}} void [[OUTER_LAMBDA:@.+]](
+ [&]() {
+ static float sfvar;
+ // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
+ // LAMBDA: call i{{[0-9]+}} @__tgt_target_teams(
+ // LAMBDA: call void [[OFFLOADING_FUN:@.+]](
+
+ // LAMBDA: define{{.+}} void [[OFFLOADING_FUN]](
+ // LAMBDA: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, i32 4, {{.+}}* [[OMP_OUTLINED:@.+]] to {{.+}})
+ #pragma omp target teams distribute lastprivate(g, g1, svar, sfvar)
+ for (int i = 0; i < 2; ++i) {
+ // LAMBDA-64: define{{.*}} internal{{.*}} void [[OMP_OUTLINED]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, i64 [[G_IN:%.+]], i64 [[G1_IN:%.+]], i64 [[SVAR_IN:%.+]], i64 [[SFVAR_IN:%.+]])
+ // LAMBDA-32: define{{.*}} internal{{.*}} void [[OMP_OUTLINED]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, double*{{.+}} [[G_IN:%.+]], double*{{.+}} [[G1_IN:%.+]], i32 [[SVAR_IN:%.+]], i32 [[SFVAR_IN:%.+]])
+ // LAMBDA-64: [[G_PRIVATE_ADDR:%.+]] = alloca i64,
+ // LAMBDA-32: [[G_PRIVATE_ADDR:%.+]] = alloca double*,
+ // LAMBDA-64: [[G1_PRIVATE_ADDR:%.+]] = alloca i64,
+ // LAMBDA-32: [[G1_PRIVATE_ADDR:%.+]] = alloca double*,
+ // LAMBDA-64: [[SVAR_PRIVATE_ADDR:%.+]] = alloca i64,
+ // LAMBDA-32: [[SVAR_PRIVATE_ADDR:%.+]] = alloca i32,
+ // LAMBDA-64: [[SFVAR_PRIVATE_ADDR:%.+]] = alloca i64,
+ // LAMBDA-32: [[SFVAR_PRIVATE_ADDR:%.+]] = alloca i32,
+ // loop variables
+ // LAMBDA: {{.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: {{.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: {{.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: {{.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: {{.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: [[OMP_IS_LAST:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[G_PRIVATE:%.+]] = alloca double,
+ // LAMBDA: [[G1_PRIVATE:%.+]] = alloca double,
+ // LAMBDA: [[TMP_G1_PRIVATE:%.+]] = alloca double*,
+ // LAMBDA: [[SVAR_PRIVATE:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[SFVAR_PRIVATE:%.+]] = alloca float,
+ // LAMBDA-64: store i64 [[G_IN]], i64* [[G_PRIVATE_ADDR]],
+ // LAMBDA-32: store double* [[G_IN]], double** [[G_PRIVATE_ADDR]],
+ // LAMBDA-64: store i64 [[G1_IN]], i64* [[G1_PRIVATE_ADDR]],
+ // LAMBDA-32: store double* [[G1_IN]], double** [[G1_PRIVATE_ADDR]],
+ // LAMBDA-64: store i64 [[SVAR_IN]], i64* [[SVAR_PRIVATE_ADDR]],
+ // LAMBDA-32: store i32 [[SVAR_IN]], i32* [[SVAR_PRIVATE_ADDR]],
+ // LAMBDA-64: store i64 [[SFVAR_IN]], i64* [[SFVAR_PRIVATE_ADDR]],
+ // LAMBDA-32: store i32 [[SFVAR_IN]], i32* [[SFVAR_PRIVATE_ADDR]],
+
+ // init private variables
+ // LAMBDA-64: [[G_IN_REF:%.+]] = bitcast i64* [[G_PRIVATE_ADDR]] to double*
+ // LAMBDA-32: [[G_IN_REF:%.+]] = load double*, double** [[G_PRIVATE_ADDR]],
+ // LAMBDA-64: [[G1_IN_REF:%.+]] = bitcast i64* [[G1_PRIVATE_ADDR]] to double*
+ // LAMBDA-64: store double* [[G1_IN_REF]], double** [[G1_IN_ADDR_REF:%.+]],
+ // LAMBDA-64: [[SVAR_IN_REF:%.+]] = bitcast i64* [[SVAR_PRIVATE_ADDR]] to i32*
+ // LAMBDA-64: [[SFVAR_IN_REF:%.+]] = bitcast i64* [[SFVAR_PRIVATE_ADDR]] to float*
+ // LAMBDA-32: [[SFVAR_IN_REF:%.+]] = bitcast i32* [[SFVAR_PRIVATE_ADDR]] to float*
+ // LAMBDA-64: [[G1_IN_REF:%.+]] = load double*, double** [[G1_IN_ADDR_REF]],
+ // LAMBDA-32: [[G1_IN_REF:%.+]] = load double*, double** [[G1_PRIVATE_ADDR]],
+ // LAMBDA: store double* [[G1_PRIVATE]], double** [[TMP_G1_PRIVATE]],
+ g = 1;
+ g1 = 1;
+ svar = 3;
+ sfvar = 4.0;
+ // LAMBDA: call {{.*}}void @__kmpc_for_static_init_4(
+ // LAMBDA: store double 1.0{{.+}}, double* [[G_PRIVATE]],
+ // LAMBDA: [[TMP_G1_REF:%.+]] = load double*, double** [[TMP_G1_PRIVATE]],
+ // LAMBDA: store{{.+}} double 1.0{{.+}}, double* [[TMP_G1_REF]],
+ // LAMBDA: store i{{[0-9]+}} 3, i{{[0-9]+}}* [[SVAR_PRIVATE]],
+ // LAMBDA: store float 4.0{{.+}}, float* [[SFVAR_PRIVATE]],
+ // LAMBDA: [[G_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // LAMBDA: store double* [[G_PRIVATE]], double** [[G_PRIVATE_ADDR_REF]],
+ // LAMBDA: [[TMP_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // LAMBDA: [[G1_PRIVATE_ADDR_FROM_TMP:%.+]] = load double*, double** [[TMP_G1_PRIVATE]],
+ // LAMBDA: store double* [[G1_PRIVATE_ADDR_FROM_TMP]], double** [[TMP_PRIVATE_ADDR_REF]],
+ // LAMBDA: [[SVAR_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+ // LAMBDA: store i{{[0-9]+}}* [[SVAR_PRIVATE]], i{{[0-9]+}}** [[SVAR_PRIVATE_ADDR_REF]]
+ // LAMBDA: [[SFVAR_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 3
+ // LAMBDA: store float* [[SFVAR_PRIVATE]], float** [[SFVAR_PRIVATE_ADDR_REF]]
+ // LAMBDA: call{{.*}} void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]])
+ // LAMBDA: call {{.*}}void @__kmpc_for_static_fini(
+ // LAMBDA: [[OMP_IS_LAST_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[OMP_IS_LAST]],
+ // LAMBDA: [[IS_LAST_IT:%.+]] = icmp ne i{{[0-9]+}} [[OMP_IS_LAST_VAL]], 0
+ // LAMBDA: br i1 [[IS_LAST_IT]], label %[[OMP_LASTPRIV_BLOCK:.+]], label %[[OMP_LASTPRIV_DONE:.+]]
+
+ // LAMBDA: [[OMP_LASTPRIV_BLOCK]]:
+ // LAMBDA: [[G_PRIV_VAL:%.+]] = load double, double* [[G_PRIVATE]],
+ // LAMBDA: store{{.*}} double [[G_PRIV_VAL]], double* [[G_IN_REF]],
+ // LAMBDA: [[TMP_G1_PRIV_REF:%.+]] = load double*, double** [[TMP_G1_PRIVATE]],
+ // LAMBDA: [[TMP_G1_PRIV_VAL:%.+]] = load double, double* [[TMP_G1_PRIV_REF]],
+ // LAMBDA: store{{.*}} double [[TMP_G1_PRIV_VAL]], double* [[G1_IN_REF]],
+
+ // LAMBDA: [[SVAR_PRIV_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SVAR_PRIVATE]],
+ // LAMBDA-64: store i{{[0-9]+}} [[SVAR_PRIV_VAL]], i{{[0-9]+}}* [[SVAR_IN_REF]],
+ // LAMBDA-32: store i{{[0-9]+}} [[SVAR_PRIV_VAL]], i{{[0-9]+}}* [[SVAR_PRIVATE_ADDR]],
+ // LAMBDA: [[SFVAR_PRIV_VAL:%.+]] = load float, float* [[SFVAR_PRIVATE]],
+ // LAMBDA: store float [[SFVAR_PRIV_VAL]], float* [[SFVAR_IN_REF]],
+ // LAMBDA: br label %[[OMP_LASTPRIV_DONE]]
+ // LAMBDA: [[OMP_LASTPRIV_DONE]]:
+ // LAMBDA: ret
+ [&]() {
+ // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]])
+ // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]],
+ g = 2;
+ g1 = 2;
+ svar = 4;
+ sfvar = 8.0;
+ // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]]
+ // LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // LAMBDA: [[G_REF:%.+]] = load double*, double** [[G_PTR_REF]]
+ // LAMBDA: store double 2.0{{.+}}, double* [[G_REF]]
+
+ // LAMBDA: [[TMP_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // LAMBDA: [[G1_REF:%.+]] = load double*, double** [[TMP_PTR_REF]]
+ // LAMBDA: store double 2.0{{.+}}, double* [[G1_REF]],
+ // LAMBDA: [[SVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+ // LAMBDA: [[SVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SVAR_PTR_REF]]
+ // LAMBDA: store i{{[0-9]+}} 4, i{{[0-9]+}}* [[SVAR_REF]]
+ // LAMBDA: [[SFVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 3
+ // LAMBDA: [[SFVAR_REF:%.+]] = load float*, float** [[SFVAR_PTR_REF]]
+ // LAMBDA: store float 8.0{{.+}}, float* [[SFVAR_REF]]
+ }();
+ }
+ }();
+ return 0;
+ #else
+ S<float> test;
+ int t_var = 0;
+ int vec[] = {1, 2};
+ S<float> s_arr[] = {1, 2};
+ S<float> &var = test;
+
+ #pragma omp target teams distribute lastprivate(t_var, vec, s_arr, s_arr, var, var, svar)
+ for (int i = 0; i < 2; ++i) {
+ vec[i] = t_var;
+ s_arr[i] = var;
+ }
+ int i;
+
+ return tmain<int>();
+ #endif
+}
+
+// CHECK: define{{.*}} i{{[0-9]+}} @main()
+// CHECK: [[TEST:%.+]] = alloca [[S_FLOAT_TY]],
+// CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR:@.+]]([[S_FLOAT_TY]]* [[TEST]])
+// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+// CHECK: call void [[OFFLOAD_FUN:@.+]]([2 x i{{[0-9]+}}]* {{.+}}, i{{[0-9]+}} {{.+}}, [2 x [[S_FLOAT_TY]]]* {{.+}}, [[S_FLOAT_TY]]* {{.+}}, i{{[0-9]+}} {{.+}})
+// CHECK: ret
+
+// CHECK: define{{.+}} [[OFFLOAD_FUN]]([2 x i{{[0-9]+}}]*{{.+}} {{.+}}, i{{[0-9]+}} {{.+}}, [2 x [[S_FLOAT_TY]]]*{{.+}} {{.+}}, [[S_FLOAT_TY]]*{{.+}} {{.+}}, i{{[0-9]+}} {{.+}})
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_teams(
+// CHECK: ret
+//
+// CHECK: define internal void [[OMP_OUTLINED:@.+]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [2 x i{{[0-9]+}}]*{{.+}} [[VEC_IN:%.+]], i{{[0-9]+}} [[T_VAR_IN:%.+]], [2 x [[S_FLOAT_TY]]]*{{.+}} [[S_ARR_IN:%.+]], [[S_FLOAT_TY]]*{{.+}} [[VAR_IN:%.+]], i{{[0-9]+}} [[S_VAR_IN:%.+]])
+// CHECK: {{.+}} = alloca i{{[0-9]+}}*,
+// CHECK: {{.+}} = alloca i{{[0-9]+}}*,
+// CHECK: [[VEC_ADDR:%.+]] = alloca [2 x i{{[0-9]+}}]*,
+// CHECK: [[T_VAR_ADDR:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[S_ARR_ADDR:%.+]] = alloca [2 x [[S_FLOAT_TY]]]*,
+// CHECK: [[VAR_ADDR:%.+]] = alloca [[S_FLOAT_TY]]*,
+// CHECK: [[SVAR_ADDR:%.+]] = alloca i{{[0-9]+}},
+// skip loop variables
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: [[OMP_IS_LAST:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]],
+// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]],
+// CHECK: [[TMP_PRIV:%.+]] = alloca [[S_FLOAT_TY]]*,
+// CHECK: [[S_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+
+// copy from parameters to local address variables
+// CHECK: store [2 x i{{[0-9]+}}]* [[VEC_IN]], [2 x i{{[0-9]+}}]** [[VEC_ADDR]],
+// CHECK: store i{{[0-9]+}} [[T_VAR_IN]], i{{[0-9]+}}* [[T_VAR_ADDR]],
+// CHECK: store [2 x [[S_FLOAT_TY]]]* [[S_ARR_IN]], [2 x [[S_FLOAT_TY]]]** [[S_ARR_ADDR]],
+// CHECK: store [[S_FLOAT_TY]]* [[VAR_IN]], [[S_FLOAT_TY]]** [[VAR_ADDR]],
+// CHECK: store i{{[0-9]+}} [[S_VAR_IN]], i{{[0-9]+}}* [[SVAR_ADDR]],
+
+// load content of local address variables
+// CHECK: [[VEC_ADDR_REF:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** [[VEC_ADDR]],
+// CHECK-64: [[T_VAR_ADDR_REF:%.+]] = bitcast i64* [[T_VAR_ADDR]] to i32*
+// CHECK: [[S_ARR_ADDR_REF:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[S_ARR_ADDR]],
+// CHECK-64: [[SVAR_ADDR_REF:%.+]] = bitcast i64* [[SVAR_ADDR]] to i32*
+// CHECK: store i{{[0-9]+}} 0, i{{[0-9]+}}* [[OMP_IS_LAST]],
+// CHECK: [[VAR_ADDR_REF:%.+]] = load {{.+}}, {{.+}} [[VAR_ADDR]],
+// the distribute loop
+// CHECK: call void @__kmpc_for_static_init_4(
+// assignment: vec[i] = t_var;
+// CHECK: [[T_VAR_PRIV_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_PRIV]],
+// CHECK: [[VEC_PTR:%.+]] = getelementptr inbounds [2 x i{{[0-9]+}}], [2 x i{{[0-9]+}}]* [[VEC_PRIV]], i{{[0-9]+}} 0, i{{[0-9]+}} {{.+}}
+// CHECK: store i{{[0-9]+}} [[T_VAR_PRIV_VAL]], i{{[0-9]+}}* [[VEC_PTR]],
+
+// assignment: s_arr[i] = var;
+// CHECK-DAG: [[S_ARR_PTR:%.+]] = getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[S_ARR_PRIV]],
+// CHECK-DAG: [[TMP_VAL:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[TMP_PRIV]],
+// CHECK-DAG: [[S_ARR_PTR_BCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[S_ARR_PTR]] to i8*
+// CHECK-DAG: [[TMP_VAL_BCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[TMP_VAL]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[S_ARR_PTR_BCAST]], i8* [[TMP_VAL_BCAST]],
+// CHECK: call void @__kmpc_for_static_fini(
+
+// lastprivates
+// CHECK: [[OMP_IS_LAST_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[OMP_IS_LAST]],
+// CHECK: [[IS_LAST_IT:%.+]] = icmp ne i{{[0-9]+}} [[OMP_IS_LAST_VAL]], 0
+// CHECK: br i1 [[IS_LAST_IT]], label %[[OMP_LASTPRIV_BLOCK:.+]], label %[[OMP_LASTPRIV_DONE:.+]]
+
+// CHECK: [[OMP_LASTPRIV_BLOCK]]:
+// CHECK: [[T_VAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_PRIV]],
+// CHECK-64: store i{{[0-9]+}} [[T_VAR_VAL]], i{{[0-9]+}}* [[T_VAR_ADDR_REF]],
+// CHECK-32: store i{{[0-9]+}} [[T_VAR_VAL]], i{{[0-9]+}}* [[T_VAR_ADDR]],
+// CHECK: [[BCAST_VEC_ADDR_REF:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_ADDR_REF]] to i8*
+// CHECK: [[BCAST_VEC_PRIV:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[BCAST_VEC_ADDR_REF]], i8* [[BCAST_VEC_PRIV]],
+// CHECK: [[S_ARR_BEGIN:%.+]] = getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[S_ARR_ADDR_REF]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+// CHECK: [[S_ARR_PRIV_BCAST:%.+]] = bitcast [2 x [[S_FLOAT_TY]]]* [[S_ARR_PRIV]] to [[S_FLOAT_TY]]*
+// CHECK: [[S_ARR_BEGIN_GEP:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[S_ARR_BEGIN]], i{{[0-9]+}} 2
+// CHECK: [[S_ARR_IS_EMPTY:%.+]] = icmp eq [[S_FLOAT_TY]]* [[S_ARR_BEGIN]], [[S_ARR_BEGIN_GEP]]
+// CHECK: br i1 [[S_ARR_IS_EMPTY]], label %[[S_ARR_COPY_DONE:.+]], label %[[S_ARR_COPY_BLOCK:.+]]
+// CHECK: [[S_ARR_COPY_BLOCK]]:
+// CHECK: [[S_ARR_SRC_EL:%.+]] = phi [[S_FLOAT_TY]]*{{.+}}
+// CHECK: [[S_ARR_DST_EL:%.+]] = phi [[S_FLOAT_TY]]*{{.+}}
+// CHECK: [[S_ARR_DST_BCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[S_ARR_DST_EL]] to i8*
+// CHECK: [[S_ARR_SRC_BCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[S_ARR_SRC_EL]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[S_ARR_DST_BCAST]], i8* [[S_ARR_SRC_BCAST]]{{.+}})
+// CHECK: [[S_ARR_DST_NEXT:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[S_ARR_DST_EL]], i{{[0-9]+}} 1
+// CHECK: [[S_ARR_SRC_NEXT:%.+]] = getelementptr{{.+}}
+// CHECK: [[CPY_IS_FINISHED:%.+]] = icmp eq [[S_FLOAT_TY]]* [[S_ARR_DST_NEXT]], [[S_ARR_BEGIN_GEP]]
+// CHECK: br i1 [[CPY_IS_FINISHED]], label %[[S_ARR_COPY_DONE]], label %[[S_ARR_COPY_BLOCK]]
+// CHECK: [[S_ARR_COPY_DONE]]:
+// CHECK: [[TMP_VAL1:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[TMP_PRIV]],
+// CHECK: [[VAR_ADDR_REF_BCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[VAR_ADDR_REF]] to i8*
+// CHECK: [[TMP_VAL1_BCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[TMP_VAL1]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[VAR_ADDR_REF_BCAST]], i8* [[TMP_VAL1_BCAST]],{{.+}})
+// CHECK: [[SVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[S_VAR_PRIV]],
+// CHECK-64: store i{{[0-9]+}} [[SVAR_VAL]], i{{[0-9]+}}* [[SVAR_ADDR_REF]],
+// CHECK-32: store i{{[0-9]+}} [[SVAR_VAL]], i{{[0-9]+}}* [[SVAR_ADDR]],
+// CHECK: ret void
+
+// template tmain
+// CHECK: define{{.*}} i{{[0-9]+}} [[TMAIN_INT:@.+]]()
+// CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]],
+// CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR:@.+]]([[S_INT_TY]]* [[TEST]])
+// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+// CHECK: call void [[OFFLOAD_FUN_1:@.+]]([2 x i{{[0-9]+}}]* {{.+}}, i{{[0-9]+}} {{.+}}, [2 x [[S_INT_TY]]]* {{.+}}, [[S_INT_TY]]* {{.+}})
+// CHECK: ret
+
+
+// CHECK: define internal void [[OFFLOAD_FUN_1]](
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_teams(%{{.+}}* @{{.+}}, i{{[0-9]+}} 4,
+// CHECK: ret
+
+// CHECK: define internal void [[OMP_OUTLINED_1:@.+]](i{{[0-9]+}}* noalias [[GTID_ADDR1:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [2 x i{{[0-9]+}}]*{{.+}} [[VEC_IN1:%.+]], i{{[0-9]+}} [[T_VAR_IN1:%.+]], [2 x [[S_INT_TY]]]*{{.+}} [[S_ARR_IN1:%.+]], [[S_INT_TY]]*{{.+}} [[VAR_IN1:%.+]])
+// skip alloca of global_tid and bound_tid
+// CHECK: {{.+}} = alloca i{{[0-9]+}}*,
+// CHECK: {{.+}} = alloca i{{[0-9]+}}*,
+// CHECK: [[VEC_ADDR1:%.+]] = alloca [2 x i{{[0-9]+}}]*,
+// CHECK: [[T_VAR_ADDR1:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[S_ARR_ADDR1:%.+]] = alloca [2 x [[S_INT_TY]]]*,
+// CHECK: [[VAR_ADDR1:%.+]] = alloca [[S_INT_TY]]*,
+// skip loop variables
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: [[OMP_IS_LAST1:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[T_VAR_PRIV1:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[VEC_PRIV1:%.+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK: [[S_ARR_PRIV1:%.+]] = alloca [2 x [[S_INT_TY]]],
+// CHECK: [[VAR_PRIV1:%.+]] = alloca [[S_INT_TY]],
+// CHECK: [[TMP_PRIV1:%.+]] = alloca [[S_INT_TY]]*,
+
+// skip init of bound and global tid
+// CHECK: store i{{[0-9]+}}* {{.*}},
+// CHECK: store i{{[0-9]+}}* {{.*}},
+// copy from parameters to local address variables
+// CHECK: store [2 x i{{[0-9]+}}]* [[VEC_IN1]], [2 x i{{[0-9]+}}]** [[VEC_ADDR1]],
+// CHECK: store i{{[0-9]+}} [[T_VAR_IN1]], i{{[0-9]+}}* [[T_VAR_ADDR1]],
+// CHECK: store [2 x [[S_INT_TY]]]* [[S_ARR_IN1]], [2 x [[S_INT_TY]]]** [[S_ARR_ADDR1]],
+// CHECK: store [[S_INT_TY]]* [[VAR_IN1]], [[S_INT_TY]]** [[VAR_ADDR1]],
+
+// load content of local address variables
+// CHECK: [[VEC_ADDR_REF1:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** [[VEC_ADDR1]],
+// CHECK-64: [[T_VAR_ADDR_REF1:%.+]] = bitcast i64* [[T_VAR_ADDR1]] to i32*
+// CHECK: [[S_ARR_ADDR_REF1:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** [[S_ARR_ADDR1]],
+// CHECK-DAG: store i{{[0-9]+}} 0, i{{[0-9]+}}* [[OMP_IS_LAST1]],
+// CHECK: [[VAR_ADDR1_REF:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[VAR_ADDR1]],
+// CHECK-DAG: store [[S_INT_TY]]* [[VAR_PRIV1]], [[S_INT_TY]]** [[TMP_PRIV1]],
+// CHECK: call void @__kmpc_for_static_init_4(
+// assignment: vec[i] = t_var;
+// CHECK: [[IV_VAL1:%.+]] =
+// CHECK: [[T_VAR_PRIV_VAL1:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_PRIV1]],
+// CHECK: [[VEC_PTR1:%.+]] = getelementptr inbounds [2 x i{{[0-9]+}}], [2 x i{{[0-9]+}}]* [[VEC_PRIV1]], i{{[0-9]+}} 0, i{{[0-9]+}} {{.+}}
+// CHECK: store i{{[0-9]+}} [[T_VAR_PRIV_VAL1]], i{{[0-9]+}}* [[VEC_PTR1]],
+
+// assignment: s_arr[i] = var;
+// CHECK-DAG: [[S_ARR_PTR1:%.+]] = getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[S_ARR_PRIV1]],
+// CHECK-DAG: [[TMP_VAL1:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[TMP_PRIV1]],
+// CHECK-DAG: [[S_ARR_PTR_BCAST1:%.+]] = bitcast [[S_INT_TY]]* [[S_ARR_PTR1]] to i8*
+// CHECK-DAG: [[TMP_VAL_BCAST1:%.+]] = bitcast [[S_INT_TY]]* [[TMP_VAL1]] to i8*
+// CHECK-DAG: call void @llvm.memcpy.{{.+}}(i8* [[S_ARR_PTR_BCAST1]], i8* [[TMP_VAL_BCAST1]],
+// CHECK: call void @__kmpc_for_static_fini(
+
+// lastprivates
+// CHECK: [[OMP_IS_LAST_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[OMP_IS_LAST1]],
+// CHECK: [[IS_LAST_IT:%.+]] = icmp ne i{{[0-9]+}} [[OMP_IS_LAST_VAL]], 0
+// CHECK: br i1 [[IS_LAST_IT]], label %[[OMP_LASTPRIV_BLOCK:.+]], label %[[OMP_LASTPRIV_DONE:.+]]
+
+// CHECK: [[OMP_LASTPRIV_BLOCK]]:
+// CHECK: [[T_VAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_PRIV1]],
+// CHECK-64: store i{{[0-9]+}} [[T_VAR_VAL]], i{{[0-9]+}}* [[T_VAR_ADDR_REF1]],
+// CHECK-32: store i{{[0-9]+}} [[T_VAR_VAL]], i{{[0-9]+}}* [[T_VAR_ADDR1]],
+// CHECK: [[BCAST_VEC_ADDR_REF:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_ADDR_REF1]] to i8*
+// CHECK: [[BCAST_VEC_PRIV:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV1]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[BCAST_VEC_ADDR_REF]], i8* [[BCAST_VEC_PRIV]],
+// CHECK: [[S_ARR_BEGIN:%.+]] = getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[S_ARR_ADDR_REF]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+// CHECK: [[S_ARR_PRIV_BCAST:%.+]] = bitcast [2 x [[S_INT_TY]]]* [[S_ARR_PRIV1]] to [[S_INT_TY]]*
+// CHECK: [[S_ARR_BEGIN_GEP:%.+]] = getelementptr [[S_INT_TY]], [[S_INT_TY]]* [[S_ARR_BEGIN]], i{{[0-9]+}} 2
+// CHECK: [[S_ARR_IS_EMPTY:%.+]] = icmp eq [[S_INT_TY]]* [[S_ARR_BEGIN]], [[S_ARR_BEGIN_GEP]]
+// CHECK: br i1 [[S_ARR_IS_EMPTY]], label %[[S_ARR_COPY_DONE:.+]], label %[[S_ARR_COPY_BLOCK:.+]]
+// CHECK: [[S_ARR_COPY_BLOCK]]:
+// CHECK: [[S_ARR_SRC_EL:%.+]] = phi [[S_INT_TY]]*{{.+}}
+// CHECK: [[S_ARR_DST_EL:%.+]] = phi [[S_INT_TY]]*{{.+}}
+// CHECK: [[S_ARR_DST_BCAST:%.+]] = bitcast [[S_INT_TY]]* [[S_ARR_DST_EL]] to i8*
+// CHECK: [[S_ARR_SRC_BCAST:%.+]] = bitcast [[S_INT_TY]]* [[S_ARR_SRC_EL]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[S_ARR_DST_BCAST]], i8* [[S_ARR_SRC_BCAST]]{{.+}})
+// CHECK: [[S_ARR_DST_NEXT:%.+]] = getelementptr [[S_INT_TY]], [[S_INT_TY]]* [[S_ARR_DST_EL]], i{{[0-9]+}} 1
+// CHECK: [[S_ARR_SRC_NEXT:%.+]] = getelementptr{{.+}}
+// CHECK: [[CPY_IS_FINISHED:%.+]] = icmp eq [[S_INT_TY]]* [[S_ARR_DST_NEXT]], [[S_ARR_BEGIN_GEP]]
+// CHECK: br i1 [[CPY_IS_FINISHED]], label %[[S_ARR_COPY_DONE]], label %[[S_ARR_COPY_BLOCK]]
+// CHECK: [[S_ARR_COPY_DONE]]:
+// CHECK: [[TMP_VAL1:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[TMP_PRIV1]],
+// CHECK: [[VAR_ADDR_REF_BCAST:%.+]] = bitcast [[S_INT_TY]]* [[VAR_ADDR1_REF]] to i8*
+// CHECK: [[TMP_VAL1_BCAST:%.+]] = bitcast [[S_INT_TY]]* [[TMP_VAL1]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[VAR_ADDR_REF_BCAST]], i8* [[TMP_VAL1_BCAST]],{{.+}})
+// CHECK: ret void
+#endif
diff --git a/test/OpenMP/target_teams_distribute_lastprivate_messages.cpp b/test/OpenMP/target_teams_distribute_lastprivate_messages.cpp
index 8d594e94b09f..898291833d20 100644
--- a/test/OpenMP/target_teams_distribute_lastprivate_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_lastprivate_messages.cpp
@@ -18,14 +18,14 @@ public:
const S2 &operator =(const S2&) const;
S2 &operator =(const S2&);
static float S2s; // expected-note {{static data member is predetermined as shared}}
- static const float S2sc;
+ static const float S2sc; // expected-note {{static data member is predetermined as shared}}
};
-const float S2::S2sc = 0; // expected-note {{static data member is predetermined as shared}}
+const float S2::S2sc = 0;
const S2 b;
const S2 ba[5];
class S3 {
int a;
- S3 &operator=(const S3 &s3); // expected-note 2 {{implicitly declared private here}}
+ S3 &operator=(const S3 &s3); // expected-note {{implicitly declared private here}}
public:
S3() : a(0) {}
@@ -52,7 +52,7 @@ public:
};
class S6 {
int a;
- S6() : a(0) {}
+ S6() : a(0) {} // expected-note {{implicitly declared private here}}
public:
S6(const S6 &s6) : a(s6.a) {}
@@ -215,10 +215,12 @@ int main(int argc, char **argv) {
#pragma omp target teams distribute lastprivate(j)
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute firstprivate(m) lastprivate(m) // expected-error {{'operator=' is a private member of 'S3'}}
+// expected-error@+1 {{firstprivate variable cannot be lastprivate}} expected-note@+1 {{defined as firstprivate}}
+#pragma omp target teams distribute firstprivate(m) lastprivate(m)
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute lastprivate(n) firstprivate(n) // OK
+// expected-error@+1 {{lastprivate variable cannot be firstprivate}} expected-note@+1 {{defined as lastprivate}}
+#pragma omp target teams distribute lastprivate(n) firstprivate(n) // expected-error {{calling a private constructor of class 'S6'}}
for (i = 0; i < argc; ++i) foo();
static int si;
diff --git a/test/OpenMP/target_teams_distribute_loop_messages.cpp b/test/OpenMP/target_teams_distribute_loop_messages.cpp
index 441abcba0049..0a825ab1e609 100644
--- a/test/OpenMP/target_teams_distribute_loop_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_loop_messages.cpp
@@ -2,7 +2,7 @@
class S {
int a;
- S() : a(0) {}
+ S() : a(0) {} // expected-note {{implicitly declared private here}}
public:
S(int v) : a(v) {}
@@ -607,7 +607,8 @@ void test_loop_eh() {
void test_loop_firstprivate_lastprivate() {
S s(4);
-#pragma omp target teams distribute lastprivate(s) firstprivate(s)
+// expected-error@+1 {{lastprivate variable cannot be firstprivate}} expected-note@+1 {{defined as lastprivate}}
+#pragma omp target teams distribute lastprivate(s) firstprivate(s) // expected-error {{calling a private constructor of class 'S'}}
for (int i = 0; i < 16; ++i)
;
}
diff --git a/test/OpenMP/target_teams_distribute_map_messages.cpp b/test/OpenMP/target_teams_distribute_map_messages.cpp
index 5d815de85b04..eafdccb66bc9 100644
--- a/test/OpenMP/target_teams_distribute_map_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_map_messages.cpp
@@ -14,8 +14,8 @@ class S2 {
public:
S2():a(0) { }
S2(S2 &s2):a(s2.a) { }
- static float S2s; // expected-note 4 {{mappable type cannot contain static members}}
- static const float S2sc; // expected-note 4 {{mappable type cannot contain static members}}
+ static float S2s;
+ static const float S2sc;
};
const float S2::S2sc = 0;
const S2 b;
@@ -116,9 +116,9 @@ T tmain(T argc) {
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute map(S1) // expected-error {{'S1' does not refer to a value}}
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} expected-error 2 {{type 'S2' is not mappable to target}}
+#pragma omp target teams distribute map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}}
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute map(ba) // expected-error 2 {{type 'S2' is not mappable to target}}
+#pragma omp target teams distribute map(ba)
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute map(ca)
for (i = 0; i < argc; ++i) foo();
@@ -222,11 +222,11 @@ int main(int argc, char **argv) {
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute map(S1) // expected-error {{'S1' does not refer to a value}}
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} expected-error 2 {{type 'S2' is not mappable to target}}
+#pragma omp target teams distribute map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}}
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute map(argv[1])
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute map(ba) // expected-error 2 {{type 'S2' is not mappable to target}}
+#pragma omp target teams distribute map(ba)
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute map(ca)
for (i = 0; i < argc; ++i) foo();
diff --git a/test/OpenMP/target_teams_distribute_misc_messages.c b/test/OpenMP/target_teams_distribute_misc_messages.c
index bf4df0894ad3..33496a70d140 100644
--- a/test/OpenMP/target_teams_distribute_misc_messages.c
+++ b/test/OpenMP/target_teams_distribute_misc_messages.c
@@ -285,12 +285,15 @@ void test_firstprivate() {
;
int x, y, z;
+// expected-error@+1 {{lastprivate variable cannot be firstprivate}} expected-note@+1 {{defined as lastprivate}}
#pragma omp target teams distribute lastprivate(x) firstprivate(x)
for (i = 0; i < 16; ++i)
;
+// expected-error@+1 2 {{lastprivate variable cannot be firstprivate}} expected-note@+1 2 {{defined as lastprivate}}
#pragma omp target teams distribute lastprivate(x, y) firstprivate(x, y)
for (i = 0; i < 16; ++i)
;
+// expected-error@+1 3 {{lastprivate variable cannot be firstprivate}} expected-note@+1 3 {{defined as lastprivate}}
#pragma omp target teams distribute lastprivate(x, y, z) firstprivate(x, y, z)
for (i = 0; i < 16; ++i)
;
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_ast_print.cpp b/test/OpenMP/target_teams_distribute_parallel_for_ast_print.cpp
index 8df3c972dce0..f51c4fe60d7f 100644
--- a/test/OpenMP/target_teams_distribute_parallel_for_ast_print.cpp
+++ b/test/OpenMP/target_teams_distribute_parallel_for_ast_print.cpp
@@ -24,8 +24,10 @@ protected:
public:
S7(typename T::type v) : a(v) {
#pragma omp target teams distribute parallel for private(a) private(this->a) private(T::a)
- for (int k = 0; k < a.a; ++k)
+ for (int k = 0; k < a.a; ++k) {
++this->a.a;
+#pragma omp cancel for
+ }
}
S7 &operator=(S7 &s) {
#pragma omp target teams distribute parallel for private(a) private(this->a)
@@ -43,6 +45,7 @@ public:
}
};
// CHECK: #pragma omp target teams distribute parallel for private(this->a) private(this->a) private(T::a)
+// CHECK: #pragma omp cancel for
// CHECK: #pragma omp target teams distribute parallel for private(this->a) private(this->a)
// CHECK: #pragma omp target teams distribute parallel for default(none) private(b) firstprivate(argv) shared(d) reduction(+: c) reduction(max: e) num_teams(f) thread_limit(d)
@@ -113,10 +116,10 @@ T tmain(T argc) {
// CHECK: #pragma omp target teams distribute parallel for default(none) private(b) firstprivate(argc) shared(d) reduction(+: c) reduction(max: e) num_teams(f) thread_limit(d)
// CHECK-NEXT: for (int k = 0; k < 10; ++k)
// CHECK-NEXT: e += d + argc;
-#pragma omp target teams distribute parallel for linear(d)
+#pragma omp target teams distribute parallel for
for (int k = 0; k < 10; ++k)
e += d + argc;
-// CHECK: #pragma omp target teams distribute parallel for linear(d)
+// CHECK: #pragma omp target teams distribute parallel for
// CHECK-NEXT: for (int k = 0; k < 10; ++k)
// CHECK-NEXT: e += d + argc;
return T();
@@ -158,10 +161,10 @@ int main (int argc, char **argv) {
// CHECK: #pragma omp target teams distribute parallel for default(none) private(b) firstprivate(argc) shared(d) reduction(+: c) reduction(max: e) num_teams(f) thread_limit(d)
// CHECK-NEXT: for (int k = 0; k < 10; ++k)
// CHECK-NEXT: e += d + argc;
-#pragma omp target teams distribute parallel for linear(d)
+#pragma omp target teams distribute parallel for
for (int k = 0; k < 10; ++k)
e += d + argc;
-// CHECK: #pragma omp target teams distribute parallel for linear(d)
+// CHECK: #pragma omp target teams distribute parallel for
// CHECK-NEXT: for (int k = 0; k < 10; ++k)
// CHECK-NEXT: e += d + argc;
return (0);
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_depend_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_depend_messages.cpp
index ca7241a16c0a..c4688958e554 100644
--- a/test/OpenMP/target_teams_distribute_parallel_for_depend_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_parallel_for_depend_messages.cpp
@@ -37,21 +37,21 @@ int main(int argc, char **argv, char *env[]) {
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute parallel for depend (out: ) // expected-error {{expected expression}}
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute parallel for depend (inout : foobool(argc)), depend (in, argc) // expected-error {{expected variable name, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}}
+#pragma omp target teams distribute parallel for depend (inout : foobool(argc)), depend (in, argc) // expected-error {{expected addressable lvalue expression, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}}
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute parallel for depend (out :S1) // expected-error {{'S1' does not refer to a value}}
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute parallel for depend(in : argv[1][1] = '2') // expected-error {{expected variable name, array element or array section}}
+#pragma omp target teams distribute parallel for depend(in : argv[1][1] = '2')
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute parallel for depend (in : vec[1]) // expected-error {{expected variable name, array element or array section}}
+#pragma omp target teams distribute parallel for depend (in : vec[1]) // expected-error {{expected addressable lvalue expression, array element or array section}}
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute parallel for depend (in : argv[0])
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute parallel for depend (in : ) // expected-error {{expected expression}}
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute parallel for depend (in : main) // expected-error {{expected variable name, array element or array section}}
+#pragma omp target teams distribute parallel for depend (in : main)
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute parallel for depend(in : a[0]) // expected-error{{expected variable name, array element or array section}}
+#pragma omp target teams distribute parallel for depend(in : a[0]) // expected-error{{expected addressable lvalue expression, array element or array section}}
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute parallel for depend (in : vec[1:2]) // expected-error {{ value is not an array or pointer}}
for (i = 0; i < argc; ++i) foo();
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_firstprivate_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_firstprivate_messages.cpp
index d4e708308a02..0d8355047830 100644
--- a/test/OpenMP/target_teams_distribute_parallel_for_firstprivate_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_parallel_for_firstprivate_messages.cpp
@@ -124,7 +124,8 @@ int main(int argc, char **argv) {
#pragma omp target teams distribute parallel for firstprivate(j)
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute parallel for lastprivate(argc), firstprivate(argc) // OK
+// expected-error@+1 {{lastprivate variable cannot be firstprivate}} expected-note@+1 {{defined as lastprivate}}
+#pragma omp target teams distribute parallel for lastprivate(argc), firstprivate(argc)
for (i = 0; i < argc; ++i) foo();
return 0;
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_lastprivate_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_lastprivate_messages.cpp
index d31acef0039d..84a6df28174d 100644
--- a/test/OpenMP/target_teams_distribute_parallel_for_lastprivate_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_parallel_for_lastprivate_messages.cpp
@@ -18,14 +18,14 @@ public:
const S2 &operator =(const S2&) const;
S2 &operator =(const S2&);
static float S2s; // expected-note {{static data member is predetermined as shared}}
- static const float S2sc;
+ static const float S2sc; // expected-note {{static data member is predetermined as shared}}
};
-const float S2::S2sc = 0; // expected-note {{static data member is predetermined as shared}}
+const float S2::S2sc = 0;
const S2 b;
const S2 ba[5];
class S3 {
int a;
- S3 &operator=(const S3 &s3); // expected-note 2 {{implicitly declared private here}}
+ S3 &operator=(const S3 &s3); // expected-note {{implicitly declared private here}}
public:
S3() : a(0) {}
@@ -52,7 +52,7 @@ public:
};
class S6 {
int a;
- S6() : a(0) {}
+ S6() : a(0) {} // expected-note {{implicitly declared private here}}
public:
S6(const S6 &s6) : a(s6.a) {}
@@ -216,10 +216,12 @@ int main(int argc, char **argv) {
#pragma omp target teams distribute parallel for lastprivate(j)
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute parallel for firstprivate(m) lastprivate(m) // expected-error {{'operator=' is a private member of 'S3'}}
+// expected-error@+1 {{firstprivate variable cannot be lastprivate}} expected-note@+1 {{defined as firstprivate}}
+#pragma omp target teams distribute parallel for firstprivate(m) lastprivate(m)
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute parallel for lastprivate(n) firstprivate(n) // OK
+// expected-error@+1 {{lastprivate variable cannot be firstprivate}} expected-note@+1 {{defined as lastprivate}}
+#pragma omp target teams distribute parallel for lastprivate(n) firstprivate(n) // expected-error {{calling a private constructor of class 'S6'}}
for (i = 0; i < argc; ++i) foo();
static int si;
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_linear_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_linear_messages.cpp
deleted file mode 100644
index 82220dcf45c6..000000000000
--- a/test/OpenMP/target_teams_distribute_parallel_for_linear_messages.cpp
+++ /dev/null
@@ -1,248 +0,0 @@
-// RUN: %clang_cc1 -verify -fopenmp %s
-
-namespace X {
- int x;
-};
-
-struct B {
- static int ib; // expected-note {{'B::ib' declared here}}
- static int bfoo() { return 8; }
-};
-
-int bfoo() { return 4; }
-
-int z;
-const int C1 = 1;
-const int C2 = 2;
-void test_linear_colons()
-{
- int B = 0;
-
-#pragma omp target teams distribute parallel for linear(B:bfoo())
- for (int i = 0; i < 10; ++i) ;
-
-#pragma omp target teams distribute parallel for linear(B::ib:B:bfoo()) // expected-error {{unexpected ':' in nested name specifier; did you mean '::'}}
- for (int i = 0; i < 10; ++i) ;
-
-#pragma omp target teams distribute parallel for linear(B:ib) // expected-error {{use of undeclared identifier 'ib'; did you mean 'B::ib'}}
- for (int i = 0; i < 10; ++i) ;
-
-#pragma omp target teams distribute parallel for linear(z:B:ib) // expected-error {{unexpected ':' in nested name specifier; did you mean '::'?}}
- for (int i = 0; i < 10; ++i) ;
-
-#pragma omp target teams distribute parallel for linear(B:B::bfoo())
- for (int i = 0; i < 10; ++i) ;
-
-#pragma omp target teams distribute parallel for linear(X::x : ::z)
- for (int i = 0; i < 10; ++i) ;
-
-#pragma omp target teams distribute parallel for linear(B,::z, X::x)
- for (int i = 0; i < 10; ++i) ;
-
-#pragma omp target teams distribute parallel for linear(::z)
- for (int i = 0; i < 10; ++i) ;
-
-#pragma omp target teams distribute parallel for linear(B::bfoo()) // expected-error {{expected variable name}}
- for (int i = 0; i < 10; ++i) ;
-
-#pragma omp target teams distribute parallel for linear(B::ib,B:C1+C2)
- for (int i = 0; i < 10; ++i) ;
-}
-
-template<int L, class T, class N> T test_template(T* arr, N num) {
- N i;
- T sum = (T)0;
- T ind2 = - num * L; // expected-note {{'ind2' defined here}}
-
-#pragma omp target teams distribute parallel for linear(ind2:L) // expected-error {{argument of a linear clause should be of integral or pointer type}}
- for (i = 0; i < num; ++i) {
- T cur = arr[(int)ind2];
- ind2 += L;
- sum += cur;
- }
- return T();
-}
-
-template<int LEN> int test_warn() {
- int ind2 = 0;
-#pragma omp target teams distribute parallel for linear(ind2:LEN) // expected-warning {{zero linear step (ind2 should probably be const)}}
- for (int i = 0; i < 100; i++) {
- ind2 += LEN;
- }
- return ind2;
-}
-
-struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}}
-extern S1 a;
-class S2 {
- mutable int a;
-public:
- S2():a(0) { }
-};
-const S2 b; // expected-note 2 {{'b' defined here}}
-const S2 ba[5];
-class S3 {
- int a;
-public:
- S3():a(0) { }
-};
-const S3 ca[5];
-class S4 {
- int a;
- S4();
-public:
- S4(int v):a(v) { }
-};
-class S5 {
- int a;
- S5():a(0) {}
-public:
- S5(int v):a(v) { }
-};
-
-S3 h;
-#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
-
-template<class I, class C> int foomain(I argc, C **argv) {
- I e(4);
- I g(5);
- int i;
- int &j = i;
-
-#pragma omp target teams distribute parallel for linear // expected-error {{expected '(' after 'linear'}}
- for (int k = 0; k < argc; ++k) ++k;
-
-#pragma omp target teams distribute parallel for linear ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
- for (int k = 0; k < argc; ++k) ++k;
-
-#pragma omp target teams distribute parallel for linear () // expected-error {{expected expression}}
- for (int k = 0; k < argc; ++k) ++k;
-
-#pragma omp target teams distribute parallel for linear (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
- for (int k = 0; k < argc; ++k) ++k;
-
-#pragma omp target teams distribute parallel for linear (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
- for (int k = 0; k < argc; ++k) ++k;
-
-#pragma omp target teams distribute parallel for linear (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
- for (int k = 0; k < argc; ++k) ++k;
-
-#pragma omp target teams distribute parallel for linear (argc : 5)
- for (int k = 0; k < argc; ++k) ++k;
-
-#pragma omp target teams distribute parallel for linear (S1) // expected-error {{'S1' does not refer to a value}}
- for (int k = 0; k < argc; ++k) ++k;
-
-#pragma omp target teams distribute parallel for linear (a, b:B::ib) // expected-error {{linear variable with incomplete type 'S1'}} expected-error {{const-qualified variable cannot be linear}}
- for (int k = 0; k < argc; ++k) ++k;
-
-#pragma omp target teams distribute parallel for linear (argv[1]) // expected-error {{expected variable name}}
- for (int k = 0; k < argc; ++k) ++k;
-
-#pragma omp target teams distribute parallel for linear(e, g)
- for (int k = 0; k < argc; ++k) ++k;
-
-#pragma omp target teams distribute parallel for linear(h) // expected-error {{threadprivate or thread local variable cannot be linear}}
- for (int k = 0; k < argc; ++k) ++k;
-
-#pragma omp target teams distribute parallel for linear(i)
- for (int k = 0; k < argc; ++k) ++k;
-
- #pragma omp parallel
- {
- int v = 0;
- int i;
- #pragma omp target teams distribute parallel for linear(v:i)
- for (int k = 0; k < argc; ++k) { i = k; v += i; }
- }
-
-#pragma omp target teams distribute parallel for linear(j)
- for (int k = 0; k < argc; ++k) ++k;
-
- int v = 0;
-
-#pragma omp target teams distribute parallel for linear(v:j)
- for (int k = 0; k < argc; ++k) { ++k; v += j; }
-
-#pragma omp target teams distribute parallel for linear(i)
- for (int k = 0; k < argc; ++k) ++k;
- return 0;
-}
-
-namespace A {
-double x;
-#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}}
-}
-namespace C {
-using A::x;
-}
-
-int main(int argc, char **argv) {
- double darr[100];
- // expected-note@+1 {{in instantiation of function template specialization 'test_template<-4, double, int>' requested here}}
- test_template<-4>(darr, 4);
- // expected-note@+1 {{in instantiation of function template specialization 'test_warn<0>' requested here}}
- test_warn<0>();
-
- S4 e(4); // expected-note {{'e' defined here}}
- S5 g(5); // expected-note {{'g' defined here}}
- int i;
- int &j = i;
-
-#pragma omp target teams distribute parallel for linear // expected-error {{expected '(' after 'linear'}}
- for (int k = 0; k < argc; ++k) ++k;
-
-#pragma omp target teams distribute parallel for linear ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
- for (int k = 0; k < argc; ++k) ++k;
-
-#pragma omp target teams distribute parallel for linear () // expected-error {{expected expression}}
- for (int k = 0; k < argc; ++k) ++k;
-
-#pragma omp target teams distribute parallel for linear (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
- for (int k = 0; k < argc; ++k) ++k;
-
-#pragma omp target teams distribute parallel for linear (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
- for (int k = 0; k < argc; ++k) ++k;
-
-#pragma omp target teams distribute parallel for linear (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
- for (int k = 0; k < argc; ++k) ++k;
-
-#pragma omp target teams distribute parallel for linear (argc)
- for (int k = 0; k < argc; ++k) ++k;
-
-#pragma omp target teams distribute parallel for linear (S1) // expected-error {{'S1' does not refer to a value}}
- for (int k = 0; k < argc; ++k) ++k;
-
-
-#pragma omp target teams distribute parallel for linear (a, b) // expected-error {{linear variable with incomplete type 'S1'}} expected-error {{const-qualified variable cannot be linear}}
- for (int k = 0; k < argc; ++k) ++k;
-
-#pragma omp target teams distribute parallel for linear (argv[1]) // expected-error {{expected variable name}}
- for (int k = 0; k < argc; ++k) ++k;
-
-#pragma omp target teams distribute parallel for linear(e, g) // expected-error {{argument of a linear clause should be of integral or pointer type, not 'S4'}} expected-error {{argument of a linear clause should be of integral or pointer type, not 'S5'}}
- for (int k = 0; k < argc; ++k) ++k;
-
-#pragma omp target teams distribute parallel for linear(h, C::x) // expected-error 2 {{threadprivate or thread local variable cannot be linear}}
- for (int k = 0; k < argc; ++k) ++k;
-
-#pragma omp parallel
-{
- int i;
-#pragma omp target teams distribute parallel for linear(i)
- for (int k = 0; k < argc; ++k) ++k;
-
-#pragma omp target teams distribute parallel for linear(i : 4)
- for (int k = 0; k < argc; ++k) { ++k; i += 4; }
-}
-
-#pragma omp target teams distribute parallel for linear(j)
- for (int k = 0; k < argc; ++k) ++k;
-
-#pragma omp target teams distribute parallel for linear(i)
- for (int k = 0; k < argc; ++k) ++k;
-
- foomain<int,char>(argc,argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}}
- return 0;
-}
-
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_loop_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_loop_messages.cpp
index d912737a2146..57ab273c4601 100644
--- a/test/OpenMP/target_teams_distribute_parallel_for_loop_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_parallel_for_loop_messages.cpp
@@ -2,7 +2,7 @@
class S {
int a;
- S() : a(0) {}
+ S() : a(0) {} // expected-note {{implicitly declared private here}}
public:
S(int v) : a(v) {}
@@ -605,7 +605,8 @@ void test_loop_eh() {
void test_loop_firstprivate_lastprivate() {
S s(4);
-#pragma omp target teams distribute parallel for lastprivate(s) firstprivate(s)
+// expected-error@+1 {{lastprivate variable cannot be firstprivate}} expected-note@+1 {{defined as lastprivate}}
+#pragma omp target teams distribute parallel for lastprivate(s) firstprivate(s) // expected-error {{calling a private constructor of class 'S'}}
for (int i = 0; i < 16; ++i)
;
}
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_map_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_map_messages.cpp
index 326db95f90f8..1fb466ee5518 100644
--- a/test/OpenMP/target_teams_distribute_parallel_for_map_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_parallel_for_map_messages.cpp
@@ -14,8 +14,8 @@ class S2 {
public:
S2():a(0) { }
S2(S2 &s2):a(s2.a) { }
- static float S2s; // expected-note 4 {{mappable type cannot contain static members}}
- static const float S2sc; // expected-note 4 {{mappable type cannot contain static members}}
+ static float S2s;
+ static const float S2sc;
};
const float S2::S2sc = 0;
const S2 b;
@@ -116,9 +116,9 @@ T tmain(T argc) {
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute parallel for map(S1) // expected-error {{'S1' does not refer to a value}}
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute parallel for map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} expected-error 2 {{type 'S2' is not mappable to target}}
+#pragma omp target teams distribute parallel for map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}}
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute parallel for map(ba) // expected-error 2 {{type 'S2' is not mappable to target}}
+#pragma omp target teams distribute parallel for map(ba)
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute parallel for map(ca)
for (i = 0; i < argc; ++i) foo();
@@ -222,11 +222,11 @@ int main(int argc, char **argv) {
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute parallel for map(S1) // expected-error {{'S1' does not refer to a value}}
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute parallel for map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} expected-error 2 {{type 'S2' is not mappable to target}}
+#pragma omp target teams distribute parallel for map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}}
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute parallel for map(argv[1])
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute parallel for map(ba) // expected-error 2 {{type 'S2' is not mappable to target}}
+#pragma omp target teams distribute parallel for map(ba)
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute parallel for map(ca)
for (i = 0; i < argc; ++i) foo();
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_messages.cpp
index cb76ef2e0124..15135838e981 100644
--- a/test/OpenMP/target_teams_distribute_parallel_for_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_parallel_for_messages.cpp
@@ -27,7 +27,7 @@ int main(int argc, char **argv) {
#pragma omp target teams distribute parallel for } // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute parallel for' are ignored}}
for (int i = 0; i < argc; ++i)
foo();
-#pragma omp target teams distribute parallel for
+#pragma omp target teams distribute parallel for linear(argc) // expected-error {{unexpected OpenMP clause 'linear' in directive '#pragma omp target teams distribute parallel for'}}
for (int i = 0; i < argc; ++i)
foo();
// expected-warning@+1 {{extra tokens at the end of '#pragma omp target teams distribute parallel for' are ignored}}
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_misc_messages.c b/test/OpenMP/target_teams_distribute_parallel_for_misc_messages.c
index 769be6c10c3a..c48a2dfa9e68 100644
--- a/test/OpenMP/target_teams_distribute_parallel_for_misc_messages.c
+++ b/test/OpenMP/target_teams_distribute_parallel_for_misc_messages.c
@@ -285,12 +285,15 @@ void test_firstprivate() {
;
int x, y, z;
+// expected-error@+1 {{lastprivate variable cannot be firstprivate}} expected-note@+1 {{defined as lastprivate}}
#pragma omp target teams distribute parallel for lastprivate(x) firstprivate(x)
for (i = 0; i < 16; ++i)
;
+// expected-error@+1 2 {{lastprivate variable cannot be firstprivate}} expected-note@+1 2 {{defined as lastprivate}}
#pragma omp target teams distribute parallel for lastprivate(x, y) firstprivate(x, y)
for (i = 0; i < 16; ++i)
;
+// expected-error@+1 3 {{lastprivate variable cannot be firstprivate}} expected-note@+1 3 {{defined as lastprivate}}
#pragma omp target teams distribute parallel for lastprivate(x, y, z) firstprivate(x, y, z)
for (i = 0; i < 16; ++i)
;
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_reduction_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_reduction_messages.cpp
index ba9586a1cef8..59b35417d401 100644
--- a/test/OpenMP/target_teams_distribute_parallel_for_reduction_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_parallel_for_reduction_messages.cpp
@@ -19,9 +19,9 @@ public:
S2() : a(0) {}
S2(S2 &s2) : a(s2.a) {}
static float S2s; // expected-note 2 {{static data member is predetermined as shared}}
- static const float S2sc;
+ static const float S2sc; // expected-note 2 {{'S2sc' declared here}}
};
-const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}}
+const float S2::S2sc = 0;
S2 b; // expected-note 3 {{'b' defined here}}
const S2 ba[5]; // expected-note 2 {{'ba' defined here}}
class S3 {
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_simd_ast_print.cpp b/test/OpenMP/target_teams_distribute_parallel_for_simd_ast_print.cpp
index 29a0c6d36333..af588f1b81d9 100644
--- a/test/OpenMP/target_teams_distribute_parallel_for_simd_ast_print.cpp
+++ b/test/OpenMP/target_teams_distribute_parallel_for_simd_ast_print.cpp
@@ -28,8 +28,9 @@ public:
++this->a.a;
}
S7 &operator=(S7 &s) {
-#pragma omp target teams distribute parallel for simd private(a) private(this->a)
- for (int k = 0; k < s.a.a; ++k)
+ int k;
+#pragma omp target teams distribute parallel for simd private(a) private(this->a) linear(k)
+ for (k = 0; k < s.a.a; ++k)
++s.a.a;
foo();
@@ -53,7 +54,7 @@ public:
}
};
// CHECK: #pragma omp target teams distribute parallel for simd private(this->a) private(this->a) private(T::a)
-// CHECK: #pragma omp target teams distribute parallel for simd private(this->a) private(this->a)
+// CHECK: #pragma omp target teams distribute parallel for simd private(this->a) private(this->a) linear(k)
// CHECK: #pragma omp target teams distribute parallel for simd default(none) private(b) firstprivate(argv) shared(d) reduction(+: c) reduction(max: e) num_teams(f) thread_limit(d)
// CHECK: #pragma omp target teams distribute parallel for simd simdlen(slen1) safelen(slen2) aligned(arr: alen)
@@ -135,10 +136,10 @@ T tmain(T argc) {
// CHECK: #pragma omp target teams distribute parallel for simd default(none) private(b) firstprivate(argc) shared(d) reduction(+: c) reduction(max: e) num_teams(f) thread_limit(d)
// CHECK-NEXT: for (int k = 0; k < 10; ++k)
// CHECK-NEXT: e += d + argc;
-#pragma omp target teams distribute parallel for simd simdlen(clen-1) linear(d)
+#pragma omp target teams distribute parallel for simd simdlen(clen-1)
for (int k = 0; k < 10; ++k)
e += d + argc;
-// CHECK: #pragma omp target teams distribute parallel for simd simdlen(clen - 1) linear(d)
+// CHECK: #pragma omp target teams distribute parallel for simd simdlen(clen - 1)
// CHECK-NEXT: for (int k = 0; k < 10; ++k)
// CHECK-NEXT: e += d + argc;
#pragma omp target teams distribute parallel for simd safelen(clen-1) aligned(arr:alen)
@@ -186,10 +187,10 @@ int main (int argc, char **argv) {
// CHECK: #pragma omp target teams distribute parallel for simd default(none) private(b) firstprivate(argc) shared(d) reduction(+: c) reduction(max: e) num_teams(f) thread_limit(d)
// CHECK-NEXT: for (int k = 0; k < 10; ++k)
// CHECK-NEXT: e += d + argc;
-#pragma omp target teams distribute parallel for simd simdlen(clen-1) linear(d)
+#pragma omp target teams distribute parallel for simd simdlen(clen-1)
for (int k = 0; k < 10; ++k)
e += d + argc;
-// CHECK: #pragma omp target teams distribute parallel for simd simdlen(clen - 1) linear(d)
+// CHECK: #pragma omp target teams distribute parallel for simd simdlen(clen - 1)
// CHECK-NEXT: for (int k = 0; k < 10; ++k)
// CHECK-NEXT: e += d + argc;
#pragma omp target teams distribute parallel for simd safelen(clen-1) aligned(arr:N+6)
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_simd_depend_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_simd_depend_messages.cpp
index 2dc9979cdc1c..4a9bf01e40bf 100644
--- a/test/OpenMP/target_teams_distribute_parallel_for_simd_depend_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_parallel_for_simd_depend_messages.cpp
@@ -37,21 +37,21 @@ int main(int argc, char **argv, char *env[]) {
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute parallel for simd depend (out: ) // expected-error {{expected expression}}
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute parallel for simd depend (inout : foobool(argc)), depend (in, argc) // expected-error {{expected variable name, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}}
+#pragma omp target teams distribute parallel for simd depend (inout : foobool(argc)), depend (in, argc) // expected-error {{expected addressable lvalue expression, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}}
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute parallel for simd depend (out :S1) // expected-error {{'S1' does not refer to a value}}
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute parallel for simd depend(in : argv[1][1] = '2') // expected-error {{expected variable name, array element or array section}}
+#pragma omp target teams distribute parallel for simd depend(in : argv[1][1] = '2')
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute parallel for simd depend (in : vec[1]) // expected-error {{expected variable name, array element or array section}}
+#pragma omp target teams distribute parallel for simd depend (in : vec[1]) // expected-error {{expected addressable lvalue expression, array element or array section}}
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute parallel for simd depend (in : argv[0])
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute parallel for simd depend (in : ) // expected-error {{expected expression}}
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute parallel for simd depend (in : main) // expected-error {{expected variable name, array element or array section}}
+#pragma omp target teams distribute parallel for simd depend (in : main)
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute parallel for simd depend(in : a[0]) // expected-error{{expected variable name, array element or array section}}
+#pragma omp target teams distribute parallel for simd depend(in : a[0]) // expected-error{{expected addressable lvalue expression, array element or array section}}
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute parallel for simd depend (in : vec[1:2]) // expected-error {{ value is not an array or pointer}}
for (i = 0; i < argc; ++i) foo();
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_simd_firstprivate_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_simd_firstprivate_messages.cpp
index d26044abc81b..4790b4bffdaf 100644
--- a/test/OpenMP/target_teams_distribute_parallel_for_simd_firstprivate_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_parallel_for_simd_firstprivate_messages.cpp
@@ -124,7 +124,8 @@ int main(int argc, char **argv) {
#pragma omp target teams distribute parallel for simd firstprivate(j)
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute parallel for simd lastprivate(argc), firstprivate(argc) // OK
+// expected-error@+1 {{lastprivate variable cannot be firstprivate}} expected-note@+1 {{defined as lastprivate}}
+#pragma omp target teams distribute parallel for simd lastprivate(argc), firstprivate(argc)
for (i = 0; i < argc; ++i) foo();
return 0;
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_simd_lastprivate_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_simd_lastprivate_messages.cpp
index 954830eb19f5..156f1a66c191 100644
--- a/test/OpenMP/target_teams_distribute_parallel_for_simd_lastprivate_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_parallel_for_simd_lastprivate_messages.cpp
@@ -18,14 +18,14 @@ public:
const S2 &operator =(const S2&) const;
S2 &operator =(const S2&);
static float S2s; // expected-note {{static data member is predetermined as shared}}
- static const float S2sc;
+ static const float S2sc; // expected-note {{static data member is predetermined as shared}}
};
-const float S2::S2sc = 0; // expected-note {{static data member is predetermined as shared}}
+const float S2::S2sc = 0;
const S2 b;
const S2 ba[5];
class S3 {
int a;
- S3 &operator=(const S3 &s3); // expected-note 2 {{implicitly declared private here}}
+ S3 &operator=(const S3 &s3); // expected-note {{implicitly declared private here}}
public:
S3() : a(0) {}
@@ -52,7 +52,7 @@ public:
};
class S6 {
int a;
- S6() : a(0) {}
+ S6() : a(0) {} // expected-note {{implicitly declared private here}}
public:
S6(const S6 &s6) : a(s6.a) {}
@@ -216,10 +216,12 @@ int main(int argc, char **argv) {
#pragma omp target teams distribute parallel for simd lastprivate(j)
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute parallel for simd firstprivate(m) lastprivate(m) // expected-error {{'operator=' is a private member of 'S3'}}
+// expected-error@+1 {{firstprivate variable cannot be lastprivate}} expected-note@+1 {{defined as firstprivate}}
+#pragma omp target teams distribute parallel for simd firstprivate(m) lastprivate(m)
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute parallel for simd lastprivate(n) firstprivate(n) // OK
+// expected-error@+1 {{lastprivate variable cannot be firstprivate}} expected-note@+1 {{defined as lastprivate}}
+#pragma omp target teams distribute parallel for simd lastprivate(n) firstprivate(n) // expected-error {{calling a private constructor of class 'S6'}}
for (i = 0; i < argc; ++i) foo();
static int si;
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_simd_linear_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_simd_linear_messages.cpp
index 24c432ade9e4..257244ede444 100644
--- a/test/OpenMP/target_teams_distribute_parallel_for_simd_linear_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_parallel_for_simd_linear_messages.cpp
@@ -18,33 +18,42 @@ void test_linear_colons()
{
int B = 0;
+// expected-error@+1 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target teams distribute parallel for simd linear(B:bfoo())
for (int i = 0; i < 10; ++i) ;
+// expected-error@+1 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target teams distribute parallel for simd linear(B::ib:B:bfoo()) // expected-error {{unexpected ':' in nested name specifier; did you mean '::'}}
for (int i = 0; i < 10; ++i) ;
+// expected-error@+1 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target teams distribute parallel for simd linear(B:ib) // expected-error {{use of undeclared identifier 'ib'; did you mean 'B::ib'}}
for (int i = 0; i < 10; ++i) ;
+// expected-error@+1 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target teams distribute parallel for simd linear(z:B:ib) // expected-error {{unexpected ':' in nested name specifier; did you mean '::'?}}
for (int i = 0; i < 10; ++i) ;
+// expected-error@+1 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target teams distribute parallel for simd linear(B:B::bfoo())
for (int i = 0; i < 10; ++i) ;
+// expected-error@+1 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target teams distribute parallel for simd linear(X::x : ::z)
for (int i = 0; i < 10; ++i) ;
+// expected-error@+1 3 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target teams distribute parallel for simd linear(B,::z, X::x)
for (int i = 0; i < 10; ++i) ;
+// expected-error@+1 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target teams distribute parallel for simd linear(::z)
for (int i = 0; i < 10; ++i) ;
#pragma omp target teams distribute parallel for simd linear(B::bfoo()) // expected-error {{expected variable name}}
for (int i = 0; i < 10; ++i) ;
+// expected-error@+1 2 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target teams distribute parallel for simd linear(B::ib,B:C1+C2)
for (int i = 0; i < 10; ++i) ;
}
@@ -65,6 +74,7 @@ template<int L, class T, class N> T test_template(T* arr, N num) {
template<int LEN> int test_warn() {
int ind2 = 0;
+// expected-error@+1 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target teams distribute parallel for simd linear(ind2:LEN) // expected-warning {{zero linear step (ind2 should probably be const)}}
for (int i = 0; i < 100; i++) {
ind2 += LEN;
@@ -118,15 +128,18 @@ template<class I, class C> int foomain(I argc, C **argv) {
#pragma omp target teams distribute parallel for simd linear () // expected-error {{expected expression}}
for (int k = 0; k < argc; ++k) ++k;
+// expected-error@+1 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target teams distribute parallel for simd linear (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
for (int k = 0; k < argc; ++k) ++k;
+// expected-error@+1 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target teams distribute parallel for simd linear (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
for (int k = 0; k < argc; ++k) ++k;
#pragma omp target teams distribute parallel for simd linear (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
for (int k = 0; k < argc; ++k) ++k;
+// expected-error@+1 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target teams distribute parallel for simd linear (argc : 5)
for (int k = 0; k < argc; ++k) ++k;
@@ -139,33 +152,17 @@ template<class I, class C> int foomain(I argc, C **argv) {
#pragma omp target teams distribute parallel for simd linear (argv[1]) // expected-error {{expected variable name}}
for (int k = 0; k < argc; ++k) ++k;
+// expected-error@+1 2 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target teams distribute parallel for simd linear(e, g)
for (int k = 0; k < argc; ++k) ++k;
#pragma omp target teams distribute parallel for simd linear(h) // expected-error {{threadprivate or thread local variable cannot be linear}}
for (int k = 0; k < argc; ++k) ++k;
+// expected-error@+1 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target teams distribute parallel for simd linear(i)
for (int k = 0; k < argc; ++k) ++k;
- #pragma omp parallel
- {
- int v = 0;
- int i;
- #pragma omp target teams distribute parallel for simd linear(v:i)
- for (int k = 0; k < argc; ++k) { i = k; v += i; }
- }
-
-#pragma omp target teams distribute parallel for simd linear(j)
- for (int k = 0; k < argc; ++k) ++k;
-
- int v = 0;
-
-#pragma omp target teams distribute parallel for simd linear(v:j)
- for (int k = 0; k < argc; ++k) { ++k; v += j; }
-
-#pragma omp target teams distribute parallel for simd linear(i)
- for (int k = 0; k < argc; ++k) ++k;
return 0;
}
@@ -198,15 +195,18 @@ int main(int argc, char **argv) {
#pragma omp target teams distribute parallel for simd linear () // expected-error {{expected expression}}
for (int k = 0; k < argc; ++k) ++k;
+// expected-error@+1 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target teams distribute parallel for simd linear (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
for (int k = 0; k < argc; ++k) ++k;
+// expected-error@+1 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target teams distribute parallel for simd linear (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
for (int k = 0; k < argc; ++k) ++k;
#pragma omp target teams distribute parallel for simd linear (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
for (int k = 0; k < argc; ++k) ++k;
+// expected-error@+1 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target teams distribute parallel for simd linear (argc)
for (int k = 0; k < argc; ++k) ++k;
@@ -226,22 +226,6 @@ int main(int argc, char **argv) {
#pragma omp target teams distribute parallel for simd linear(h, C::x) // expected-error 2 {{threadprivate or thread local variable cannot be linear}}
for (int k = 0; k < argc; ++k) ++k;
- #pragma omp parallel
- {
- int i;
- #pragma omp target teams distribute parallel for simd linear(i)
- for (int k = 0; k < argc; ++k) ++k;
-
- #pragma omp target teams distribute parallel for simd linear(i : 4)
- for (int k = 0; k < argc; ++k) { ++k; i += 4; }
- }
-
-#pragma omp target teams distribute parallel for simd linear(j)
- for (int k = 0; k < argc; ++k) ++k;
-
-#pragma omp target teams distribute parallel for simd linear(i)
- for (int k = 0; k < argc; ++k) ++k;
-
foomain<int,char>(argc,argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}}
return 0;
}
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_simd_loop_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_simd_loop_messages.cpp
index 0ed57baa5c3b..a16dec190dd2 100644
--- a/test/OpenMP/target_teams_distribute_parallel_for_simd_loop_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_parallel_for_simd_loop_messages.cpp
@@ -2,7 +2,7 @@
class S {
int a;
- S() : a(0) {}
+ S() : a(0) {} // expected-note {{implicitly declared private here}}
public:
S(int v) : a(v) {}
@@ -608,7 +608,8 @@ void test_loop_eh() {
void test_loop_firstprivate_lastprivate() {
S s(4);
-#pragma omp target teams distribute parallel for simd lastprivate(s) firstprivate(s)
+// expected-error@+1 {{lastprivate variable cannot be firstprivate}} expected-note@+1 {{defined as lastprivate}}
+#pragma omp target teams distribute parallel for simd lastprivate(s) firstprivate(s) // expected-error {{calling a private constructor of class 'S'}}
for (int i = 0; i < 16; ++i)
;
}
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_simd_map_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_simd_map_messages.cpp
index 8f9c3e7e073c..b230d9ab24fe 100644
--- a/test/OpenMP/target_teams_distribute_parallel_for_simd_map_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_parallel_for_simd_map_messages.cpp
@@ -14,8 +14,8 @@ class S2 {
public:
S2():a(0) { }
S2(S2 &s2):a(s2.a) { }
- static float S2s; // expected-note 4 {{mappable type cannot contain static members}}
- static const float S2sc; // expected-note 4 {{mappable type cannot contain static members}}
+ static float S2s;
+ static const float S2sc;
};
const float S2::S2sc = 0;
const S2 b;
@@ -116,9 +116,9 @@ T tmain(T argc) {
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute parallel for simd map(S1) // expected-error {{'S1' does not refer to a value}}
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute parallel for simd map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} expected-error 2 {{type 'S2' is not mappable to target}}
+#pragma omp target teams distribute parallel for simd map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}}
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute parallel for simd map(ba) // expected-error 2 {{type 'S2' is not mappable to target}}
+#pragma omp target teams distribute parallel for simd map(ba)
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute parallel for simd map(ca)
for (i = 0; i < argc; ++i) foo();
@@ -222,11 +222,11 @@ int main(int argc, char **argv) {
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute parallel for simd map(S1) // expected-error {{'S1' does not refer to a value}}
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute parallel for simd map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} expected-error 2 {{type 'S2' is not mappable to target}}
+#pragma omp target teams distribute parallel for simd map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}}
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute parallel for simd map(argv[1])
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute parallel for simd map(ba) // expected-error 2 {{type 'S2' is not mappable to target}}
+#pragma omp target teams distribute parallel for simd map(ba)
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute parallel for simd map(ca)
for (i = 0; i < argc; ++i) foo();
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_simd_misc_messages.c b/test/OpenMP/target_teams_distribute_parallel_for_simd_misc_messages.c
index d444844be5b4..1ea02f6d2b57 100644
--- a/test/OpenMP/target_teams_distribute_parallel_for_simd_misc_messages.c
+++ b/test/OpenMP/target_teams_distribute_parallel_for_simd_misc_messages.c
@@ -285,15 +285,22 @@ void test_firstprivate() {
;
int x, y, z;
+// expected-error@+1 {{lastprivate variable cannot be firstprivate}} expected-note@+1 {{defined as lastprivate}}
#pragma omp target teams distribute parallel for simd lastprivate(x) firstprivate(x)
for (i = 0; i < 16; ++i)
;
+// expected-error@+1 2 {{lastprivate variable cannot be firstprivate}} expected-note@+1 2 {{defined as lastprivate}}
#pragma omp target teams distribute parallel for simd lastprivate(x, y) firstprivate(x, y)
for (i = 0; i < 16; ++i)
;
+// expected-error@+1 3 {{lastprivate variable cannot be firstprivate}} expected-note@+1 3 {{defined as lastprivate}}
#pragma omp target teams distribute parallel for simd lastprivate(x, y, z) firstprivate(x, y, z)
for (i = 0; i < 16; ++i)
;
+// expected-error@+1 {{the value of 'simdlen' parameter must be less than or equal to the value of the 'safelen' parameter}}
+#pragma omp target teams distribute parallel for simd simdlen(64) safelen(8)
+ for (i = 0; i < 16; ++i)
+ ;
}
void test_loop_messages() {
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_simd_reduction_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_simd_reduction_messages.cpp
index cadccbf5cda3..63744c77fb3a 100644
--- a/test/OpenMP/target_teams_distribute_parallel_for_simd_reduction_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_parallel_for_simd_reduction_messages.cpp
@@ -19,9 +19,9 @@ public:
S2() : a(0) {}
S2(S2 &s2) : a(s2.a) {}
static float S2s; // expected-note 2 {{static data member is predetermined as shared}}
- static const float S2sc;
+ static const float S2sc; // expected-note 2 {{'S2sc' declared here}}
};
-const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}}
+const float S2::S2sc = 0;
S2 b; // expected-note 3 {{'b' defined here}}
const S2 ba[5]; // expected-note 2 {{'ba' defined here}}
class S3 {
diff --git a/test/OpenMP/target_teams_distribute_private_codegen.cpp b/test/OpenMP/target_teams_distribute_private_codegen.cpp
new file mode 100644
index 000000000000..7c88c01c4ab3
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_private_codegen.cpp
@@ -0,0 +1,233 @@
+// RUN: %clang_cc1 -DCHECK -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -DCHECK -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+
+// RUN: %clang_cc1 -DLAMBDA -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+struct St {
+ int a, b;
+ St() : a(0), b(0) {}
+ St(const St &st) : a(st.a + st.b), b(0) {}
+ ~St() {}
+};
+
+volatile int g = 1212;
+volatile int &g1 = g;
+
+template <class T>
+struct S {
+ T f;
+ S(T a) : f(a + g) {}
+ S() : f(g) {}
+ S(const S &s, St t = St()) : f(s.f + t.a) {}
+ operator T() { return T(); }
+ ~S() {}
+};
+
+// CHECK-DAG: [[S_FLOAT_TY:%.+]] = type { float }
+// CHECK-DAG: [[S_INT_TY:%.+]] = type { i{{[0-9]+}} }
+
+template <typename T>
+T tmain() {
+ S<T> test;
+ T t_var = T();
+ T vec[] = {1, 2};
+ S<T> s_arr[] = {1, 2};
+ S<T> &var = test;
+#pragma omp target teams distribute private(t_var, vec, s_arr, var)
+ for (int i = 0; i < 2; ++i) {
+ vec[i] = t_var;
+ s_arr[i] = var;
+ }
+ return T();
+}
+
+// CHECK-DAG: [[TEST:@.+]] = global [[S_FLOAT_TY]] zeroinitializer,
+S<float> test;
+// CHECK-DAG: [[T_VAR:@.+]] = global i{{[0-9]+}} 333,
+int t_var = 333;
+// CHECK-DAG: [[VEC:@.+]] = global [2 x i{{[0-9]+}}] [i{{[0-9]+}} 1, i{{[0-9]+}} 2],
+int vec[] = {1, 2};
+// CHECK-DAG: [[S_ARR:@.+]] = global [2 x [[S_FLOAT_TY]]] zeroinitializer,
+S<float> s_arr[] = {1, 2};
+// CHECK-DAG: [[VAR:@.+]] = global [[S_FLOAT_TY]] zeroinitializer,
+S<float> var(3);
+// CHECK-DAG: [[SIVAR:@.+]] = internal global i{{[0-9]+}} 0,
+
+int main() {
+ static int sivar;
+#ifdef LAMBDA
+ // LAMBDA: [[G:@.+]] = global i{{[0-9]+}} 1212,
+ // LAMBDA-LABEL: @main
+ // LAMBDA: call void [[OUTER_LAMBDA:@.+]](
+ [&]() {
+ // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
+ // LAMBDA: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 0, i8** null, i8** null, i{{64|32}}* null, i64* null, i32 0, i32 0)
+ // LAMBDA: call void @[[LOFFL1:.+]]()
+ // LAMBDA: ret
+#pragma omp target teams distribute private(g, g1, sivar)
+ for (int i = 0; i < 2; ++i) {
+ // LAMBDA: define{{.*}} internal{{.*}} void @[[LOFFL1]]()
+ // LAMBDA: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 0, {{.+}} @[[LOUTL1:.+]] to {{.+}})
+ // LAMBDA: ret void
+
+ // LAMBDA: define internal void @[[LOUTL1]]({{.+}})
+ // Skip global, bound tid and loop vars
+ // LAMBDA: {{.+}} = alloca i32*,
+ // LAMBDA: {{.+}} = alloca i32*,
+ // LAMBDA: alloca i32,
+ // LAMBDA: alloca i32,
+ // LAMBDA: alloca i32,
+ // LAMBDA: alloca i32,
+ // LAMBDA: alloca i32,
+ // LAMBDA: alloca i32,
+ // LAMBDA: [[G_PRIV:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[G1_PRIV:%.+]] = alloca i{{[0-9]+}}
+ // LAMBDA: [[TMP:%.+]] = alloca i{{[0-9]+}}*,
+ // LAMBDA: [[SIVAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: store{{.+}} [[G1_PRIV]], {{.+}} [[TMP]],
+ g = 1;
+ g1 = 1;
+ sivar = 2;
+ // LAMBDA: call void @__kmpc_for_static_init_4(
+ // LAMBDA-DAG: store{{.+}} 1, {{.+}} [[G_PRIV]],
+ // LAMBDA-DAG: store{{.+}} 2, {{.+}} [[SIVAR_PRIV]],
+ // LAMBDA-DAG: [[G1_REF:%.+]] = load{{.+}}, {{.+}} [[TMP]],
+ // LAMBDA-DAG: store{{.+}} 1, {{.+}} [[G1_REF]],
+ // LAMBDA: call void [[INNER_LAMBDA:@.+]](
+ // LAMBDA: call void @__kmpc_for_static_fini(
+ [&]() {
+ // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]])
+ // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]],
+ g = 2;
+ g1 = 2;
+ sivar = 4;
+ // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]]
+
+ // LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // LAMBDA: [[G_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G_PTR_REF]]
+ // LAMBDA: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[G_REF]]
+ // LAMBDA: [[G1_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // LAMBDA: [[G1_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G1_PTR_REF]]
+ // LAMBDA: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[G1_REF]]
+ // LAMBDA: [[SIVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+ // LAMBDA: [[SIVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SIVAR_PTR_REF]]
+ // LAMBDA: store i{{[0-9]+}} 4, i{{[0-9]+}}* [[SIVAR_REF]]
+ }();
+ }
+ }();
+ return 0;
+#else
+#pragma omp target teams distribute private(t_var, vec, s_arr, var, sivar)
+ for (int i = 0; i < 2; ++i) {
+ vec[i] = t_var;
+ s_arr[i] = var;
+ sivar += i;
+ }
+ return tmain<int>();
+#endif
+}
+
+// CHECK: define {{.*}}i{{[0-9]+}} @main()
+// CHECK: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 0, i8** null, i8** null, i{{64|32}}* null, i64* null, i32 0, i32 0)
+// CHECK: call void @[[OFFL1:.+]]()
+// CHECK: {{%.+}} = call{{.*}} i32 @[[TMAIN_INT:.+]]()
+// CHECK: ret
+
+// CHECK: define{{.*}} void @[[OFFL1]]()
+// CHECK: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 0, {{.+}} @[[OUTL1:.+]] to {{.+}})
+// CHECK: ret void
+
+// CHECK: define internal void @[[OUTL1]]({{.+}})
+// Skip global, bound tid and loop vars
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: {{.+}} = alloca i32,
+// CHECK: {{.+}} = alloca i32,
+// CHECK: {{.+}} = alloca i32,
+// CHECK: {{.+}} = alloca i32,
+// CHECK: {{.+}} = alloca i32,
+// CHECK: {{.+}} = alloca i32,
+// CHECK-DAG: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK-DAG: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK-DAG: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]],
+// CHECK-DAG: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]],
+// CHECK-DAG: [[SIVAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+
+// private(s_arr)
+// CHECK-DAG: [[S_ARR_PRIV_BGN:%.+]] = getelementptr{{.*}} [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[S_ARR_PRIV]],
+// CHECK-DAG: [[S_ARR_PTR_ALLOC:%.+]] = phi{{.+}} [ [[S_ARR_PRIV_BGN]], {{.+}} ], [ [[S_ARR_NEXT:%.+]], {{.+}} ]
+// CHECK-DAG: call void @{{.+}}({{.+}} [[S_ARR_PTR_ALLOC]])
+// CHECK-DAG: [[S_ARR_NEXT]] = getelementptr {{.+}} [[S_ARR_PTR_ALLOC]],
+
+// private(var)
+// CHECK-DAG: call void @{{.+}}({{.+}} [[VAR_PRIV]])
+
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK-DAG: {{.+}} = {{.+}} [[T_VAR_PRIV]]
+// CHECK-DAG: {{.+}} = {{.+}} [[VEC_PRIV]]
+// CHECK-DAG: {{.+}} = {{.+}} [[S_ARR_PRIV]]
+// CHECK-DAG: {{.+}} = {{.+}} [[VAR_PRIV]]
+// CHECK-DAG: {{.+}} = {{.+}} [[SIVAR_PRIV]]
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: ret void
+
+
+// CHECK: define{{.*}} i{{[0-9]+}} @[[TMAIN_INT]]()
+// CHECK: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 0,
+// CHECK: call void @[[TOFFL1:.+]]()
+// CHECK: ret
+
+// CHECK: define {{.*}}void @[[TOFFL1]]()
+// CHECK: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 0, {{.+}} @[[TOUTL1:.+]] to {{.+}})
+// CHECK: ret void
+
+// CHECK: define internal void @[[TOUTL1]]({{.+}})
+// Skip global, bound tid and loop vars
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_INT_TY]]],
+// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_INT_TY]],
+// CHECK: [[TMP:%.+]] = alloca [[S_INT_TY]]*,
+
+// private(s_arr)
+// CHECK-DAG: [[S_ARR_PRIV_BGN:%.+]] = getelementptr{{.*}} [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[S_ARR_PRIV]],
+// CHECK-DAG: [[S_ARR_PTR_ALLOC:%.+]] = phi{{.+}} [ [[S_ARR_PRIV_BGN]], {{.+}} ], [ [[S_ARR_NEXT:%.+]], {{.+}} ]
+// CHECK-DAG: call void @{{.+}}({{.+}} [[S_ARR_PTR_ALLOC]])
+// CHECK-DAG: [[S_ARR_NEXT]] = getelementptr {{.+}} [[S_ARR_PTR_ALLOC]],
+
+// CHECK-DAG: [[S_ARR_PRIV_BGN:%.+]] = getelementptr{{.*}} [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[S_ARR_PRIV]],
+// CHECK-DAG: [[S_ARR_PTR_ALLOC:%.+]] = phi{{.+}} [ [[S_ARR_PRIV_BGN]], {{.+}} ], [ [[S_ARR_NEXT:%.+]], {{.+}} ]
+// CHECK-DAG: call void @{{.+}}({{.+}} [[S_ARR_PTR_ALLOC]])
+// CHECK-DAG: [[S_ARR_NEXT]] = getelementptr {{.+}} [[S_ARR_PTR_ALLOC]],
+
+// private(var)
+// CHECK-DAG: call void @{{.+}}({{.+}} [[VAR_PRIV]])
+// CHECK-DAG: store{{.+}} [[VAR_PRIV]], {{.+}} [[TMP]]
+
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK-DAG: {{.+}} = {{.+}} [[T_VAR_PRIV]]
+// CHECK-DAG: {{.+}} = {{.+}} [[VEC_PRIV]]
+// CHECK-DAG: {{.+}} = {{.+}} [[S_ARR_PRIV]]
+// CHECK-DAG: {{.+}} = {{.+}} [[TMP]]
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: ret void
+
+#endif
diff --git a/test/OpenMP/target_teams_distribute_reduction_codegen.cpp b/test/OpenMP/target_teams_distribute_reduction_codegen.cpp
new file mode 100644
index 000000000000..188b75306453
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_reduction_codegen.cpp
@@ -0,0 +1,211 @@
+// RUN: %clang_cc1 -DCHECK -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -DCHECK -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+
+// RUN: %clang_cc1 -DLAMBDA -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+template <typename T>
+T tmain() {
+ T t_var = T();
+ T vec[] = {1, 2};
+#pragma omp target teams distribute reduction(+: t_var)
+ for (int i = 0; i < 2; ++i) {
+ t_var += (T) i;
+ }
+ return T();
+}
+
+int main() {
+ static int sivar;
+#ifdef LAMBDA
+ // LAMBDA: [[RED_VAR:@.+]] = common global [8 x {{.+}}] zeroinitializer
+
+ // LAMBDA-LABEL: @main
+ // LAMBDA: call void [[OUTER_LAMBDA:@.+]](
+ [&]() {
+ // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
+ // LAMBDA: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 1, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 0)
+ // LAMBDA: call void @[[LOFFL1:.+]](
+ // LAMBDA: ret
+#pragma omp target teams distribute reduction(+: sivar)
+ for (int i = 0; i < 2; ++i) {
+ // LAMBDA: define{{.*}} internal{{.*}} void @[[LOFFL1]](i32*{{.+}} [[SIVAR_ARG:%.+]])
+ // LAMBDA: [[SIVAR_ADDR:%.+]] = alloca i{{.+}}*,
+ // LAMBDA: store{{.+}} [[SIVAR_ARG]], {{.+}} [[SIVAR_ADDR]],
+ // LAMBDA: [[SIVAR:%.+]] = load i32*, i32** [[SIVAR_ADDR]],
+ // LAMBDA: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[LOUTL1:.+]] to {{.+}}, {{.+}} [[SIVAR]])
+ // LAMBDA: ret void
+
+ // LAMBDA: define internal void @[[LOUTL1]]({{.+}}, {{.+}}, {{.+}}*{{.+}} [[SIVAR_ARG:%.+]])
+ // Skip global and bound tid vars
+ // LAMBDA: {{.+}} = alloca i32*,
+ // LAMBDA: {{.+}} = alloca i32*,
+ // LAMBDA: [[SIVAR_ADDR:%.+]] = alloca i{{.+}}*,
+ // LAMBDA: [[SIVAR_PRIV:%.+]] = alloca i{{.+}},
+ // LAMBDA: [[RED_LIST:%.+]] = alloca [1 x {{.+}}],
+ // LAMBDA: store{{.+}} [[SIVAR_ARG]], {{.+}} [[SIVAR_ADDR]],
+ // LAMBDA: [[SIVAR_REF:%.+]] = load {{.+}}, {{.+}} [[SIVAR_ADDR]],
+ // LAMBDA: store{{.+}} 0, {{.+}} [[SIVAR_PRIV]],
+
+ // LAMBDA: call void @__kmpc_for_static_init_4(
+ // LAMBDA: store{{.+}}, {{.+}} [[SIVAR_PRIV]],
+ // LAMBDA: call void [[INNER_LAMBDA:@.+]](
+ // LAMBDA: call void @__kmpc_for_static_fini(
+ // LAMBDA: [[RED_LIST_GEP:%.+]] = getelementptr{{.+}} [[RED_LIST]],
+ // LAMBDA: [[SIVAR_PRIV_CAST:%.+]] = bitcast{{.+}} [[SIVAR_PRIV]] to
+ // LAMBDA: store{{.+}} [[SIVAR_PRIV_CAST]], {{.+}} [[RED_LIST_GEP]],
+ // LAMBDA: [[RED_LIST_BCAST:%.+]] = bitcast{{.+}} [[RED_LIST]] to
+ // LAMBDA: [[K_RED_RET:%.+]] = call{{.+}} @__kmpc_reduce({{.+}}, {{.+}}, {{.+}}, {{.+}}, {{.+}} [[RED_LIST_BCAST]], {{.+}} [[RED_FUN:@.+]], {{.+}} [[RED_VAR]])
+ // LAMBDA: switch{{.+}} [[K_RED_RET]], label{{.+}} [
+ // LAMBDA: {{.+}}, label %[[CASE1:.+]]
+ // LAMBDA: {{.+}}, label %[[CASE2:.+]]
+ // LAMBDA: ]
+ // LAMBDA: [[CASE1]]:
+ // LAMBDA-DAG: [[SIVAR_VAL:%.+]] = load{{.+}}, {{.+}} [[SIVAR_REF]],
+ // LAMBDA-DAG: [[SIVAR_PRIV_VAL:%.+]] = load{{.+}}, {{.+}} [[SIVAR_PRIV]],
+ // LAMBDA-DAG: [[SIVAR_INC:%.+]] = add{{.+}} [[SIVAR_VAL]], [[SIVAR_PRIV_VAL]]
+ // LAMBDA: store{{.+}} [[SIVAR_INC]], {{.+}} [[SIVAR_REF]],
+ // LAMBDA: call void @__kmpc_end_reduce({{.+}}, {{.+}}, {{.+}} [[RED_VAR]])
+ // LAMBDA: br
+ // LAMBDA: [[CASE2]]:
+ // LAMBDA-DAG: [[SIVAR_PRIV_VAL:%.+]] = load{{.+}}, {{.+}} [[SIVAR_PRIV]],
+ // LAMBDA-DAG: [[ATOMIC_RES:%.+]] = atomicrmw add{{.+}} [[SIVAR_REF]], {{.+}} [[SIVAR_PRIV_VAL]]
+ // LAMBDA: call void @__kmpc_end_reduce({{.+}}, {{.+}}, {{.+}} [[RED_VAR]])
+ // LAMBDA: br
+ sivar += i;
+
+ [&]() {
+ // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]])
+ // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]],
+
+ sivar += 4;
+ // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]]
+
+ // LAMBDA: [[SIVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // LAMBDA: [[SIVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SIVAR_PTR_REF]]
+ // LAMBDA: [[SIVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR_REF]]
+ // LAMBDA: [[SIVAR_INC:%.+]] = add{{.+}} [[SIVAR_VAL]], 4
+ // LAMBDA: store i{{[0-9]+}} [[SIVAR_INC]], i{{[0-9]+}}* [[SIVAR_REF]]
+ }();
+ }
+ }();
+ return 0;
+#else
+#pragma omp target teams distribute reduction(+: sivar)
+ for (int i = 0; i < 2; ++i) {
+ sivar += i;
+ }
+ return tmain<int>();
+#endif
+}
+
+// CHECK: [[RED_VAR:@.+]] = common global [8 x {{.+}}] zeroinitializer
+
+// CHECK: define {{.*}}i{{[0-9]+}} @main()
+// CHECK: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 1, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 0)
+// CHECK: call void @[[OFFL1:.+]](i32* {{.+}})
+// CHECK: [[RES:%.+]] = call{{.*}} i32 @[[TMAIN_INT:[^(]+]]()
+// CHECK: ret i32 [[RES]]
+
+// CHECK: define{{.*}} void @[[OFFL1]](i32*{{.+}} [[SIVAR_ARG:%.+]])
+// CHECK: [[SIVAR_ADDR:%.+]] = alloca i{{.+}}*,
+// CHECK: store{{.+}} [[SIVAR_ARG]], {{.+}}** [[SIVAR_ADDR]],
+// CHECK: [[SIVAR_LOAD:%.+]] = load i32*, i32** [[SIVAR_ADDR]],
+// CHECK: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTL1:.+]] to {{.+}}, {{.+}} [[SIVAR_LOAD]])
+// CHECK: ret void
+
+// CHECK: define internal void @[[OUTL1]]({{.+}}, {{.+}}, i32*{{.+}} [[SIVAR_ARG:%.+]])
+// Skip global and bound tid vars
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: [[SIVAR_ADDR:%.+]] = alloca i{{.+}}*,
+// CHECK: [[SIVAR_PRIV:%.+]] = alloca i32,
+// CHECK: [[RED_LIST:%.+]] = alloca [1 x {{.+}}],
+// CHECK: store{{.+}} [[SIVAR_ARG]], {{.+}} [[SIVAR_ADDR]],
+// CHECK: [[SIVAR_REF:%.+]] = load i32*, i32** [[SIVAR_ADDR]],
+// CHECK: store{{.+}} 0, {{.+}} [[SIVAR_PRIV]],
+
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: store{{.+}}, {{.+}} [[SIVAR_PRIV]],
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: [[RED_LIST_GEP:%.+]] = getelementptr{{.+}} [[RED_LIST]],
+// CHECK: [[SIVAR_PRIV_CAST:%.+]] = bitcast{{.+}} [[SIVAR_PRIV]] to
+// CHECK: store{{.+}} [[SIVAR_PRIV_CAST]], {{.+}} [[RED_LIST_GEP]],
+// CHECK: [[RED_LIST_BCAST:%.+]] = bitcast{{.+}} [[RED_LIST]] to
+// CHECK: [[K_RED_RET:%.+]] = call{{.+}} @__kmpc_reduce({{.+}}, {{.+}}, {{.+}}, {{.+}}, {{.+}} [[RED_LIST_BCAST]], {{.+}} [[RED_FUN:@.+]], {{.+}} [[RED_VAR]])
+// CHECK: switch{{.+}} [[K_RED_RET]], label{{.+}} [
+// CHECK: {{.+}}, label %[[CASE1:.+]]
+// CHECK: {{.+}}, label %[[CASE2:.+]]
+// CHECK: ]
+// CHECK: [[CASE1]]:
+// CHECK-DAG: [[SIVAR_VAL:%.+]] = load{{.+}}, {{.+}} [[SIVAR_REF]],
+// CHECK-DAG: [[SIVAR_PRIV_VAL:%.+]] = load{{.+}}, {{.+}} [[SIVAR_PRIV]],
+// CHECK-DAG: [[SIVAR_INC:%.+]] = add{{.+}} [[SIVAR_VAL]], [[SIVAR_PRIV_VAL]]
+// CHECK: store{{.+}} [[SIVAR_INC]], {{.+}} [[SIVAR_REF]],
+// CHECK: call void @__kmpc_end_reduce({{.+}}, {{.+}}, {{.+}} [[RED_VAR]])
+// CHECK: br
+// CHECK: [[CASE2]]:
+// CHECK-DAG: [[SIVAR_PRIV_VAL:%.+]] = load{{.+}}, {{.+}} [[SIVAR_PRIV]],
+// CHECK-DAG: [[ATOMIC_RES:%.+]] = atomicrmw add{{.+}} [[SIVAR_REF]], {{.+}} [[SIVAR_PRIV_VAL]]
+// CHECK: call void @__kmpc_end_reduce({{.+}}, {{.+}}, {{.+}} [[RED_VAR]])
+// CHECK: br
+
+
+// CHECK: define{{.*}} i{{[0-9]+}} @[[TMAIN_INT]]()
+// CHECK: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 1,
+// CHECK: call void @[[TOFFL1:.+]]({{.+}}* {{.+}})
+// CHECK: ret
+
+// CHECK: define{{.*}} void @[[TOFFL1]](i32*{{.+}} [[TVAR_ARG:%.+]])
+// CHECK: [[TVAR_ADDR:%.+]] = alloca i{{.+}}*,
+// CHECK: store{{.+}} [[TVAR_ARG]], {{.+}} [[TVAR_ADDR]],
+// CHECK: [[TVAR:%.+]] = load i32*, i32** [[TVAR_ADDR]],
+// CHECK: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[TOUTL1:.+]] to {{.+}}, {{.+}} [[TVAR]])
+// CHECK: ret void
+
+// CHECK: define internal void @[[TOUTL1]]({{.+}}, {{.+}}, {{.+}}*{{.+}} [[TVAR_ARG:%.+]])
+// Skip global and bound tid vars
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: [[TVAR_ADDR:%.+]] = alloca i{{.+}}*,
+// CHECK: [[TVAR_PRIV:%.+]] = alloca i{{.+}},
+// CHECK: [[RED_LIST:%.+]] = alloca [1 x {{.+}}],
+// CHECK: store{{.+}} [[TVAR_ARG]], {{.+}} [[TVAR_ADDR]],
+// CHECK: [[TVAR_REF:%.+]] = load i32*, i32** [[TVAR_ADDR]],
+// CHECK: store{{.+}} 0, {{.+}} [[TVAR_PRIV]],
+
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: store{{.+}}, {{.+}} [[TVAR_PRIV]],
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: [[RED_LIST_GEP:%.+]] = getelementptr{{.+}} [[RED_LIST]],
+// CHECK: [[TVAR_PRIV_CAST:%.+]] = bitcast{{.+}} [[TVAR_PRIV]] to
+// CHECK: store{{.+}} [[TVAR_PRIV_CAST]], {{.+}} [[RED_LIST_GEP]],
+// CHECK: [[RED_LIST_BCAST:%.+]] = bitcast{{.+}} [[RED_LIST]] to
+// CHECK: [[K_RED_RET:%.+]] = call{{.+}} @__kmpc_reduce({{.+}}, {{.+}}, {{.+}}, {{.+}}, {{.+}} [[RED_LIST_BCAST]], {{.+}} [[RED_FUN:@.+]], {{.+}} [[RED_VAR]])
+// CHECK: switch{{.+}} [[K_RED_RET]], label{{.+}} [
+// CHECK: {{.+}}, label %[[CASE1:.+]]
+// CHECK: {{.+}}, label %[[CASE2:.+]]
+// CHECK: ]
+// CHECK: [[CASE1]]:
+// CHECK-DAG: [[TVAR_VAL:%.+]] = load{{.+}}, {{.+}} [[TVAR_REF]],
+// CHECK-DAG: [[TVAR_PRIV_VAL:%.+]] = load{{.+}}, {{.+}} [[TVAR_PRIV]],
+// CHECK-DAG: [[TVAR_INC:%.+]] = add{{.+}} [[TVAR_VAL]], [[TVAR_PRIV_VAL]]
+// CHECK: store{{.+}} [[TVAR_INC]], {{.+}} [[TVAR_REF]],
+// CHECK: call void @__kmpc_end_reduce({{.+}}, {{.+}}, {{.+}} [[RED_VAR]])
+// CHECK: br
+// CHECK: [[CASE2]]:
+// CHECK-DAG: [[TVAR_PRIV_VAL:%.+]] = load{{.+}}, {{.+}} [[TVAR_PRIV]],
+// CHECK-DAG: [[ATOMIC_RES:%.+]] = atomicrmw add{{.+}} [[TVAR_REF]], {{.+}} [[TVAR_PRIV_VAL]]
+// CHECK: call void @__kmpc_end_reduce({{.+}}, {{.+}}, {{.+}} [[RED_VAR]])
+// CHECK: br
+
+#endif
diff --git a/test/OpenMP/target_teams_distribute_reduction_messages.cpp b/test/OpenMP/target_teams_distribute_reduction_messages.cpp
index d52ee076130b..3cfb08651a61 100644
--- a/test/OpenMP/target_teams_distribute_reduction_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_reduction_messages.cpp
@@ -24,9 +24,9 @@ public:
S2() : a(0) {}
S2(S2 &s2) : a(s2.a) {}
static float S2s; // expected-note 2 {{static data member is predetermined as shared}}
- static const float S2sc;
+ static const float S2sc; // expected-note 2 {{'S2sc' declared here}}
};
-const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}}
+const float S2::S2sc = 0;
S2 b; // expected-note 3 {{'b' defined here}}
const S2 ba[5]; // expected-note 2 {{'ba' defined here}}
class S3 {
diff --git a/test/OpenMP/target_teams_distribute_simd_ast_print.cpp b/test/OpenMP/target_teams_distribute_simd_ast_print.cpp
index 77732ef56011..31b9ad0c5fc1 100644
--- a/test/OpenMP/target_teams_distribute_simd_ast_print.cpp
+++ b/test/OpenMP/target_teams_distribute_simd_ast_print.cpp
@@ -28,8 +28,9 @@ public:
++this->a.a;
}
S7 &operator=(S7 &s) {
-#pragma omp target teams distribute simd private(a) private(this->a)
- for (int k = 0; k < s.a.a; ++k)
+ int k;
+#pragma omp target teams distribute simd private(a) private(this->a) linear(k)
+ for (k = 0; k < s.a.a; ++k)
++s.a.a;
return *this;
}
@@ -50,7 +51,7 @@ public:
}
};
// CHECK: #pragma omp target teams distribute simd private(this->a) private(this->a) private(T::a)
-// CHECK: #pragma omp target teams distribute simd private(this->a) private(this->a)
+// CHECK: #pragma omp target teams distribute simd private(this->a) private(this->a) linear(k)
// CHECK: #pragma omp target teams distribute simd private(b) firstprivate(argv) shared(d) reduction(+: c) reduction(max: e) num_teams(f) thread_limit(d)
// CHECK: #pragma omp target teams distribute simd simdlen(slen1) safelen(slen2) aligned(arr: alen)
// CHECK: #pragma omp target teams distribute simd private(this->a) private(this->a) private(this->S::a)
@@ -129,10 +130,10 @@ T tmain(T argc) {
// CHECK: #pragma omp target teams distribute simd private(b) firstprivate(argc) shared(d) reduction(+: c) reduction(max: e) num_teams(f) thread_limit(d)
// CHECK-NEXT: for (int k = 0; k < 10; ++k)
// CHECK-NEXT: e += d + argc;
-#pragma omp target teams distribute simd simdlen(clen-1) linear(d)
+#pragma omp target teams distribute simd simdlen(clen-1)
for (int k = 0; k < 10; ++k)
e += d + argc;
-// CHECK: #pragma omp target teams distribute simd simdlen(clen - 1) linear(d)
+// CHECK: #pragma omp target teams distribute simd simdlen(clen - 1)
// CHECK-NEXT: for (int k = 0; k < 10; ++k)
// CHECK-NEXT: e += d + argc;
#pragma omp target teams distribute simd safelen(clen-1) aligned(arr:alen)
@@ -180,10 +181,10 @@ int main (int argc, char **argv) {
// CHECK: #pragma omp target teams distribute simd private(b) firstprivate(argc) shared(d) reduction(+: c) reduction(max: e) num_teams(f) thread_limit(d)
// CHECK-NEXT: for (int k = 0; k < 10; ++k)
// CHECK-NEXT: e += d + argc;
-#pragma omp target teams distribute simd simdlen(clen-1) linear(d)
+#pragma omp target teams distribute simd simdlen(clen-1)
for (int k = 0; k < 10; ++k)
e += d + argc;
-// CHECK: #pragma omp target teams distribute simd simdlen(clen - 1) linear(d)
+// CHECK: #pragma omp target teams distribute simd simdlen(clen - 1)
// CHECK-NEXT: for (int k = 0; k < 10; ++k)
// CHECK-NEXT: e += d + argc;
#pragma omp target teams distribute simd safelen(clen-1) aligned(arr:N+6)
diff --git a/test/OpenMP/target_teams_distribute_simd_codegen.cpp b/test/OpenMP/target_teams_distribute_simd_codegen.cpp
new file mode 100644
index 000000000000..7fb76d9198db
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_simd_codegen.cpp
@@ -0,0 +1,824 @@
+// Test host codegen.
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+
+// Test target codegen - host bc file has to be created first.
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm-bc %s -o %t-ppc-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-64
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-64
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm-bc %s -o %t-x86-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-32
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-32
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+
+// CHECK-DAG: %ident_t = type { i32, i32, i32, i32, i8* }
+// CHECK-DAG: [[STR:@.+]] = private unnamed_addr constant [23 x i8] c";unknown;unknown;0;0;;\00"
+// CHECK-DAG: [[DEF_LOC:@.+]] = private unnamed_addr constant %ident_t { i32 0, i32 2, i32 0, i32 0, i8* getelementptr inbounds ([23 x i8], [23 x i8]* [[STR]], i32 0, i32 0) }
+
+// CHECK-DAG: [[TT:%.+]] = type { i64, i8 }
+// CHECK-DAG: [[S1:%.+]] = type { double }
+// CHECK-DAG: [[ENTTY:%.+]] = type { i8*, i8*, i[[SZ:32|64]], i32, i32 }
+// CHECK-DAG: [[DEVTY:%.+]] = type { i8*, i8*, [[ENTTY]]*, [[ENTTY]]* }
+// CHECK-DAG: [[DSCTY:%.+]] = type { i32, [[DEVTY]]*, [[ENTTY]]*, [[ENTTY]]* }
+
+// TCHECK: [[ENTTY:%.+]] = type { i8*, i8*, i{{32|64}}, i32, i32 }
+
+// CHECK-DAG: $[[REGFN:\.omp_offloading\..+]] = comdat
+
+// We have 8 target regions, but only 7 that actually will generate offloading
+// code, only 6 will have mapped arguments, and only 4 have all-constant map
+// sizes.
+
+// CHECK-DAG: [[SIZET:@.+]] = private unnamed_addr constant [3 x i[[SZ]]] [i[[SZ]] 2, i[[SZ]] 4, i[[SZ]] 4]
+// CHECK-DAG: [[MAPT:@.+]] = private unnamed_addr constant [3 x i64] [i64 288, i64 288, i64 288]
+// CHECK-DAG: [[SIZET2:@.+]] = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 2]
+// CHECK-DAG: [[MAPT2:@.+]] = private unnamed_addr constant [1 x i64] [i64 288]
+// CHECK-DAG: [[SIZET3:@.+]] = private unnamed_addr constant [2 x i[[SZ]]] [i[[SZ]] 4, i[[SZ]] 2]
+// CHECK-DAG: [[MAPT3:@.+]] = private unnamed_addr constant [2 x i64] [i64 288, i64 288]
+// CHECK-DAG: [[MAPT4:@.+]] = private unnamed_addr constant [9 x i64] [i64 288, i64 547, i64 288, i64 547, i64 547, i64 288, i64 288, i64 547, i64 547]
+// CHECK-DAG: [[MAPT5:@.+]] = private unnamed_addr constant [5 x i64] [i64 547, i64 288, i64 288, i64 288, i64 547]
+// CHECK-DAG: [[SIZET6:@.+]] = private unnamed_addr constant [5 x i[[SZ]]] [i[[SZ]] 4, i[[SZ]] 4, i[[SZ]] 2, i[[SZ]] 1, i[[SZ]] 40]
+// CHECK-DAG: [[MAPT6:@.+]] = private unnamed_addr constant [5 x i64] [i64 288, i64 288, i64 288, i64 288, i64 547]
+// CHECK-DAG: [[SIZET7:@.+]] = private unnamed_addr constant [3 x i[[SZ]]] [i[[SZ]] 4, i[[SZ]] 2, i[[SZ]] 40]
+// CHECK-DAG: [[MAPT7:@.+]] = private unnamed_addr constant [3 x i64] [i64 288, i64 288, i64 547]
+// CHECK-DAG: @{{.*}} = private constant i8 0
+// CHECK-DAG: @{{.*}} = private constant i8 0
+// CHECK-DAG: @{{.*}} = private constant i8 0
+// CHECK-DAG: @{{.*}} = private constant i8 0
+// CHECK-DAG: @{{.*}} = private constant i8 0
+// CHECK-DAG: @{{.*}} = private constant i8 0
+// CHECK-DAG: @{{.*}} = private constant i8 0
+
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+// TCHECK: @{{.+}} = constant [[ENTTY]]
+// TCHECK-NOT: @{{.+}} = constant [[ENTTY]]
+
+// Check if offloading descriptor is created.
+// CHECK: [[ENTBEGIN:@.+]] = external constant [[ENTTY]]
+// CHECK: [[ENTEND:@.+]] = external constant [[ENTTY]]
+// CHECK: [[DEVBEGIN:@.+]] = external constant i8
+// CHECK: [[DEVEND:@.+]] = external constant i8
+// CHECK: [[IMAGES:@.+]] = internal unnamed_addr constant [1 x [[DEVTY]]] [{{.+}} { i8* [[DEVBEGIN]], i8* [[DEVEND]], [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }], comdat($[[REGFN]])
+// CHECK: [[DESC:@.+]] = internal constant [[DSCTY]] { i32 1, [[DEVTY]]* getelementptr inbounds ([1 x [[DEVTY]]], [1 x [[DEVTY]]]* [[IMAGES]], i32 0, i32 0), [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }, comdat($[[REGFN]])
+
+// Check target registration is registered as a Ctor.
+// CHECK: appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 0, void ()* bitcast (void (i8*)* @[[REGFN]] to void ()*), i8* bitcast (void (i8*)* @[[REGFN]] to i8*) }]
+
+
+template<typename tx, typename ty>
+struct TT{
+ tx X;
+ ty Y;
+};
+
+int global;
+
+// CHECK: define {{.*}}[[FOO:@.+]](
+int foo(int n) {
+ int a = 0;
+ short aa = 0;
+ float b[10];
+ float bn[n];
+ double c[5][10];
+ double cn[5][n];
+ TT<long long, char> d;
+
+ // CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams_nowait(i64 -1, i8* @{{[^,]+}}, i32 3, i8** [[BP:%[^,]+]], i8** [[P:%[^,]+]], i[[SZ]]* getelementptr inbounds ([3 x i[[SZ]]], [3 x i[[SZ]]]* [[SIZET]], i32 0, i32 0), i64* getelementptr inbounds ([3 x i64], [3 x i64]* [[MAPT]], i32 0, i32 0), i32 {{[^,]+}}, i32 {{[^)]+}})
+ // CHECK-DAG: [[BP]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BPR:%[^,]+]], i32 0, i32 0
+ // CHECK-DAG: [[P]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[PR:%[^,]+]], i32 0, i32 0
+ // CHECK-DAG: [[BPADDR0:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BPR]], i32 0, i32 [[IDX0:[0-9]+]]
+ // CHECK-DAG: [[PADDR0:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[PR]], i32 0, i32 [[IDX0]]
+ // CHECK-DAG: [[CBPADDR0:%.+]] = bitcast i8** [[BPADDR0]] to i[[SZ]]*
+ // CHECK-DAG: [[CPADDR0:%.+]] = bitcast i8** [[PADDR0]] to i[[SZ]]*
+ // CHECK-DAG: store i[[SZ]] %{{.+}}, i[[SZ]]* [[CBPADDR0]]
+ // CHECK-DAG: store i[[SZ]] %{{.+}}, i[[SZ]]* [[CPADDR0]]
+ // CHECK-DAG: [[BPADDR1:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BPR]], i32 0, i32 [[IDX1:[0-9]+]]
+ // CHECK-DAG: [[PADDR1:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[PR]], i32 0, i32 [[IDX1]]
+ // CHECK-DAG: [[CBPADDR1:%.+]] = bitcast i8** [[BPADDR1]] to i[[SZ]]*
+ // CHECK-DAG: [[CPADDR1:%.+]] = bitcast i8** [[PADDR1]] to i[[SZ]]*
+ // CHECK-DAG: store i[[SZ]] %{{.+}}, i[[SZ]]* [[CBPADDR1]]
+ // CHECK-DAG: store i[[SZ]] %{{.+}}, i[[SZ]]* [[CPADDR1]]
+ // CHECK-DAG: [[BPADDR2:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BPR]], i32 0, i32 [[IDX1:[0-9]+]]
+ // CHECK-DAG: [[PADDR2:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[PR]], i32 0, i32 [[IDX1]]
+ // CHECK-DAG: [[CBPADDR2:%.+]] = bitcast i8** [[BPADDR2]] to i[[SZ]]*
+ // CHECK-DAG: [[CPADDR2:%.+]] = bitcast i8** [[PADDR2]] to i[[SZ]]*
+ // CHECK-DAG: store i[[SZ]] %{{.+}}, i[[SZ]]* [[CBPADDR2]]
+ // CHECK-DAG: store i[[SZ]] %{{.+}}, i[[SZ]]* [[CPADDR2]]
+ // CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
+ // CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:[^,]+]], label %[[END:[^,]+]]
+ // CHECK: [[FAIL]]
+ // CHECK: call void [[HVT0:@.+]](i[[SZ]] {{[^,]+}}, i[[SZ]] {{[^,]+}}, i[[SZ]] {{[^)]+}})
+ // CHECK-NEXT: br label %[[END]]
+ // CHECK: [[END]]
+ #pragma omp target teams distribute simd num_teams(a) thread_limit(a) firstprivate(aa) simdlen(16) nowait
+ for (int i = 0; i < 10; ++i) {
+ }
+
+ // CHECK: call void [[HVT1:@.+]](i[[SZ]] {{[^,]+}})
+ #pragma omp target teams distribute simd if(target: 0) safelen(32) linear(a)
+ for (a = 0; a < 10; ++a) {
+ a += 1;
+ }
+
+ // CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 1, i8** [[BP:%[^,]+]], i8** [[P:%[^,]+]], i[[SZ]]* getelementptr inbounds ([1 x i[[SZ]]], [1 x i[[SZ]]]* [[SIZET2]], i32 0, i32 0), i64* getelementptr inbounds ([1 x i64], [1 x i64]* [[MAPT2]], i32 0, i32 0), i32 0, i32 0)
+ // CHECK-DAG: [[BP]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[BPR:%[^,]+]], i32 0, i32 0
+ // CHECK-DAG: [[P]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[PR:%[^,]+]], i32 0, i32 0
+ // CHECK-DAG: [[BPADDR0:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[BPR]], i32 0, i32 [[IDX0:[0-9]+]]
+ // CHECK-DAG: [[PADDR0:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[PR]], i32 0, i32 [[IDX0]]
+ // CHECK-DAG: [[CBPADDR0:%.+]] = bitcast i8** [[BPADDR0]] to i[[SZ]]*
+ // CHECK-DAG: [[CPADDR0:%.+]] = bitcast i8** [[PADDR0]] to i[[SZ]]*
+ // CHECK-DAG: store i[[SZ]] %{{.+}}, i[[SZ]]* [[CBPADDR0]]
+ // CHECK-DAG: store i[[SZ]] %{{.+}}, i[[SZ]]* [[CPADDR0]]
+
+ // CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
+ // CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:[^,]+]], label %[[END:[^,]+]]
+ // CHECK: [[FAIL]]
+ // CHECK: call void [[HVT2:@.+]](i[[SZ]] {{[^,]+}})
+ // CHECK-NEXT: br label %[[END]]
+ // CHECK: [[END]]
+ #pragma omp target teams distribute simd if(target: 1)
+ for (int i = 0; i < 10; ++i) {
+ aa += 1;
+ }
+
+ // CHECK: [[IF:%.+]] = icmp sgt i32 {{[^,]+}}, 10
+ // CHECK: br i1 [[IF]], label %[[IFTHEN:[^,]+]], label %[[IFELSE:[^,]+]]
+ // CHECK: [[IFTHEN]]
+ // CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 2, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* getelementptr inbounds ([2 x i[[SZ]]], [2 x i[[SZ]]]* [[SIZET3]], i32 0, i32 0), i64* getelementptr inbounds ([2 x i64], [2 x i64]* [[MAPT3]], i32 0, i32 0), i32 0, i32 0)
+ // CHECK-DAG: [[BPR]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[BP:%[^,]+]], i32 0, i32 0
+ // CHECK-DAG: [[PR]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[P:%[^,]+]], i32 0, i32 0
+
+ // CHECK-DAG: [[BPADDR0:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[BP]], i32 0, i32 0
+ // CHECK-DAG: [[PADDR0:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[P]], i32 0, i32 0
+ // CHECK-DAG: [[CBPADDR0:%.+]] = bitcast i8** [[BPADDR0]] to i[[SZ]]*
+ // CHECK-DAG: [[CPADDR0:%.+]] = bitcast i8** [[PADDR0]] to i[[SZ]]*
+ // CHECK-DAG: store i[[SZ]] %{{.+}}, i[[SZ]]* [[CBPADDR0]]
+ // CHECK-DAG: store i[[SZ]] %{{.+}}, i[[SZ]]* [[CPADDR0]]
+
+ // CHECK-DAG: [[BPADDR1:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[BP]], i32 0, i32 1
+ // CHECK-DAG: [[PADDR1:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[P]], i32 0, i32 1
+ // CHECK-DAG: [[CBPADDR1:%.+]] = bitcast i8** [[BPADDR1]] to i[[SZ]]*
+ // CHECK-DAG: [[CPADDR1:%.+]] = bitcast i8** [[PADDR1]] to i[[SZ]]*
+ // CHECK-DAG: store i[[SZ]] %{{.+}}, i[[SZ]]* [[CBPADDR1]]
+ // CHECK-DAG: store i[[SZ]] %{{.+}}, i[[SZ]]* [[CPADDR1]]
+ // CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
+ // CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
+ // CHECK: [[FAIL]]
+ // CHECK: call void [[HVT3:@.+]]({{[^,]+}}, {{[^,]+}})
+ // CHECK-NEXT: br label %[[END]]
+ // CHECK: [[END]]
+ // CHECK-NEXT: br label %[[IFEND:.+]]
+ // CHECK: [[IFELSE]]
+ // CHECK: call void [[HVT3]]({{[^,]+}}, {{[^,]+}})
+ // CHECK-NEXT: br label %[[IFEND]]
+ // CHECK: [[IFEND]]
+ #pragma omp target teams distribute simd if(target: n>10)
+ for (int i = 0; i < 10; ++i) {
+ a += 1;
+ aa += 1;
+ }
+
+ // We capture 3 VLA sizes in this target region
+ // CHECK-64: [[A_VAL:%.+]] = load i32, i32* %{{.+}},
+ // CHECK-64: [[A_ADDR:%.+]] = bitcast i[[SZ]]* [[A_CADDR:%.+]] to i32*
+ // CHECK-64: store i32 [[A_VAL]], i32* [[A_ADDR]],
+ // CHECK-64: [[A_CVAL:%.+]] = load i[[SZ]], i[[SZ]]* [[A_CADDR]],
+
+ // CHECK-32: [[A_VAL:%.+]] = load i32, i32* %{{.+}},
+ // CHECK-32: store i32 [[A_VAL]], i32* [[A_CADDR:%.+]],
+ // CHECK-32: [[A_CVAL:%.+]] = load i[[SZ]], i[[SZ]]* [[A_CADDR]],
+
+ // CHECK: [[BNSIZE:%.+]] = mul nuw i[[SZ]] [[VLA0:%.+]], 4
+ // CHECK: [[CNELEMSIZE2:%.+]] = mul nuw i[[SZ]] 5, [[VLA1:%.+]]
+ // CHECK: [[CNSIZE:%.+]] = mul nuw i[[SZ]] [[CNELEMSIZE2]], 8
+
+ // CHECK: [[IF:%.+]] = icmp sgt i32 {{[^,]+}}, 20
+ // CHECK: br i1 [[IF]], label %[[TRY:[^,]+]], label %[[FAIL:[^,]+]]
+ // CHECK: [[TRY]]
+ // CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 9, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* [[SR:%[^,]+]], i64* getelementptr inbounds ([9 x i64], [9 x i64]* [[MAPT4]], i32 0, i32 0), i32 0, i32 0)
+ // CHECK-DAG: [[BPR]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP:%[^,]+]], i32 0, i32 0
+ // CHECK-DAG: [[PR]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P:%[^,]+]], i32 0, i32 0
+ // CHECK-DAG: [[SR]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S:%[^,]+]], i32 0, i32 0
+
+ // CHECK-DAG: [[SADDR0:%.+]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX0:[0-9]+]]
+ // CHECK-DAG: [[BPADDR0:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP]], i32 0, i32 [[IDX0]]
+ // CHECK-DAG: [[PADDR0:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P]], i32 0, i32 [[IDX0]]
+ // CHECK-DAG: [[SADDR1:%.+]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX1:[0-9]+]]
+ // CHECK-DAG: [[BPADDR1:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP]], i32 0, i32 [[IDX1]]
+ // CHECK-DAG: [[PADDR1:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P]], i32 0, i32 [[IDX1]]
+ // CHECK-DAG: [[SADDR2:%.+]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX2:[0-9]+]]
+ // CHECK-DAG: [[BPADDR2:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP]], i32 0, i32 [[IDX2]]
+ // CHECK-DAG: [[PADDR2:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P]], i32 0, i32 [[IDX2]]
+ // CHECK-DAG: [[SADDR3:%.+]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX3:[0-9]+]]
+ // CHECK-DAG: [[BPADDR3:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP]], i32 0, i32 [[IDX3]]
+ // CHECK-DAG: [[PADDR3:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P]], i32 0, i32 [[IDX3]]
+ // CHECK-DAG: [[SADDR4:%.+]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX4:[0-9]+]]
+ // CHECK-DAG: [[BPADDR4:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP]], i32 0, i32 [[IDX4]]
+ // CHECK-DAG: [[PADDR4:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P]], i32 0, i32 [[IDX4]]
+ // CHECK-DAG: [[SADDR5:%.+]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX5:[0-9]+]]
+ // CHECK-DAG: [[BPADDR5:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP]], i32 0, i32 [[IDX5]]
+ // CHECK-DAG: [[PADDR5:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P]], i32 0, i32 [[IDX5]]
+ // CHECK-DAG: [[SADDR6:%.+]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX6:[0-9]+]]
+ // CHECK-DAG: [[BPADDR6:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP]], i32 0, i32 [[IDX6]]
+ // CHECK-DAG: [[PADDR6:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P]], i32 0, i32 [[IDX6]]
+ // CHECK-DAG: [[SADDR7:%.+]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX7:[0-9]+]]
+ // CHECK-DAG: [[BPADDR7:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP]], i32 0, i32 [[IDX7]]
+ // CHECK-DAG: [[PADDR7:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P]], i32 0, i32 [[IDX7]]
+ // CHECK-DAG: [[SADDR8:%.+]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX8:[0-9]+]]
+ // CHECK-DAG: [[BPADDR8:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP]], i32 0, i32 [[IDX8]]
+ // CHECK-DAG: [[PADDR8:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P]], i32 0, i32 [[IDX8]]
+
+ // The names below are not necessarily consistent with the names used for the
+ // addresses above as some are repeated.
+ // CHECK-DAG: store i[[SZ]] [[VLA0]], i[[SZ]]* [[CBPADDR0:%.+]],
+ // CHECK-DAG: store i[[SZ]] [[VLA0]], i[[SZ]]* [[CPADDR0:%.+]],
+ // CHECK-DAG: [[CBPADDR0]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+ // CHECK-DAG: [[CPADDR0]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+ // CHECK-DAG: store i[[SZ]] {{4|8}}, i[[SZ]]* {{%[^,]+}}
+
+ // CHECK-DAG: store i[[SZ]] [[VLA1]], i[[SZ]]* [[CBPADDR1:%.+]],
+ // CHECK-DAG: store i[[SZ]] [[VLA1]], i[[SZ]]* [[CPADDR1:%.+]],
+ // CHECK-DAG: [[CBPADDR1]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+ // CHECK-DAG: [[CPADDR1]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+ // CHECK-DAG: store i[[SZ]] {{4|8}}, i[[SZ]]* {{%[^,]+}}
+
+ // CHECK-DAG: store i[[SZ]] 5, i[[SZ]]* [[CBPADDR2:%.+]],
+ // CHECK-DAG: store i[[SZ]] 5, i[[SZ]]* [[CPADDR2:%.+]],
+ // CHECK-DAG: [[CBPADDR2]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+ // CHECK-DAG: [[CPADDR2]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+ // CHECK-DAG: store i[[SZ]] {{4|8}}, i[[SZ]]* {{%[^,]+}}
+
+ // CHECK-DAG: store i[[SZ]] [[A_CVAL]], i[[SZ]]* [[CBPADDR3:%.+]],
+ // CHECK-DAG: store i[[SZ]] [[A_CVAL]], i[[SZ]]* [[CPADDR3:%.+]],
+ // CHECK-DAG: [[CBPADDR3]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+ // CHECK-DAG: [[CPADDR3]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+ // CHECK-DAG: store i[[SZ]] 4, i[[SZ]]* {{%[^,]+}}
+
+ // CHECK-DAG: store [10 x float]* %{{.+}}, [10 x float]** [[CBPADDR4:%.+]],
+ // CHECK-DAG: store [10 x float]* %{{.+}}, [10 x float]** [[CPADDR4:%.+]],
+ // CHECK-DAG: [[CBPADDR4]] = bitcast i8** {{%[^,]+}} to [10 x float]**
+ // CHECK-DAG: [[CPADDR4]] = bitcast i8** {{%[^,]+}} to [10 x float]**
+ // CHECK-DAG: store i[[SZ]] 40, i[[SZ]]* {{%[^,]+}}
+
+ // CHECK-DAG: store float* %{{.+}}, float** [[CBPADDR5:%.+]],
+ // CHECK-DAG: store float* %{{.+}}, float** [[CPADDR5:%.+]],
+ // CHECK-DAG: [[CBPADDR5]] = bitcast i8** {{%[^,]+}} to float**
+ // CHECK-DAG: [[CPADDR5]] = bitcast i8** {{%[^,]+}} to float**
+ // CHECK-DAG: store i[[SZ]] [[BNSIZE]], i[[SZ]]* {{%[^,]+}}
+
+ // CHECK-DAG: store [5 x [10 x double]]* %{{.+}}, [5 x [10 x double]]** [[CBPADDR6:%.+]],
+ // CHECK-DAG: store [5 x [10 x double]]* %{{.+}}, [5 x [10 x double]]** [[CPADDR6:%.+]],
+ // CHECK-DAG: [[CBPADDR6]] = bitcast i8** {{%[^,]+}} to [5 x [10 x double]]**
+ // CHECK-DAG: [[CPADDR6]] = bitcast i8** {{%[^,]+}} to [5 x [10 x double]]**
+ // CHECK-DAG: store i[[SZ]] 400, i[[SZ]]* {{%[^,]+}}
+
+ // CHECK-DAG: store double* %{{.+}}, double** [[CBPADDR7:%.+]],
+ // CHECK-DAG: store double* %{{.+}}, double** [[CPADDR7:%.+]],
+ // CHECK-DAG: [[CBPADDR7]] = bitcast i8** {{%[^,]+}} to double**
+ // CHECK-DAG: [[CPADDR7]] = bitcast i8** {{%[^,]+}} to double**
+ // CHECK-DAG: store i[[SZ]] [[CNSIZE]], i[[SZ]]* {{%[^,]+}}
+
+ // CHECK-DAG: store [[TT]]* %{{.+}}, [[TT]]** [[CBPADDR8:%.+]],
+ // CHECK-DAG: store [[TT]]* %{{.+}}, [[TT]]** [[CPADDR8:%.+]],
+ // CHECK-DAG: [[CBPADDR8]] = bitcast i8** {{%[^,]+}} to [[TT]]**
+ // CHECK-DAG: [[CPADDR8]] = bitcast i8** {{%[^,]+}} to [[TT]]**
+ // CHECK-DAG: store i[[SZ]] {{12|16}}, i[[SZ]]* {{%[^,]+}}
+
+ // CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
+ // CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:[^,]+]], label %[[END:[^,]+]]
+
+ // CHECK: [[FAIL]]
+ // CHECK: call void [[HVT4:@.+]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}})
+ // CHECK-NEXT: br label %[[END]]
+ // CHECK: [[END]]
+ #pragma omp target teams distribute simd if(target: n>20) aligned(b)
+ for (int i = 0; i < 10; ++i) {
+ a += 1;
+ b[2] += 1.0;
+ bn[3] += 1.0;
+ c[1][2] += 1.0;
+ cn[1][3] += 1.0;
+ d.X += 1;
+ d.Y += 1;
+ }
+
+ return a;
+}
+
+// Check that the offloading functions are emitted and that the arguments are
+// correct and loaded correctly for the target regions in foo().
+
+// CHECK: define internal void [[HVT0]](i[[SZ]] {{[^,]+}}, i[[SZ]] {{[^,]+}}, i[[SZ]] {{[^)]+}})
+// CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams(%ident_t* [[DEF_LOC]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i[[SZ]])* [[OMP_OUTLINED:@.+]] to void (i32*, i32*, ...)*), i[[SZ]] {{[^)]+}})
+//
+//
+// CHECK: define internal {{.*}}void [[OMP_OUTLINED]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i[[SZ]] {{[^)]+}})
+// CHECK: alloca i16,
+// CHECK: ret void
+// CHECK-NEXT: }
+
+
+// CHECK: define internal void [[HVT1]](i[[SZ]] %{{.+}})
+// Create stack storage and store argument in there.
+// CHECK: [[AA_ADDR:%.+]] = alloca i[[SZ]], align
+// CHECK: [[AA_CASTED:%.+]] = alloca i[[SZ]], align
+// CHECK: store i[[SZ]] %{{.+}}, i[[SZ]]* [[AA_ADDR]], align
+// CHECK-64: [[AA_CADDR:%.+]] = bitcast i[[SZ]]* [[AA_ADDR]] to i32*
+// CHECK-64: [[AA:%.+]] = load i32, i32* [[AA_CADDR]], align
+// CHECK-32: [[AA:%.+]] = load i32, i32* [[AA_ADDR]], align
+// CHECK-64: [[AA_C:%.+]] = bitcast i[[SZ]]* [[AA_CASTED]] to i32*
+// CHECK-64: store i32 [[AA]], i32* [[AA_C]], align
+// CHECK-32: store i32 [[AA]], i32* [[AA_CASTED]], align
+// CHECK: [[PARAM:%.+]] = load i[[SZ]], i[[SZ]]* [[AA_CASTED]], align
+// CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams(%ident_t* [[DEF_LOC]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i[[SZ]])* [[OMP_OUTLINED1:@.+]] to void (i32*, i32*, ...)*), i[[SZ]] [[PARAM]])
+//
+//
+// CHECK: define internal {{.*}}void [[OMP_OUTLINED1]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i[[SZ]] %{{.+}})
+// CHECK: [[AA_ADDR:%.+]] = alloca i[[SZ]], align
+// CHECK: store i[[SZ]] %{{.+}}, i[[SZ]]* [[AA_ADDR]], align
+// CHECK-64: [[AA_CADDR:%.+]] = bitcast i[[SZ]]* [[AA_ADDR]] to i32*
+// CHECK-64: store i32 10, i32* [[AA_CADDR]], align
+// CHECK-32: store i32 10, i32* [[AA_ADDR]], align
+// CHECK: ret void
+// CHECK-NEXT: }
+
+// CHECK: define internal void [[HVT2]](i[[SZ]] %{{.+}})
+// Create stack storage and store argument in there.
+// CHECK: [[AA_ADDR:%.+]] = alloca i[[SZ]], align
+// CHECK: [[AA_CASTED:%.+]] = alloca i[[SZ]], align
+// CHECK: store i[[SZ]] %{{.+}}, i[[SZ]]* [[AA_ADDR]], align
+// CHECK: [[AA_CADDR:%.+]] = bitcast i[[SZ]]* [[AA_ADDR]] to i16*
+// CHECK: [[AA:%.+]] = load i16, i16* [[AA_CADDR]], align
+// CHECK: [[AA_C:%.+]] = bitcast i[[SZ]]* [[AA_CASTED]] to i16*
+// CHECK: store i16 [[AA]], i16* [[AA_C]], align
+// CHECK: [[PARAM:%.+]] = load i[[SZ]], i[[SZ]]* [[AA_CASTED]], align
+// CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams(%ident_t* [[DEF_LOC]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i[[SZ]])* [[OMP_OUTLINED2:@.+]] to void (i32*, i32*, ...)*), i[[SZ]] [[PARAM]])
+//
+//
+// CHECK: define internal {{.*}}void [[OMP_OUTLINED2]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i[[SZ]] %{{.+}})
+// CHECK: [[AA_ADDR:%.+]] = alloca i[[SZ]], align
+// CHECK: store i[[SZ]] %{{.+}}, i[[SZ]]* [[AA_ADDR]], align
+// CHECK: [[AA_CADDR:%.+]] = bitcast i[[SZ]]* [[AA_ADDR]] to i16*
+// CHECK: [[AA:%.+]] = load i16, i16* [[AA_CADDR]], align
+// CHECK: ret void
+// CHECK-NEXT: }
+
+// CHECK: define internal void [[HVT3]]
+// Create stack storage and store argument in there.
+// CHECK: [[A_ADDR:%.+]] = alloca i[[SZ]], align
+// CHECK: [[AA_ADDR:%.+]] = alloca i[[SZ]], align
+// CHECK: [[A_CASTED:%.+]] = alloca i[[SZ]], align
+// CHECK: [[AA_CASTED:%.+]] = alloca i[[SZ]], align
+// CHECK-DAG: store i[[SZ]] %{{.+}}, i[[SZ]]* [[A_ADDR]], align
+// CHECK-DAG: store i[[SZ]] %{{.+}}, i[[SZ]]* [[AA_ADDR]], align
+// CHECK-64-DAG:[[A_CADDR:%.+]] = bitcast i[[SZ]]* [[A_ADDR]] to i32*
+// CHECK-DAG: [[AA_CADDR:%.+]] = bitcast i[[SZ]]* [[AA_ADDR]] to i16*
+// CHECK-64-DAG:[[A:%.+]] = load i32, i32* [[A_CADDR]], align
+// CHECK-32-DAG:[[A:%.+]] = load i32, i32* [[A_ADDR]], align
+// CHECK-64-DAG:[[A_C:%.+]] = bitcast i[[SZ]]* [[A_CASTED]] to i32*
+// CHECK-64-DAG:store i32 [[A]], i32* [[A_C]], align
+// CHECK-32-DAG:store i32 [[A]], i32* [[A_CASTED]], align
+// CHECK-DAG: [[AA:%.+]] = load i16, i16* [[AA_CADDR]], align
+// CHECK-DAG: [[AA_C:%.+]] = bitcast i[[SZ]]* [[AA_CASTED]] to i16*
+// CHECK-DAG: store i16 [[AA]], i16* [[AA_C]], align
+// CHECK-DAG: [[PARAM1:%.+]] = load i[[SZ]], i[[SZ]]* [[A_CASTED]], align
+// CHECK-DAG: [[PARAM2:%.+]] = load i[[SZ]], i[[SZ]]* [[AA_CASTED]], align
+// CHECK-DAG: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams(%ident_t* [[DEF_LOC]], i32 2, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i[[SZ]], i[[SZ]])* [[OMP_OUTLINED3:@.+]] to void (i32*, i32*, ...)*), i[[SZ]] [[PARAM1]], i[[SZ]] [[PARAM2]])
+//
+//
+// CHECK: define internal {{.*}}void [[OMP_OUTLINED3]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}})
+// CHECK: [[A_ADDR:%.+]] = alloca i[[SZ]], align
+// CHECK: [[AA_ADDR:%.+]] = alloca i[[SZ]], align
+// CHECK-DAG: store i[[SZ]] %{{.+}}, i[[SZ]]* [[A_ADDR]], align
+// CHECK-DAG: store i[[SZ]] %{{.+}}, i[[SZ]]* [[AA_ADDR]], align
+// CHECK-64-DAG:[[A_CADDR:%.+]] = bitcast i[[SZ]]* [[A_ADDR]] to i32*
+// CHECK-DAG: [[AA_CADDR:%.+]] = bitcast i[[SZ]]* [[AA_ADDR]] to i16*
+// CHECK: ret void
+// CHECK-NEXT: }
+
+// CHECK: define internal void [[HVT4]]
+// Create local storage for each capture.
+// CHECK: [[LOCAL_A:%.+]] = alloca i[[SZ]]
+// CHECK: [[LOCAL_B:%.+]] = alloca [10 x float]*
+// CHECK: [[LOCAL_VLA1:%.+]] = alloca i[[SZ]]
+// CHECK: [[LOCAL_BN:%.+]] = alloca float*
+// CHECK: [[LOCAL_C:%.+]] = alloca [5 x [10 x double]]*
+// CHECK: [[LOCAL_VLA2:%.+]] = alloca i[[SZ]]
+// CHECK: [[LOCAL_VLA3:%.+]] = alloca i[[SZ]]
+// CHECK: [[LOCAL_CN:%.+]] = alloca double*
+// CHECK: [[LOCAL_D:%.+]] = alloca [[TT]]*
+// CHECK: [[LOCAL_A_CASTED:%.+]] = alloca i[[SZ]]
+// CHECK-DAG: store i[[SZ]] [[ARG_A:%.+]], i[[SZ]]* [[LOCAL_A]]
+// CHECK-DAG: store [10 x float]* [[ARG_B:%.+]], [10 x float]** [[LOCAL_B]]
+// CHECK-DAG: store i[[SZ]] [[ARG_VLA1:%.+]], i[[SZ]]* [[LOCAL_VLA1]]
+// CHECK-DAG: store float* [[ARG_BN:%.+]], float** [[LOCAL_BN]]
+// CHECK-DAG: store [5 x [10 x double]]* [[ARG_C:%.+]], [5 x [10 x double]]** [[LOCAL_C]]
+// CHECK-DAG: store i[[SZ]] [[ARG_VLA2:%.+]], i[[SZ]]* [[LOCAL_VLA2]]
+// CHECK-DAG: store i[[SZ]] [[ARG_VLA3:%.+]], i[[SZ]]* [[LOCAL_VLA3]]
+// CHECK-DAG: store double* [[ARG_CN:%.+]], double** [[LOCAL_CN]]
+// CHECK-DAG: store [[TT]]* [[ARG_D:%.+]], [[TT]]** [[LOCAL_D]]
+
+// CHECK-64-DAG:[[CONV_AP:%.+]] = bitcast i[[SZ]]* [[LOCAL_A]] to i32*
+// CHECK-DAG: [[REF_B:%.+]] = load [10 x float]*, [10 x float]** [[LOCAL_B]],
+// CHECK-DAG: [[VAL_VLA1:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_VLA1]],
+// CHECK-DAG: [[REF_BN:%.+]] = load float*, float** [[LOCAL_BN]],
+// CHECK-DAG: [[REF_C:%.+]] = load [5 x [10 x double]]*, [5 x [10 x double]]** [[LOCAL_C]],
+// CHECK-DAG: [[VAL_VLA2:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_VLA2]],
+// CHECK-DAG: [[VAL_VLA3:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_VLA3]],
+// CHECK-DAG: [[REF_CN:%.+]] = load double*, double** [[LOCAL_CN]],
+// CHECK-DAG: [[REF_D:%.+]] = load [[TT]]*, [[TT]]** [[LOCAL_D]],
+
+// CHECK-64-DAG:[[CONV_A:%.+]] = load i32, i32* [[CONV_AP]]
+// CHECK-64-DAG:[[CONV:%.+]] = bitcast i[[SZ]]* [[LOCAL_A_CASTED]] to i32*
+// CHECK-64-DAG:store i32 [[CONV_A]], i32* [[CONV]], align
+// CHECK-32-DAG:[[LOCAL_AV:%.+]] = load i32, i32* [[LOCAL_A]]
+// CHECK-32-DAG:store i32 [[LOCAL_AV]], i32* [[LOCAL_A_CASTED]], align
+// CHECK-DAG: [[REF_A:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_A_CASTED]],
+
+// CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams(%ident_t* [[DEF_LOC]], i32 9, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i[[SZ]], [10 x float]*, i[[SZ]], float*, [5 x [10 x double]]*, i[[SZ]], i[[SZ]], double*, [[TT]]*)* [[OMP_OUTLINED4:@.+]] to void (i32*, i32*, ...)*), i[[SZ]] [[REF_A]], [10 x float]* [[REF_B]], i[[SZ]] [[VAL_VLA1]], float* [[REF_BN]], [5 x [10 x double]]* [[REF_C]], i[[SZ]] [[VAL_VLA2]], i[[SZ]] [[VAL_VLA3]], double* [[REF_CN]], [[TT]]* [[REF_D]])
+//
+//
+// CHECK: define internal {{.*}}void [[OMP_OUTLINED4]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i[[SZ]] %{{.+}}, [10 x float]* {{.+}}, i[[SZ]] %{{.+}}, float* {{.+}}, [5 x [10 x double]]* {{.+}}, i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, double* {{.+}}, [[TT]]* {{.+}})
+// To reduce complexity, we're only going as far as validating the signature of the outlined parallel function.
+
+template<typename tx>
+tx ftemplate(int n) {
+ tx a = 0;
+ short aa = 0;
+ tx b[10];
+
+ #pragma omp target teams distribute simd if(target: n>40)
+ for (int i = 0; i < 10; ++i) {
+ a += 1;
+ aa += 1;
+ b[2] += 1;
+ }
+
+ return a;
+}
+
+static
+int fstatic(int n) {
+ int a = 0;
+ short aa = 0;
+ char aaa = 0;
+ int b[10];
+
+ #pragma omp target teams distribute simd if(target: n>50)
+ for (int i = a; i < n; ++i) {
+ a += 1;
+ aa += 1;
+ aaa += 1;
+ b[2] += 1;
+ }
+
+ return a;
+}
+
+struct S1 {
+ double a;
+
+ int r1(int n){
+ int b = n+1;
+ short int c[2][n];
+
+ #pragma omp target teams distribute simd if(target: n>60)
+ for (int i = 0; i < 10; ++i) {
+ this->a = (double)b + 1.5;
+ c[1][1] = ++a;
+ }
+
+ return c[1][1] + (int)b;
+ }
+};
+
+// CHECK: define {{.*}}@{{.*}}bar{{.*}}
+int bar(int n){
+ int a = 0;
+
+ // CHECK: call {{.*}}i32 [[FOO]](i32 {{.*}})
+ a += foo(n);
+
+ S1 S;
+ // CHECK: call {{.*}}i32 [[FS1:@.+]]([[S1]]* {{.*}}, i32 {{.*}})
+ a += S.r1(n);
+
+ // CHECK: call {{.*}}i32 [[FSTATIC:@.+]](i32 {{.*}})
+ a += fstatic(n);
+
+ // CHECK: call {{.*}}i32 [[FTEMPLATE:@.+]](i32 {{.*}})
+ a += ftemplate<int>(n);
+
+ return a;
+}
+
+//
+// CHECK: define {{.*}}[[FS1]]
+//
+// CHECK: i8* @llvm.stacksave()
+// CHECK-64: [[B_ADDR:%.+]] = bitcast i[[SZ]]* [[B_CADDR:%.+]] to i32*
+// CHECK-64: store i32 %{{.+}}, i32* [[B_ADDR]],
+// CHECK-64: [[B_CVAL:%.+]] = load i[[SZ]], i[[SZ]]* [[B_CADDR]],
+
+// CHECK-32: store i32 %{{.+}}, i32* [[B_ADDR:%.+]],
+// CHECK-32: [[B_CVAL:%.+]] = load i[[SZ]], i[[SZ]]* [[B_ADDR]],
+
+// We capture 2 VLA sizes in this target region
+// CHECK: [[CELEMSIZE2:%.+]] = mul nuw i[[SZ]] 2, [[VLA0:%.+]]
+// CHECK: [[CSIZE:%.+]] = mul nuw i[[SZ]] [[CELEMSIZE2]], 2
+
+// CHECK: [[IF:%.+]] = icmp sgt i32 {{[^,]+}}, 60
+// CHECK: br i1 [[IF]], label %[[TRY:[^,]+]], label %[[FAIL:[^,]+]]
+// CHECK: [[TRY]]
+// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 5, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* [[SR:%[^,]+]], i64* getelementptr inbounds ([5 x i64], [5 x i64]* [[MAPT5]], i32 0, i32 0), i32 0, i32 0)
+// CHECK-DAG: [[BPR]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[BP:%.+]], i32 0, i32 0
+// CHECK-DAG: [[PR]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[P:%.+]], i32 0, i32 0
+// CHECK-DAG: [[SR]] = getelementptr inbounds [5 x i[[SZ]]], [5 x i[[SZ]]]* [[S:%.+]], i32 0, i32 0
+// CHECK-DAG: [[SADDR0:%.+]] = getelementptr inbounds [5 x i[[SZ]]], [5 x i[[SZ]]]* [[S]], i32 [[IDX0:[0-9]+]]
+// CHECK-DAG: [[BPADDR0:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[BP]], i32 [[IDX0]]
+// CHECK-DAG: [[PADDR0:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[P]], i32 [[IDX0]]
+// CHECK-DAG: [[SADDR1:%.+]] = getelementptr inbounds [5 x i[[SZ]]], [5 x i[[SZ]]]* [[S]], i32 [[IDX1:[0-9]+]]
+// CHECK-DAG: [[BPADDR1:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[BP]], i32 [[IDX1]]
+// CHECK-DAG: [[PADDR1:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[P]], i32 [[IDX1]]
+// CHECK-DAG: [[SADDR2:%.+]] = getelementptr inbounds [5 x i[[SZ]]], [5 x i[[SZ]]]* [[S]], i32 [[IDX2:[0-9]+]]
+// CHECK-DAG: [[BPADDR2:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[BP]], i32 [[IDX2]]
+// CHECK-DAG: [[PADDR2:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[P]], i32 [[IDX2]]
+// CHECK-DAG: [[SADDR3:%.+]] = getelementptr inbounds [5 x i[[SZ]]], [5 x i[[SZ]]]* [[S]], i32 [[IDX3:[0-9]+]]
+// CHECK-DAG: [[BPADDR3:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[BP]], i32 [[IDX3]]
+// CHECK-DAG: [[PADDR3:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[P]], i32 [[IDX3]]
+
+// The names below are not necessarily consistent with the names used for the
+// addresses above as some are repeated.
+// CHECK-DAG: store i[[SZ]] [[VLA0]], i[[SZ]]* [[CBPADDR0:%.+]],
+// CHECK-DAG: store i[[SZ]] [[VLA0]], i[[SZ]]* [[CPADDR0:%.+]],
+// CHECK-DAG: [[CBPADDR0]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+// CHECK-DAG: [[CPADDR0]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+// CHECK-DAG: store i[[SZ]] {{4|8}}, i[[SZ]]* {{%[^,]+}}
+
+// CHECK-DAG: store i[[SZ]] 2, i[[SZ]]* [[CBPADDR1:%.+]],
+// CHECK-DAG: store i[[SZ]] 2, i[[SZ]]* [[CPADDR1:%.+]],
+// CHECK-DAG: [[CBPADDR1]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+// CHECK-DAG: [[CPADDR1]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+// CHECK-DAG: store i[[SZ]] {{4|8}}, i[[SZ]]* {{%[^,]+}}
+
+// CHECK-DAG: store i[[SZ]] [[B_CVAL]], i[[SZ]]* [[CBPADDR2:%.+]],
+// CHECK-DAG: store i[[SZ]] [[B_CVAL]], i[[SZ]]* [[CPADDR2:%.+]],
+// CHECK-DAG: [[CBPADDR2]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+// CHECK-DAG: [[CPADDR2]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+// CHECK-DAG: store i[[SZ]] 4, i[[SZ]]* {{%[^,]+}}
+
+// CHECK-DAG: store [[S1]]* %{{.+}}, [[S1]]** [[CBPADDR3:%.+]],
+// CHECK-DAG: store [[S1]]* %{{.+}}, [[S1]]** [[CPADDR3:%.+]],
+// CHECK-DAG: [[CBPADDR3]] = bitcast i8** {{%[^,]+}} to [[S1]]**
+// CHECK-DAG: [[CPADDR3]] = bitcast i8** {{%[^,]+}} to [[S1]]**
+// CHECK-DAG: store i[[SZ]] 8, i[[SZ]]* {{%[^,]+}}
+
+// CHECK-DAG: store i16* %{{.+}}, i16** [[CBPADDR4:%.+]],
+// CHECK-DAG: store i16* %{{.+}}, i16** [[CPADDR4:%.+]],
+// CHECK-DAG: [[CBPADDR4]] = bitcast i8** {{%[^,]+}} to i16**
+// CHECK-DAG: [[CPADDR4]] = bitcast i8** {{%[^,]+}} to i16**
+// CHECK-DAG: store i[[SZ]] [[CSIZE]], i[[SZ]]* {{%[^,]+}}
+
+// CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
+// CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:[^,]+]], label %[[END:[^,]+]]
+
+// CHECK: [[FAIL]]
+// CHECK: call void [[HVT7:@.+]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}})
+// CHECK-NEXT: br label %[[END]]
+// CHECK: [[END]]
+
+//
+// CHECK: define {{.*}}[[FSTATIC]]
+//
+// CHECK: [[IF:%.+]] = icmp sgt i32 {{[^,]+}}, 50
+// CHECK: br i1 [[IF]], label %[[IFTHEN:[^,]+]], label %[[IFELSE:[^,]+]]
+// CHECK: [[IFTHEN]]
+// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 5, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* getelementptr inbounds ([5 x i[[SZ]]], [5 x i[[SZ]]]* [[SIZET6]], i32 0, i32 0), i64* getelementptr inbounds ([5 x i64], [5 x i64]* [[MAPT6]], i32 0, i32 0), i32 0, i32 0)
+// CHECK-DAG: [[BPR]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[BP:%.+]], i32 0, i32 0
+// CHECK-DAG: [[PR]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[P:%.+]], i32 0, i32 0
+
+// CHECK-DAG: [[BPADDR0:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[BP]], i32 0, i32 0
+// CHECK-DAG: [[PADDR0:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[P]], i32 0, i32 0
+// CHECK-DAG: store i[[SZ]] [[VAL0:%.+]], i[[SZ]]* [[CBPADDR0:%.+]],
+// CHECK-DAG: store i[[SZ]] [[VAL0]], i[[SZ]]* [[CPADDR0:%.+]],
+// CHECK-DAG: [[CBPADDR0]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+// CHECK-DAG: [[CPADDR0]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+
+// CHECK-DAG: [[BPADDR1:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[BP]], i32 0, i32 1
+// CHECK-DAG: [[PADDR1:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[P]], i32 0, i32 1
+// CHECK-DAG: store i[[SZ]] [[VAL1:%.+]], i[[SZ]]* [[CBPADDR1:%.+]],
+// CHECK-DAG: store i[[SZ]] [[VAL1]], i[[SZ]]* [[CPADDR1:%.+]],
+// CHECK-DAG: [[CBPADDR1]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+// CHECK-DAG: [[CPADDR1]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+
+// CHECK-DAG: [[BPADDR2:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[BP]], i32 0, i32 2
+// CHECK-DAG: [[PADDR2:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[P]], i32 0, i32 2
+// CHECK-DAG: store i[[SZ]] [[VAL2:%.+]], i[[SZ]]* [[CBPADDR2:%.+]],
+// CHECK-DAG: store i[[SZ]] [[VAL2]], i[[SZ]]* [[CPADDR2:%.+]],
+// CHECK-DAG: [[CBPADDR2]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+// CHECK-DAG: [[CPADDR2]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+
+// CHECK-DAG: [[BPADDR3:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[BP]], i32 0, i32 3
+// CHECK-DAG: [[PADDR3:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[P]], i32 0, i32 3
+// CHECK-DAG: store i[[SZ]] [[VAL3:%.+]], i[[SZ]]* [[CBPADDR3:%.+]],
+// CHECK-DAG: store i[[SZ]] [[VAL3]], i[[SZ]]* [[CPADDR3:%.+]],
+// CHECK-DAG: [[CBPADDR3]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+// CHECK-DAG: [[CPADDR3]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+
+// CHECK-DAG: [[BPADDR4:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[BP]], i32 0, i32 4
+// CHECK-DAG: [[PADDR4:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[P]], i32 0, i32 4
+// CHECK-DAG: store [10 x i32]* %{{.+}}, [10 x i32]** [[CBPADDR4:%.+]],
+// CHECK-DAG: store [10 x i32]* %{{.+}}, [10 x i32]** [[CPADDR4:%.+]],
+// CHECK-DAG: [[CBPADDR4]] = bitcast i8** {{%[^,]+}} to [10 x i32]**
+// CHECK-DAG: [[CPADDR4]] = bitcast i8** {{%[^,]+}} to [10 x i32]**
+
+// CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
+// CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
+// CHECK: [[FAIL]]
+// CHECK: call void [[HVT6:@.+]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}})
+// CHECK-NEXT: br label %[[END]]
+// CHECK: [[END]]
+// CHECK-NEXT: br label %[[IFEND:.+]]
+// CHECK: [[IFELSE]]
+// CHECK: call void [[HVT6]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}})
+// CHECK-NEXT: br label %[[IFEND]]
+// CHECK: [[IFEND]]
+
+//
+// CHECK: define {{.*}}[[FTEMPLATE]]
+//
+// CHECK: [[IF:%.+]] = icmp sgt i32 {{[^,]+}}, 40
+// CHECK: br i1 [[IF]], label %[[IFTHEN:[^,]+]], label %[[IFELSE:[^,]+]]
+// CHECK: [[IFTHEN]]
+// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 3, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* getelementptr inbounds ([3 x i[[SZ]]], [3 x i[[SZ]]]* [[SIZET7]], i32 0, i32 0), i64* getelementptr inbounds ([3 x i64], [3 x i64]* [[MAPT7]], i32 0, i32 0), i32 0, i32 0)
+// CHECK-DAG: [[BPR]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BP:%.+]], i32 0, i32 0
+// CHECK-DAG: [[PR]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[P:%.+]], i32 0, i32 0
+
+// CHECK-DAG: [[BPADDR0:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BP]], i32 0, i32 0
+// CHECK-DAG: [[PADDR0:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[P]], i32 0, i32 0
+// CHECK-DAG: store i[[SZ]] [[VAL0:%.+]], i[[SZ]]* [[CBPADDR0:%.+]],
+// CHECK-DAG: store i[[SZ]] [[VAL0]], i[[SZ]]* [[CPADDR0:%.+]],
+// CHECK-DAG: [[CBPADDR0]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+// CHECK-DAG: [[CPADDR0]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+
+// CHECK-DAG: [[BPADDR1:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BP]], i32 0, i32 1
+// CHECK-DAG: [[PADDR1:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[P]], i32 0, i32 1
+// CHECK-DAG: store i[[SZ]] [[VAL1:%.+]], i[[SZ]]* [[CBPADDR1:%.+]],
+// CHECK-DAG: store i[[SZ]] [[VAL1]], i[[SZ]]* [[CPADDR1:%.+]],
+// CHECK-DAG: [[CBPADDR1]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+// CHECK-DAG: [[CPADDR1]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+
+// CHECK-DAG: [[BPADDR2:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BP]], i32 0, i32 2
+// CHECK-DAG: [[PADDR2:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[P]], i32 0, i32 2
+// CHECK-DAG: store i[[SZ]] [[VAL2:%.+]], i[[SZ]]* [[CBPADDR2:%.+]],
+// CHECK-DAG: store i[[SZ]] [[VAL2]], i[[SZ]]* [[CPADDR2:%.+]],
+// CHECK-DAG: [[CBPADDR2]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+// CHECK-DAG: [[CPADDR2]] = bitcast i8** {{%[^,]+}} to i[[SZ]]*
+
+// CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
+// CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
+// CHECK: [[FAIL]]
+// CHECK: call void [[HVT5:@.+]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}})
+// CHECK-NEXT: br label %[[END]]
+// CHECK: [[END]]
+// CHECK-NEXT: br label %[[IFEND:.+]]
+// CHECK: [[IFELSE]]
+// CHECK: call void [[HVT5]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}})
+// CHECK-NEXT: br label %[[IFEND]]
+// CHECK: [[IFEND]]
+
+
+
+// Check that the offloading functions are emitted and that the arguments are
+// correct and loaded correctly for the target regions of the callees of bar().
+
+// CHECK: define internal void [[HVT7]]
+// Create local storage for each capture.
+// CHECK: [[LOCAL_THIS:%.+]] = alloca [[S1]]*
+// CHECK: [[LOCAL_B:%.+]] = alloca i[[SZ]]
+// CHECK: [[LOCAL_VLA1:%.+]] = alloca i[[SZ]]
+// CHECK: [[LOCAL_VLA2:%.+]] = alloca i[[SZ]]
+// CHECK: [[LOCAL_C:%.+]] = alloca i16*
+// CHECK: [[LOCAL_B_CASTED:%.+]] = alloca i[[SZ]]
+// CHECK-DAG: store [[S1]]* [[ARG_THIS:%.+]], [[S1]]** [[LOCAL_THIS]]
+// CHECK-DAG: store i[[SZ]] [[ARG_B:%.+]], i[[SZ]]* [[LOCAL_B]]
+// CHECK-DAG: store i[[SZ]] [[ARG_VLA1:%.+]], i[[SZ]]* [[LOCAL_VLA1]]
+// CHECK-DAG: store i[[SZ]] [[ARG_VLA2:%.+]], i[[SZ]]* [[LOCAL_VLA2]]
+// CHECK-DAG: store i16* [[ARG_C:%.+]], i16** [[LOCAL_C]]
+// Store captures in the context.
+// CHECK-DAG: [[REF_THIS:%.+]] = load [[S1]]*, [[S1]]** [[LOCAL_THIS]],
+// CHECK-64-DAG:[[CONV_BP:%.+]] = bitcast i[[SZ]]* [[LOCAL_B]] to i32*
+// CHECK-DAG: [[VAL_VLA1:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_VLA1]],
+// CHECK-DAG: [[VAL_VLA2:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_VLA2]],
+// CHECK-DAG: [[REF_C:%.+]] = load i16*, i16** [[LOCAL_C]],
+
+// CHECK-64-DAG:[[CONV_B:%.+]] = load i32, i32* [[CONV_BP]]
+// CHECK-64-DAG:[[CONV:%.+]] = bitcast i[[SZ]]* [[LOCAL_B_CASTED]] to i32*
+// CHECK-64-DAG:store i32 [[CONV_B]], i32* [[CONV]], align
+// CHECK-32-DAG:[[LOCAL_BV:%.+]] = load i32, i32* [[LOCAL_B]]
+// CHECK-32-DAG:store i32 [[LOCAL_BV]], i32* [[LOCAL_B_CASTED]], align
+// CHECK-DAG: [[REF_B:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_B_CASTED]],
+
+// CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams(%ident_t* [[DEF_LOC]], i32 5, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, [[S1]]*, i[[SZ]], i[[SZ]], i[[SZ]], i16*)* [[OMP_OUTLINED5:@.+]] to void (i32*, i32*, ...)*), [[S1]]* [[REF_THIS]], i[[SZ]] [[REF_B]], i[[SZ]] [[VAL_VLA1]], i[[SZ]] [[VAL_VLA2]], i16* [[REF_C]])
+//
+//
+// CHECK: define internal {{.*}}void [[OMP_OUTLINED5]](i32* noalias %.global_tid., i32* noalias %.bound_tid., [[S1]]* %{{.+}}, i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, i16* {{.+}})
+// To reduce complexity, we're only going as far as validating the signature of the outlined parallel function.
+
+
+// CHECK: define internal void [[HVT6]]
+// Create local storage for each capture.
+// CHECK: [[LOCAL_A:%.+]] = alloca i[[SZ]]
+// CHECK: alloca i[[SZ]],
+// CHECK: [[LOCAL_AA:%.+]] = alloca i[[SZ]]
+// CHECK: [[LOCAL_AAA:%.+]] = alloca i[[SZ]]
+// CHECK: [[LOCAL_B:%.+]] = alloca [10 x i32]*
+// CHECK: [[LOCAL_A_CASTED:%.+]] = alloca i[[SZ]]
+// CHECK: alloca i[[SZ]],
+// CHECK: [[LOCAL_AA_CASTED:%.+]] = alloca i[[SZ]]
+// CHECK: [[LOCAL_AAA_CASTED:%.+]] = alloca i[[SZ]]
+// CHECK-DAG: store i[[SZ]] [[ARG_A:%.+]], i[[SZ]]* [[LOCAL_A]]
+// CHECK-DAG: store i[[SZ]] [[ARG_AA:%.+]], i[[SZ]]* [[LOCAL_AA]]
+// CHECK-DAG: store i[[SZ]] [[ARG_AAA:%.+]], i[[SZ]]* [[LOCAL_AAA]]
+// CHECK-DAG: store [10 x i32]* [[ARG_B:%.+]], [10 x i32]** [[LOCAL_B]]
+// Store captures in the context.
+// CHECK-64-DAG:[[CONV_AP:%.+]] = bitcast i[[SZ]]* [[LOCAL_A]] to i32*
+// CHECK-DAG: [[CONV_AAP:%.+]] = bitcast i[[SZ]]* [[LOCAL_AA]] to i16*
+// CHECK-DAG: [[CONV_AAAP:%.+]] = bitcast i[[SZ]]* [[LOCAL_AAA]] to i8*
+// CHECK-DAG: [[REF_B:%.+]] = load [10 x i32]*, [10 x i32]** [[LOCAL_B]],
+
+// CHECK-64-DAG:[[CONV_A:%.+]] = load i32, i32* [[CONV_AP]]
+// CHECK-64-DAG:[[CONV:%.+]] = bitcast i[[SZ]]* [[LOCAL_A_CASTED]] to i32*
+// CHECK-64-DAG:store i32 [[CONV_A]], i32* [[CONV]], align
+// CHECK-32-DAG:[[LOCAL_AV:%.+]] = load i32, i32* [[LOCAL_A]]
+// CHECK-32-DAG:store i32 [[LOCAL_AV]], i32* [[LOCAL_A_CASTED]], align
+// CHECK-DAG: [[REF_A:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_A_CASTED]],
+
+// CHECK-DAG: [[CONV_AA:%.+]] = load i16, i16* [[CONV_AAP]]
+// CHECK-DAG: [[CONV:%.+]] = bitcast i[[SZ]]* [[LOCAL_AA_CASTED]] to i16*
+// CHECK-DAG: store i16 [[CONV_AA]], i16* [[CONV]], align
+// CHECK-DAG: [[REF_AA:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_AA_CASTED]],
+
+// CHECK-DAG: [[CONV_AAA:%.+]] = load i8, i8* [[CONV_AAAP]]
+// CHECK-DAG: [[CONV:%.+]] = bitcast i[[SZ]]* [[LOCAL_AAA_CASTED]] to i8*
+// CHECK-DAG: store i8 [[CONV_AAA]], i8* [[CONV]], align
+// CHECK-DAG: [[REF_AAA:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_AAA_CASTED]],
+
+// CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams(%ident_t* [[DEF_LOC]], i32 5, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i[[SZ]], i[[SZ]], i[[SZ]], i[[SZ]], [10 x i32]*)* [[OMP_OUTLINED6:@.+]] to void (i32*, i32*, ...)*), i[[SZ]] [[REF_A]], i[[SZ]] {{.+}}, i[[SZ]] [[REF_AA]], i[[SZ]] [[REF_AAA]], [10 x i32]* [[REF_B]])
+//
+//
+// CHECK: define internal {{.*}}void [[OMP_OUTLINED6]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, [10 x i32]* {{.+}})
+// To reduce complexity, we're only going as far as validating the signature of the outlined parallel function.
+
+// CHECK: define internal void [[HVT5]]
+// Create local storage for each capture.
+// CHECK: [[LOCAL_A:%.+]] = alloca i[[SZ]]
+// CHECK: [[LOCAL_AA:%.+]] = alloca i[[SZ]]
+// CHECK: [[LOCAL_B:%.+]] = alloca [10 x i32]*
+// CHECK: [[LOCAL_A_CASTED:%.+]] = alloca i[[SZ]]
+// CHECK: [[LOCAL_AA_CASTED:%.+]] = alloca i[[SZ]]
+// CHECK-DAG: store i[[SZ]] [[ARG_A:%.+]], i[[SZ]]* [[LOCAL_A]]
+// CHECK-DAG: store i[[SZ]] [[ARG_AA:%.+]], i[[SZ]]* [[LOCAL_AA]]
+// CHECK-DAG: store [10 x i32]* [[ARG_B:%.+]], [10 x i32]** [[LOCAL_B]]
+// Store captures in the context.
+// CHECK-64-DAG:[[CONV_AP:%.+]] = bitcast i[[SZ]]* [[LOCAL_A]] to i32*
+// CHECK-DAG: [[CONV_AAP:%.+]] = bitcast i[[SZ]]* [[LOCAL_AA]] to i16*
+// CHECK-DAG: [[REF_B:%.+]] = load [10 x i32]*, [10 x i32]** [[LOCAL_B]],
+
+// CHECK-64-DAG:[[CONV_A:%.+]] = load i32, i32* [[CONV_AP]]
+// CHECK-64-DAG:[[CONV:%.+]] = bitcast i[[SZ]]* [[LOCAL_A_CASTED]] to i32*
+// CHECK-64-DAG:store i32 [[CONV_A]], i32* [[CONV]], align
+// CHECK-32-DAG:[[LOCAL_AV:%.+]] = load i32, i32* [[LOCAL_A]]
+// CHECK-32-DAG:store i32 [[LOCAL_AV]], i32* [[LOCAL_A_CASTED]], align
+// CHECK-DAG: [[REF_A:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_A_CASTED]],
+
+// CHECK-DAG: [[CONV_AA:%.+]] = load i16, i16* [[CONV_AAP]]
+// CHECK-DAG: [[CONV:%.+]] = bitcast i[[SZ]]* [[LOCAL_AA_CASTED]] to i16*
+// CHECK-DAG: store i16 [[CONV_AA]], i16* [[CONV]], align
+// CHECK-DAG: [[REF_AA:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_AA_CASTED]],
+
+// CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams(%ident_t* [[DEF_LOC]], i32 3, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i[[SZ]], i[[SZ]], [10 x i32]*)* [[OMP_OUTLINED7:@.+]] to void (i32*, i32*, ...)*), i[[SZ]] [[REF_A]], i[[SZ]] [[REF_AA]], [10 x i32]* [[REF_B]])
+//
+//
+// CHECK: define internal {{.*}}void [[OMP_OUTLINED7]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, [10 x i32]* {{.+}})
+// To reduce complexity, we're only going as far as validating the signature of the outlined parallel function.
+
+// CHECK-DAG: !{!"llvm.loop.vectorize.width", i32 16}
+// CHECK-DAG: !{!"llvm.loop.vectorize.enable", i1 true}
+// CHECK-DAG: !{!"llvm.loop.vectorize.width", i32 32}
+
+#endif
diff --git a/test/OpenMP/target_teams_distribute_simd_codegen_registration.cpp b/test/OpenMP/target_teams_distribute_simd_codegen_registration.cpp
new file mode 100644
index 000000000000..d138114633ea
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_simd_codegen_registration.cpp
@@ -0,0 +1,454 @@
+// Test host codegen.
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+
+// Test target teams distribute simd codegen - host bc file has to be created first.
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm-bc %s -o %t-ppc-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s -check-prefix=TCHECK
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s -check-prefix=TCHECK
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm-bc %s -o %t-x86-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s -check-prefix=TCHECK
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s -check-prefix=TCHECK
+
+// Check that no target code is emmitted if no omptests flag was provided.
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s -check-prefix=CHECK-NTARGET
+
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+// CHECK-DAG: [[SA:%.+]] = type { [4 x i32] }
+// CHECK-DAG: [[SB:%.+]] = type { [8 x i32] }
+// CHECK-DAG: [[SC:%.+]] = type { [16 x i32] }
+// CHECK-DAG: [[SD:%.+]] = type { [32 x i32] }
+// CHECK-DAG: [[SE:%.+]] = type { [64 x i32] }
+// CHECK-DAG: [[ST1:%.+]] = type { [228 x i32] }
+// CHECK-DAG: [[ST2:%.+]] = type { [1128 x i32] }
+// CHECK-DAG: [[ENTTY:%.+]] = type { i8*, i8*, i[[SZ:32|64]], i32, i32 }
+// CHECK-DAG: [[DEVTY:%.+]] = type { i8*, i8*, [[ENTTY]]*, [[ENTTY]]* }
+// CHECK-DAG: [[DSCTY:%.+]] = type { i32, [[DEVTY]]*, [[ENTTY]]*, [[ENTTY]]* }
+
+// TCHECK: [[ENTTY:%.+]] = type { i8*, i8*, i[[SZ:32|64]], i32, i32 }
+
+// CHECK-DAG: $[[REGFN:\.omp_offloading\..+]] = comdat
+
+// CHECK-DAG: [[A1:@.+]] = internal global [[SA]]
+// CHECK-DAG: [[A2:@.+]] = global [[SA]]
+// CHECK-DAG: [[B1:@.+]] = global [[SB]]
+// CHECK-DAG: [[B2:@.+]] = global [[SB]]
+// CHECK-DAG: [[C1:@.+]] = internal global [[SC]]
+// CHECK-DAG: [[D1:@.+]] = global [[SD]]
+// CHECK-DAG: [[E1:@.+]] = global [[SE]]
+// CHECK-DAG: [[T1:@.+]] = global [[ST1]]
+// CHECK-DAG: [[T2:@.+]] = global [[ST2]]
+
+// CHECK-NTARGET-DAG: [[SA:%.+]] = type { [4 x i32] }
+// CHECK-NTARGET-DAG: [[SB:%.+]] = type { [8 x i32] }
+// CHECK-NTARGET-DAG: [[SC:%.+]] = type { [16 x i32] }
+// CHECK-NTARGET-DAG: [[SD:%.+]] = type { [32 x i32] }
+// CHECK-NTARGET-DAG: [[SE:%.+]] = type { [64 x i32] }
+// CHECK-NTARGET-DAG: [[ST1:%.+]] = type { [228 x i32] }
+// CHECK-NTARGET-DAG: [[ST2:%.+]] = type { [1128 x i32] }
+// CHECK-NTARGET-NOT: type { i8*, i8*, %
+// CHECK-NTARGET-NOT: type { i32, %
+
+// We have 7 target regions
+
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// TCHECK-NOT: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
+// CHECK-DAG: {{@.+}} = private constant i8 0
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i64] [i64 288]
+
+// CHECK-NTARGET-NOT: private constant i8 0
+// CHECK-NTARGET-NOT: private unnamed_addr constant [1 x i
+
+// CHECK-DAG: [[NAMEPTR1:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME1:__omp_offloading_[0-9a-f]+_[0-9a-f]+__Z.+_l[0-9]+]]\00"
+// CHECK-DAG: [[ENTRY1:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR1]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR2:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME2:.+]]\00"
+// CHECK-DAG: [[ENTRY2:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR2]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR3:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME3:.+]]\00"
+// CHECK-DAG: [[ENTRY3:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR3]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR4:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME4:.+]]\00"
+// CHECK-DAG: [[ENTRY4:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR4]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR5:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME5:.+]]\00"
+// CHECK-DAG: [[ENTRY5:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR5]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR6:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME6:.+]]\00"
+// CHECK-DAG: [[ENTRY6:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR6]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR7:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME7:.+]]\00"
+// CHECK-DAG: [[ENTRY7:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR7]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR8:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME8:.+]]\00"
+// CHECK-DAG: [[ENTRY8:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR8]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR9:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME9:.+]]\00"
+// CHECK-DAG: [[ENTRY9:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR9]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR10:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME10:.+]]\00"
+// CHECK-DAG: [[ENTRY10:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR10]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR11:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME11:.+]]\00"
+// CHECK-DAG: [[ENTRY11:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR11]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// CHECK-DAG: [[NAMEPTR12:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME12:.+]]\00"
+// CHECK-DAG: [[ENTRY12:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR12]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+
+// TCHECK-DAG: [[NAMEPTR1:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME1:__omp_offloading_[0-9a-f]+_[0-9a-f]+__Z.+_l[0-9]+]]\00"
+// TCHECK-DAG: [[ENTRY1:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR1]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR2:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME2:.+]]\00"
+// TCHECK-DAG: [[ENTRY2:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR2]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR3:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME3:.+]]\00"
+// TCHECK-DAG: [[ENTRY3:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR3]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR4:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME4:.+]]\00"
+// TCHECK-DAG: [[ENTRY4:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR4]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR5:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME5:.+]]\00"
+// TCHECK-DAG: [[ENTRY5:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR5]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR6:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME6:.+]]\00"
+// TCHECK-DAG: [[ENTRY6:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR6]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR7:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME7:.+]]\00"
+// TCHECK-DAG: [[ENTRY7:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR7]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR8:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME8:.+]]\00"
+// TCHECK-DAG: [[ENTRY8:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR8]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR9:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME9:.+]]\00"
+// TCHECK-DAG: [[ENTRY9:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR9]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR10:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME10:.+]]\00"
+// TCHECK-DAG: [[ENTRY10:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR10]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR11:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME11:.+]]\00"
+// TCHECK-DAG: [[ENTRY11:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR11]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+// TCHECK-DAG: [[NAMEPTR12:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME12:.+]]\00"
+// TCHECK-DAG: [[ENTRY12:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR12]], i32 0, i32 0), i[[SZ]] 0, i32 0, i32 0 }, section ".omp_offloading.entries", align 1
+
+// CHECK: [[ENTBEGIN:@.+]] = external constant [[ENTTY]]
+// CHECK: [[ENTEND:@.+]] = external constant [[ENTTY]]
+// CHECK: [[DEVBEGIN:@.+]] = external constant i8
+// CHECK: [[DEVEND:@.+]] = external constant i8
+// CHECK: [[IMAGES:@.+]] = internal unnamed_addr constant [1 x [[DEVTY]]] [{{.+}} { i8* [[DEVBEGIN]], i8* [[DEVEND]], [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }], comdat($[[REGFN]])
+// CHECK: [[DESC:@.+]] = internal constant [[DSCTY]] { i32 1, [[DEVTY]]* getelementptr inbounds ([1 x [[DEVTY]]], [1 x [[DEVTY]]]* [[IMAGES]], i32 0, i32 0), [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }, comdat($[[REGFN]])
+
+// We have 4 initializers, one for the 500 priority, another one for 501, or more for the default priority, and the last one for the offloading registration function.
+// CHECK: @llvm.global_ctors = appending global [4 x { i32, void ()*, i8* }] [
+// CHECK-SAME: { i32, void ()*, i8* } { i32 500, void ()* [[P500:@[^,]+]], i8* null },
+// CHECK-SAME: { i32, void ()*, i8* } { i32 501, void ()* [[P501:@[^,]+]], i8* null },
+// CHECK-SAME: { i32, void ()*, i8* } { i32 65535, void ()* [[PMAX:@[^,]+]], i8* null },
+// CHECK-SAME: { i32, void ()*, i8* } { i32 0, void ()* bitcast (void (i8*)* @[[REGFN]] to void ()*), i8* bitcast (void (i8*)* @[[REGFN]] to i8*) }]
+
+// CHECK-NTARGET: @llvm.global_ctors = appending global [3 x { i32, void ()*, i8* }] [
+
+extern int *R;
+
+struct SA {
+ int arr[4];
+ void foo() {
+ int a = *R;
+ a += 1;
+ *R = a;
+ }
+ SA() {
+ int a = *R;
+ a += 2;
+ *R = a;
+ }
+ ~SA() {
+ int a = *R;
+ a += 3;
+ *R = a;
+ }
+};
+
+struct SB {
+ int arr[8];
+ void foo() {
+ int a = *R;
+ #pragma omp target teams distribute simd
+ for (int i = 0; i < 10; ++i)
+ a += 4;
+ *R = a;
+ }
+ SB() {
+ int a = *R;
+ a += 5;
+ *R = a;
+ }
+ ~SB() {
+ int a = *R;
+ a += 6;
+ *R = a;
+ }
+};
+
+struct SC {
+ int arr[16];
+ void foo() {
+ int a = *R;
+ a += 7;
+ *R = a;
+ }
+ SC() {
+ int a = *R;
+ #pragma omp target teams distribute simd
+ for (int i = 0; i < 10; ++i)
+ a += 8;
+ *R = a;
+ }
+ ~SC() {
+ int a = *R;
+ a += 9;
+ *R = a;
+ }
+};
+
+struct SD {
+ int arr[32];
+ void foo() {
+ int a = *R;
+ a += 10;
+ *R = a;
+ }
+ SD() {
+ int a = *R;
+ a += 11;
+ *R = a;
+ }
+ ~SD() {
+ int a = *R;
+ #pragma omp target teams distribute simd
+ for (int i = 0; i < 10; ++i)
+ a += 12;
+ *R = a;
+ }
+};
+
+struct SE {
+ int arr[64];
+ void foo() {
+ int a = *R;
+ #pragma omp target teams distribute simd if(target: 0)
+ for (int i = 0; i < 10; ++i)
+ a += 13;
+ *R = a;
+ }
+ SE() {
+ int a = *R;
+ #pragma omp target teams distribute simd
+ for (int i = 0; i < 10; ++i)
+ a += 14;
+ *R = a;
+ }
+ ~SE() {
+ int a = *R;
+ #pragma omp target teams distribute simd
+ for (int i = 0; i < 10; ++i)
+ a += 15;
+ *R = a;
+ }
+};
+
+template <int x>
+struct ST {
+ int arr[128 + x];
+ void foo() {
+ int a = *R;
+ #pragma omp target teams distribute simd
+ for (int i = 0; i < 10; ++i)
+ a += 16 + x;
+ *R = a;
+ }
+ ST() {
+ int a = *R;
+ #pragma omp target teams distribute simd
+ for (int i = 0; i < 10; ++i)
+ a += 17 + x;
+ *R = a;
+ }
+ ~ST() {
+ int a = *R;
+ #pragma omp target teams distribute simd
+ for (int i = 0; i < 10; ++i)
+ a += 18 + x;
+ *R = a;
+ }
+};
+
+// We have to make sure we us all the target regions:
+//CHECK-DAG: define internal void @[[NAME1]](
+//CHECK-DAG: call void @[[NAME1]](
+//CHECK-DAG: define internal void @[[NAME2]](
+//CHECK-DAG: call void @[[NAME2]](
+//CHECK-DAG: define internal void @[[NAME3]](
+//CHECK-DAG: call void @[[NAME3]](
+//CHECK-DAG: define internal void @[[NAME4]](
+//CHECK-DAG: call void @[[NAME4]](
+//CHECK-DAG: define internal void @[[NAME5]](
+//CHECK-DAG: call void @[[NAME5]](
+//CHECK-DAG: define internal void @[[NAME6]](
+//CHECK-DAG: call void @[[NAME6]](
+//CHECK-DAG: define internal void @[[NAME7]](
+//CHECK-DAG: call void @[[NAME7]](
+//CHECK-DAG: define internal void @[[NAME8]](
+//CHECK-DAG: call void @[[NAME8]](
+//CHECK-DAG: define internal void @[[NAME9]](
+//CHECK-DAG: call void @[[NAME9]](
+//CHECK-DAG: define internal void @[[NAME10]](
+//CHECK-DAG: call void @[[NAME10]](
+//CHECK-DAG: define internal void @[[NAME11]](
+//CHECK-DAG: call void @[[NAME11]](
+//CHECK-DAG: define internal void @[[NAME12]](
+//CHECK-DAG: call void @[[NAME12]](
+
+//TCHECK-DAG: define void @[[NAME1]](
+//TCHECK-DAG: define void @[[NAME2]](
+//TCHECK-DAG: define void @[[NAME3]](
+//TCHECK-DAG: define void @[[NAME4]](
+//TCHECK-DAG: define void @[[NAME5]](
+//TCHECK-DAG: define void @[[NAME6]](
+//TCHECK-DAG: define void @[[NAME7]](
+//TCHECK-DAG: define void @[[NAME8]](
+//TCHECK-DAG: define void @[[NAME9]](
+//TCHECK-DAG: define void @[[NAME10]](
+//TCHECK-DAG: define void @[[NAME11]](
+//TCHECK-DAG: define void @[[NAME12]](
+
+// CHECK-NTARGET-NOT: __tgt_target
+// CHECK-NTARGET-NOT: __tgt_register_lib
+// CHECK-NTARGET-NOT: __tgt_unregister_lib
+
+// TCHECK-NOT: __tgt_target
+// TCHECK-NOT: __tgt_register_lib
+// TCHECK-NOT: __tgt_unregister_lib
+
+// We have 2 initializers with priority 500
+//CHECK: define internal void [[P500]](
+//CHECK: call void @{{.+}}()
+//CHECK: call void @{{.+}}()
+//CHECK-NOT: call void @{{.+}}()
+//CHECK: ret void
+
+// We have 1 initializers with priority 501
+//CHECK: define internal void [[P501]](
+//CHECK: call void @{{.+}}()
+//CHECK-NOT: call void @{{.+}}()
+//CHECK: ret void
+
+// We have 6 initializers with default priority
+//CHECK: define internal void [[PMAX]](
+//CHECK: call void @{{.+}}()
+//CHECK: call void @{{.+}}()
+//CHECK: call void @{{.+}}()
+//CHECK: call void @{{.+}}()
+//CHECK: call void @{{.+}}()
+//CHECK: call void @{{.+}}()
+//CHECK-NOT: call void @{{.+}}()
+//CHECK: ret void
+
+// Check registration and unregistration
+
+//CHECK: define internal void @[[UNREGFN:.+]](i8*)
+//CHECK-SAME: comdat($[[REGFN]]) {
+//CHECK: call i32 @__tgt_unregister_lib([[DSCTY]]* [[DESC]])
+//CHECK: ret void
+//CHECK: declare i32 @__tgt_unregister_lib([[DSCTY]]*)
+
+//CHECK: define linkonce hidden void @[[REGFN]](i8*)
+//CHECK-SAME: comdat {
+//CHECK: call i32 @__tgt_register_lib([[DSCTY]]* [[DESC]])
+//CHECK: call i32 @__cxa_atexit(void (i8*)* @[[UNREGFN]], i8* bitcast ([[DSCTY]]* [[DESC]] to i8*),
+//CHECK: ret void
+//CHECK: declare i32 @__tgt_register_lib([[DSCTY]]*)
+
+static __attribute__((init_priority(500))) SA a1;
+SA a2;
+SB __attribute__((init_priority(500))) b1;
+SB __attribute__((init_priority(501))) b2;
+static SC c1;
+SD d1;
+SE e1;
+ST<100> t1;
+ST<1000> t2;
+
+
+int bar(int a){
+ int r = a;
+
+ a1.foo();
+ a2.foo();
+ b1.foo();
+ b2.foo();
+ c1.foo();
+ d1.foo();
+ e1.foo();
+ t1.foo();
+ t2.foo();
+
+ #pragma omp target teams distribute simd
+ for (int i = 0; i < 10; ++i)
+ ++r;
+
+ return r + *R;
+}
+
+// Check metadata is properly generated:
+// CHECK: !omp_offload.info = !{!{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID:-?[0-9]+]], i32 [[FILEID:-?[0-9]+]], !"_ZN2SB3fooEv", i32 195, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SDD1Ev", i32 247, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SEC1Ev", i32 265, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SED1Ev", i32 272, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EE3fooEv", i32 284, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EEC1Ev", i32 291, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_Z3bari", i32 415, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EED1Ev", i32 298, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EEC1Ev", i32 291, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EED1Ev", i32 298, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EE3fooEv", i32 284, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SCC1Ev", i32 221, i32 {{[0-9]+}}}
+
+// TCHECK: !omp_offload.info = !{!{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID:-?[0-9]+]], i32 [[FILEID:-?[0-9]+]], !"_ZN2SB3fooEv", i32 195, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SDD1Ev", i32 247, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SEC1Ev", i32 265, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SED1Ev", i32 272, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EE3fooEv", i32 284, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EEC1Ev", i32 291, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_Z3bari", i32 415, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EED1Ev", i32 298, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EEC1Ev", i32 291, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EED1Ev", i32 298, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EE3fooEv", i32 284, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SCC1Ev", i32 221, i32 {{[0-9]+}}}
+
+// TCHECK-DAG: !{!"llvm.loop.vectorize.enable", i1 true}
+// CHECK-DAG: !{!"llvm.loop.vectorize.enable", i1 true}
+
+#endif
diff --git a/test/OpenMP/target_teams_distribute_simd_codegen_registration_naming.cpp b/test/OpenMP/target_teams_distribute_simd_codegen_registration_naming.cpp
new file mode 100644
index 000000000000..76618accbd68
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_simd_codegen_registration_naming.cpp
@@ -0,0 +1,71 @@
+// Test host codegen.
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+
+// Test target teams distribute simd codegen - host bc file has to be created first.
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm-bc %s -o %t-ppc-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s -check-prefix=TCHECK
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s -check-prefix=TCHECK
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm-bc %s -o %t-x86-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s -check-prefix=TCHECK
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s -check-prefix=TCHECK
+
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+// CHECK: [[CA:%.+]] = type { i32* }
+
+// CHECK: define {{.*}}i32 @[[NNAME:.+]](i32 {{.*}}%{{.+}})
+int nested(int a){
+ // CHECK: call void @__omp_offloading_[[FILEID:[0-9a-f]+_[0-9a-f]+]]_[[NNAME]]_l[[T1L:[0-9]+]](
+ #pragma omp target teams distribute simd
+ for (int i = 0; i < 10; ++i)
+ ++a;
+
+ // CHECK: call void @"[[LNAME:.+]]"([[CA]]*
+ auto F = [&](){
+ #pragma omp parallel
+ {
+ #pragma omp target teams distribute simd
+ for (int i = 0; i < 10; ++i)
+ ++a;
+ }
+ };
+
+ F();
+
+ return a;
+}
+
+// CHECK: define {{.*}}void @__omp_offloading_[[FILEID]]_[[NNAME]]_l[[T1L]](
+// TCHECK: define {{.*}}void @__omp_offloading_[[FILEID:[0-9a-f]+_[0-9a-f]+]]_[[NNAME:.+]]_l[[T1L:[0-9]+]](
+
+// CHECK: define {{.*}}void @"[[LNAME]]"(
+// CHECK: call void {{.*}}@__kmpc_fork_call{{.+}}[[PNAME:@.+]] to
+
+// CHECK: define {{.*}}void [[PNAME]](
+// CHECK: call void @__omp_offloading_[[FILEID]]_[[NNAME]]_l[[T2L:[0-9]+]](
+
+// CHECK: define {{.*}}void @__omp_offloading_[[FILEID]]_[[NNAME]]_l[[T2L]](
+// TCHECK: define {{.*}}void @__omp_offloading_[[FILEID]]_[[NNAME:.+]]_l[[T2L:[0-9]+]](
+
+
+// Check metadata is properly generated:
+// CHECK: !omp_offload.info = !{!{{[0-9]+}}, !{{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 {{-?[0-9]+}}, i32 {{-?[0-9]+}}, !"[[NNAME]]", i32 [[T1L]], i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 {{-?[0-9]+}}, i32 {{-?[0-9]+}}, !"[[NNAME]]", i32 [[T2L]], i32 {{[0-9]+}}}
+
+// TCHECK: !omp_offload.info = !{!{{[0-9]+}}, !{{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 {{-?[0-9]+}}, i32 {{-?[0-9]+}}, !"[[NNAME]]", i32 [[T1L]], i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 {{-?[0-9]+}}, i32 {{-?[0-9]+}}, !"[[NNAME]]", i32 [[T2L]], i32 {{[0-9]+}}}
+
+// CHECK-DAG: !{!"llvm.loop.vectorize.enable", i1 true}
+// TCHECK-DAG: !{!"llvm.loop.vectorize.enable", i1 true}
+#endif
diff --git a/test/OpenMP/target_teams_distribute_simd_collapse_codegen.cpp b/test/OpenMP/target_teams_distribute_simd_collapse_codegen.cpp
new file mode 100644
index 000000000000..703136f0652e
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_simd_collapse_codegen.cpp
@@ -0,0 +1,125 @@
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+// Test host codegen.
+// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64
+// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32
+#ifdef CK1
+
+template <typename T, int X, long long Y>
+struct SS{
+ T a[X][Y];
+
+ // CK1: define {{.*}}i32 @{{.+}}foo{{.+}}(
+ int foo(void) {
+
+ // CK1: call i32 @__tgt_target_teams(
+ // CK1: call void @[[OFFL1:.+]](
+ #pragma omp target teams distribute simd collapse(2)
+ for(int i = 0; i < X; i++) {
+ for(int j = 0; j < Y; j++) {
+ a[i][j] = (T)0;
+ }
+ }
+ // CK1: define internal void @[[OFFL1]](
+ // CK1: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTL1:.+]] to {{.+}},
+ // CK1: ret void
+
+ // CK1: define internal void @[[OUTL1]]({{.+}})
+ // discard loop variables not needed here
+ // CK1: = alloca i32,
+ // CK1: = alloca i32,
+ // CK1: = alloca i32,
+ // CK1: = alloca i32,
+ // CK1: [[OMP_UB:%.+]] = alloca i32,
+ // CK1: store i32 56087, i32* [[OMP_UB]],
+ // CK1: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 92, {{.+}}, {{.+}}, i32* [[OMP_UB]],
+ // CK1: call void @__kmpc_for_static_fini(
+ // CK1: ret void
+
+ return a[0][0];
+ }
+};
+
+int teams_template_struct(void) {
+ SS<int, 123, 456> V;
+ return V.foo();
+
+}
+#endif // CK1
+
+// Test host codegen.
+// RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64
+// RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32
+#ifdef CK2
+
+template <typename T, int n, int m>
+int tmain(T argc) {
+ T a[n][m];
+ #pragma omp target teams distribute simd collapse(2)
+ for(int i = 0; i < n; i++) {
+ for(int j = 0; j < m; j++) {
+ a[i][j] = (T)0;
+ }
+ }
+ return 0;
+}
+
+int main (int argc, char **argv) {
+ int n = 100;
+ int m = 2;
+ int a[n][m];
+ #pragma omp target teams distribute simd collapse(2)
+ for(int i = 0; i < n; i++) {
+ for(int j = 0; j < m; j++) {
+ a[i][j] = 0;
+ }
+ }
+ return tmain<int, 10, 2>(argc);
+}
+
+// CK2: define {{.*}}i32 @{{[^,]+}}(i{{.+}}{{.+}} %[[ARGC:.+]], {{.+}})
+// CK2: call i32 @__tgt_target_teams(
+// CK2: call void @[[OFFL1:.+]]({{.+}})
+// CK2: {{%.+}} = call{{.*}} i32 @[[TMAIN:.+]]({{.+}})
+// CK2: ret
+
+// CK2: define {{.*}}void @[[OFFL1]]({{.+}})
+// CK2: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 5, {{.+}} @[[OUTL1:.+]] to {{.+}},
+// CK2: ret void
+
+// CK2: define internal void @[[OUTL1]]({{.+}})
+// CK2: [[OMP_UB:%.omp.ub]] = alloca i64,
+// CK2: store i64 {{.+}}, i64* [[OMP_UB]],
+// CK2: call void @__kmpc_for_static_init_8({{.+}}, {{.+}}, i32 92, {{.+}}, {{.+}}, i64* [[OMP_UB]],
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+// CK2: define {{.*}}i32 @[[TMAIN]]({{.+}})
+// CK2: call i32 @__tgt_target_teams(
+// CK2: call void @[[OFFLT1:.+]]({{.+}})
+// CK2: ret
+// CK2-NEXT: }
+
+// CK2: define {{.*}}void @[[OFFLT1]]({{.+}})
+// CK2: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTLT1:.+]] to {{.+}},
+// CK2: ret void
+
+// CK2: define internal void @[[OUTLT1]]({{.+}})
+// discard loop variables not needed here
+// CK2: [[OMP_UB:%.omp.ub]] = alloca i32,
+// CK2: store i32 {{.+}}, i32* [[OMP_UB]],
+// CK2: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 92, {{.+}}, {{.+}}, i32* [[OMP_UB]],
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+#endif // CK2
+#endif // #ifndef HEADER
diff --git a/test/OpenMP/target_teams_distribute_simd_depend_messages.cpp b/test/OpenMP/target_teams_distribute_simd_depend_messages.cpp
index 39d12d8d4d0e..c24c7438b0b5 100644
--- a/test/OpenMP/target_teams_distribute_simd_depend_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_simd_depend_messages.cpp
@@ -37,21 +37,21 @@ int main(int argc, char **argv, char *env[]) {
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute simd depend (out: ) // expected-error {{expected expression}}
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute simd depend (inout : foobool(argc)), depend (in, argc) // expected-error {{expected variable name, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}}
+#pragma omp target teams distribute simd depend (inout : foobool(argc)), depend (in, argc) // expected-error {{expected addressable lvalue expression, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}}
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute simd depend (out :S1) // expected-error {{'S1' does not refer to a value}}
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute simd depend(in : argv[1][1] = '2') // expected-error {{expected variable name, array element or array section}}
+#pragma omp target teams distribute simd depend(in : argv[1][1] = '2')
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute simd depend (in : vec[1]) // expected-error {{expected variable name, array element or array section}}
+#pragma omp target teams distribute simd depend (in : vec[1]) // expected-error {{expected addressable lvalue expression, array element or array section}}
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute simd depend (in : argv[0])
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute simd depend (in : ) // expected-error {{expected expression}}
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute simd depend (in : main) // expected-error {{expected variable name, array element or array section}}
+#pragma omp target teams distribute simd depend (in : main)
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute simd depend(in : a[0]) // expected-error{{expected variable name, array element or array section}}
+#pragma omp target teams distribute simd depend(in : a[0]) // expected-error{{expected addressable lvalue expression, array element or array section}}
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute simd depend (in : vec[1:2]) // expected-error {{ value is not an array or pointer}}
for (i = 0; i < argc; ++i) foo();
diff --git a/test/OpenMP/target_teams_distribute_simd_dist_schedule_codegen.cpp b/test/OpenMP/target_teams_distribute_simd_dist_schedule_codegen.cpp
new file mode 100644
index 000000000000..d096da329abc
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_simd_dist_schedule_codegen.cpp
@@ -0,0 +1,197 @@
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+// Test host codegen.
+// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64
+// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32
+#ifdef CK1
+
+template <typename T, int X, long long Y>
+struct SS{
+ T a[X];
+ float b;
+ // CK1: define {{.*}}i32 @{{.+}}foo{{.+}}(
+ int foo(void) {
+
+ // CK1: call i32 @__tgt_target_teams(
+ // CK1: call void @[[OFFL1:.+]](
+ #pragma omp target teams distribute simd
+ for(int i = 0; i < X; i++) {
+ a[i] = (T)0;
+ }
+ // CK1: call i32 @__tgt_target_teams(
+ // CK1: call void @[[OFFL2:.+]](
+ #pragma omp target teams distribute simd dist_schedule(static)
+ for(int i = 0; i < X; i++) {
+ a[i] = (T)0;
+ }
+ // CK1: call i32 @__tgt_target_teams(
+ // CK1: call void @[[OFFL3:.+]](
+ #pragma omp target teams distribute simd dist_schedule(static, X/2)
+ for(int i = 0; i < X; i++) {
+ a[i] = (T)0;
+ }
+ // CK1: define internal void @[[OFFL1]](
+ // CK1: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTL1:.+]] to {{.+}},
+ // CK1: ret void
+
+ // CK1: define internal void @[[OUTL1]]({{.+}})
+ // CK1: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 92
+ // CK1: call void @__kmpc_for_static_fini(
+ // CK1: ret void
+
+ // CK1: define internal void @[[OFFL2]](
+ // CK1: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTL2:.+]] to {{.+}},
+ // CK1: ret void
+
+ // CK1: define internal void @[[OUTL2]]({{.+}})
+ // CK1: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 92
+ // CK1: call void @__kmpc_for_static_fini(
+ // CK1: ret void
+
+ // CK1: define internal void @[[OFFL3]](
+ // CK1: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTL3:.+]] to {{.+}},
+ // CK1: ret void
+
+ // CK1: define internal void @[[OUTL3]]({{.+}})
+ // CK1: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 91
+ // CK1: call void @__kmpc_for_static_fini(
+ // CK1: ret void
+
+ return a[0];
+ }
+};
+
+int teams_template_struct(void) {
+ SS<int, 123, 456> V;
+ return V.foo();
+
+}
+#endif // CK1
+
+// Test host codegen.
+// RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64
+// RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32
+#ifdef CK2
+
+template <typename T, int n>
+int tmain(T argc) {
+ T a[n];
+#pragma omp target teams distribute simd
+ for(int i = 0; i < n; i++) {
+ a[i] = (T)0;
+ }
+#pragma omp target teams distribute simd dist_schedule(static)
+ for(int i = 0; i < n; i++) {
+ a[i] = (T)0;
+ }
+#pragma omp target teams distribute simd dist_schedule(static, n)
+ for(int i = 0; i < n; i++) {
+ a[i] = (T)0;
+ }
+ return 0;
+}
+
+int main (int argc, char **argv) {
+ int n = 100;
+ int a[n];
+#pragma omp target teams distribute simd
+ for(int i = 0; i < n; i++) {
+ a[i] = 0;
+ }
+#pragma omp target teams distribute simd dist_schedule(static)
+ for(int i = 0; i < n; i++) {
+ a[i] = 0;
+ }
+#pragma omp target teams distribute simd dist_schedule(static, n)
+ for(int i = 0; i < n; i++) {
+ a[i] = 0;
+ }
+ return tmain<int, 10>(argc);
+}
+
+// CK2: define {{.*}}i32 @{{[^,]+}}(i{{.+}}{{.+}} %[[ARGC:.+]], {{.+}})
+// CK2: call i32 @__tgt_target_teams(
+// CK2: call void @[[OFFL1:.+]]({{.+}})
+// CK2: call i32 @__tgt_target_teams(
+// CK2: call void @[[OFFL2:.+]]({{.+}})
+// CK2: call i32 @__tgt_target_teams(
+// CK2: call void @[[OFFL3:.+]]({{.+}})
+// CK2: {{%.+}} = call{{.*}} i32 @[[TMAIN:.+]]({{.+}})
+// CK2: ret
+
+// CK2: define {{.*}}void @[[OFFL1]]({{.+}})
+// CK2: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 3, {{.+}} @[[OUTL1:.+]] to {{.+}},
+// CK2: ret void
+
+// CK2: define internal void @[[OUTL1]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 92
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define {{.*}}void @[[OFFL2]]({{.+}})
+// CK2: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 3, {{.+}} @[[OUTL2:.+]] to {{.+}},
+// CK2: ret void
+
+// CK2: define internal void @[[OUTL2]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 92
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define {{.*}}void @[[OFFL3]]({{.+}})
+// CK2: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 4, {{.+}} @[[OUTL3:.+]] to {{.+}},
+// CK2: ret void
+
+// CK2: define internal void @[[OUTL3]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 91
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define {{.*}}i32 @[[TMAIN]]({{.+}})
+// CK2: call i32 @__tgt_target_teams(
+// CK2: call void @[[OFFLT1:.+]]({{.+}})
+// CK2: call i32 @__tgt_target_teams(
+// CK2: call void @[[OFFLT2:.+]]({{.+}})
+// CK2: call i32 @__tgt_target_teams(
+// CK2: call void @[[OFFLT3:.+]]({{.+}})
+// CK2: ret
+// CK2-NEXT: }
+
+// CK2: define {{.*}}void @[[OFFLT1]]({{.+}})
+// CK2: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTLT1:.+]] to {{.+}},
+// CK2: ret void
+
+// CK2: define internal void @[[OUTLT1]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 92
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define {{.*}}void @[[OFFLT2]]({{.+}})
+// CK2: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTLT2:.+]] to {{.+}},
+// CK2: ret void
+
+// CK2: define internal void @[[OUTLT2]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 92
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define {{.*}}void @[[OFFLT3]]({{.+}})
+// CK2: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTLT3:.+]] to {{.+}},
+// CK2: ret void
+
+// CK2: define internal void @[[OUTLT3]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 91
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+#endif // CK2
+#endif // #ifndef HEADER
diff --git a/test/OpenMP/target_teams_distribute_simd_firstprivate_codegen.cpp b/test/OpenMP/target_teams_distribute_simd_firstprivate_codegen.cpp
new file mode 100644
index 000000000000..f2871f811833
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_simd_firstprivate_codegen.cpp
@@ -0,0 +1,342 @@
+// RUN: %clang_cc1 -DCHECK -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -DCHECK -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+
+// RUN: %clang_cc1 -DLAMBDA -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+struct St {
+ int a, b;
+ St() : a(0), b(0) {}
+ St(const St &st) : a(st.a + st.b), b(0) {}
+ ~St() {}
+};
+
+volatile int g = 1212;
+volatile int &g1 = g;
+
+template <class T>
+struct S {
+ T f;
+ S(T a) : f(a + g) {}
+ S() : f(g) {}
+ S(const S &s, St t = St()) : f(s.f + t.a) {}
+ operator T() { return T(); }
+ ~S() {}
+};
+
+// CHECK-DAG: [[S_FLOAT_TY:%.+]] = type { float }
+// CHECK-DAG: [[S_INT_TY:%.+]] = type { i{{[0-9]+}} }
+// CHECK-DAG: [[ST_TY:%.+]] = type { i{{[0-9]+}}, i{{[0-9]+}} }
+
+template <typename T>
+T tmain() {
+ S<T> test;
+ T t_var = T();
+ T vec[] = {1, 2};
+ S<T> s_arr[] = {1, 2};
+ S<T> &var = test;
+#pragma omp target teams distribute simd firstprivate(t_var, vec, s_arr, var)
+ for (int i = 0; i < 2; ++i) {
+ vec[i] = t_var;
+ s_arr[i] = var;
+ }
+ return T();
+}
+
+// CHECK-DAG: [[TEST:@.+]] = global [[S_FLOAT_TY]] zeroinitializer,
+S<float> test;
+// CHECK-DAG: [[T_VAR:@.+]] = global i{{[0-9]+}} 333,
+int t_var = 333;
+// CHECK-DAG: [[VEC:@.+]] = global [2 x i{{[0-9]+}}] [i{{[0-9]+}} 1, i{{[0-9]+}} 2],
+int vec[] = {1, 2};
+// CHECK-DAG: [[S_ARR:@.+]] = global [2 x [[S_FLOAT_TY]]] zeroinitializer,
+S<float> s_arr[] = {1, 2};
+// CHECK-DAG: [[VAR:@.+]] = global [[S_FLOAT_TY]] zeroinitializer,
+S<float> var(3);
+// CHECK-DAG: [[SIVAR:@.+]] = internal global i{{[0-9]+}} 0,
+
+int main() {
+ static int sivar;
+#ifdef LAMBDA
+ // LAMBDA: [[G:@.+]] = global i{{[0-9]+}} 1212,
+ // LAMBDA-LABEL: @main
+ // LAMBDA: call void [[OUTER_LAMBDA:@.+]](
+ [&]() {
+ // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
+ // LAMBDA: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 3, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 0)
+ // LAMBDA: call void @[[LOFFL1:.+]](i{{64|32}} %{{.+}})
+ // LAMBDA: ret
+#pragma omp target teams distribute simd firstprivate(g, g1, sivar)
+ for (int i = 0; i < 2; ++i) {
+ // LAMBDA: define{{.*}} internal{{.*}} void @[[LOFFL1]](i{{64|32}} {{%.+}}, i{{64|32}} {{%.+}})
+ // LAMBDA: {{%.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: {{%.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: {{%.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: [[G_CAST:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[G1_CAST:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[SIVAR_CAST:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA-DAG: [[G_CAST_VAL:%.+]] = load{{.+}} [[G_CAST]],
+ // LAMBDA-DAG: [[G1_CAST_VAL:%.+]] = load{{.+}} [[G1_CAST]],
+ // LAMBDA-DAG: [[SIVAR_CAST_VAL:%.+]] = load{{.+}} [[SIVAR_CAST]],
+ // LAMBDA: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 3, {{.+}} @[[LOUTL1:.+]] to {{.+}}, {{.+}} [[G_CAST_VAL]], {{.+}} [[G1_CAST_VAL]], {{.+}} [[SIVAR_CAST_VAL]])
+ // LAMBDA: ret void
+
+ // LAMBDA: define internal void @[[LOUTL1]]({{.+}})
+ // Skip global and bound tid vars
+ // LAMBDA: {{.+}} = alloca i32*,
+ // LAMBDA: {{.+}} = alloca i32*,
+ // LAMBDA: [[G_ADDR:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[G1_ADDR:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[SIVAR_ADDR:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: {{%.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: {{%.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: {{%.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: {{%.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: {{%.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: {{%.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: [[G_PRIV_ADDR:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[G1_PRIV_ADDR:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[G1_TMP:%.+]] = alloca i32*,
+ // LAMBDA: [[SIVAR_PRIV_ADDR:%.+]] = alloca i{{[0-9]+}},
+ // skip loop vars
+ // LAMBDA-DAG: store {{.+}}, {{.+}} [[G_ADDR]],
+ // LAMBDA-DAG: store {{.+}}, {{.+}} [[G1_ADDR]],
+ // LAMBDA-DAG: store {{.+}}, {{.+}} [[SIVAR_ADDR]],
+ // LAMBDA-DAG: [[G_CONV:%.+]] = bitcast {{.+}} [[G_ADDR]] to
+ // LAMBDA-DAG: [[G1_CONV:%.+]] = bitcast {{.+}} [[G1_ADDR]] to
+ // LAMBDA-DAG: [[SIVAR_CONV:%.+]] = bitcast {{.+}} [[SIVAR_ADDR]] to
+ // LAMBDA-DAG: store{{.+}} [[G1_PRIV_ADDR]], {{.+}} [[G1_TMP]],
+ g = 1;
+ g1 = 1;
+ sivar = 2;
+ // LAMBDA: call void @__kmpc_for_static_init_4(
+ // LAMBDA-DAG: store{{.+}} 1, {{.+}} [[G_PRIV_ADDR]],
+ // LAMBDA-DAG: [[G1:%.+]] = load{{.+}}, {{.+}}* [[G1_TMP]]
+ // LAMBDA-DAG: store{{.+}} 1, {{.+}} [[G1]],
+ // LAMBDA-DAG: store{{.+}} 2, {{.+}} [[SIVAR_PRIV_ADDR]],
+ // LAMBDA-DAG: [[G1_REF:%.+]] = load{{.+}}, {{.+}} [[G1_TMP]],
+ // LAMBDA-DAG: store{{.+}} 1, {{.+}} [[G1_REF]],
+ // LAMBDA: call void [[INNER_LAMBDA:@.+]](
+ // LAMBDA: call void @__kmpc_for_static_fini(
+ [&]() {
+ // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]])
+ // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]],
+ g = 2;
+ g1 = 2;
+ sivar = 4;
+ // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]]
+
+ // LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // LAMBDA: [[G_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G_PTR_REF]]
+ // LAMBDA: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[G_REF]]
+ // LAMBDA: [[G1_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // LAMBDA: [[G1_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G1_PTR_REF]]
+ // LAMBDA: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[G1_REF]]
+ // LAMBDA: [[SIVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+ // LAMBDA: [[SIVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SIVAR_PTR_REF]]
+ // LAMBDA: store i{{[0-9]+}} 4, i{{[0-9]+}}* [[SIVAR_REF]]
+ }();
+ }
+ }();
+ return 0;
+#else
+#pragma omp target teams distribute simd firstprivate(t_var, vec, s_arr, var, sivar)
+ for (int i = 0; i < 2; ++i) {
+ vec[i] = t_var;
+ s_arr[i] = var;
+ sivar += i;
+ }
+ return tmain<int>();
+#endif
+}
+
+// CHECK: define {{.*}}i{{[0-9]+}} @main()
+// CHECK: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 5, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 0)
+// CHECK: call void @[[OFFL1:.+]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}})
+// CHECK: {{%.+}} = call{{.*}} i32 @[[TMAIN_INT:.+]]()
+// CHECK: ret
+
+// CHECK: define{{.*}} void @[[OFFL1]]({{.+}})
+// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}]*,
+// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]]*,
+// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]]*,
+// CHECK: [[SIVAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[T_VAR_CAST:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[SIVAR_CAST:%.+]] = alloca i{{[0-9]+}},
+
+// CHECK-DAG: [[VEC_TE_PAR:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** [[VEC_PRIV]],
+// CHECK-DAG: [[T_VAR_TE_PAR:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_CAST]],
+// CHECK-DAG: [[S_ARR_TE_PAR:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[S_ARR_PRIV]],
+// CHECK-DAG: [[VAR_TE_PAR:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[VAR_PRIV]],
+// CHECK-DAG: [[SIVAR_TE_PAR:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR_CAST]],
+
+// CHECK: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 5, {{.+}} @[[OUTL1:.+]] to {{.+}}, [2 x i{{[0-9]+}}]* [[VEC_TE_PAR]], i{{[0-9]+}} [[T_VAR_TE_PAR]], [2 x [[S_FLOAT_TY]]]* [[S_ARR_TE_PAR]], [[S_FLOAT_TY]]* [[VAR_TE_PAR]], i{{[0-9]+}} [[SIVAR_TE_PAR]])
+// CHECK: ret void
+
+// CHECK: define internal void @[[OUTL1]]({{.+}})
+// Skip global and bound tid vars
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: [[VEC_ADDR:%.+]] = alloca [2 x i{{[0-9]+}}]*,
+// CHECK: [[T_VAR_ADDR:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[S_ARR_ADDR:%.+]] = alloca [2 x [[S_FLOAT_TY]]]*,
+// CHECK: [[VAR_ADDR:%.+]] = alloca [[S_FLOAT_TY]]*,
+// CHECK: [[SIVAR_ADDR:%.+]] = alloca i{{[0-9]+}},
+// Skip temp vars for loop
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]],
+// CHECK: [[AGG_TMP1:%.+]] = alloca [[ST_TY]],
+// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]],
+// CHECK: [[AGG_TMP2:%.+]] = alloca [[ST_TY]],
+
+// param copy
+// CHECK: store [2 x i{{[0-9]+}}]* {{.+}}, [2 x i{{[0-9]+}}]** [[VEC_ADDR]],
+// CHECK: store i{{[0-9]+}} {{.+}}, i{{[0-9]+}}* [[T_VAR_ADDR]],
+// CHECK: store [2 x [[S_FLOAT_TY]]]* {{.+}}, [2 x [[S_FLOAT_TY]]]** [[S_ARR_ADDR]],
+// CHECK: store [[S_FLOAT_TY]]* {{.+}}, [[S_FLOAT_TY]]** [[VAR_ADDR]],
+// CHECK: store i{{[0-9]+}} {{.+}}, i{{[0-9]+}}* [[SIVAR_ADDR]],
+
+// T_VAR and SIVAR
+// CHECK-DAG-64: [[CONV_TVAR:%.+]] = bitcast i64* [[T_VAR_ADDR]] to i32*
+// CHECK-DAG-64: [[CONV_SIVAR:%.+]] = bitcast i64* [[SIVAR_ADDR]] to i32*
+
+// preparation vars
+// CHECK-DAG: [[VEC_ADDR_VAL:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** [[VEC_ADDR]],
+// CHECK-DAG: [[S_ARR_ADDR_REF:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[S_ARR_ADDR]],
+// CHECK-DAG: [[VAR_ADDR_REF:%.+]] = load{{.+}} [[VAR_ADDR]],
+
+// firstprivate vec(vec): copy from *_addr into priv1 and then from priv1 into priv2
+// CHECK-DAG: [[VEC_DEST_PRIV:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV]] to i8*
+// CHECK-DAG: [[VEC_SRC:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_ADDR_VAL]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[VEC_DEST_PRIV]], i8* [[VEC_SRC]], {{.+}})
+
+// firstprivate(s_arr)
+// CHECK-DAG: [[S_ARR_PRIV_BGN:%.+]] = getelementptr{{.*}} [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[S_ARR_PRIV]],
+// CHECK-DAG: [[S_ARR_ADDR_BGN:%.+]] = bitcast [2 x [[S_FLOAT_TY]]]* [[S_ARR_ADDR_REF]] to
+// CHECK-DAG: [[S_ARR_FIN:%.+]] = icmp{{.+}} [[S_ARR_PRIV_BGN]],
+// CHECK-DAG: [[S_ARR_SRC_COPY:%.+]] = phi{{.+}} [ [[S_ARR_ADDR_BGN]], {{.+}} ], [ [[S_ARR_SRC:%.+]], {{.+}} ]
+// CHECK-DAG: [[S_ARR_DST_COPY:%.+]] = phi{{.+}} [ [[S_ARR_PRIV_BGN]], {{.+}}], [ [[S_ARR_DST:%.+]], {{.+}} ]
+// CHECK-DAG: call void @{{.+}}({{.+}} [[AGG_TMP1]])
+// CHECK-DAG: call void @{{.+}}({{.+}} [[S_ARR_DST_COPY]], {{.+}} [[S_ARR_SRC_COPY]], {{.+}} [[AGG_TMP1]])
+// CHECK-DAG: call void @{{.+}}({{.+}} [[AGG_TMP1]])
+// CHECK-DAG: [[S_ARR_DST]] = getelementptr {{.+}} [[S_ARR_DST_COPY]],
+// CHECK-DAG: [[S_ARR_SRC]] = getelementptr {{.+}} [[S_ARR_SRC_COPY]],
+
+// firstprivate(var)
+// CHECK-DAG: call void @{{.+}}({{.+}} [[AGG_TMP2]])
+// CHECK-DAG: call void @{{.+}}({{.+}} [[VAR_PRIV]], {{.+}} [[VAR_ADDR_REF]], {{.+}} [[AGG_TMP2]])
+// CHECK-DAG: call void @{{.+}}({{.+}} [[AGG_TMP2]])
+
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK-DAG-32: {{.+}} = {{.+}} [[T_VAR_ADDR]]
+// CHECK-DAG-64: {{.+}} = {{.+}} [[CONV_TVAR]]
+// CHECK-DAG: {{.+}} = {{.+}} [[VEC_PRIV]]
+// CHECK-DAG: {{.+}} = {{.+}} [[S_ARR_PRIV]]
+// CHECK-DAG: {{.+}} = {{.+}} [[VAR_PRIV]]
+// CHECK-DAG-32: {{.+}} = {{.+}} [[SIVAR_ADDR]]
+// CHECK-DAG-64: {{.+}} = {{.+}} [[CONV_SIVAR]]
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: ret void
+
+// CHECK: define{{.*}} i{{[0-9]+}} @[[TMAIN_INT]]()
+// CHECK: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 4, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 0)
+// CHECK: call void @[[TOFFL1:.+]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}})
+// CHECK: ret
+
+// CHECK: define {{.*}}void @[[TOFFL1]]({{.+}})
+// CHECK: [[TVEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}]*,
+// CHECK: [[TT_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[TS_ARR_PRIV:%.+]] = alloca [2 x [[S_INT_TY]]]*,
+// CHECK: [[TVAR_PRIV:%.+]] = alloca [[S_INT_TY]]*,
+// CHECK: [[TT_VAR_CAST:%.+]] = alloca i{{[0-9]+}},
+
+// CHECK-DAG: [[TVEC_TE_PAR:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** [[TVEC_PRIV]],
+// CHECK-DAG: [[TT_VAR_TE_PAR:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[TT_VAR_CAST]],
+// CHECK-DAG: [[TS_ARR_TE_PAR:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** [[TS_ARR_PRIV]],
+// CHECK-DAG: [[TVAR_TE_PAR:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[TVAR_PRIV]],
+
+// CHECK: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 4, {{.+}} @[[TOUTL1:.+]] to {{.+}}, [2 x i{{[0-9]+}}]* [[TVEC_TE_PAR]], i{{[0-9]+}} [[TT_VAR_TE_PAR]], [2 x [[S_INT_TY]]]* [[TS_ARR_TE_PAR]], [[S_INT_TY]]* [[TVAR_TE_PAR]])
+// CHECK: ret void
+
+// CHECK: define internal void @[[TOUTL1]]({{.+}})
+// Skip global and bound tid vars
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: [[VEC_ADDR:%.+]] = alloca [2 x i{{[0-9]+}}]*,
+// CHECK: [[T_VAR_ADDR:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[S_ARR_ADDR:%.+]] = alloca [2 x [[S_INT_TY]]]*,
+// CHECK: [[VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*,
+// Skip temp vars for loop
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_INT_TY]]],
+// CHECK: [[AGG_TMP1:%.+]] = alloca [[ST_TY]],
+// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_INT_TY]],
+// CHECK: [[AGG_TMP2:%.+]] = alloca [[ST_TY]],
+// CHECK: [[TMP:%.+]] = alloca [[S_INT_TY]]*,
+
+// param copy
+// CHECK: store [2 x i{{[0-9]+}}]* {{.+}}, [2 x i{{[0-9]+}}]** [[VEC_ADDR]],
+// CHECK: store i{{[0-9]+}} {{.+}}, i{{[0-9]+}}* [[T_VAR_ADDR]],
+// CHECK: store [2 x [[S_INT_TY]]]* {{.+}}, [2 x [[S_INT_TY]]]** [[S_ARR_ADDR]],
+// CHECK: store [[S_INT_TY]]* {{.+}}, [[S_INT_TY]]** [[VAR_ADDR]],
+
+
+// T_VAR and preparation variables
+// CHECK: [[VEC_ADDR_VAL:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** [[VEC_ADDR]],
+// CHECK-64: [[CONV_TVAR:%.+]] = bitcast i64* [[T_VAR_ADDR]] to i32*
+// CHECK: [[S_ARR_ADDR_REF:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** [[S_ARR_ADDR]],
+
+// firstprivate vec(vec): copy from *_addr into priv1 and then from priv1 into priv2
+// CHECK-DAG: [[VEC_DEST_PRIV:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV]] to i8*
+// CHECK-DAG: [[VEC_SRC:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_ADDR_VAL]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[VEC_DEST_PRIV]], i8* [[VEC_SRC]], {{.+}})
+
+// firstprivate(s_arr)
+// CHECK-DAG: [[S_ARR_PRIV_BGN:%.+]] = getelementptr{{.*}} [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[S_ARR_PRIV]],
+// CHECK-DAG: [[S_ARR_ADDR_BGN:%.+]] = bitcast [2 x [[S_INT_TY]]]* [[S_ARR_ADDR_REF]] to
+// CHECK-DAG: [[S_ARR_FIN:%.+]] = icmp{{.+}} [[S_ARR_PRIV_BGN]],
+// CHECK-DAG: [[S_ARR_SRC_COPY:%.+]] = phi{{.+}} [ [[S_ARR_ADDR_BGN]], {{.+}} ], [ [[S_ARR_SRC:%.+]], {{.+}} ]
+// CHECK-DAG: [[S_ARR_DST_COPY:%.+]] = phi{{.+}} [ [[S_ARR_PRIV_BGN]], {{.+}} ], [ [[S_ARR_DST:%.+]], {{.+}} ]
+// CHECK-DAG: call void @{{.+}}({{.+}} [[AGG_TMP1]])
+// CHECK-DAG: call void @{{.+}}({{.+}} [[S_ARR_DST_COPY]], {{.+}} [[S_ARR_SRC_COPY]], {{.+}} [[AGG_TMP1]])
+// CHECK-DAG: call void @{{.+}}({{.+}} [[AGG_TMP1]])
+// CHECK-DAG: [[S_ARR_DST]] = getelementptr {{.+}} [[S_ARR_DST_COPY]],
+// CHECK-DAG: [[S_ARR_SRC]] = getelementptr {{.+}} [[S_ARR_SRC_COPY]],
+
+// firstprivate(var)
+// CHECK-DAG: [[VAR_ADDR_REF:%.+]] = load{{.+}} [[VAR_ADDR]],
+// CHECK-DAG: call void @{{.+}}({{.+}} [[AGG_TMP2]])
+// CHECK-DAG: call void @{{.+}}({{.+}} [[VAR_PRIV]], {{.+}} [[VAR_ADDR_REF]], {{.+}} [[AGG_TMP2]])
+// CHECK-DAG: call void @{{.+}}({{.+}} [[AGG_TMP2]])
+// CHECK-DAG: store [[S_INT_TY]]* [[VAR_PRIV]], [[S_INT_TY]]** [[TMP]],
+
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK-DAG-32: {{.+}} = {{.+}} [[T_VAR_ADDR]]
+// CHECK-DAG-64: {{.+}} = {{.+}} [[CONV_TVAR]]
+// CHECK-DAG: {{.+}} = {{.+}} [[VEC_PRIV]]
+// CHECK-DAG: {{.+}} = {{.+}} [[TMP]]
+// CHECK-DAG: {{.+}} = {{.+}} [[S_ARR_PRIV]]
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: ret void
+
+#endif
diff --git a/test/OpenMP/target_teams_distribute_simd_firstprivate_messages.cpp b/test/OpenMP/target_teams_distribute_simd_firstprivate_messages.cpp
index b9b039efd929..235533b49d16 100644
--- a/test/OpenMP/target_teams_distribute_simd_firstprivate_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_simd_firstprivate_messages.cpp
@@ -124,7 +124,8 @@ int main(int argc, char **argv) {
#pragma omp target teams distribute simd firstprivate(j)
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute simd lastprivate(argc), firstprivate(argc) // OK
+// expected-error@+1 {{lastprivate variable cannot be firstprivate}} expected-note@+1 {{defined as lastprivate}}
+#pragma omp target teams distribute simd lastprivate(argc), firstprivate(argc)
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute simd firstprivate(argc) map(argc) // expected-error {{firstprivate variable cannot be in a map clause in '#pragma omp target teams distribute simd' directive}} expected-note {{defined as firstprivate}}
diff --git a/test/OpenMP/target_teams_distribute_simd_lastprivate_codegen.cpp b/test/OpenMP/target_teams_distribute_simd_lastprivate_codegen.cpp
new file mode 100644
index 000000000000..8a978a221954
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_simd_lastprivate_codegen.cpp
@@ -0,0 +1,385 @@
+// RUN: %clang_cc1 -DLAMBDA -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+// RUN: %clang_cc1 -DLAMBDA -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-32
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-32
+
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+template <class T>
+struct S {
+ T f;
+ S(T a) : f(a) {}
+ S() : f() {}
+ operator T() { return T(); }
+ ~S() {}
+};
+
+// CHECK: [[S_FLOAT_TY:%.+]] = type { float }
+// CHECK: [[S_INT_TY:%.+]] = type { i{{[0-9]+}} }
+template <typename T>
+T tmain() {
+ S<T> test;
+ T t_var = T();
+ T vec[] = {1, 2};
+ S<T> s_arr[] = {1, 2};
+ S<T> &var = test;
+ #pragma omp target teams distribute simd lastprivate(t_var, vec, s_arr, s_arr, var, var)
+ for (int i = 0; i < 2; ++i) {
+ vec[i] = t_var;
+ s_arr[i] = var;
+ }
+ return T();
+}
+
+int main() {
+ static int svar;
+ volatile double g;
+ volatile double &g1 = g;
+
+ #ifdef LAMBDA
+ // LAMBDA-LABEL: @main
+ // LAMBDA: call{{.*}} void [[OUTER_LAMBDA:@.+]](
+ [&]() {
+ static float sfvar;
+ // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
+ // LAMBDA: call i{{[0-9]+}} @__tgt_target_teams(
+ // LAMBDA: call void [[OFFLOADING_FUN:@.+]](
+
+ // LAMBDA: define{{.+}} void [[OFFLOADING_FUN]](
+ // LAMBDA: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, i32 4, {{.+}}* [[OMP_OUTLINED:@.+]] to {{.+}})
+ #pragma omp target teams distribute simd lastprivate(g, g1, svar, sfvar)
+ for (int i = 0; i < 2; ++i) {
+ // LAMBDA-64: define{{.*}} internal{{.*}} void [[OMP_OUTLINED]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, i64 [[G_IN:%.+]], i64 [[G1_IN:%.+]], i64 [[SVAR_IN:%.+]], i64 [[SFVAR_IN:%.+]])
+ // LAMBDA-32: define{{.*}} internal{{.*}} void [[OMP_OUTLINED]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, double*{{.+}} [[G_IN:%.+]], double*{{.+}} [[G1_IN:%.+]], i32 [[SVAR_IN:%.+]], i32 [[SFVAR_IN:%.+]])
+ // LAMBDA-64: [[G_PRIVATE_ADDR:%.+]] = alloca i64,
+ // LAMBDA-32: [[G_PRIVATE_ADDR:%.+]] = alloca double*,
+ // LAMBDA-64: [[G1_PRIVATE_ADDR:%.+]] = alloca i64,
+ // LAMBDA-32: [[G1_PRIVATE_ADDR:%.+]] = alloca double*,
+ // LAMBDA-64: [[SVAR_PRIVATE_ADDR:%.+]] = alloca i64,
+ // LAMBDA-32: [[SVAR_PRIVATE_ADDR:%.+]] = alloca i32,
+ // LAMBDA-64: [[SFVAR_PRIVATE_ADDR:%.+]] = alloca i64,
+ // LAMBDA-32: [[SFVAR_PRIVATE_ADDR:%.+]] = alloca i32,
+ // loop variables
+ // LAMBDA: {{.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: {{.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: {{.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: {{.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: {{.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: [[OMP_IS_LAST:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[G_PRIVATE:%.+]] = alloca double,
+ // LAMBDA: [[G1_PRIVATE:%.+]] = alloca double,
+ // LAMBDA: [[TMP_G1_PRIVATE:%.+]] = alloca double*,
+ // LAMBDA: [[SVAR_PRIVATE:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[SFVAR_PRIVATE:%.+]] = alloca float,
+ // LAMBDA-64: store i64 [[G_IN]], i64* [[G_PRIVATE_ADDR]],
+ // LAMBDA-32: store double* [[G_IN]], double** [[G_PRIVATE_ADDR]],
+ // LAMBDA-64: store i64 [[G1_IN]], i64* [[G1_PRIVATE_ADDR]],
+ // LAMBDA-32: store double* [[G1_IN]], double** [[G1_PRIVATE_ADDR]],
+ // LAMBDA-64: store i64 [[SVAR_IN]], i64* [[SVAR_PRIVATE_ADDR]],
+ // LAMBDA-32: store i32 [[SVAR_IN]], i32* [[SVAR_PRIVATE_ADDR]],
+ // LAMBDA-64: store i64 [[SFVAR_IN]], i64* [[SFVAR_PRIVATE_ADDR]],
+ // LAMBDA-32: store i32 [[SFVAR_IN]], i32* [[SFVAR_PRIVATE_ADDR]],
+
+ // init private variables
+ // LAMBDA-64: [[G_IN_REF:%.+]] = bitcast i64* [[G_PRIVATE_ADDR]] to double*
+ // LAMBDA-32: [[G_IN_REF:%.+]] = load double*, double** [[G_PRIVATE_ADDR]],
+ // LAMBDA-64: [[G1_IN_REF:%.+]] = bitcast i64* [[G1_PRIVATE_ADDR]] to double*
+ // LAMBDA-64: store double* [[G1_IN_REF]], double** [[G1_IN_ADDR_REF:%.+]],
+ // LAMBDA-64: [[SVAR_IN_REF:%.+]] = bitcast i64* [[SVAR_PRIVATE_ADDR]] to i32*
+ // LAMBDA-64: [[SFVAR_IN_REF:%.+]] = bitcast i64* [[SFVAR_PRIVATE_ADDR]] to float*
+ // LAMBDA-32: [[SFVAR_IN_REF:%.+]] = bitcast i32* [[SFVAR_PRIVATE_ADDR]] to float*
+ // LAMBDA-64: [[G1_IN_REF:%.+]] = load double*, double** [[G1_IN_ADDR_REF]],
+ // LAMBDA-32: [[G1_IN_REF:%.+]] = load double*, double** [[G1_PRIVATE_ADDR]],
+ // LAMBDA: store double* [[G1_PRIVATE]], double** [[TMP_G1_PRIVATE]],
+ g = 1;
+ g1 = 1;
+ svar = 3;
+ sfvar = 4.0;
+ // LAMBDA: call {{.*}}void @__kmpc_for_static_init_4(
+ // LAMBDA: store double 1.0{{.+}}, double* [[G_PRIVATE]],
+ // LAMBDA: [[TMP_G1_REF:%.+]] = load double*, double** [[TMP_G1_PRIVATE]],
+ // LAMBDA: store{{.+}} double 1.0{{.+}}, double* [[TMP_G1_REF]],
+ // LAMBDA: store i{{[0-9]+}} 3, i{{[0-9]+}}* [[SVAR_PRIVATE]],
+ // LAMBDA: store float 4.0{{.+}}, float* [[SFVAR_PRIVATE]],
+ // LAMBDA: [[G_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // LAMBDA: store double* [[G_PRIVATE]], double** [[G_PRIVATE_ADDR_REF]],
+ // LAMBDA: [[TMP_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // LAMBDA: [[G1_PRIVATE_ADDR_FROM_TMP:%.+]] = load double*, double** [[TMP_G1_PRIVATE]],
+ // LAMBDA: store double* [[G1_PRIVATE_ADDR_FROM_TMP]], double** [[TMP_PRIVATE_ADDR_REF]],
+ // LAMBDA: [[SVAR_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+ // LAMBDA: store i{{[0-9]+}}* [[SVAR_PRIVATE]], i{{[0-9]+}}** [[SVAR_PRIVATE_ADDR_REF]]
+ // LAMBDA: [[SFVAR_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 3
+ // LAMBDA: store float* [[SFVAR_PRIVATE]], float** [[SFVAR_PRIVATE_ADDR_REF]]
+ // LAMBDA: call{{.*}} void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]])
+ // LAMBDA: call {{.*}}void @__kmpc_for_static_fini(
+ // LAMBDA: store i32 2, i32* %
+ // LAMBDA: [[OMP_IS_LAST_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[OMP_IS_LAST]],
+ // LAMBDA: [[IS_LAST_IT:%.+]] = icmp ne i{{[0-9]+}} [[OMP_IS_LAST_VAL]], 0
+ // LAMBDA: br i1 [[IS_LAST_IT]], label %[[OMP_LASTPRIV_BLOCK:.+]], label %[[OMP_LASTPRIV_DONE:.+]]
+
+ // LAMBDA: [[OMP_LASTPRIV_BLOCK]]:
+ // LAMBDA: [[G_PRIV_VAL:%.+]] = load double, double* [[G_PRIVATE]],
+ // LAMBDA: store{{.*}} double [[G_PRIV_VAL]], double* [[G_IN_REF]],
+ // LAMBDA: [[TMP_G1_PRIV_REF:%.+]] = load double*, double** [[TMP_G1_PRIVATE]],
+ // LAMBDA: [[TMP_G1_PRIV_VAL:%.+]] = load double, double* [[TMP_G1_PRIV_REF]],
+ // LAMBDA: store{{.*}} double [[TMP_G1_PRIV_VAL]], double* [[G1_IN_REF]],
+
+ // LAMBDA: [[SVAR_PRIV_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SVAR_PRIVATE]],
+ // LAMBDA-64: store i{{[0-9]+}} [[SVAR_PRIV_VAL]], i{{[0-9]+}}* [[SVAR_IN_REF]],
+ // LAMBDA-32: store i{{[0-9]+}} [[SVAR_PRIV_VAL]], i{{[0-9]+}}* [[SVAR_PRIVATE_ADDR]],
+ // LAMBDA: [[SFVAR_PRIV_VAL:%.+]] = load float, float* [[SFVAR_PRIVATE]],
+ // LAMBDA: store float [[SFVAR_PRIV_VAL]], float* [[SFVAR_IN_REF]],
+ // LAMBDA: br label %[[OMP_LASTPRIV_DONE]]
+ // LAMBDA: [[OMP_LASTPRIV_DONE]]:
+ // LAMBDA: ret
+ [&]() {
+ // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]])
+ // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]],
+ g = 2;
+ g1 = 2;
+ svar = 4;
+ sfvar = 8.0;
+ // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]]
+ // LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // LAMBDA: [[G_REF:%.+]] = load double*, double** [[G_PTR_REF]]
+ // LAMBDA: store double 2.0{{.+}}, double* [[G_REF]]
+
+ // LAMBDA: [[TMP_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // LAMBDA: [[G1_REF:%.+]] = load double*, double** [[TMP_PTR_REF]]
+ // LAMBDA: store double 2.0{{.+}}, double* [[G1_REF]],
+ // LAMBDA: [[SVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+ // LAMBDA: [[SVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SVAR_PTR_REF]]
+ // LAMBDA: store i{{[0-9]+}} 4, i{{[0-9]+}}* [[SVAR_REF]]
+ // LAMBDA: [[SFVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 3
+ // LAMBDA: [[SFVAR_REF:%.+]] = load float*, float** [[SFVAR_PTR_REF]]
+ // LAMBDA: store float 8.0{{.+}}, float* [[SFVAR_REF]]
+ }();
+ }
+ }();
+ return 0;
+ #else
+ S<float> test;
+ int t_var = 0;
+ int vec[] = {1, 2};
+ S<float> s_arr[] = {1, 2};
+ S<float> &var = test;
+
+ #pragma omp target teams distribute simd lastprivate(t_var, vec, s_arr, s_arr, var, var, svar)
+ for (int i = 0; i < 2; ++i) {
+ vec[i] = t_var;
+ s_arr[i] = var;
+ }
+ int i;
+
+ return tmain<int>();
+ #endif
+}
+
+// CHECK: define{{.*}} i{{[0-9]+}} @main()
+// CHECK: [[TEST:%.+]] = alloca [[S_FLOAT_TY]],
+// CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR:@.+]]([[S_FLOAT_TY]]* [[TEST]])
+// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+// CHECK: call void [[OFFLOAD_FUN:@.+]]([2 x i{{[0-9]+}}]* {{.+}}, i{{[0-9]+}} {{.+}}, [2 x [[S_FLOAT_TY]]]* {{.+}}, [[S_FLOAT_TY]]* {{.+}}, i{{[0-9]+}} {{.+}})
+// CHECK: ret
+
+// CHECK: define{{.+}} [[OFFLOAD_FUN]]([2 x i{{[0-9]+}}]*{{.+}} {{.+}}, i{{[0-9]+}} {{.+}}, [2 x [[S_FLOAT_TY]]]*{{.+}} {{.+}}, [[S_FLOAT_TY]]*{{.+}} {{.+}}, i{{[0-9]+}} {{.+}})
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_teams(
+// CHECK: ret
+//
+// CHECK: define internal void [[OMP_OUTLINED:@.+]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [2 x i{{[0-9]+}}]*{{.+}} [[VEC_IN:%.+]], i{{[0-9]+}} [[T_VAR_IN:%.+]], [2 x [[S_FLOAT_TY]]]*{{.+}} [[S_ARR_IN:%.+]], [[S_FLOAT_TY]]*{{.+}} [[VAR_IN:%.+]], i{{[0-9]+}} [[S_VAR_IN:%.+]])
+// CHECK: {{.+}} = alloca i{{[0-9]+}}*,
+// CHECK: {{.+}} = alloca i{{[0-9]+}}*,
+// CHECK: [[VEC_ADDR:%.+]] = alloca [2 x i{{[0-9]+}}]*,
+// CHECK: [[T_VAR_ADDR:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[S_ARR_ADDR:%.+]] = alloca [2 x [[S_FLOAT_TY]]]*,
+// CHECK: [[VAR_ADDR:%.+]] = alloca [[S_FLOAT_TY]]*,
+// CHECK: [[SVAR_ADDR:%.+]] = alloca i{{[0-9]+}},
+// skip loop variables
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: [[OMP_IS_LAST:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]],
+// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]],
+// CHECK: [[TMP_PRIV:%.+]] = alloca [[S_FLOAT_TY]]*,
+// CHECK: [[S_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+
+// copy from parameters to local address variables
+// CHECK: store [2 x i{{[0-9]+}}]* [[VEC_IN]], [2 x i{{[0-9]+}}]** [[VEC_ADDR]],
+// CHECK: store i{{[0-9]+}} [[T_VAR_IN]], i{{[0-9]+}}* [[T_VAR_ADDR]],
+// CHECK: store [2 x [[S_FLOAT_TY]]]* [[S_ARR_IN]], [2 x [[S_FLOAT_TY]]]** [[S_ARR_ADDR]],
+// CHECK: store [[S_FLOAT_TY]]* [[VAR_IN]], [[S_FLOAT_TY]]** [[VAR_ADDR]],
+// CHECK: store i{{[0-9]+}} [[S_VAR_IN]], i{{[0-9]+}}* [[SVAR_ADDR]],
+
+// load content of local address variables
+// CHECK: [[VEC_ADDR_REF:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** [[VEC_ADDR]],
+// CHECK-64: [[T_VAR_ADDR_REF:%.+]] = bitcast i64* [[T_VAR_ADDR]] to i32*
+// CHECK: [[S_ARR_ADDR_REF:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[S_ARR_ADDR]],
+// CHECK-64: [[SVAR_ADDR_REF:%.+]] = bitcast i64* [[SVAR_ADDR]] to i32*
+// CHECK: store i{{[0-9]+}} 0, i{{[0-9]+}}* [[OMP_IS_LAST]],
+// CHECK: [[VAR_ADDR_REF:%.+]] = load {{.+}}, {{.+}} [[VAR_ADDR]],
+// the distribute loop
+// CHECK: call void @__kmpc_for_static_init_4(
+// assignment: vec[i] = t_var;
+// CHECK: [[T_VAR_PRIV_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_PRIV]],
+// CHECK: [[VEC_PTR:%.+]] = getelementptr inbounds [2 x i{{[0-9]+}}], [2 x i{{[0-9]+}}]* [[VEC_PRIV]], i{{[0-9]+}} 0, i{{[0-9]+}} {{.+}}
+// CHECK: store i{{[0-9]+}} [[T_VAR_PRIV_VAL]], i{{[0-9]+}}* [[VEC_PTR]],
+
+// assignment: s_arr[i] = var;
+// CHECK-DAG: [[S_ARR_PTR:%.+]] = getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[S_ARR_PRIV]],
+// CHECK-DAG: [[TMP_VAL:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[TMP_PRIV]],
+// CHECK-DAG: [[S_ARR_PTR_BCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[S_ARR_PTR]] to i8*
+// CHECK-DAG: [[TMP_VAL_BCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[TMP_VAL]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[S_ARR_PTR_BCAST]], i8* [[TMP_VAL_BCAST]],
+// CHECK: call void @__kmpc_for_static_fini(
+
+// lastprivates
+// CHECK: [[OMP_IS_LAST_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[OMP_IS_LAST]],
+// CHECK: [[IS_LAST_IT:%.+]] = icmp ne i{{[0-9]+}} [[OMP_IS_LAST_VAL]], 0
+// CHECK: br i1 [[IS_LAST_IT]], label %[[OMP_LASTPRIV_BLOCK:.+]], label %[[OMP_LASTPRIV_DONE:.+]]
+
+// CHECK: [[OMP_LASTPRIV_BLOCK]]:
+// CHECK: [[T_VAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_PRIV]],
+// CHECK-64: store i{{[0-9]+}} [[T_VAR_VAL]], i{{[0-9]+}}* [[T_VAR_ADDR_REF]],
+// CHECK-32: store i{{[0-9]+}} [[T_VAR_VAL]], i{{[0-9]+}}* [[T_VAR_ADDR]],
+// CHECK: [[BCAST_VEC_ADDR_REF:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_ADDR_REF]] to i8*
+// CHECK: [[BCAST_VEC_PRIV:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[BCAST_VEC_ADDR_REF]], i8* [[BCAST_VEC_PRIV]],
+// CHECK: [[S_ARR_BEGIN:%.+]] = getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[S_ARR_ADDR_REF]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+// CHECK: [[S_ARR_PRIV_BCAST:%.+]] = bitcast [2 x [[S_FLOAT_TY]]]* [[S_ARR_PRIV]] to [[S_FLOAT_TY]]*
+// CHECK: [[S_ARR_BEGIN_GEP:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[S_ARR_BEGIN]], i{{[0-9]+}} 2
+// CHECK: [[S_ARR_IS_EMPTY:%.+]] = icmp eq [[S_FLOAT_TY]]* [[S_ARR_BEGIN]], [[S_ARR_BEGIN_GEP]]
+// CHECK: br i1 [[S_ARR_IS_EMPTY]], label %[[S_ARR_COPY_DONE:.+]], label %[[S_ARR_COPY_BLOCK:.+]]
+// CHECK: [[S_ARR_COPY_BLOCK]]:
+// CHECK: [[S_ARR_SRC_EL:%.+]] = phi [[S_FLOAT_TY]]*{{.+}}
+// CHECK: [[S_ARR_DST_EL:%.+]] = phi [[S_FLOAT_TY]]*{{.+}}
+// CHECK: [[S_ARR_DST_BCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[S_ARR_DST_EL]] to i8*
+// CHECK: [[S_ARR_SRC_BCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[S_ARR_SRC_EL]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[S_ARR_DST_BCAST]], i8* [[S_ARR_SRC_BCAST]]{{.+}})
+// CHECK: [[S_ARR_DST_NEXT:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[S_ARR_DST_EL]], i{{[0-9]+}} 1
+// CHECK: [[S_ARR_SRC_NEXT:%.+]] = getelementptr{{.+}}
+// CHECK: [[CPY_IS_FINISHED:%.+]] = icmp eq [[S_FLOAT_TY]]* [[S_ARR_DST_NEXT]], [[S_ARR_BEGIN_GEP]]
+// CHECK: br i1 [[CPY_IS_FINISHED]], label %[[S_ARR_COPY_DONE]], label %[[S_ARR_COPY_BLOCK]]
+// CHECK: [[S_ARR_COPY_DONE]]:
+// CHECK: [[TMP_VAL1:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[TMP_PRIV]],
+// CHECK: [[VAR_ADDR_REF_BCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[VAR_ADDR_REF]] to i8*
+// CHECK: [[TMP_VAL1_BCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[TMP_VAL1]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[VAR_ADDR_REF_BCAST]], i8* [[TMP_VAL1_BCAST]],{{.+}})
+// CHECK: [[SVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[S_VAR_PRIV]],
+// CHECK-64: store i{{[0-9]+}} [[SVAR_VAL]], i{{[0-9]+}}* [[SVAR_ADDR_REF]],
+// CHECK-32: store i{{[0-9]+}} [[SVAR_VAL]], i{{[0-9]+}}* [[SVAR_ADDR]],
+// CHECK: ret void
+
+// template tmain
+// CHECK: define{{.*}} i{{[0-9]+}} [[TMAIN_INT:@.+]]()
+// CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]],
+// CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR:@.+]]([[S_INT_TY]]* [[TEST]])
+// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+// CHECK: call void [[OFFLOAD_FUN_1:@.+]]([2 x i{{[0-9]+}}]* {{.+}}, i{{[0-9]+}} {{.+}}, [2 x [[S_INT_TY]]]* {{.+}}, [[S_INT_TY]]* {{.+}})
+// CHECK: ret
+
+
+// CHECK: define internal void [[OFFLOAD_FUN_1]](
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_teams(%{{.+}}* @{{.+}}, i{{[0-9]+}} 4,
+// CHECK: ret
+
+// CHECK: define internal void [[OMP_OUTLINED_1:@.+]](i{{[0-9]+}}* noalias [[GTID_ADDR1:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [2 x i{{[0-9]+}}]*{{.+}} [[VEC_IN1:%.+]], i{{[0-9]+}} [[T_VAR_IN1:%.+]], [2 x [[S_INT_TY]]]*{{.+}} [[S_ARR_IN1:%.+]], [[S_INT_TY]]*{{.+}} [[VAR_IN1:%.+]])
+// skip alloca of global_tid and bound_tid
+// CHECK: {{.+}} = alloca i{{[0-9]+}}*,
+// CHECK: {{.+}} = alloca i{{[0-9]+}}*,
+// CHECK: [[VEC_ADDR1:%.+]] = alloca [2 x i{{[0-9]+}}]*,
+// CHECK: [[T_VAR_ADDR1:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[S_ARR_ADDR1:%.+]] = alloca [2 x [[S_INT_TY]]]*,
+// CHECK: [[VAR_ADDR1:%.+]] = alloca [[S_INT_TY]]*,
+// skip loop variables
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: [[OMP_IS_LAST1:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[T_VAR_PRIV1:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[VEC_PRIV1:%.+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK: [[S_ARR_PRIV1:%.+]] = alloca [2 x [[S_INT_TY]]],
+// CHECK: [[VAR_PRIV1:%.+]] = alloca [[S_INT_TY]],
+// CHECK: [[TMP_PRIV1:%.+]] = alloca [[S_INT_TY]]*,
+
+// skip init of bound and global tid
+// CHECK: store i{{[0-9]+}}* {{.*}},
+// CHECK: store i{{[0-9]+}}* {{.*}},
+// copy from parameters to local address variables
+// CHECK: store [2 x i{{[0-9]+}}]* [[VEC_IN1]], [2 x i{{[0-9]+}}]** [[VEC_ADDR1]],
+// CHECK: store i{{[0-9]+}} [[T_VAR_IN1]], i{{[0-9]+}}* [[T_VAR_ADDR1]],
+// CHECK: store [2 x [[S_INT_TY]]]* [[S_ARR_IN1]], [2 x [[S_INT_TY]]]** [[S_ARR_ADDR1]],
+// CHECK: store [[S_INT_TY]]* [[VAR_IN1]], [[S_INT_TY]]** [[VAR_ADDR1]],
+
+// load content of local address variables
+// CHECK: [[VEC_ADDR_REF1:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** [[VEC_ADDR1]],
+// CHECK-64: [[T_VAR_ADDR_REF1:%.+]] = bitcast i64* [[T_VAR_ADDR1]] to i32*
+// CHECK: [[S_ARR_ADDR_REF1:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** [[S_ARR_ADDR1]],
+// CHECK-DAG: store i{{[0-9]+}} 0, i{{[0-9]+}}* [[OMP_IS_LAST1]],
+// CHECK: [[VAR_ADDR1_REF:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[VAR_ADDR1]],
+// CHECK-DAG: store [[S_INT_TY]]* [[VAR_PRIV1]], [[S_INT_TY]]** [[TMP_PRIV1]],
+// CHECK: call void @__kmpc_for_static_init_4(
+// assignment: vec[i] = t_var;
+// CHECK: [[IV_VAL1:%.+]] =
+// CHECK: [[T_VAR_PRIV_VAL1:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_PRIV1]],
+// CHECK: [[VEC_PTR1:%.+]] = getelementptr inbounds [2 x i{{[0-9]+}}], [2 x i{{[0-9]+}}]* [[VEC_PRIV1]], i{{[0-9]+}} 0, i{{[0-9]+}} {{.+}}
+// CHECK: store i{{[0-9]+}} [[T_VAR_PRIV_VAL1]], i{{[0-9]+}}* [[VEC_PTR1]],
+
+// assignment: s_arr[i] = var;
+// CHECK-DAG: [[S_ARR_PTR1:%.+]] = getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[S_ARR_PRIV1]],
+// CHECK-DAG: [[TMP_VAL1:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[TMP_PRIV1]],
+// CHECK-DAG: [[S_ARR_PTR_BCAST1:%.+]] = bitcast [[S_INT_TY]]* [[S_ARR_PTR1]] to i8*
+// CHECK-DAG: [[TMP_VAL_BCAST1:%.+]] = bitcast [[S_INT_TY]]* [[TMP_VAL1]] to i8*
+// CHECK-DAG: call void @llvm.memcpy.{{.+}}(i8* [[S_ARR_PTR_BCAST1]], i8* [[TMP_VAL_BCAST1]],
+// CHECK: call void @__kmpc_for_static_fini(
+
+// lastprivates
+// CHECK: [[OMP_IS_LAST_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[OMP_IS_LAST1]],
+// CHECK: [[IS_LAST_IT:%.+]] = icmp ne i{{[0-9]+}} [[OMP_IS_LAST_VAL]], 0
+// CHECK: br i1 [[IS_LAST_IT]], label %[[OMP_LASTPRIV_BLOCK:.+]], label %[[OMP_LASTPRIV_DONE:.+]]
+
+// CHECK: [[OMP_LASTPRIV_BLOCK]]:
+// CHECK: [[T_VAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_PRIV1]],
+// CHECK-64: store i{{[0-9]+}} [[T_VAR_VAL]], i{{[0-9]+}}* [[T_VAR_ADDR_REF1]],
+// CHECK-32: store i{{[0-9]+}} [[T_VAR_VAL]], i{{[0-9]+}}* [[T_VAR_ADDR1]],
+// CHECK: [[BCAST_VEC_ADDR_REF:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_ADDR_REF1]] to i8*
+// CHECK: [[BCAST_VEC_PRIV:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV1]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[BCAST_VEC_ADDR_REF]], i8* [[BCAST_VEC_PRIV]],
+// CHECK: [[S_ARR_BEGIN:%.+]] = getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[S_ARR_ADDR_REF]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+// CHECK: [[S_ARR_PRIV_BCAST:%.+]] = bitcast [2 x [[S_INT_TY]]]* [[S_ARR_PRIV1]] to [[S_INT_TY]]*
+// CHECK: [[S_ARR_BEGIN_GEP:%.+]] = getelementptr [[S_INT_TY]], [[S_INT_TY]]* [[S_ARR_BEGIN]], i{{[0-9]+}} 2
+// CHECK: [[S_ARR_IS_EMPTY:%.+]] = icmp eq [[S_INT_TY]]* [[S_ARR_BEGIN]], [[S_ARR_BEGIN_GEP]]
+// CHECK: br i1 [[S_ARR_IS_EMPTY]], label %[[S_ARR_COPY_DONE:.+]], label %[[S_ARR_COPY_BLOCK:.+]]
+// CHECK: [[S_ARR_COPY_BLOCK]]:
+// CHECK: [[S_ARR_SRC_EL:%.+]] = phi [[S_INT_TY]]*{{.+}}
+// CHECK: [[S_ARR_DST_EL:%.+]] = phi [[S_INT_TY]]*{{.+}}
+// CHECK: [[S_ARR_DST_BCAST:%.+]] = bitcast [[S_INT_TY]]* [[S_ARR_DST_EL]] to i8*
+// CHECK: [[S_ARR_SRC_BCAST:%.+]] = bitcast [[S_INT_TY]]* [[S_ARR_SRC_EL]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[S_ARR_DST_BCAST]], i8* [[S_ARR_SRC_BCAST]]{{.+}})
+// CHECK: [[S_ARR_DST_NEXT:%.+]] = getelementptr [[S_INT_TY]], [[S_INT_TY]]* [[S_ARR_DST_EL]], i{{[0-9]+}} 1
+// CHECK: [[S_ARR_SRC_NEXT:%.+]] = getelementptr{{.+}}
+// CHECK: [[CPY_IS_FINISHED:%.+]] = icmp eq [[S_INT_TY]]* [[S_ARR_DST_NEXT]], [[S_ARR_BEGIN_GEP]]
+// CHECK: br i1 [[CPY_IS_FINISHED]], label %[[S_ARR_COPY_DONE]], label %[[S_ARR_COPY_BLOCK]]
+// CHECK: [[S_ARR_COPY_DONE]]:
+// CHECK: [[TMP_VAL1:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[TMP_PRIV1]],
+// CHECK: [[VAR_ADDR_REF_BCAST:%.+]] = bitcast [[S_INT_TY]]* [[VAR_ADDR1_REF]] to i8*
+// CHECK: [[TMP_VAL1_BCAST:%.+]] = bitcast [[S_INT_TY]]* [[TMP_VAL1]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[VAR_ADDR_REF_BCAST]], i8* [[TMP_VAL1_BCAST]],{{.+}})
+// CHECK: ret void
+#endif
diff --git a/test/OpenMP/target_teams_distribute_simd_lastprivate_messages.cpp b/test/OpenMP/target_teams_distribute_simd_lastprivate_messages.cpp
index 3b533e2e5484..a143dc2fd883 100644
--- a/test/OpenMP/target_teams_distribute_simd_lastprivate_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_simd_lastprivate_messages.cpp
@@ -18,14 +18,14 @@ public:
const S2 &operator =(const S2&) const;
S2 &operator =(const S2&);
static float S2s; // expected-note {{static data member is predetermined as shared}}
- static const float S2sc;
+ static const float S2sc; // expected-note {{static data member is predetermined as shared}}
};
-const float S2::S2sc = 0; // expected-note {{static data member is predetermined as shared}}
+const float S2::S2sc = 0;
const S2 b;
const S2 ba[5];
class S3 {
int a;
- S3 &operator=(const S3 &s3); // expected-note 2 {{implicitly declared private here}}
+ S3 &operator=(const S3 &s3); // expected-note {{implicitly declared private here}}
public:
S3() : a(0) {}
@@ -52,7 +52,7 @@ public:
};
class S6 {
int a;
- S6() : a(0) {}
+ S6() : a(0) {} // expected-note {{implicitly declared private here}}
public:
S6(const S6 &s6) : a(s6.a) {}
@@ -216,10 +216,12 @@ int main(int argc, char **argv) {
#pragma omp target teams distribute simd lastprivate(j)
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute simd firstprivate(m) lastprivate(m) // expected-error {{'operator=' is a private member of 'S3'}}
+// expected-error@+1 {{firstprivate variable cannot be lastprivate}} expected-note@+1 {{defined as firstprivate}}
+#pragma omp target teams distribute simd firstprivate(m) lastprivate(m)
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute simd lastprivate(n) firstprivate(n) // OK
+// expected-error@+1 {{lastprivate variable cannot be firstprivate}} expected-note@+1 {{defined as lastprivate}}
+#pragma omp target teams distribute simd lastprivate(n) firstprivate(n) // expected-error {{calling a private constructor of class 'S6'}}
for (i = 0; i < argc; ++i) foo();
static int si;
diff --git a/test/OpenMP/target_teams_distribute_simd_linear_messages.cpp b/test/OpenMP/target_teams_distribute_simd_linear_messages.cpp
index 8db57a0f3665..2be792bbda74 100644
--- a/test/OpenMP/target_teams_distribute_simd_linear_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_simd_linear_messages.cpp
@@ -18,33 +18,42 @@ void test_linear_colons()
{
int B = 0;
+// expected-error@+1 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target teams distribute simd linear(B:bfoo())
for (int i = 0; i < 10; ++i) ;
+// expected-error@+1 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target teams distribute simd linear(B::ib:B:bfoo()) // expected-error {{unexpected ':' in nested name specifier; did you mean '::'}}
for (int i = 0; i < 10; ++i) ;
+// expected-error@+1 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target teams distribute simd linear(B:ib) // expected-error {{use of undeclared identifier 'ib'; did you mean 'B::ib'}}
for (int i = 0; i < 10; ++i) ;
+// expected-error@+1 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target teams distribute simd linear(z:B:ib) // expected-error {{unexpected ':' in nested name specifier; did you mean '::'?}}
for (int i = 0; i < 10; ++i) ;
+// expected-error@+1 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target teams distribute simd linear(B:B::bfoo())
for (int i = 0; i < 10; ++i) ;
+// expected-error@+1 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target teams distribute simd linear(X::x : ::z)
for (int i = 0; i < 10; ++i) ;
+// expected-error@+1 3 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target teams distribute simd linear(B,::z, X::x)
for (int i = 0; i < 10; ++i) ;
+// expected-error@+1 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target teams distribute simd linear(::z)
for (int i = 0; i < 10; ++i) ;
#pragma omp target teams distribute simd linear(B::bfoo()) // expected-error {{expected variable name}}
for (int i = 0; i < 10; ++i) ;
+// expected-error@+1 2 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target teams distribute simd linear(B::ib,B:C1+C2)
for (int i = 0; i < 10; ++i) ;
}
@@ -65,6 +74,7 @@ template<int L, class T, class N> T test_template(T* arr, N num) {
template<int LEN> int test_warn() {
int ind2 = 0;
+// expected-error@+1 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target teams distribute simd linear(ind2:LEN) // expected-warning {{zero linear step (ind2 should probably be const)}}
for (int i = 0; i < 100; i++) {
ind2 += LEN;
@@ -118,15 +128,18 @@ template<class I, class C> int foomain(I argc, C **argv) {
#pragma omp target teams distribute simd linear () // expected-error {{expected expression}}
for (int k = 0; k < argc; ++k) ++k;
+// expected-error@+1 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target teams distribute simd linear (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
for (int k = 0; k < argc; ++k) ++k;
+// expected-error@+1 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target teams distribute simd linear (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
for (int k = 0; k < argc; ++k) ++k;
#pragma omp target teams distribute simd linear (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
for (int k = 0; k < argc; ++k) ++k;
+// expected-error@+1 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target teams distribute simd linear (argc : 5)
for (int k = 0; k < argc; ++k) ++k;
@@ -139,33 +152,17 @@ template<class I, class C> int foomain(I argc, C **argv) {
#pragma omp target teams distribute simd linear (argv[1]) // expected-error {{expected variable name}}
for (int k = 0; k < argc; ++k) ++k;
+// expected-error@+1 2 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target teams distribute simd linear(e, g)
for (int k = 0; k < argc; ++k) ++k;
#pragma omp target teams distribute simd linear(h) // expected-error {{threadprivate or thread local variable cannot be linear}}
for (int k = 0; k < argc; ++k) ++k;
+// expected-error@+1 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target teams distribute simd linear(i)
for (int k = 0; k < argc; ++k) ++k;
- #pragma omp parallel
- {
- int v = 0;
- int i;
- #pragma omp target teams distribute simd linear(v:i)
- for (int k = 0; k < argc; ++k) { i = k; v += i; }
- }
-
-#pragma omp target teams distribute simd linear(j)
- for (int k = 0; k < argc; ++k) ++k;
-
- int v = 0;
-
-#pragma omp target teams distribute simd linear(v:j)
- for (int k = 0; k < argc; ++k) { ++k; v += j; }
-
-#pragma omp target teams distribute simd linear(i)
- for (int k = 0; k < argc; ++k) ++k;
return 0;
}
@@ -198,15 +195,18 @@ int main(int argc, char **argv) {
#pragma omp target teams distribute simd linear () // expected-error {{expected expression}}
for (int k = 0; k < argc; ++k) ++k;
+// expected-error@+1 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target teams distribute simd linear (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
for (int k = 0; k < argc; ++k) ++k;
+// expected-error@+1 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target teams distribute simd linear (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
for (int k = 0; k < argc; ++k) ++k;
#pragma omp target teams distribute simd linear (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
for (int k = 0; k < argc; ++k) ++k;
+// expected-error@+1 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target teams distribute simd linear (argc)
for (int k = 0; k < argc; ++k) ++k;
@@ -226,22 +226,6 @@ int main(int argc, char **argv) {
#pragma omp target teams distribute simd linear(h, C::x) // expected-error 2 {{threadprivate or thread local variable cannot be linear}}
for (int k = 0; k < argc; ++k) ++k;
- #pragma omp parallel
- {
- int i;
- #pragma omp target teams distribute simd linear(i)
- for (int k = 0; k < argc; ++k) ++k;
-
- #pragma omp target teams distribute simd linear(i : 4)
- for (int k = 0; k < argc; ++k) { ++k; i += 4; }
- }
-
-#pragma omp target teams distribute simd linear(j)
- for (int k = 0; k < argc; ++k) ++k;
-
-#pragma omp target teams distribute simd linear(i)
- for (int k = 0; k < argc; ++k) ++k;
-
foomain<int,char>(argc,argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}}
return 0;
}
diff --git a/test/OpenMP/target_teams_distribute_simd_loop_messages.cpp b/test/OpenMP/target_teams_distribute_simd_loop_messages.cpp
index aae00a4433bc..09aa548bd5c6 100644
--- a/test/OpenMP/target_teams_distribute_simd_loop_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_simd_loop_messages.cpp
@@ -2,7 +2,7 @@
class S {
int a;
- S() : a(0) {}
+ S() : a(0) {} // expected-note {{implicitly declared private here}}
public:
S(int v) : a(v) {}
@@ -607,7 +607,8 @@ void test_loop_eh() {
void test_loop_firstprivate_lastprivate() {
S s(4);
-#pragma omp target teams distribute simd lastprivate(s) firstprivate(s)
+// expected-error@+1 {{lastprivate variable cannot be firstprivate}} expected-note@+1 {{defined as lastprivate}}
+#pragma omp target teams distribute simd lastprivate(s) firstprivate(s) // expected-error {{calling a private constructor of class 'S'}}
for (int i = 0; i < 16; ++i)
;
}
diff --git a/test/OpenMP/target_teams_distribute_simd_map_messages.cpp b/test/OpenMP/target_teams_distribute_simd_map_messages.cpp
index 414f6f83debb..29d48d958a3d 100644
--- a/test/OpenMP/target_teams_distribute_simd_map_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_simd_map_messages.cpp
@@ -14,8 +14,8 @@ class S2 {
public:
S2():a(0) { }
S2(S2 &s2):a(s2.a) { }
- static float S2s; // expected-note 4 {{mappable type cannot contain static members}}
- static const float S2sc; // expected-note 4 {{mappable type cannot contain static members}}
+ static float S2s;
+ static const float S2sc;
};
const float S2::S2sc = 0;
const S2 b;
@@ -116,9 +116,9 @@ T tmain(T argc) {
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute simd map(S1) // expected-error {{'S1' does not refer to a value}}
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute simd map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} expected-error 2 {{type 'S2' is not mappable to target}}
+#pragma omp target teams distribute simd map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}}
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute simd map(ba) // expected-error 2 {{type 'S2' is not mappable to target}}
+#pragma omp target teams distribute simd map(ba)
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute simd map(ca)
for (i = 0; i < argc; ++i) foo();
@@ -222,11 +222,11 @@ int main(int argc, char **argv) {
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute simd map(S1) // expected-error {{'S1' does not refer to a value}}
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute simd map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} expected-error 2 {{type 'S2' is not mappable to target}}
+#pragma omp target teams distribute simd map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}}
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute simd map(argv[1])
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute simd map(ba) // expected-error 2 {{type 'S2' is not mappable to target}}
+#pragma omp target teams distribute simd map(ba)
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute simd map(ca)
for (i = 0; i < argc; ++i) foo();
diff --git a/test/OpenMP/target_teams_distribute_simd_misc_messages.c b/test/OpenMP/target_teams_distribute_simd_misc_messages.c
index c76fdea4fcf1..70ec508f6798 100644
--- a/test/OpenMP/target_teams_distribute_simd_misc_messages.c
+++ b/test/OpenMP/target_teams_distribute_simd_misc_messages.c
@@ -285,15 +285,22 @@ void test_firstprivate() {
;
int x, y, z;
+// expected-error@+1 {{lastprivate variable cannot be firstprivate}} expected-note@+1 {{defined as lastprivate}}
#pragma omp target teams distribute simd lastprivate(x) firstprivate(x)
for (i = 0; i < 16; ++i)
;
+// expected-error@+1 2 {{lastprivate variable cannot be firstprivate}} expected-note@+1 2 {{defined as lastprivate}}
#pragma omp target teams distribute simd lastprivate(x, y) firstprivate(x, y)
for (i = 0; i < 16; ++i)
;
+// expected-error@+1 3 {{lastprivate variable cannot be firstprivate}} expected-note@+1 3 {{defined as lastprivate}}
#pragma omp target teams distribute simd lastprivate(x, y, z) firstprivate(x, y, z)
for (i = 0; i < 16; ++i)
;
+// expected-error@+1 {{the value of 'simdlen' parameter must be less than or equal to the value of the 'safelen' parameter}}
+#pragma omp target teams distribute simd simdlen(64) safelen(8)
+ for (i = 0; i < 16; ++i)
+ ;
}
void test_loop_messages() {
diff --git a/test/OpenMP/target_teams_distribute_simd_private_codegen.cpp b/test/OpenMP/target_teams_distribute_simd_private_codegen.cpp
new file mode 100644
index 000000000000..c8883e18d7d9
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_simd_private_codegen.cpp
@@ -0,0 +1,233 @@
+// RUN: %clang_cc1 -DCHECK -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -DCHECK -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+
+// RUN: %clang_cc1 -DLAMBDA -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+struct St {
+ int a, b;
+ St() : a(0), b(0) {}
+ St(const St &st) : a(st.a + st.b), b(0) {}
+ ~St() {}
+};
+
+volatile int g = 1212;
+volatile int &g1 = g;
+
+template <class T>
+struct S {
+ T f;
+ S(T a) : f(a + g) {}
+ S() : f(g) {}
+ S(const S &s, St t = St()) : f(s.f + t.a) {}
+ operator T() { return T(); }
+ ~S() {}
+};
+
+// CHECK-DAG: [[S_FLOAT_TY:%.+]] = type { float }
+// CHECK-DAG: [[S_INT_TY:%.+]] = type { i{{[0-9]+}} }
+
+template <typename T>
+T tmain() {
+ S<T> test;
+ T t_var = T();
+ T vec[] = {1, 2};
+ S<T> s_arr[] = {1, 2};
+ S<T> &var = test;
+#pragma omp target teams distribute simd private(t_var, vec, s_arr, var)
+ for (int i = 0; i < 2; ++i) {
+ vec[i] = t_var;
+ s_arr[i] = var;
+ }
+ return T();
+}
+
+// CHECK-DAG: [[TEST:@.+]] = global [[S_FLOAT_TY]] zeroinitializer,
+S<float> test;
+// CHECK-DAG: [[T_VAR:@.+]] = global i{{[0-9]+}} 333,
+int t_var = 333;
+// CHECK-DAG: [[VEC:@.+]] = global [2 x i{{[0-9]+}}] [i{{[0-9]+}} 1, i{{[0-9]+}} 2],
+int vec[] = {1, 2};
+// CHECK-DAG: [[S_ARR:@.+]] = global [2 x [[S_FLOAT_TY]]] zeroinitializer,
+S<float> s_arr[] = {1, 2};
+// CHECK-DAG: [[VAR:@.+]] = global [[S_FLOAT_TY]] zeroinitializer,
+S<float> var(3);
+// CHECK-DAG: [[SIVAR:@.+]] = internal global i{{[0-9]+}} 0,
+
+int main() {
+ static int sivar;
+#ifdef LAMBDA
+ // LAMBDA: [[G:@.+]] = global i{{[0-9]+}} 1212,
+ // LAMBDA-LABEL: @main
+ // LAMBDA: call void [[OUTER_LAMBDA:@.+]](
+ [&]() {
+ // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
+ // LAMBDA: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 0, i8** null, i8** null, i{{64|32}}* null, i64* null, i32 0, i32 0)
+ // LAMBDA: call void @[[LOFFL1:.+]]()
+ // LAMBDA: ret
+#pragma omp target teams distribute simd private(g, g1, sivar)
+ for (int i = 0; i < 2; ++i) {
+ // LAMBDA: define{{.*}} internal{{.*}} void @[[LOFFL1]]()
+ // LAMBDA: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 0, {{.+}} @[[LOUTL1:.+]] to {{.+}})
+ // LAMBDA: ret void
+
+ // LAMBDA: define internal void @[[LOUTL1]]({{.+}})
+ // Skip global, bound tid and loop vars
+ // LAMBDA: {{.+}} = alloca i32*,
+ // LAMBDA: {{.+}} = alloca i32*,
+ // LAMBDA: alloca i32,
+ // LAMBDA: alloca i32,
+ // LAMBDA: alloca i32,
+ // LAMBDA: alloca i32,
+ // LAMBDA: alloca i32,
+ // LAMBDA: alloca i32,
+ // LAMBDA: [[G_PRIV:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[G1_PRIV:%.+]] = alloca i{{[0-9]+}}
+ // LAMBDA: [[TMP:%.+]] = alloca i{{[0-9]+}}*,
+ // LAMBDA: [[SIVAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: store{{.+}} [[G1_PRIV]], {{.+}} [[TMP]],
+ g = 1;
+ g1 = 1;
+ sivar = 2;
+ // LAMBDA: call void @__kmpc_for_static_init_4(
+ // LAMBDA-DAG: store{{.+}} 1, {{.+}} [[G_PRIV]],
+ // LAMBDA-DAG: store{{.+}} 2, {{.+}} [[SIVAR_PRIV]],
+ // LAMBDA-DAG: [[G1_REF:%.+]] = load{{.+}}, {{.+}} [[TMP]],
+ // LAMBDA-DAG: store{{.+}} 1, {{.+}} [[G1_REF]],
+ // LAMBDA: call void [[INNER_LAMBDA:@.+]](
+ // LAMBDA: call void @__kmpc_for_static_fini(
+ [&]() {
+ // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]])
+ // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]],
+ g = 2;
+ g1 = 2;
+ sivar = 4;
+ // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]]
+
+ // LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // LAMBDA: [[G_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G_PTR_REF]]
+ // LAMBDA: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[G_REF]]
+ // LAMBDA: [[G1_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // LAMBDA: [[G1_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G1_PTR_REF]]
+ // LAMBDA: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[G1_REF]]
+ // LAMBDA: [[SIVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+ // LAMBDA: [[SIVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SIVAR_PTR_REF]]
+ // LAMBDA: store i{{[0-9]+}} 4, i{{[0-9]+}}* [[SIVAR_REF]]
+ }();
+ }
+ }();
+ return 0;
+#else
+#pragma omp target teams distribute simd private(t_var, vec, s_arr, var, sivar)
+ for (int i = 0; i < 2; ++i) {
+ vec[i] = t_var;
+ s_arr[i] = var;
+ sivar += i;
+ }
+ return tmain<int>();
+#endif
+}
+
+// CHECK: define {{.*}}i{{[0-9]+}} @main()
+// CHECK: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 0, i8** null, i8** null, i{{64|32}}* null, i64* null, i32 0, i32 0)
+// CHECK: call void @[[OFFL1:.+]]()
+// CHECK: {{%.+}} = call{{.*}} i32 @[[TMAIN_INT:.+]]()
+// CHECK: ret
+
+// CHECK: define{{.*}} void @[[OFFL1]]()
+// CHECK: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 0, {{.+}} @[[OUTL1:.+]] to {{.+}})
+// CHECK: ret void
+
+// CHECK: define internal void @[[OUTL1]]({{.+}})
+// Skip global, bound tid and loop vars
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: {{.+}} = alloca i32,
+// CHECK: {{.+}} = alloca i32,
+// CHECK: {{.+}} = alloca i32,
+// CHECK: {{.+}} = alloca i32,
+// CHECK: {{.+}} = alloca i32,
+// CHECK: {{.+}} = alloca i32,
+// CHECK-DAG: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK-DAG: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK-DAG: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]],
+// CHECK-DAG: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]],
+// CHECK-DAG: [[SIVAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+
+// private(s_arr)
+// CHECK-DAG: [[S_ARR_PRIV_BGN:%.+]] = getelementptr{{.*}} [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[S_ARR_PRIV]],
+// CHECK-DAG: [[S_ARR_PTR_ALLOC:%.+]] = phi{{.+}} [ [[S_ARR_PRIV_BGN]], {{.+}} ], [ [[S_ARR_NEXT:%.+]], {{.+}} ]
+// CHECK-DAG: call void @{{.+}}({{.+}} [[S_ARR_PTR_ALLOC]])
+// CHECK-DAG: [[S_ARR_NEXT]] = getelementptr {{.+}} [[S_ARR_PTR_ALLOC]],
+
+// private(var)
+// CHECK-DAG: call void @{{.+}}({{.+}} [[VAR_PRIV]])
+
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK-DAG: {{.+}} = {{.+}} [[T_VAR_PRIV]]
+// CHECK-DAG: {{.+}} = {{.+}} [[VEC_PRIV]]
+// CHECK-DAG: {{.+}} = {{.+}} [[S_ARR_PRIV]]
+// CHECK-DAG: {{.+}} = {{.+}} [[VAR_PRIV]]
+// CHECK-DAG: {{.+}} = {{.+}} [[SIVAR_PRIV]]
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: ret void
+
+
+// CHECK: define{{.*}} i{{[0-9]+}} @[[TMAIN_INT]]()
+// CHECK: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 0,
+// CHECK: call void @[[TOFFL1:.+]]()
+// CHECK: ret
+
+// CHECK: define {{.*}}void @[[TOFFL1]]()
+// CHECK: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 0, {{.+}} @[[TOUTL1:.+]] to {{.+}})
+// CHECK: ret void
+
+// CHECK: define internal void @[[TOUTL1]]({{.+}})
+// Skip global, bound tid and loop vars
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_INT_TY]]],
+// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_INT_TY]],
+// CHECK: [[TMP:%.+]] = alloca [[S_INT_TY]]*,
+
+// private(s_arr)
+// CHECK-DAG: [[S_ARR_PRIV_BGN:%.+]] = getelementptr{{.*}} [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[S_ARR_PRIV]],
+// CHECK-DAG: [[S_ARR_PTR_ALLOC:%.+]] = phi{{.+}} [ [[S_ARR_PRIV_BGN]], {{.+}} ], [ [[S_ARR_NEXT:%.+]], {{.+}} ]
+// CHECK-DAG: call void @{{.+}}({{.+}} [[S_ARR_PTR_ALLOC]])
+// CHECK-DAG: [[S_ARR_NEXT]] = getelementptr {{.+}} [[S_ARR_PTR_ALLOC]],
+
+// CHECK-DAG: [[S_ARR_PRIV_BGN:%.+]] = getelementptr{{.*}} [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[S_ARR_PRIV]],
+// CHECK-DAG: [[S_ARR_PTR_ALLOC:%.+]] = phi{{.+}} [ [[S_ARR_PRIV_BGN]], {{.+}} ], [ [[S_ARR_NEXT:%.+]], {{.+}} ]
+// CHECK-DAG: call void @{{.+}}({{.+}} [[S_ARR_PTR_ALLOC]])
+// CHECK-DAG: [[S_ARR_NEXT]] = getelementptr {{.+}} [[S_ARR_PTR_ALLOC]],
+
+// private(var)
+// CHECK-DAG: call void @{{.+}}({{.+}} [[VAR_PRIV]])
+// CHECK-DAG: store{{.+}} [[VAR_PRIV]], {{.+}} [[TMP]]
+
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK-DAG: {{.+}} = {{.+}} [[T_VAR_PRIV]]
+// CHECK-DAG: {{.+}} = {{.+}} [[VEC_PRIV]]
+// CHECK-DAG: {{.+}} = {{.+}} [[S_ARR_PRIV]]
+// CHECK-DAG: {{.+}} = {{.+}} [[TMP]]
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: ret void
+
+#endif
diff --git a/test/OpenMP/target_teams_distribute_simd_reduction_codegen.cpp b/test/OpenMP/target_teams_distribute_simd_reduction_codegen.cpp
new file mode 100644
index 000000000000..76a1299981cb
--- /dev/null
+++ b/test/OpenMP/target_teams_distribute_simd_reduction_codegen.cpp
@@ -0,0 +1,211 @@
+// RUN: %clang_cc1 -DCHECK -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -DCHECK -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+
+// RUN: %clang_cc1 -DLAMBDA -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+template <typename T>
+T tmain() {
+ T t_var = T();
+ T vec[] = {1, 2};
+#pragma omp target teams distribute simd reduction(+: t_var)
+ for (int i = 0; i < 2; ++i) {
+ t_var += (T) i;
+ }
+ return T();
+}
+
+int main() {
+ static int sivar;
+#ifdef LAMBDA
+ // LAMBDA: [[RED_VAR:@.+]] = common global [8 x {{.+}}] zeroinitializer
+
+ // LAMBDA-LABEL: @main
+ // LAMBDA: call void [[OUTER_LAMBDA:@.+]](
+ [&]() {
+ // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
+ // LAMBDA: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 1, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 0)
+ // LAMBDA: call void @[[LOFFL1:.+]](
+ // LAMBDA: ret
+#pragma omp target teams distribute simd reduction(+: sivar)
+ for (int i = 0; i < 2; ++i) {
+ // LAMBDA: define{{.*}} internal{{.*}} void @[[LOFFL1]](i32*{{.+}} [[SIVAR_ARG:%.+]])
+ // LAMBDA: [[SIVAR_ADDR:%.+]] = alloca i{{.+}}*,
+ // LAMBDA: store{{.+}} [[SIVAR_ARG]], {{.+}} [[SIVAR_ADDR]],
+ // LAMBDA: [[SIVAR:%.+]] = load i32*, i32** [[SIVAR_ADDR]],
+ // LAMBDA: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[LOUTL1:.+]] to {{.+}}, {{.+}} [[SIVAR]])
+ // LAMBDA: ret void
+
+ // LAMBDA: define internal void @[[LOUTL1]]({{.+}}, {{.+}}, {{.+}}*{{.+}} [[SIVAR_ARG:%.+]])
+ // Skip global and bound tid vars
+ // LAMBDA: {{.+}} = alloca i32*,
+ // LAMBDA: {{.+}} = alloca i32*,
+ // LAMBDA: [[SIVAR_ADDR:%.+]] = alloca i{{.+}}*,
+ // LAMBDA: [[SIVAR_PRIV:%.+]] = alloca i{{.+}},
+ // LAMBDA: [[RED_LIST:%.+]] = alloca [1 x {{.+}}],
+ // LAMBDA: store{{.+}} [[SIVAR_ARG]], {{.+}} [[SIVAR_ADDR]],
+ // LAMBDA: [[SIVAR_REF:%.+]] = load {{.+}}, {{.+}} [[SIVAR_ADDR]],
+ // LAMBDA: store{{.+}} 0, {{.+}} [[SIVAR_PRIV]],
+
+ // LAMBDA: call void @__kmpc_for_static_init_4(
+ // LAMBDA: store{{.+}}, {{.+}} [[SIVAR_PRIV]],
+ // LAMBDA: call void [[INNER_LAMBDA:@.+]](
+ // LAMBDA: call void @__kmpc_for_static_fini(
+ // LAMBDA: [[RED_LIST_GEP:%.+]] = getelementptr{{.+}} [[RED_LIST]],
+ // LAMBDA: [[SIVAR_PRIV_CAST:%.+]] = bitcast{{.+}} [[SIVAR_PRIV]] to
+ // LAMBDA: store{{.+}} [[SIVAR_PRIV_CAST]], {{.+}} [[RED_LIST_GEP]],
+ // LAMBDA: [[RED_LIST_BCAST:%.+]] = bitcast{{.+}} [[RED_LIST]] to
+ // LAMBDA: [[K_RED_RET:%.+]] = call{{.+}} @__kmpc_reduce({{.+}}, {{.+}}, {{.+}}, {{.+}}, {{.+}} [[RED_LIST_BCAST]], {{.+}} [[RED_FUN:@.+]], {{.+}} [[RED_VAR]])
+ // LAMBDA: switch{{.+}} [[K_RED_RET]], label{{.+}} [
+ // LAMBDA: {{.+}}, label %[[CASE1:.+]]
+ // LAMBDA: {{.+}}, label %[[CASE2:.+]]
+ // LAMBDA: ]
+ // LAMBDA: [[CASE1]]:
+ // LAMBDA-DAG: [[SIVAR_VAL:%.+]] = load{{.+}}, {{.+}} [[SIVAR_REF]],
+ // LAMBDA-DAG: [[SIVAR_PRIV_VAL:%.+]] = load{{.+}}, {{.+}} [[SIVAR_PRIV]],
+ // LAMBDA-DAG: [[SIVAR_INC:%.+]] = add{{.+}} [[SIVAR_VAL]], [[SIVAR_PRIV_VAL]]
+ // LAMBDA: store{{.+}} [[SIVAR_INC]], {{.+}} [[SIVAR_REF]],
+ // LAMBDA: call void @__kmpc_end_reduce({{.+}}, {{.+}}, {{.+}} [[RED_VAR]])
+ // LAMBDA: br
+ // LAMBDA: [[CASE2]]:
+ // LAMBDA-DAG: [[SIVAR_PRIV_VAL:%.+]] = load{{.+}}, {{.+}} [[SIVAR_PRIV]],
+ // LAMBDA-DAG: [[ATOMIC_RES:%.+]] = atomicrmw add{{.+}} [[SIVAR_REF]], {{.+}} [[SIVAR_PRIV_VAL]]
+ // LAMBDA: call void @__kmpc_end_reduce({{.+}}, {{.+}}, {{.+}} [[RED_VAR]])
+ // LAMBDA: br
+ sivar += i;
+
+ [&]() {
+ // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]])
+ // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]],
+
+ sivar += 4;
+ // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]]
+
+ // LAMBDA: [[SIVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // LAMBDA: [[SIVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SIVAR_PTR_REF]]
+ // LAMBDA: [[SIVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR_REF]]
+ // LAMBDA: [[SIVAR_INC:%.+]] = add{{.+}} [[SIVAR_VAL]], 4
+ // LAMBDA: store i{{[0-9]+}} [[SIVAR_INC]], i{{[0-9]+}}* [[SIVAR_REF]]
+ }();
+ }
+ }();
+ return 0;
+#else
+#pragma omp target teams distribute simd reduction(+: sivar)
+ for (int i = 0; i < 2; ++i) {
+ sivar += i;
+ }
+ return tmain<int>();
+#endif
+}
+
+// CHECK: [[RED_VAR:@.+]] = common global [8 x {{.+}}] zeroinitializer
+
+// CHECK: define {{.*}}i{{[0-9]+}} @main()
+// CHECK: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 1, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 0)
+// CHECK: call void @[[OFFL1:.+]](i32* {{.+}})
+// CHECK: [[RES:%.+]] = call{{.*}} i32 @[[TMAIN_INT:[^(]+]]()
+// CHECK: ret i32 [[RES]]
+
+// CHECK: define{{.*}} void @[[OFFL1]](i32*{{.+}} [[SIVAR_ARG:%.+]])
+// CHECK: [[SIVAR_ADDR:%.+]] = alloca i{{.+}}*,
+// CHECK: store{{.+}} [[SIVAR_ARG]], {{.+}}** [[SIVAR_ADDR]],
+// CHECK: [[SIVAR_LOAD:%.+]] = load i32*, i32** [[SIVAR_ADDR]],
+// CHECK: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTL1:.+]] to {{.+}}, {{.+}} [[SIVAR_LOAD]])
+// CHECK: ret void
+
+// CHECK: define internal void @[[OUTL1]]({{.+}}, {{.+}}, i32*{{.+}} [[SIVAR_ARG:%.+]])
+// Skip global and bound tid vars
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: [[SIVAR_ADDR:%.+]] = alloca i{{.+}}*,
+// CHECK: [[SIVAR_PRIV:%.+]] = alloca i32,
+// CHECK: [[RED_LIST:%.+]] = alloca [1 x {{.+}}],
+// CHECK: store{{.+}} [[SIVAR_ARG]], {{.+}} [[SIVAR_ADDR]],
+// CHECK: [[SIVAR_REF:%.+]] = load i32*, i32** [[SIVAR_ADDR]],
+// CHECK: store{{.+}} 0, {{.+}} [[SIVAR_PRIV]],
+
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: store{{.+}}, {{.+}} [[SIVAR_PRIV]],
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: [[RED_LIST_GEP:%.+]] = getelementptr{{.+}} [[RED_LIST]],
+// CHECK: [[SIVAR_PRIV_CAST:%.+]] = bitcast{{.+}} [[SIVAR_PRIV]] to
+// CHECK: store{{.+}} [[SIVAR_PRIV_CAST]], {{.+}} [[RED_LIST_GEP]],
+// CHECK: [[RED_LIST_BCAST:%.+]] = bitcast{{.+}} [[RED_LIST]] to
+// CHECK: [[K_RED_RET:%.+]] = call{{.+}} @__kmpc_reduce({{.+}}, {{.+}}, {{.+}}, {{.+}}, {{.+}} [[RED_LIST_BCAST]], {{.+}} [[RED_FUN:@.+]], {{.+}} [[RED_VAR]])
+// CHECK: switch{{.+}} [[K_RED_RET]], label{{.+}} [
+// CHECK: {{.+}}, label %[[CASE1:.+]]
+// CHECK: {{.+}}, label %[[CASE2:.+]]
+// CHECK: ]
+// CHECK: [[CASE1]]:
+// CHECK-DAG: [[SIVAR_VAL:%.+]] = load{{.+}}, {{.+}} [[SIVAR_REF]],
+// CHECK-DAG: [[SIVAR_PRIV_VAL:%.+]] = load{{.+}}, {{.+}} [[SIVAR_PRIV]],
+// CHECK-DAG: [[SIVAR_INC:%.+]] = add{{.+}} [[SIVAR_VAL]], [[SIVAR_PRIV_VAL]]
+// CHECK: store{{.+}} [[SIVAR_INC]], {{.+}} [[SIVAR_REF]],
+// CHECK: call void @__kmpc_end_reduce({{.+}}, {{.+}}, {{.+}} [[RED_VAR]])
+// CHECK: br
+// CHECK: [[CASE2]]:
+// CHECK-DAG: [[SIVAR_PRIV_VAL:%.+]] = load{{.+}}, {{.+}} [[SIVAR_PRIV]],
+// CHECK-DAG: [[ATOMIC_RES:%.+]] = atomicrmw add{{.+}} [[SIVAR_REF]], {{.+}} [[SIVAR_PRIV_VAL]]
+// CHECK: call void @__kmpc_end_reduce({{.+}}, {{.+}}, {{.+}} [[RED_VAR]])
+// CHECK: br
+
+
+// CHECK: define{{.*}} i{{[0-9]+}} @[[TMAIN_INT]]()
+// CHECK: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 1,
+// CHECK: call void @[[TOFFL1:.+]]({{.+}}* {{.+}})
+// CHECK: ret
+
+// CHECK: define{{.*}} void @[[TOFFL1]](i32*{{.+}} [[TVAR_ARG:%.+]])
+// CHECK: [[TVAR_ADDR:%.+]] = alloca i{{.+}}*,
+// CHECK: store{{.+}} [[TVAR_ARG]], {{.+}} [[TVAR_ADDR]],
+// CHECK: [[TVAR:%.+]] = load i32*, i32** [[TVAR_ADDR]],
+// CHECK: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[TOUTL1:.+]] to {{.+}}, {{.+}} [[TVAR]])
+// CHECK: ret void
+
+// CHECK: define internal void @[[TOUTL1]]({{.+}}, {{.+}}, {{.+}}*{{.+}} [[TVAR_ARG:%.+]])
+// Skip global and bound tid vars
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: [[TVAR_ADDR:%.+]] = alloca i{{.+}}*,
+// CHECK: [[TVAR_PRIV:%.+]] = alloca i{{.+}},
+// CHECK: [[RED_LIST:%.+]] = alloca [1 x {{.+}}],
+// CHECK: store{{.+}} [[TVAR_ARG]], {{.+}} [[TVAR_ADDR]],
+// CHECK: [[TVAR_REF:%.+]] = load i32*, i32** [[TVAR_ADDR]],
+// CHECK: store{{.+}} 0, {{.+}} [[TVAR_PRIV]],
+
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: store{{.+}}, {{.+}} [[TVAR_PRIV]],
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: [[RED_LIST_GEP:%.+]] = getelementptr{{.+}} [[RED_LIST]],
+// CHECK: [[TVAR_PRIV_CAST:%.+]] = bitcast{{.+}} [[TVAR_PRIV]] to
+// CHECK: store{{.+}} [[TVAR_PRIV_CAST]], {{.+}} [[RED_LIST_GEP]],
+// CHECK: [[RED_LIST_BCAST:%.+]] = bitcast{{.+}} [[RED_LIST]] to
+// CHECK: [[K_RED_RET:%.+]] = call{{.+}} @__kmpc_reduce({{.+}}, {{.+}}, {{.+}}, {{.+}}, {{.+}} [[RED_LIST_BCAST]], {{.+}} [[RED_FUN:@.+]], {{.+}} [[RED_VAR]])
+// CHECK: switch{{.+}} [[K_RED_RET]], label{{.+}} [
+// CHECK: {{.+}}, label %[[CASE1:.+]]
+// CHECK: {{.+}}, label %[[CASE2:.+]]
+// CHECK: ]
+// CHECK: [[CASE1]]:
+// CHECK-DAG: [[TVAR_VAL:%.+]] = load{{.+}}, {{.+}} [[TVAR_REF]],
+// CHECK-DAG: [[TVAR_PRIV_VAL:%.+]] = load{{.+}}, {{.+}} [[TVAR_PRIV]],
+// CHECK-DAG: [[TVAR_INC:%.+]] = add{{.+}} [[TVAR_VAL]], [[TVAR_PRIV_VAL]]
+// CHECK: store{{.+}} [[TVAR_INC]], {{.+}} [[TVAR_REF]],
+// CHECK: call void @__kmpc_end_reduce({{.+}}, {{.+}}, {{.+}} [[RED_VAR]])
+// CHECK: br
+// CHECK: [[CASE2]]:
+// CHECK-DAG: [[TVAR_PRIV_VAL:%.+]] = load{{.+}}, {{.+}} [[TVAR_PRIV]],
+// CHECK-DAG: [[ATOMIC_RES:%.+]] = atomicrmw add{{.+}} [[TVAR_REF]], {{.+}} [[TVAR_PRIV_VAL]]
+// CHECK: call void @__kmpc_end_reduce({{.+}}, {{.+}}, {{.+}} [[RED_VAR]])
+// CHECK: br
+
+#endif
diff --git a/test/OpenMP/target_teams_distribute_simd_reduction_messages.cpp b/test/OpenMP/target_teams_distribute_simd_reduction_messages.cpp
index 1c0283285aa5..35d4e12dc339 100644
--- a/test/OpenMP/target_teams_distribute_simd_reduction_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_simd_reduction_messages.cpp
@@ -19,9 +19,9 @@ public:
S2() : a(0) {}
S2(S2 &s2) : a(s2.a) {}
static float S2s; // expected-note 2 {{static data member is predetermined as shared}}
- static const float S2sc;
+ static const float S2sc; // expected-note 2 {{'S2sc' declared here}}
};
-const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}}
+const float S2::S2sc = 0;
S2 b; // expected-note 3 {{'b' defined here}}
const S2 ba[5]; // expected-note 2 {{'ba' defined here}}
class S3 {
diff --git a/test/OpenMP/target_teams_map_messages.cpp b/test/OpenMP/target_teams_map_messages.cpp
index 89425d622c10..7874c2e105cf 100644
--- a/test/OpenMP/target_teams_map_messages.cpp
+++ b/test/OpenMP/target_teams_map_messages.cpp
@@ -265,7 +265,7 @@ void SAclient(int arg) {
{}
#pragma omp target teams map((p+1)->A) // expected-error {{expected expression containing only member accesses and/or array sections based on named variables}}
{}
- #pragma omp target teams map(u.B) // expected-error {{mapped storage cannot be derived from a union}}
+ #pragma omp target teams map(u.B) // expected-error {{mapping of union members is not allowed}}
{}
#pragma omp target data map(to: r.C) //expected-note {{used here}}
@@ -312,8 +312,8 @@ class S2 {
public:
S2():a(0) { }
S2(S2 &s2):a(s2.a) { }
- static float S2s; // expected-note 4 {{mappable type cannot contain static members}}
- static const float S2sc; // expected-note 4 {{mappable type cannot contain static members}}
+ static float S2s;
+ static const float S2sc;
};
const float S2::S2sc = 0;
const S2 b;
@@ -346,7 +346,7 @@ template <class T>
struct S6;
template<>
-struct S6<int> // expected-note {{mappable type cannot be polymorphic}}
+struct S6<int>
{
virtual void foo();
};
@@ -414,8 +414,8 @@ T tmain(T argc) {
#pragma omp target data map(tofrom: argc > 0 ? x : y) // expected-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}}
#pragma omp target data map(argc)
#pragma omp target data map(S1) // expected-error {{'S1' does not refer to a value}}
-#pragma omp target data map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} expected-error 2 {{type 'S2' is not mappable to target}}
-#pragma omp target data map(ba) // expected-error 2 {{type 'S2' is not mappable to target}}
+#pragma omp target data map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}}
+#pragma omp target data map(ba)
#pragma omp target data map(ca)
#pragma omp target data map(da)
#pragma omp target data map(S2::S2s)
@@ -488,9 +488,9 @@ int main(int argc, char **argv) {
#pragma omp target data map(tofrom: argc > 0 ? argv[1] : argv[2]) // expected-error {{xpected expression containing only member accesses and/or array sections based on named variables}}
#pragma omp target data map(argc)
#pragma omp target data map(S1) // expected-error {{'S1' does not refer to a value}}
-#pragma omp target data map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} expected-error 2 {{type 'S2' is not mappable to target}}
+#pragma omp target data map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}}
#pragma omp target data map(argv[1])
-#pragma omp target data map(ba) // expected-error 2 {{type 'S2' is not mappable to target}}
+#pragma omp target data map(ba)
#pragma omp target data map(ca)
#pragma omp target data map(da)
#pragma omp target data map(S2::S2s)
@@ -530,7 +530,7 @@ int main(int argc, char **argv) {
#pragma omp target teams firstprivate(j) map(j) // expected-error {{firstprivate variable cannot be in a map clause in '#pragma omp target teams' directive}} expected-note {{defined as firstprivate}}
{}
-#pragma omp target teams map(m) // expected-error {{type 'S6<int>' is not mappable to target}}
+#pragma omp target teams map(m)
{}
return tmain<int, 3>(argc)+tmain<from, 4>(argc); // expected-note {{in instantiation of function template specialization 'tmain<int, 3>' requested here}} expected-note {{in instantiation of function template specialization 'tmain<int, 4>' requested here}}
diff --git a/test/OpenMP/target_teams_num_teams_codegen.cpp b/test/OpenMP/target_teams_num_teams_codegen.cpp
index ad3626515f50..91288458c5aa 100644
--- a/test/OpenMP/target_teams_num_teams_codegen.cpp
+++ b/test/OpenMP/target_teams_num_teams_codegen.cpp
@@ -147,10 +147,8 @@ int bar(int n){
// CHECK: [[ARG:%.+]] = load i[[SZ]], i[[SZ]]* [[CAPEC_ADDR]], align
// CHECK: [[TEAMS:%.+]] = load i32, i32* [[CAPE_ADDR]], align
//
-// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 3, {{.*}}, i32 [[TEAMS]], i32 0)
-// CHECK: store i32 [[RET]], i32* [[RHV:%.+]], align
-// CHECK: [[RET2:%.+]] = load i32, i32* [[RHV]], align
-// CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 3, {{.*}}, i32 [[TEAMS]], i32 0)
+// CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
// CHECK: br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
//
// CHECK: [[FAIL]]
@@ -160,10 +158,8 @@ int bar(int n){
//
//
//
-// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 1, {{.+}}, i32 1024, i32 0)
-// CHECK: store i32 [[RET]], i32* [[RHV:%.+]], align
-// CHECK: [[RET2:%.+]] = load i32, i32* [[RHV]], align
-// CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 1, {{.+}}, i32 1024, i32 0)
+// CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
// CHECK: br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
//
// CHECK: [[FAIL]]
@@ -190,10 +186,8 @@ int bar(int n){
// CHECK: [[ARG:%.+]] = load i[[SZ]], i[[SZ]]* [[CAPEC_ADDR]], align
// CHECK: [[TEAMS:%.+]] = load i32, i32* [[CAPE_ADDR]], align
//
-// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 1, {{.*}}, i32 [[TEAMS]], i32 0)
-// CHECK: store i32 [[RET]], i32* [[RHV:%.+]], align
-// CHECK: [[RET2:%.+]] = load i32, i32* [[RHV]], align
-// CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 1, {{.*}}, i32 [[TEAMS]], i32 0)
+// CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
// CHECK: br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
//
// CHECK: [[FAIL]]
@@ -213,10 +207,8 @@ int bar(int n){
// CHECK: [[ARG:%.+]] = load i[[SZ]], i[[SZ]]* [[CAPEC_ADDR]], align
// CHECK: [[TEAMS:%.+]] = load i32, i32* [[CAPE_ADDR]], align
//
-// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 1, {{.*}}, i32 [[TEAMS]], i32 0)
-// CHECK: store i32 [[RET]], i32* [[RHV:%.+]], align
-// CHECK: [[RET2:%.+]] = load i32, i32* [[RHV]], align
-// CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 1, {{.*}}, i32 [[TEAMS]], i32 0)
+// CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
// CHECK: br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
//
// CHECK: [[FAIL]]
@@ -233,10 +225,8 @@ int bar(int n){
//
// CHECK: define {{.*}}[[FTEMPLATE]]
//
-// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 0, {{.*}}, i32 20, i32 0)
-// CHECK-NEXT: store i32 [[RET]], i32* [[RHV:%.+]], align
-// CHECK-NEXT: [[RET2:%.+]] = load i32, i32* [[RHV]], align
-// CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 0, {{.*}}, i32 20, i32 0)
+// CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
// CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
//
// CHECK: [[FAIL]]
@@ -257,10 +247,8 @@ int bar(int n){
// CHECK: [[T:%.+]] = load i16, i16* [[CAPE_ADDR]], align
// CHECK: [[TEAMS:%.+]] = sext i16 [[T]] to i32
//
-// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 3, {{.*}}, i32 [[TEAMS]], i32 0)
-// CHECK: store i32 [[RET]], i32* [[RHV:%.+]], align
-// CHECK: [[RET2:%.+]] = load i32, i32* [[RHV]], align
-// CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 3, {{.*}}, i32 [[TEAMS]], i32 0)
+// CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
// CHECK: br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
//
// CHECK: [[FAIL]]
diff --git a/test/OpenMP/target_teams_reduction_messages.cpp b/test/OpenMP/target_teams_reduction_messages.cpp
index 48fa310253c8..b5876b108508 100644
--- a/test/OpenMP/target_teams_reduction_messages.cpp
+++ b/test/OpenMP/target_teams_reduction_messages.cpp
@@ -24,9 +24,9 @@ public:
S2() : a(0) {}
S2(S2 &s2) : a(s2.a) {}
static float S2s; // expected-note 2 {{static data member is predetermined as shared}}
- static const float S2sc;
+ static const float S2sc; // expected-note 2 {{'S2sc' declared here}}
};
-const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}}
+const float S2::S2sc = 0;
S2 b; // expected-note 3 {{'b' defined here}}
const S2 ba[5]; // expected-note 2 {{'ba' defined here}}
class S3 {
diff --git a/test/OpenMP/target_teams_thread_limit_codegen.cpp b/test/OpenMP/target_teams_thread_limit_codegen.cpp
index d89f51561712..5d93c1de77fe 100644
--- a/test/OpenMP/target_teams_thread_limit_codegen.cpp
+++ b/test/OpenMP/target_teams_thread_limit_codegen.cpp
@@ -147,10 +147,8 @@ int bar(int n){
// CHECK: [[ARG:%.+]] = load i[[SZ]], i[[SZ]]* [[CAPEC_ADDR]], align
// CHECK: [[TL:%.+]] = load i32, i32* [[CAPE_ADDR]], align
//
-// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 3, {{.*}}, i32 0, i32 [[TL]])
-// CHECK: store i32 [[RET]], i32* [[RHV:%.+]], align
-// CHECK: [[RET2:%.+]] = load i32, i32* [[RHV]], align
-// CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 3, {{.*}}, i32 0, i32 [[TL]])
+// CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
// CHECK: br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
//
// CHECK: [[FAIL]]
@@ -160,10 +158,8 @@ int bar(int n){
//
//
//
-// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 1, {{.+}}, i32 0, i32 1024)
-// CHECK: store i32 [[RET]], i32* [[RHV:%.+]], align
-// CHECK: [[RET2:%.+]] = load i32, i32* [[RHV]], align
-// CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 1, {{.+}}, i32 0, i32 1024)
+// CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
// CHECK: br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
//
// CHECK: [[FAIL]]
@@ -199,10 +195,8 @@ int bar(int n){
// CHECK: [[TEAMS:%.+]] = load i32, i32* [[CAPE_ADDR1]], align
// CHECK: [[TL:%.+]] = load i32, i32* [[CAPE_ADDR2]], align
//
-// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 2, {{.*}}, i32 [[TEAMS]], i32 [[TL]])
-// CHECK: store i32 [[RET]], i32* [[RHV:%.+]], align
-// CHECK: [[RET2:%.+]] = load i32, i32* [[RHV]], align
-// CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 2, {{.*}}, i32 [[TEAMS]], i32 [[TL]])
+// CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
// CHECK: br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
//
// CHECK: [[FAIL]]
@@ -222,10 +216,8 @@ int bar(int n){
// CHECK: [[ARG:%.+]] = load i[[SZ]], i[[SZ]]* [[CAPEC_ADDR]], align
// CHECK: [[TL:%.+]] = load i32, i32* [[CAPE_ADDR]], align
//
-// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 1, {{.*}}, i32 0, i32 [[TL]])
-// CHECK: store i32 [[RET]], i32* [[RHV:%.+]], align
-// CHECK: [[RET2:%.+]] = load i32, i32* [[RHV]], align
-// CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 1, {{.*}}, i32 0, i32 [[TL]])
+// CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
// CHECK: br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
//
// CHECK: [[FAIL]]
@@ -242,10 +234,8 @@ int bar(int n){
//
// CHECK: define {{.*}}[[FTEMPLATE]]
//
-// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 0, {{.*}}, i32 0, i32 20)
-// CHECK-NEXT: store i32 [[RET]], i32* [[RHV:%.+]], align
-// CHECK-NEXT: [[RET2:%.+]] = load i32, i32* [[RHV]], align
-// CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 0, {{.*}}, i32 0, i32 20)
+// CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
// CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
//
// CHECK: [[FAIL]]
@@ -266,10 +256,8 @@ int bar(int n){
// CHECK: [[T:%.+]] = load i16, i16* [[CAPE_ADDR]], align
// CHECK: [[TEAMS:%.+]] = sext i16 [[T]] to i32
//
-// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 3, {{.*}}, i32 [[TEAMS]], i32 1024)
-// CHECK: store i32 [[RET]], i32* [[RHV:%.+]], align
-// CHECK: [[RET2:%.+]] = load i32, i32* [[RHV]], align
-// CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
+// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 3, {{.*}}, i32 [[TEAMS]], i32 1024)
+// CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
// CHECK: br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
//
// CHECK: [[FAIL]]
diff --git a/test/OpenMP/target_update_codegen.cpp b/test/OpenMP/target_update_codegen.cpp
index f1e61a54c6e2..7f45c313a8a1 100644
--- a/test/OpenMP/target_update_codegen.cpp
+++ b/test/OpenMP/target_update_codegen.cpp
@@ -22,15 +22,15 @@ ST<int> gb;
double gc[100];
// CK1: [[SIZE00:@.+]] = {{.+}}constant [1 x i[[sz:64|32]]] [i{{64|32}} 800]
-// CK1: [[MTYPE00:@.+]] = {{.+}}constant [1 x i32] [i32 34]
+// CK1: [[MTYPE00:@.+]] = {{.+}}constant [1 x i64] [i64 34]
// CK1: [[SIZE02:@.+]] = {{.+}}constant [1 x i[[sz]]] [i[[sz]] 4]
-// CK1: [[MTYPE02:@.+]] = {{.+}}constant [1 x i32] [i32 33]
+// CK1: [[MTYPE02:@.+]] = {{.+}}constant [1 x i64] [i64 33]
-// CK1: [[MTYPE03:@.+]] = {{.+}}constant [1 x i32] [i32 34]
+// CK1: [[MTYPE03:@.+]] = {{.+}}constant [1 x i64] [i64 34]
// CK1: [[SIZE04:@.+]] = {{.+}}constant [2 x i[[sz]]] [i[[sz]] {{8|4}}, i[[sz]] 24]
-// CK1: [[MTYPE04:@.+]] = {{.+}}constant [2 x i32] [i32 33, i32 17]
+// CK1: [[MTYPE04:@.+]] = {{.+}}constant [2 x i64] [i64 33, i64 17]
// CK1-LABEL: _Z3fooi
void foo(int arg) {
@@ -38,8 +38,9 @@ void foo(int arg) {
float lb[arg];
// Region 00
- // CK1-DAG: call void @__tgt_target_data_update(i32 [[DEV:%[^,]+]], i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE00]]{{.+}})
- // CK1-DAG: [[DEV]] = load i32, i32* %{{[^,]+}},
+ // CK1-DAG: call void @__tgt_target_data_update_nowait(i64 [[DEV:%[^,]+]], i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE00]]{{.+}})
+ // CK1-DAG: [[DEV]] = sext i32 [[DEVi32:%[^,]+]] to i64
+ // CK1-DAG: [[DEVi32]] = load i32, i32* %{{[^,]+}},
// CK1-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK1-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -51,7 +52,7 @@ void foo(int arg) {
// CK1-DAG: store [100 x double]* @gc, [100 x double]** [[PC0]]
// CK1: %{{.+}} = add nsw i32 %{{[^,]+}}, 1
- #pragma omp target update if(1+3-5) device(arg) from(gc)
+ #pragma omp target update if(1+3-5) device(arg) from(gc) nowait
{++arg;}
// Region 01
@@ -62,7 +63,7 @@ void foo(int arg) {
// Region 02
// CK1: br i1 %{{[^,]+}}, label %[[IFTHEN:[^,]+]], label %[[IFELSE:[^,]+]]
// CK1: [[IFTHEN]]
- // CK1-DAG: call void @__tgt_target_data_update(i32 4, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE02]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE02]]{{.+}})
+ // CK1-DAG: call void @__tgt_target_data_update(i64 4, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE02]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE02]]{{.+}})
// CK1-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK1-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -85,7 +86,7 @@ void foo(int arg) {
{++arg;}
// Region 03
- // CK1-DAG: call void @__tgt_target_data_update(i32 -1, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[sz]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE03]]{{.+}})
+ // CK1-DAG: call void @__tgt_target_data_update(i64 -1, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[sz]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE03]]{{.+}})
// CK1-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK1-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
// CK1-DAG: [[GEPS]] = getelementptr inbounds {{.+}}[[S:%[^,]+]]
@@ -108,7 +109,7 @@ void foo(int arg) {
{++arg;}
// Region 04
- // CK1-DAG: call void @__tgt_target_data_update(i32 -1, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE04]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE04]]{{.+}})
+ // CK1-DAG: call void @__tgt_target_data_update(i64 -1, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE04]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE04]]{{.+}})
// CK1-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK1-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
@@ -159,7 +160,7 @@ struct ST {
};
// CK2: [[SIZE00:@.+]] = {{.+}}constant [2 x i[[sz:64|32]]] [i{{64|32}} {{8|4}}, i{{64|32}} 24]
-// CK2: [[MTYPE00:@.+]] = {{.+}}constant [2 x i32] [i32 34, i32 18]
+// CK2: [[MTYPE00:@.+]] = {{.+}}constant [2 x i64] [i64 34, i64 18]
// CK2-LABEL: _Z3bari
int bar(int arg){
@@ -170,8 +171,9 @@ int bar(int arg){
// Region 00
// CK2: br i1 %{{[^,]+}}, label %[[IFTHEN:[^,]+]], label %[[IFELSE:[^,]+]]
// CK2: [[IFTHEN]]
-// CK2-DAG: call void @__tgt_target_data_update(i32 [[DEV:%[^,]+]], i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE00]]{{.+}})
-// CK2-DAG: [[DEV]] = load i32, i32* %{{[^,]+}},
+// CK2-DAG: call void @__tgt_target_data_update(i64 [[DEV:%[^,]+]], i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE00]]{{.+}})
+// CK2-DAG: [[DEV]] = sext i32 [[DEVi32:%[^,]+]] to i64
+// CK2-DAG: [[DEVi32]] = load i32, i32* %{{[^,]+}},
// CK2-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK2-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
diff --git a/test/OpenMP/target_update_depend_messages.cpp b/test/OpenMP/target_update_depend_messages.cpp
index 64383a049104..59e159e99fdb 100644
--- a/test/OpenMP/target_update_depend_messages.cpp
+++ b/test/OpenMP/target_update_depend_messages.cpp
@@ -35,14 +35,14 @@ int tmain(T argc, S **argv, R *env[]) {
#pragma omp target update to(z) depend(source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}}
#pragma omp target update to(z) depend(in : argc)) // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}}
#pragma omp target update to(z) depend(out: ) // expected-error {{expected expression}}
- #pragma omp target update to(z) depend(inout : foobool(argc)), depend (in, argc) // expected-error {{expected variable name, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}}
+ #pragma omp target update to(z) depend(inout : foobool(argc)), depend (in, argc) // expected-error {{expected addressable lvalue expression, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}}
#pragma omp target update to(z) depend(out :S1) // expected-error {{'S1' does not refer to a value}}
- #pragma omp target update to(z) depend(in : argv[1][1] = '2') // expected-error {{expected variable name, array element or array section}}
- #pragma omp target update to(z) depend(in : vec[1]) // expected-error {{expected variable name, array element or array section}}
+ #pragma omp target update to(z) depend(in : argv[1][1] = '2') // expected-error {{expected addressable lvalue expression, array element or array section}}
+ #pragma omp target update to(z) depend(in : vec[1]) // expected-error {{expected addressable lvalue expression, array element or array section}}
#pragma omp target update to(z) depend(in : argv[0])
#pragma omp target update to(z) depend(in : ) // expected-error {{expected expression}}
- #pragma omp target update to(z) depend(in : tmain) // expected-error {{expected variable name, array element or array section}}
- #pragma omp target update to(z) depend(in : a[0]) // expected-error{{expected variable name, array element or array section}}
+ #pragma omp target update to(z) depend(in : tmain)
+ #pragma omp target update to(z) depend(in : a[0]) // expected-error{{expected addressable lvalue expression, array element or array section}}
#pragma omp target update to(z) depend(in : vec[1:2]) // expected-error {{ value is not an array or pointer}}
#pragma omp target update to(z) depend(in : argv[ // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}}
#pragma omp target update to(z) depend(in : argv[: // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}}
@@ -83,14 +83,14 @@ int main(int argc, char **argv, char *env[]) {
#pragma omp target update to(z) depend(source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}}
#pragma omp target update to(z) depend(in : argc)) // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}}
#pragma omp target update to(z) depend(out: ) // expected-error {{expected expression}}
- #pragma omp target update to(z) depend(inout : foobool(argc)), depend (in, argc) // expected-error {{expected variable name, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}}
+ #pragma omp target update to(z) depend(inout : foobool(argc)), depend (in, argc) // expected-error {{expected addressable lvalue expression, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}}
#pragma omp target update to(z) depend(out :S1) // expected-error {{'S1' does not refer to a value}}
- #pragma omp target update to(z) depend(in : argv[1][1] = '2') // expected-error {{expected variable name, array element or array section}}
- #pragma omp target update to(z) depend(in : vec[1]) // expected-error {{expected variable name, array element or array section}}
+ #pragma omp target update to(z) depend(in : argv[1][1] = '2')
+ #pragma omp target update to(z) depend(in : vec[1]) // expected-error {{expected addressable lvalue expression, array element or array section}}
#pragma omp target update to(z) depend(in : argv[0])
#pragma omp target update to(z) depend(in : ) // expected-error {{expected expression}}
- #pragma omp target update to(z) depend(in : main) // expected-error {{expected variable name, array element or array section}}
- #pragma omp target update to(z) depend(in : a[0]) // expected-error{{expected variable name, array element or array section}}
+ #pragma omp target update to(z) depend(in : main)
+ #pragma omp target update to(z) depend(in : a[0]) // expected-error{{expected addressable lvalue expression, array element or array section}}
#pragma omp target update to(z) depend(in : vec[1:2]) // expected-error {{ value is not an array or pointer}}
#pragma omp target update to(z) depend(in : argv[ // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}}
#pragma omp target update to(z) depend(in : argv[: // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}}
diff --git a/test/OpenMP/target_update_from_messages.cpp b/test/OpenMP/target_update_from_messages.cpp
index 6aff083b6a48..c42bd12f75b8 100644
--- a/test/OpenMP/target_update_from_messages.cpp
+++ b/test/OpenMP/target_update_from_messages.cpp
@@ -14,8 +14,8 @@ class S2 {
public:
S2():a(0) { }
S2(S2 &s2):a(s2.a) { }
- static float S2s; // expected-note 4 {{mappable type cannot contain static members}}
- static const float S2sc; // expected-note 4 {{mappable type cannot contain static members}}
+ static float S2s;
+ static const float S2sc;
};
const float S2::S2sc = 0;
const S2 b;
@@ -94,8 +94,8 @@ T tmain(T argc) {
#pragma omp target update from(y x) // expected-error {{expected ',' or ')' in 'from' clause}}
#pragma omp target update from(argc > 0 ? x : y) // expected-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}}
#pragma omp target update from(S1) // expected-error {{'S1' does not refer to a value}}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
-#pragma omp target update from(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} expected-error 2 {{type 'S2' is not mappable to target}}
-#pragma omp target update from(ba) // expected-error 2 {{type 'S2' is not mappable to target}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update from(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}}
+#pragma omp target update from(ba)
#pragma omp target update from(h) // expected-error {{threadprivate variables are not allowed in 'from' clause}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
#pragma omp target update from(k), to(k) // expected-error 2 {{variable can appear only once in OpenMP 'target update' construct}} expected-note 2 {{used here}}
#pragma omp target update from(t), from(t[:5]) // expected-error 2 {{variable can appear only once in OpenMP 'target update' construct}} expected-note 2 {{used here}}
@@ -148,8 +148,8 @@ int main(int argc, char **argv) {
#pragma omp target update from(y x) // expected-error {{expected ',' or ')' in 'from' clause}}
#pragma omp target update from(argc > 0 ? x : y) // expected-error {{expected expression containing only member accesses and/or array sections based on named variables}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
#pragma omp target update from(S1) // expected-error {{'S1' does not refer to a value}}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
-#pragma omp target update from(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} expected-error 2 {{type 'S2' is not mappable to target}}
-#pragma omp target update from(ba) // expected-error 2 {{type 'S2' is not mappable to target}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update from(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}}
+#pragma omp target update from(ba)
#pragma omp target update from(h) // expected-error {{threadprivate variables are not allowed in 'from' clause}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
#pragma omp target update from(k), to(k) // expected-error {{variable can appear only once in OpenMP 'target update' construct}} expected-note {{used here}}
#pragma omp target update from(t), from(t[:5]) // expected-error {{variable can appear only once in OpenMP 'target update' construct}} expected-note {{used here}}
diff --git a/test/OpenMP/target_update_to_messages.cpp b/test/OpenMP/target_update_to_messages.cpp
index 641d0bd949a2..9bde51e9839b 100644
--- a/test/OpenMP/target_update_to_messages.cpp
+++ b/test/OpenMP/target_update_to_messages.cpp
@@ -14,8 +14,8 @@ class S2 {
public:
S2():a(0) { }
S2(S2 &s2):a(s2.a) { }
- static float S2s; // expected-note 4 {{mappable type cannot contain static members}}
- static const float S2sc; // expected-note 4 {{mappable type cannot contain static members}}
+ static float S2s;
+ static const float S2sc;
};
const float S2::S2sc = 0;
const S2 b;
@@ -94,8 +94,8 @@ T tmain(T argc) {
#pragma omp target update to(y x) // expected-error {{expected ',' or ')' in 'to' clause}}
#pragma omp target update to(argc > 0 ? x : y) // expected-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}}
#pragma omp target update to(S1) // expected-error {{'S1' does not refer to a value}}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
-#pragma omp target update to(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} expected-error 2 {{type 'S2' is not mappable to target}}
-#pragma omp target update to(ba) // expected-error 2 {{type 'S2' is not mappable to target}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update to(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}}
+#pragma omp target update to(ba)
#pragma omp target update to(h) // expected-error {{threadprivate variables are not allowed in 'to' clause}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
#pragma omp target update to(k), from(k) // expected-error 2 {{variable can appear only once in OpenMP 'target update' construct}} expected-note 2 {{used here}}
#pragma omp target update to(t), to(t[:5]) // expected-error 2 {{variable can appear only once in OpenMP 'target update' construct}} expected-note 2 {{used here}}
@@ -147,8 +147,8 @@ int main(int argc, char **argv) {
#pragma omp target update to(y x) // expected-error {{expected ',' or ')' in 'to' clause}}
#pragma omp target update to(argc > 0 ? x : y) // expected-error {{expected expression containing only member accesses and/or array sections based on named variables}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
#pragma omp target update to(S1) // expected-error {{'S1' does not refer to a value}}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
-#pragma omp target update to(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} expected-error 2 {{type 'S2' is not mappable to target}}
-#pragma omp target update to(ba) // expected-error 2 {{type 'S2' is not mappable to target}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update to(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}}
+#pragma omp target update to(ba)
#pragma omp target update to(h) // expected-error {{threadprivate variables are not allowed in 'to' clause}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
#pragma omp target update to(k), from(k) // expected-error {{variable can appear only once in OpenMP 'target update' construct}} expected-note {{used here}}
#pragma omp target update to(t), to(t[:5]) // expected-error {{variable can appear only once in OpenMP 'target update' construct}} expected-note {{used here}}
diff --git a/test/OpenMP/target_vla_messages.cpp b/test/OpenMP/target_vla_messages.cpp
new file mode 100644
index 000000000000..c970d0def661
--- /dev/null
+++ b/test/OpenMP/target_vla_messages.cpp
@@ -0,0 +1,201 @@
+// PowerPC supports VLAs.
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-unknown-unknown -emit-llvm-bc %s -o %t-ppc-host-ppc.bc
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-unknown-unknown -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host-ppc.bc -o %t-ppc-device.ll
+
+// Nvidia GPUs don't support VLAs.
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host-nvptx.bc
+// RUN: %clang_cc1 -verify -DNO_VLA -fopenmp -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host-nvptx.bc -o %t-nvptx-device.ll
+
+#ifndef NO_VLA
+// expected-no-diagnostics
+#endif
+
+#pragma omp declare target
+void declare(int arg) {
+ int a[2];
+#ifdef NO_VLA
+ // expected-error@+2 {{variable length arrays are not supported for the current target}}
+#endif
+ int vla[arg];
+}
+
+void declare_parallel_reduction(int arg) {
+ int a[2];
+
+#pragma omp parallel reduction(+: a)
+ { }
+
+#pragma omp parallel reduction(+: a[0:2])
+ { }
+
+#ifdef NO_VLA
+ // expected-error@+3 {{cannot generate code for reduction on array section, which requires a variable length array}}
+ // expected-note@+2 {{variable length arrays are not supported for the current target}}
+#endif
+#pragma omp parallel reduction(+: a[0:arg])
+ { }
+}
+#pragma omp end declare target
+
+template <typename T>
+void target_template(int arg) {
+#pragma omp target
+ {
+#ifdef NO_VLA
+ // expected-error@+2 {{variable length arrays are not supported for the current target}}
+#endif
+ T vla[arg];
+ }
+}
+
+void target(int arg) {
+#pragma omp target
+ {
+#ifdef NO_VLA
+ // expected-error@+2 {{variable length arrays are not supported for the current target}}
+#endif
+ int vla[arg];
+ }
+
+#pragma omp target
+ {
+#pragma omp parallel
+ {
+#ifdef NO_VLA
+ // expected-error@+2 {{variable length arrays are not supported for the current target}}
+#endif
+ int vla[arg];
+ }
+ }
+
+ target_template<long>(arg);
+}
+
+void teams_reduction(int arg) {
+ int a[2];
+ int vla[arg];
+
+#pragma omp target map(a)
+#pragma omp teams reduction(+: a)
+ { }
+
+#ifdef NO_VLA
+ // expected-error@+4 {{cannot generate code for reduction on variable length array}}
+ // expected-note@+3 {{variable length arrays are not supported for the current target}}
+#endif
+#pragma omp target map(vla)
+#pragma omp teams reduction(+: vla)
+ { }
+
+#pragma omp target map(a[0:2])
+#pragma omp teams reduction(+: a[0:2])
+ { }
+
+#pragma omp target map(vla[0:2])
+#pragma omp teams reduction(+: vla[0:2])
+ { }
+
+#ifdef NO_VLA
+ // expected-error@+4 {{cannot generate code for reduction on array section, which requires a variable length array}}
+ // expected-note@+3 {{variable length arrays are not supported for the current target}}
+#endif
+#pragma omp target map(a[0:arg])
+#pragma omp teams reduction(+: a[0:arg])
+ { }
+
+#ifdef NO_VLA
+ // expected-error@+4 {{cannot generate code for reduction on array section, which requires a variable length array}}
+ // expected-note@+3 {{variable length arrays are not supported for the current target}}
+#endif
+#pragma omp target map(vla[0:arg])
+#pragma omp teams reduction(+: vla[0:arg])
+ { }
+}
+
+void parallel_reduction(int arg) {
+ int a[2];
+ int vla[arg];
+
+#pragma omp target map(a)
+#pragma omp parallel reduction(+: a)
+ { }
+
+#ifdef NO_VLA
+ // expected-error@+4 {{cannot generate code for reduction on variable length array}}
+ // expected-note@+3 {{variable length arrays are not supported for the current target}}
+#endif
+#pragma omp target map(vla)
+#pragma omp parallel reduction(+: vla)
+ { }
+
+#pragma omp target map(a[0:2])
+#pragma omp parallel reduction(+: a[0:2])
+ { }
+
+#pragma omp target map(vla[0:2])
+#pragma omp parallel reduction(+: vla[0:2])
+ { }
+
+#ifdef NO_VLA
+ // expected-error@+4 {{cannot generate code for reduction on array section, which requires a variable length array}}
+ // expected-note@+3 {{variable length arrays are not supported for the current target}}
+#endif
+#pragma omp target map(a[0:arg])
+#pragma omp parallel reduction(+: a[0:arg])
+ { }
+
+#ifdef NO_VLA
+ // expected-error@+4 {{cannot generate code for reduction on array section, which requires a variable length array}}
+ // expected-note@+3 {{variable length arrays are not supported for the current target}}
+#endif
+#pragma omp target map(vla[0:arg])
+#pragma omp parallel reduction(+: vla[0:arg])
+ { }
+}
+
+void for_reduction(int arg) {
+ int a[2];
+ int vla[arg];
+
+#pragma omp target map(a)
+#pragma omp parallel
+#pragma omp for reduction(+: a)
+ for (int i = 0; i < arg; i++) ;
+
+#ifdef NO_VLA
+ // expected-error@+5 {{cannot generate code for reduction on variable length array}}
+ // expected-note@+4 {{variable length arrays are not supported for the current target}}
+#endif
+#pragma omp target map(vla)
+#pragma omp parallel
+#pragma omp for reduction(+: vla)
+ for (int i = 0; i < arg; i++) ;
+
+#pragma omp target map(a[0:2])
+#pragma omp parallel
+#pragma omp for reduction(+: a[0:2])
+ for (int i = 0; i < arg; i++) ;
+
+#pragma omp target map(vla[0:2])
+#pragma omp parallel
+#pragma omp for reduction(+: vla[0:2])
+ for (int i = 0; i < arg; i++) ;
+
+#ifdef NO_VLA
+ // expected-error@+5 {{cannot generate code for reduction on array section, which requires a variable length array}}
+ // expected-note@+4 {{variable length arrays are not supported for the current target}}
+#endif
+#pragma omp target map(a[0:arg])
+#pragma omp parallel
+#pragma omp for reduction(+: a[0:arg])
+ for (int i = 0; i < arg; i++) ;
+
+#ifdef NO_VLA
+ // expected-error@+5 {{cannot generate code for reduction on array section, which requires a variable length array}}
+ // expected-note@+4 {{variable length arrays are not supported for the current target}}
+#endif
+#pragma omp target map(vla[0:arg])
+#pragma omp parallel
+#pragma omp for reduction(+: vla[0:arg])
+ for (int i = 0; i < arg; i++) ;
+}
diff --git a/test/OpenMP/task_ast_print.cpp b/test/OpenMP/task_ast_print.cpp
index 9a7d64ee5462..54c05d8ed410 100644
--- a/test/OpenMP/task_ast_print.cpp
+++ b/test/OpenMP/task_ast_print.cpp
@@ -13,17 +13,19 @@ struct S1 {
S1(int v) : a(v) {}
int a;
typedef int type;
+ S1 operator +(const S1&);
};
template <typename T>
class S7 : public T {
protected:
- T a;
+ T a, b;
S7() : a(0) {}
public:
S7(typename T::type v) : a(v) {
-#pragma omp task private(a) private(this->a) private(T::a)
+#pragma omp taskgroup task_reduction(+:b)
+#pragma omp task private(a) private(this->a) private(T::a) in_reduction(+:this->b)
for (int k = 0; k < a.a; ++k)
++this->a.a;
}
@@ -35,7 +37,8 @@ public:
}
};
-// CHECK: #pragma omp task private(this->a) private(this->a) private(T::a)
+// CHECK: #pragma omp taskgroup task_reduction(+: this->b)
+// CHECK: #pragma omp task private(this->a) private(this->a) private(T::a) in_reduction(+: this->b)
// CHECK: #pragma omp task private(this->a) private(this->a)
// CHECK: #pragma omp task private(this->a) private(this->a) private(this->S1::a)
@@ -89,7 +92,8 @@ T tmain(T argc, T *argv) {
a = 2;
#pragma omp task default(none), private(argc, b) firstprivate(argv) shared(d) if (argc > 0) final(S<T>::TS > 0) priority(argc)
foo();
-#pragma omp task if (C) mergeable priority(C)
+#pragma omp taskgroup task_reduction(-: argc)
+#pragma omp task if (C) mergeable priority(C) in_reduction(-: argc)
foo();
return 0;
}
@@ -103,7 +107,8 @@ T tmain(T argc, T *argv) {
// CHECK-NEXT: a = 2;
// CHECK-NEXT: #pragma omp task default(none) private(argc,b) firstprivate(argv) shared(d) if(argc > 0) final(S<T>::TS > 0) priority(argc)
// CHECK-NEXT: foo()
-// CHECK-NEXT: #pragma omp task if(C) mergeable priority(C)
+// CHECK-NEXT: #pragma omp taskgroup task_reduction(-: argc)
+// CHECK-NEXT: #pragma omp task if(C) mergeable priority(C) in_reduction(-: argc)
// CHECK-NEXT: foo()
// CHECK: template<> int tmain<int, 5>(int argc, int *argv) {
// CHECK-NEXT: int b = argc, c, d, e, f, g;
@@ -114,7 +119,8 @@ T tmain(T argc, T *argv) {
// CHECK-NEXT: a = 2;
// CHECK-NEXT: #pragma omp task default(none) private(argc,b) firstprivate(argv) shared(d) if(argc > 0) final(S<int>::TS > 0) priority(argc)
// CHECK-NEXT: foo()
-// CHECK-NEXT: #pragma omp task if(5) mergeable priority(5)
+// CHECK-NEXT: #pragma omp taskgroup task_reduction(-: argc)
+// CHECK-NEXT: #pragma omp task if(5) mergeable priority(5) in_reduction(-: argc)
// CHECK-NEXT: foo()
// CHECK: template<> long tmain<long, 1>(long argc, long *argv) {
// CHECK-NEXT: long b = argc, c, d, e, f, g;
@@ -125,7 +131,8 @@ T tmain(T argc, T *argv) {
// CHECK-NEXT: a = 2;
// CHECK-NEXT: #pragma omp task default(none) private(argc,b) firstprivate(argv) shared(d) if(argc > 0) final(S<long>::TS > 0) priority(argc)
// CHECK-NEXT: foo()
-// CHECK-NEXT: #pragma omp task if(1) mergeable priority(1)
+// CHECK-NEXT: #pragma omp taskgroup task_reduction(-: argc)
+// CHECK-NEXT: #pragma omp task if(1) mergeable priority(1) in_reduction(-: argc)
// CHECK-NEXT: foo()
enum Enum {};
@@ -134,7 +141,7 @@ int main(int argc, char **argv) {
long x;
int b = argc, c, d, e, f, g;
static int a;
- int arr[10];
+ int arr[10], arr1[argc];
#pragma omp threadprivate(a)
Enum ee;
// CHECK: Enum ee;
@@ -142,8 +149,18 @@ int main(int argc, char **argv) {
// CHECK-NEXT: #pragma omp task untied mergeable depend(out : argv[:a][1],(arr)[0:]) if(task: argc > 0) priority(f)
a = 2;
// CHECK-NEXT: a = 2;
-#pragma omp task default(none), private(argc, b) firstprivate(argv) if (argc > 0) final(a > 0) depend(inout : a, argv[:argc],arr[:a]) priority(23)
- // CHECK-NEXT: #pragma omp task default(none) private(argc,b) firstprivate(argv) if(argc > 0) final(a > 0) depend(inout : a,argv[:argc],arr[:a]) priority(23)
+#pragma omp taskgroup task_reduction(min: arr1)
+#pragma omp task default(none), private(argc, b) firstprivate(argv) if (argc > 0) final(a > 0) depend(inout : a, argv[:argc],arr[:a]) priority(23) in_reduction(min: arr1)
+ // CHECK-NEXT: #pragma omp taskgroup task_reduction(min: arr1)
+ // CHECK-NEXT: #pragma omp task default(none) private(argc,b) firstprivate(argv) if(argc > 0) final(a > 0) depend(inout : a,argv[:argc],arr[:a]) priority(23) in_reduction(min: arr1)
+ foo();
+ // CHECK-NEXT: foo();
+#pragma omp taskgroup task_reduction(min: arr1)
+#pragma omp parallel reduction(+:arr1)
+#pragma omp task in_reduction(min: arr1)
+ // CHECK-NEXT: #pragma omp taskgroup task_reduction(min: arr1)
+ // CHECK-NEXT: #pragma omp parallel reduction(+: arr1)
+ // CHECK-NEXT: #pragma omp task in_reduction(min: arr1)
foo();
// CHECK-NEXT: foo();
return tmain<int, 5>(b, &b) + tmain<long, 1>(x, &x);
diff --git a/test/OpenMP/task_depend_messages.cpp b/test/OpenMP/task_depend_messages.cpp
index 576738ceac46..1e51b479dd96 100644
--- a/test/OpenMP/task_depend_messages.cpp
+++ b/test/OpenMP/task_depend_messages.cpp
@@ -28,14 +28,14 @@ int main(int argc, char **argv, char *env[]) {
#pragma omp task depend (source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}}
#pragma omp task depend (in : argc)) // expected-warning {{extra tokens at the end of '#pragma omp task' are ignored}}
#pragma omp task depend (out: ) // expected-error {{expected expression}}
- #pragma omp task depend (inout : foobool(argc)), depend (in, argc) // expected-error {{expected variable name, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}}
+ #pragma omp task depend (inout : foobool(argc)), depend (in, argc) // expected-error {{expected addressable lvalue expression, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}}
#pragma omp task depend (out :S1) // expected-error {{'S1' does not refer to a value}}
- #pragma omp task depend(in : argv[1][1] = '2') // expected-error {{expected variable name, array element or array section}}
- #pragma omp task depend (in : vec[1]) // expected-error {{expected variable name, array element or array section}}
+ #pragma omp task depend(in : argv[1][1] = '2')
+ #pragma omp task depend (in : vec[1]) // expected-error {{expected addressable lvalue expression, array element or array section}}
#pragma omp task depend (in : argv[0])
#pragma omp task depend (in : ) // expected-error {{expected expression}}
- #pragma omp task depend (in : main) // expected-error {{expected variable name, array element or array section}}
- #pragma omp task depend(in : a[0]) // expected-error{{expected variable name, array element or array section}}
+ #pragma omp task depend (in : main)
+ #pragma omp task depend(in : a[0]) // expected-error{{expected addressable lvalue expression, array element or array section}}
#pragma omp task depend (in : vec[1:2]) // expected-error {{ value is not an array or pointer}}
#pragma omp task depend (in : argv[ // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}}
#pragma omp task depend (in : argv[: // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}}
diff --git a/test/OpenMP/task_in_reduction_codegen.cpp b/test/OpenMP/task_in_reduction_codegen.cpp
new file mode 100644
index 000000000000..2ad013a14a57
--- /dev/null
+++ b/test/OpenMP/task_in_reduction_codegen.cpp
@@ -0,0 +1,81 @@
+// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp -x c++ -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-apple-darwin10 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-apple-darwin10 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+// CHECK: [[PRIVATES:%.+]] = type { i8*, i8* }
+
+struct S {
+ int a;
+ S() : a(0) {}
+ S(const S&) {}
+ S& operator=(const S&) {return *this;}
+ ~S() {}
+ friend S operator+(const S&a, const S&b) {return a;}
+};
+
+
+int main(int argc, char **argv) {
+ int a;
+ float b;
+ S c[5];
+ short d[argc];
+#pragma omp taskgroup task_reduction(+: a, b, argc)
+ {
+#pragma omp taskgroup task_reduction(-:c, d)
+#pragma omp parallel
+#pragma omp task in_reduction(+:a) in_reduction(-:d)
+ a += d[a];
+ }
+ return 0;
+}
+
+// CHECK-LABEL: @main
+// CHECK: void @__kmpc_taskgroup(%ident_t* @0, i32 [[GTID:%.+]])
+// CHECK: [[TD1:%.+]] = call i8* @__kmpc_task_reduction_init(i32 [[GTID]], i32 3, i8* %
+// CHECK-NEXT: store i8* [[TD1]], i8** [[TD1_ADDR:%[^,]+]],
+// CHECK-NEXT: call void @__kmpc_taskgroup(%ident_t* @0, i32 [[GTID]])
+// CHECK: [[TD2:%.+]] = call i8* @__kmpc_task_reduction_init(i32 [[GTID]], i32 2, i8* %
+// CHECK-NEXT: store i8* [[TD2]], i8** [[TD2_ADDR:%[^,]+]],
+// CHECK-NEXT: call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* @0, i32 5, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*, i64, i16*, i8**, i8**)* [[OMP_PARALLEL:@.+]] to void (i32*, i32*, ...)*), i32* %{{.+}}, i64 %{{.+}}, i16* %{{.+}}, i8** [[TD1_ADDR]], i8** [[TD2_ADDR]])
+// CHECK-NEXT: call void @__kmpc_end_taskgroup(%ident_t* @0, i32 [[GTID]])
+// CHECK-NEXT: call void @__kmpc_end_taskgroup(%ident_t* @0, i32 [[GTID]])
+
+// CHECK: define internal void [[OMP_PARALLEL]](
+// CHECK: [[TASK_T:%.+]] = call i8* @__kmpc_omp_task_alloc(%ident_t* @0, i32 [[GTID:%.+]], i32 1, i64 56, i64 40, i32 (i32, i8*)* bitcast (i32 (i32, [[T:%.+]]*)* [[OMP_TASK:@.+]] to i32 (i32, i8*)*))
+// CHECK-NEXT: [[TASK_T_WITH_PRIVS:%.+]] = bitcast i8* [[TASK_T]] to [[T]]*
+// CHECK: [[PRIVS:%.+]] = getelementptr inbounds [[T]], [[T]]* [[TASK_T_WITH_PRIVS]], i32 0, i32 1
+// CHECK: [[TD1_REF:%.+]] = getelementptr inbounds [[PRIVATES]], [[PRIVATES]]* [[PRIVS]], i32 0, i32 0
+// CHECK-NEXT: [[TD1_SHAR:%.+]] = getelementptr inbounds %
+// CHECK-NEXT: [[TD1_ADDR:%.+]] = load i8**, i8*** [[TD1_SHAR]],
+// CHECK-NEXT: [[TD1:%.+]] = load i8*, i8** [[TD1_ADDR]],
+// CHECK-NEXT: store i8* [[TD1]], i8** [[TD1_REF]],
+// CHECK-NEXT: [[TD2_REF:%.+]] = getelementptr inbounds [[PRIVATES]], [[PRIVATES]]* [[PRIVS]], i32 0, i32 1
+// CHECK-NEXT: [[TD2_SHAR:%.+]] = getelementptr inbounds %
+// CHECK-NEXT: [[TD2_ADDR:%.+]] = load i8**, i8*** [[TD2_SHAR]],
+// CHECK-NEXT: [[TD2:%.+]] = load i8*, i8** [[TD2_ADDR]],
+// CHECK-NEXT: store i8* [[TD2]], i8** [[TD2_REF]],
+// CHECK-NEXT: call i32 @__kmpc_omp_task(%ident_t* @0, i32 [[GTID]], i8* [[TASK_T]])
+// CHECK-NEXT: ret void
+// CHECK-NEXT: }
+
+// CHECK: define internal {{.*}} [[OMP_TASK]](
+// CHECK: call void (i8*, ...) %{{[^(]+}}(i8* %{{.+}}, i8*** [[TD1_REF:%[^,]+]], i8*** [[TD2_REF:%[^,]+]])
+// CHECK-NEXT: [[TD1_ADDR:%.+]] = load i8**, i8*** [[TD1_REF]],
+// CHECK-NEXT: [[TD2_ADDR:%.+]] = load i8**, i8*** [[TD2_REF]],
+// CHECK-NEXT: [[A_REF:%.+]] = getelementptr inbounds %
+// CHECK-NEXT: [[A_ADDR:%.+]] = load i32*, i32** [[A_REF]],
+// CHECK-NEXT: [[TD1:%.+]] = load i8*, i8** [[TD1_ADDR]],
+// CHECK-NEXT: [[GTID:%.+]] = load i32, i32* %
+// CHECK-NEXT: [[A_PTR:%.+]] = bitcast i32* [[A_ADDR]] to i8*
+// CHECK-NEXT: call i8* @__kmpc_task_reduction_get_th_data(i32 [[GTID]], i8* [[TD1]], i8* [[A_PTR]])
+// CHECK: [[D_REF:%.+]] = getelementptr inbounds %
+// CHECK-NEXT: [[D_ADDR:%.+]] = load i16*, i16** [[D_REF]],
+// CHECK: [[TD2:%.+]] = load i8*, i8** [[TD2_ADDR]],
+// CHECK-NEXT: [[D_PTR:%.+]] = bitcast i16* [[D_ADDR]] to i8*
+// CHECK-NEXT: call i8* @__kmpc_task_reduction_get_th_data(i32 [[GTID]], i8* [[TD2]], i8* [[D_PTR]])
+// CHECK: add nsw i32
+// CHECK: store i32 %
+#endif
diff --git a/test/OpenMP/task_in_reduction_message.cpp b/test/OpenMP/task_in_reduction_message.cpp
new file mode 100644
index 000000000000..e176dc9305b3
--- /dev/null
+++ b/test/OpenMP/task_in_reduction_message.cpp
@@ -0,0 +1,308 @@
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 150 -o - %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++98 -ferror-limit 150 -o - %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 -ferror-limit 150 -o - %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+void foobar(int &ref) {
+#pragma omp taskgroup task_reduction(+:ref)
+#pragma omp task in_reduction(+:ref)
+ foo();
+}
+
+void foobar1(int &ref) {
+#pragma omp taskgroup task_reduction(+:ref)
+#pragma omp task in_reduction(-:ref)
+ foo();
+}
+
+#pragma omp declare reduction (red:int:omp_out += omp_in)
+
+void foobar2(int &ref) {
+#pragma omp taskgroup task_reduction(+:ref) // expected-note {{previously marked as task_reduction with different reduction operation}}
+#pragma omp task in_reduction(red:ref) // expected-error{{in_reduction variable must have the same reduction operation as in a task_reduction clause}}
+ foo();
+}
+
+void foobar3(int &ref) {
+#pragma omp taskgroup task_reduction(red:ref) // expected-note {{previously marked as task_reduction with different reduction operation}}
+#pragma omp task in_reduction(min:ref) // expected-error{{in_reduction variable must have the same reduction operation as in a task_reduction clause}}
+ foo();
+}
+
+void foobar4(int &ref) {
+#pragma omp task in_reduction(min:ref) // expected-error {{in_reduction variable must appear in a task_reduction clause}}
+ foo();
+}
+
+struct S1; // expected-note {{declared here}} expected-note 4 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+ mutable int a;
+ S2 &operator+(const S2 &arg) { return (*this); } // expected-note 3 {{implicitly declared private here}}
+
+public:
+ S2() : a(0) {}
+ S2(S2 &s2) : a(s2.a) {}
+ static float S2s; // expected-note 2 {{static data member is predetermined as shared}}
+ static const float S2sc; // expected-note 2 {{'S2sc' declared here}}
+};
+const float S2::S2sc = 0;
+S2 b; // expected-note 3 {{'b' defined here}}
+const S2 ba[5]; // expected-note 2 {{'ba' defined here}}
+class S3 {
+ int a;
+
+public:
+ int b;
+ S3() : a(0) {}
+ S3(const S3 &s3) : a(s3.a) {}
+ S3 operator+(const S3 &arg1) { return arg1; }
+};
+int operator+(const S3 &arg1, const S3 &arg2) { return 5; }
+S3 c; // expected-note 3 {{'c' defined here}}
+const S3 ca[5]; // expected-note 2 {{'ca' defined here}}
+extern const int f; // expected-note 4 {{'f' declared here}}
+class S4 {
+ int a;
+ S4(); // expected-note {{implicitly declared private here}}
+ S4(const S4 &s4);
+ S4 &operator+(const S4 &arg) { return (*this); }
+
+public:
+ S4(int v) : a(v) {}
+};
+S4 &operator&=(S4 &arg1, S4 &arg2) { return arg1; }
+class S5 {
+ int a;
+ S5() : a(0) {} // expected-note {{implicitly declared private here}}
+ S5(const S5 &s5) : a(s5.a) {}
+ S5 &operator+(const S5 &arg);
+
+public:
+ S5(int v) : a(v) {}
+};
+class S6 { // expected-note 3 {{candidate function (the implicit copy assignment operator) not viable: no known conversion from 'int' to 'const S6' for 1st argument}}
+#if __cplusplus >= 201103L // C++11 or later
+// expected-note@-2 3 {{candidate function (the implicit move assignment operator) not viable}}
+#endif
+ int a;
+
+public:
+ S6() : a(6) {}
+ operator int() { return 6; }
+} o;
+
+S3 h, k;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class T> // expected-note {{declared here}}
+T tmain(T argc) {
+ const T d = T(); // expected-note 4 {{'d' defined here}}
+ const T da[5] = {T()}; // expected-note 2 {{'da' defined here}}
+ T qa[5] = {T()};
+ T i;
+ T &j = i; // expected-note 2 {{'j' defined here}}
+ S3 &p = k; // expected-note 2 {{'p' defined here}}
+ const T &r = da[(int)i]; // expected-note 2 {{'r' defined here}}
+ T &q = qa[(int)i];
+ T fl;
+#pragma omp taskgroup task_reduction(+:argc)
+#pragma omp task in_reduction // expected-error {{expected '(' after 'in_reduction'}}
+ foo();
+#pragma omp taskgroup task_reduction(+:argc)
+#pragma omp task in_reduction + // expected-error {{expected '(' after 'in_reduction'}} expected-warning {{extra tokens at the end of '#pragma omp task' are ignored}}
+ foo();
+#pragma omp taskgroup task_reduction(+:argc)
+#pragma omp task in_reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+#pragma omp taskgroup task_reduction(+:argc)
+#pragma omp task in_reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+#pragma omp taskgroup task_reduction(+:argc)
+#pragma omp task in_reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+ foo();
+#pragma omp taskgroup task_reduction(+:argc)
+#pragma omp task in_reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}}
+ foo();
+#pragma omp taskgroup task_reduction(+:argc)
+#pragma omp task in_reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+ foo();
+#pragma omp taskgroup task_reduction(&:argc) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
+#pragma omp task in_reduction(& : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{invalid operands to binary expression ('float' and 'float')}}
+ foo();
+#pragma omp taskgroup task_reduction(|:argc) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
+#pragma omp task in_reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{invalid operands to binary expression ('float' and 'float')}}
+ foo();
+#pragma omp task in_reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name, array element or array section}}
+ foo();
+#pragma omp task in_reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}}
+ foo();
+#pragma omp taskgroup task_reduction(&&:argc)
+#pragma omp task in_reduction(&& : argc)
+ foo();
+#pragma omp task in_reduction(^ : T) // expected-error {{'T' does not refer to a value}}
+ foo();
+#pragma omp taskgroup task_reduction(+:c)
+#pragma omp task in_reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}} expected-error 2 {{in_reduction variable must appear in a task_reduction clause}}
+ foo();
+#pragma omp task in_reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'in_reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}}
+ foo();
+#pragma omp task in_reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
+ foo();
+#pragma omp task in_reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+ foo();
+#pragma omp task in_reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+ foo();
+#pragma omp task in_reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}}
+ foo();
+#pragma omp task in_reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} expected-error {{in_reduction variable must appear in a task_reduction clause}}
+ foo();
+#pragma omp task in_reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
+ foo();
+#pragma omp task in_reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+ foo();
+#pragma omp taskgroup task_reduction(+:k)
+#pragma omp task in_reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}}
+ foo();
+#pragma omp task in_reduction(+ : o) // expected-error 2 {{no viable overloaded '='}}
+ foo();
+#pragma omp parallel private(k)
+#pragma omp task in_reduction(+ : p), in_reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'in_reduction' must reference the same object in all threads}}
+ foo();
+#pragma omp taskgroup task_reduction(+:p)
+#pragma omp task in_reduction(+ : p), in_reduction(+ : p) // expected-error 2 {{variable can appear only once in OpenMP 'in_reduction' clause}} expected-note 2 {{previously referenced here}}
+ foo();
+#pragma omp task in_reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}}
+ foo();
+#pragma omp parallel shared(i)
+#pragma omp parallel reduction(min : i)
+#pragma omp task in_reduction(max : j) // expected-error 2 {{argument of OpenMP clause 'in_reduction' must reference the same object in all threads}}
+ foo();
+#pragma omp taskgroup task_reduction(+:fl)
+#pragma omp task in_reduction(+ : fl)
+ foo();
+#pragma omp parallel
+#pragma omp for reduction(- : fl)
+ for (int i = 0; i < 10; ++i)
+#pragma omp taskgroup task_reduction(+:fl)
+#pragma omp task in_reduction(+ : fl)
+ foo();
+
+ return T();
+}
+
+namespace A {
+double x;
+#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}}
+}
+namespace B {
+using A::x;
+}
+
+int main(int argc, char **argv) {
+ const int d = 5; // expected-note 2 {{'d' defined here}}
+ const int da[5] = {0}; // expected-note {{'da' defined here}}
+ int qa[5] = {0};
+ S4 e(4);
+ S5 g(5);
+ int i;
+ int &j = i; // expected-note {{'j' defined here}}
+ S3 &p = k; // expected-note 2 {{'p' defined here}}
+ const int &r = da[i]; // expected-note {{'r' defined here}}
+ int &q = qa[i];
+ float fl;
+#pragma omp task in_reduction // expected-error {{expected '(' after 'in_reduction'}}
+ foo();
+#pragma omp task in_reduction + // expected-error {{expected '(' after 'in_reduction'}} expected-warning {{extra tokens at the end of '#pragma omp task' are ignored}}
+ foo();
+#pragma omp task in_reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+#pragma omp task in_reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+#pragma omp task in_reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+ foo();
+#pragma omp task in_reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}}
+ foo();
+#pragma omp task in_reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+ foo();
+#pragma omp task in_reduction(foo : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}}
+ foo();
+#pragma omp taskgroup task_reduction(|:argc)
+{
+#pragma omp taskgroup task_reduction(+:argc) // expected-note {{previously marked as task_reduction with different reduction operation}}
+{
+#pragma omp task in_reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{in_reduction variable must have the same reduction operation as in a task_reduction clause}}
+ foo();
+}
+#pragma omp task in_reduction(| : argc)
+ foo();
+}
+#pragma omp task in_reduction(|| : argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name, array element or array section}}
+ foo();
+#pragma omp task in_reduction(~ : argc) // expected-error {{expected unqualified-id}}
+ foo();
+#pragma omp taskgroup task_reduction(&&:argc)
+#pragma omp task in_reduction(&& : argc)
+ foo();
+#pragma omp task in_reduction(^ : S1) // expected-error {{'S1' does not refer to a value}}
+ foo();
+#pragma omp taskgroup task_reduction(+:c)
+#pragma omp task in_reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified list item cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}} expected-error {{in_reduction variable must appear in a task_reduction clause}}
+ foo();
+#pragma omp task in_reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'in_reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified list item cannot be reduction}}
+ foo();
+#pragma omp task in_reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
+ foo();
+#pragma omp task in_reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+ foo();
+#pragma omp task in_reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+ foo();
+#pragma omp task in_reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}}
+ foo();
+#pragma omp task in_reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
+ foo();
+#pragma omp task in_reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
+ foo();
+#pragma omp task in_reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+ foo();
+#pragma omp task in_reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{nvalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
+ foo();
+#pragma omp taskgroup task_reduction(+:k)
+#pragma omp task in_reduction(+ : h, k, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be reduction}}
+ foo();
+#pragma omp task in_reduction(+ : o) // expected-error {{no viable overloaded '='}}
+ foo();
+#pragma omp parallel private(k)
+#pragma omp task in_reduction(+ : p), in_reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'in_reduction' must reference the same object in all threads}}
+ foo();
+#pragma omp taskgroup task_reduction(+:p)
+#pragma omp task in_reduction(+ : p), in_reduction(+ : p) // expected-error {{variable can appear only once in OpenMP 'in_reduction' clause}} expected-note {{previously referenced here}}
+ foo();
+#pragma omp task in_reduction(+ : r) // expected-error {{const-qualified list item cannot be reduction}}
+ foo();
+#pragma omp parallel shared(i)
+#pragma omp parallel reduction(min : i)
+#pragma omp task in_reduction(max : j) // expected-error {{argument of OpenMP clause 'in_reduction' must reference the same object in all threads}}
+ foo();
+#pragma omp parallel
+#pragma omp for private(fl)
+ for (int i = 0; i < 10; ++i)
+#pragma omp taskgroup task_reduction(+:fl)
+#pragma omp task in_reduction(+ : fl)
+ foo();
+#pragma omp taskgroup task_reduction(+:fl)
+#pragma omp task in_reduction(+ : fl)
+ foo();
+ static int m;
+#pragma omp taskgroup task_reduction(+:m)
+#pragma omp task in_reduction(+ : m) // OK
+ m++;
+
+ return tmain(argc) + tmain(fl); // expected-note {{in instantiation of function template specialization 'tmain<int>' requested here}} expected-note {{in instantiation of function template specialization 'tmain<float>' requested here}}
+}
diff --git a/test/OpenMP/taskgroup_task_reduction_codegen.cpp b/test/OpenMP/taskgroup_task_reduction_codegen.cpp
new file mode 100644
index 000000000000..63e015182420
--- /dev/null
+++ b/test/OpenMP/taskgroup_task_reduction_codegen.cpp
@@ -0,0 +1,212 @@
+// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp -x c++ -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-apple-darwin10 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-apple-darwin10 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ %s -verify -debug-info-kind=limited -emit-llvm -o - -triple x86_64-apple-darwin10 | FileCheck %s --check-prefix=CHECK --check-prefix=DEBUG
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+struct S {
+ int a;
+ S() : a(0) {}
+ S(const S&) {}
+ S& operator=(const S&) {return *this;}
+ ~S() {}
+ friend S operator+(const S&a, const S&b) {return a;}
+};
+
+
+int main(int argc, char **argv) {
+ int a;
+ float b;
+ S c[5];
+ short d[argc];
+#pragma omp taskgroup task_reduction(+: a, b, argc)
+ {
+#pragma omp taskgroup task_reduction(-:c, d)
+ ;
+ }
+ return 0;
+}
+// CHECK-LABEL: @main
+// CHECK: alloca i32,
+// CHECK: [[ARGC_ADDR:%.+]] = alloca i32,
+// CHECK: [[ARGV_ADDR:%.+]] = alloca i8**,
+// CHECK: [[A:%.+]] = alloca i32,
+// CHECK: [[B:%.+]] = alloca float,
+// CHECK: [[C:%.+]] = alloca [5 x %struct.S],
+// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num(%ident_t*
+// CHECK: [[RD_IN1:%.+]] = alloca [3 x [[T1:%[^,]+]]],
+// CHECK: [[TD1:%.+]] = alloca i8*,
+// CHECK: [[RD_IN2:%.+]] = alloca [2 x [[T2:%[^,]+]]],
+// CHECK: [[TD2:%.+]] = alloca i8*,
+
+// CHECK: [[VLA:%.+]] = alloca i16, i64 [[VLA_SIZE:%[^,]+]],
+
+// CHECK: call void @__kmpc_taskgroup(%ident_t* {{[^,]+}}, i32 [[GTID]])
+// CHECK-DAG: [[BC_A:%.+]] = bitcast i32* [[A]] to i8*
+// CHECK-DAG: store i8* [[BC_A]], i8** [[A_REF:[^,]+]],
+// CHECK-DAG: [[A_REF]] = getelementptr inbounds [[T1]], [[T1]]* [[GEPA:%[^,]+]], i32 0, i32 0
+// CHECK-DAG: [[GEPA]] = getelementptr inbounds [3 x [[T1]]], [3 x [[T1]]]* [[RD_IN1]], i64 0, i64
+// CHECK-DAG: [[TMP6:%.+]] = getelementptr inbounds [[T1]], [[T1]]* [[GEPA]], i32 0, i32 1
+// CHECK-DAG: store i64 4, i64* [[TMP6]],
+// CHECK-DAG: [[TMP7:%.+]] = getelementptr inbounds [[T1]], [[T1]]* [[GEPA]], i32 0, i32 2
+// CHECK-DAG: store i8* bitcast (void (i8*)* [[AINIT:@.+]] to i8*), i8** [[TMP7]],
+// CHECK-DAG: [[TMP8:%.+]] = getelementptr inbounds [[T1]], [[T1]]* [[GEPA]], i32 0, i32 3
+// CHECK-DAG: store i8* null, i8** [[TMP8]],
+// CHECK-DAG: [[TMP9:%.+]] = getelementptr inbounds [[T1]], [[T1]]* [[GEPA]], i32 0, i32 4
+// CHECK-DAG: store i8* bitcast (void (i8*, i8*)* [[ACOMB:@.+]] to i8*), i8** [[TMP9]],
+// CHECK-DAG: [[TMP10:%.+]] = getelementptr inbounds [[T1]], [[T1]]* [[GEPA]], i32 0, i32 5
+// CHECK-DAG: [[TMP11:%.+]] = bitcast i32* [[TMP10]] to i8*
+// CHECK-DAG: call void @llvm.memset.p0i8.i64(i8* [[TMP11]], i8 0, i64 4, i32 8, i1 false)
+// CHECK-DAG: [[TMP13:%.+]] = bitcast float* [[B]] to i8*
+// CHECK-DAG: store i8* [[TMP13]], i8** [[TMP12:%[^,]+]],
+// CHECK-DAG: [[TMP12]] = getelementptr inbounds [[T1]], [[T1]]* [[GEPB:%[^,]+]], i32 0, i32 0
+// CHECK-DAG: [[GEPB]] = getelementptr inbounds [3 x [[T1]]], [3 x [[T1]]]* [[RD_IN1]], i64 0, i64
+// CHECK-DAG: [[TMP14:%.+]] = getelementptr inbounds [[T1]], [[T1]]* [[GEPB]], i32 0, i32 1
+// CHECK-DAG: store i64 4, i64* [[TMP14]],
+// CHECK-DAG: [[TMP15:%.+]] = getelementptr inbounds [[T1]], [[T1]]* [[GEPB]], i32 0, i32 2
+// CHECK-DAG: store i8* bitcast (void (i8*)* [[BINIT:@.+]] to i8*), i8** [[TMP15]],
+// CHECK-DAG: [[TMP16:%.+]] = getelementptr inbounds [[T1]], [[T1]]* [[GEPB]], i32 0, i32 3
+// CHECK-DAG: store i8* null, i8** [[TMP16]],
+// CHECK-DAG: [[TMP17:%.+]] = getelementptr inbounds [[T1]], [[T1]]* [[GEPB]], i32 0, i32 4
+// CHECK-DAG: store i8* bitcast (void (i8*, i8*)* [[BCOMB:@.+]] to i8*), i8** [[TMP17]],
+// CHECK-DAG: [[TMP18:%.+]] = getelementptr inbounds [[T1]], [[T1]]* [[GEPB]], i32 0, i32 5
+// CHECK-DAG: [[TMP19:%.+]] = bitcast i32* [[TMP18]] to i8*
+// CHECK-DAG: call void @llvm.memset.p0i8.i64(i8* [[TMP19]], i8 0, i64 4, i32 8, i1 false)
+// CHECK-DAG: [[TMP21:%.+]] = bitcast i32* [[ARGC_ADDR]] to i8*
+// CHECK-DAG: store i8* [[TMP21]], i8** [[TMP20:%[^,]+]],
+// CHECK-DAG: [[TMP20]] = getelementptr inbounds [[T1]], [[T1]]* [[GEPARGC:%[^,]+]], i32 0, i32 0
+// CHECK-DAG: [[GEPARGC]] = getelementptr inbounds [3 x [[T1]]], [3 x [[T1]]]* [[RD_IN1]], i64 0, i64
+// CHECK-DAG: [[TMP22:%.+]] = getelementptr inbounds [[T1]], [[T1]]* [[GEPARGC]], i32 0, i32 1
+// CHECK-DAG: store i64 4, i64* [[TMP22]],
+// CHECK-DAG: [[TMP23:%.+]] = getelementptr inbounds [[T1]], [[T1]]* [[GEPARGC]], i32 0, i32 2
+// CHECK-DAG: store i8* bitcast (void (i8*)* [[ARGCINIT:@.+]] to i8*), i8** [[TMP23]],
+// CHECK-DAG: [[TMP24:%.+]] = getelementptr inbounds [[T1]], [[T1]]* [[GEPARGC]], i32 0, i32 3
+// CHECK-DAG: store i8* null, i8** [[TMP24]],
+// CHECK-DAG: [[TMP25:%.+]] = getelementptr inbounds [[T1]], [[T1]]* [[GEPARGC]], i32 0, i32 4
+// CHECK-DAG: store i8* bitcast (void (i8*, i8*)* [[ARGCCOMB:@.+]] to i8*), i8** [[TMP25]],
+// CHECK-DAG: [[TMP26:%.+]] = getelementptr inbounds [[T1]], [[T1]]* [[GEPARGC]], i32 0, i32 5
+// CHECK-DAG: [[TMP27:%.+]] = bitcast i32* [[TMP26]] to i8*
+// CHECK-DAG: call void @llvm.memset.p0i8.i64(i8* [[TMP27]], i8 0, i64 4, i32 8, i1 false)
+// CHECK-DAG: [[TMP28:%.+]] = bitcast [3 x [[T1]]]* [[RD_IN1]] to i8*
+// CHECK-DAG: [[TMP29:%.+]] = call i8* @__kmpc_task_reduction_init(i32 [[GTID]], i32 3, i8* [[TMP28]])
+// DEBUG-DAG: call void @llvm.dbg.declare(metadata i8** [[TD1]],
+// CHECK-DAG: store i8* [[TMP29]], i8** [[TD1]],
+// CHECK-DAG: call void @__kmpc_taskgroup(%ident_t* {{[^,]+}}, i32 [[GTID]])
+// CHECK-DAG: [[TMP31:%.+]] = bitcast [5 x %struct.S]* [[C]] to i8*
+// CHECK-DAG: store i8* [[TMP31]], i8** [[TMP30:%[^,]+]],
+// CHECK-DAG: [[TMP30]] = getelementptr inbounds [[T2]], [[T2]]* [[GEPC:%[^,]+]], i32 0, i32 0
+// CHECK-DAG: [[GEPC]] = getelementptr inbounds [2 x [[T2]]], [2 x [[T2]]]* [[RD_IN2]], i64 0, i64
+// CHECK-DAG: [[TMP32:%.+]] = getelementptr inbounds [[T2]], [[T2]]* [[GEPC]], i32 0, i32 1
+// CHECK-DAG: store i64 20, i64* [[TMP32]],
+// CHECK-DAG: [[TMP33:%.+]] = getelementptr inbounds [[T2]], [[T2]]* [[GEPC]], i32 0, i32 2
+// CHECK-DAG: store i8* bitcast (void (i8*)* [[CINIT:@.+]] to i8*), i8** [[TMP33]],
+// CHECK-DAG: [[TMP34:%.+]] = getelementptr inbounds [[T2]], [[T2]]* [[GEPC]], i32 0, i32 3
+// CHECK-DAG: store i8* bitcast (void (i8*)* [[CFINI:@.+]] to i8*), i8** [[TMP34]],
+// CHECK-DAG: [[TMP35:%.+]] = getelementptr inbounds [[T2]], [[T2]]* [[GEPC]], i32 0, i32 4
+// CHECK-DAG: store i8* bitcast (void (i8*, i8*)* [[CCOMB:@.+]] to i8*), i8** [[TMP35]],
+// CHECK-DAG: [[TMP36:%.+]] = getelementptr inbounds [[T2]], [[T2]]* [[GEPC]], i32 0, i32 5
+// CHECK-DAG: [[TMP37:%.+]] = bitcast i32* [[TMP36]] to i8*
+// CHECK-DAG: call void @llvm.memset.p0i8.i64(i8* [[TMP37]], i8 0, i64 4, i32 8, i1 false)
+// CHECK-DAG: [[TMP39:%.+]] = bitcast i16* [[VLA]] to i8*
+// CHECK-DAG: store i8* [[TMP39]], i8** [[TMP38:%[^,]+]],
+// CHECK-DAG: [[TMP38]] = getelementptr inbounds [[T2]], [[T2]]* [[GEPVLA:%[^,]+]], i32 0, i32 0
+// CHECK-DAG: [[GEPVLA]] = getelementptr inbounds [2 x [[T2]]], [2 x [[T2]]]* [[RD_IN2]], i64 0, i64
+// CHECK-DAG: [[TMP40:%.+]] = mul nuw i64 [[VLA_SIZE]], 2
+// CHECK-DAG: [[TMP41:%.+]] = udiv exact i64 [[TMP40]], ptrtoint (i16* getelementptr (i16, i16* null, i32 1) to i64)
+// CHECK-DAG: [[TMP42:%.+]] = getelementptr inbounds [[T2]], [[T2]]* [[GEPVLA]], i32 0, i32 1
+// CHECK-DAG: store i64 [[TMP40]], i64* [[TMP42]],
+// CHECK-DAG: [[TMP43:%.+]] = getelementptr inbounds [[T2]], [[T2]]* [[GEPVLA]], i32 0, i32 2
+// CHECK-DAG: store i8* bitcast (void (i8*)* [[VLAINIT:@.+]] to i8*), i8** [[TMP43]],
+// CHECK-DAG: [[TMP44:%.+]] = getelementptr inbounds [[T2]], [[T2]]* [[GEPVLA]], i32 0, i32 3
+// CHECK-DAG: store i8* null, i8** [[TMP44]],
+// CHECK-DAG: [[TMP45:%.+]] = getelementptr inbounds [[T2]], [[T2]]* [[GEPVLA]], i32 0, i32 4
+// CHECK-DAG: store i8* bitcast (void (i8*, i8*)* [[VLACOMB:@.+]] to i8*), i8** [[TMP45]],
+// CHECK-DAG: [[TMP46:%.+]] = getelementptr inbounds [[T2]], [[T2]]* [[GEPVLA]], i32 0, i32 5
+// CHECK-DAG: store i32 1, i32* [[TMP46]],
+// CHECK: [[TMP47:%.+]] = bitcast [2 x [[T2]]]* [[RD_IN2]] to i8*
+// CHECK: [[TMP48:%.+]] = call i8* @__kmpc_task_reduction_init(i32 [[GTID]], i32 2, i8* [[TMP47]])
+// CHECK: store i8* [[TMP48]], i8** [[TD2]],
+// CHECK: call void @__kmpc_end_taskgroup(%ident_t* {{[^,]+}}, i32 [[GTID]])
+// CHECK: call void @__kmpc_end_taskgroup(%ident_t* {{[^,]+}}, i32 [[GTID]])
+
+// CHECK-DAG: define internal void [[AINIT]](i8*)
+// CHECK-DAG: store i32 0, i32* %
+// CHECK-DAG: ret void
+// CHECK-DAG: }
+
+// CHECK-DAG: define internal void [[ACOMB]](i8*, i8*)
+// CHECK-DAG: add nsw i32 %
+// CHECK-DAG: store i32 %
+// CHECK-DAG: ret void
+// CHECK-DAG: }
+
+// CHECK-DAG: define internal void [[BINIT]](i8*)
+// CHECK-DAG: store float 0.000000e+00, float* %
+// CHECK-DAG: ret void
+// CHECK-DAG: }
+
+// CHECK-DAG: define internal void [[BCOMB]](i8*, i8*)
+// CHECK-DAG: fadd float %
+// CHECK-DAG: store float %
+// CHECK-DAG: ret void
+// CHECK-DAG: }
+
+// CHECK-DAG: define internal void [[ARGCINIT]](i8*)
+// CHECK-DAG: store i32 0, i32* %
+// CHECK-DAG: ret void
+// CHECK-DAG: }
+
+// CHECK-DAG: define internal void [[ARGCCOMB]](i8*, i8*)
+// CHECK-DAG: add nsw i32 %
+// CHECK-DAG: store i32 %
+// CHECK-DAG: ret void
+// CHECK-DAG: }
+
+// CHECK-DAG: define internal void [[CINIT]](i8*)
+// CHECK-DAG: phi %struct.S* [
+// CHECK-DAG: call {{.+}}(%struct.S* {{.+}})
+// CHECK-DAG: br i1 %
+// CHECK-DAG: ret void
+// CHECK-DAG: }
+
+// CHECK-DAG: define internal void [[CFINI]](i8*)
+// CHECK-DAG: phi %struct.S* [
+// CHECK-DAG: call {{.+}}(%struct.S* {{.+}})
+// CHECK-DAG: br i1 %
+// CHECK-DAG: ret void
+// CHECK-DAG: }
+
+// CHECK-DAG: define internal void [[CCOMB]](i8*, i8*)
+// CHECK-DAG: phi %struct.S* [
+// CHECK-DAG: phi %struct.S* [
+// CHECK-DAG: call {{.+}}(%struct.S* {{.+}}, %struct.S* {{.+}}, %struct.S* {{.+}})
+// CHECK-DAG: call {{.+}}(%struct.S* {{.+}}, %struct.S* {{.+}})
+// CHECK-DAG: call {{.+}}(%struct.S* {{.+}})
+// CHECK-DAG: br i1 %
+// CHECK-DAG: ret void
+// CHECK_DAG: }
+
+// CHECK-DAG: define internal void [[VLAINIT]](i8*)
+// CHECK-DAG: call i32 @__kmpc_global_thread_num(%ident_t* {{[^,]+}})
+// CHECK-DAG: call i8* @__kmpc_threadprivate_cached(%ident_t*
+// CHECK-DAG: phi i16* [
+// CHECK-DAG: store i16 0, i16* %
+// CHECK-DAG: br i1 %
+// CHECK-DAG: ret void
+// CHECK-DAG: }
+
+// CHECK-DAG: define internal void [[VLACOMB]](i8*, i8*)
+// CHECK-DAG: call i32 @__kmpc_global_thread_num(%ident_t* {{[^,]+}})
+// CHECK-DAG: call i8* @__kmpc_threadprivate_cached(%ident_t*
+// CHECK-DAG: phi i16* [
+// CHECK-DAG: phi i16* [
+// CHECK-DAG: sext i16 %{{.+}} to i32
+// CHECK-DAG: add nsw i32 %
+// CHECK-DAG: trunc i32 %{{.+}} to i16
+// CHECK-DAG: store i16 %
+// CHECK_DAG: br i1 %
+// CHECK-DAG: ret void
+// CHECK-DAG: }
+#endif
diff --git a/test/OpenMP/taskgroup_task_reduction_messages.cpp b/test/OpenMP/taskgroup_task_reduction_messages.cpp
index 9c8177b0bd43..819dc5bdaf68 100644
--- a/test/OpenMP/taskgroup_task_reduction_messages.cpp
+++ b/test/OpenMP/taskgroup_task_reduction_messages.cpp
@@ -24,9 +24,9 @@ public:
S2() : a(0) {}
S2(S2 &s2) : a(s2.a) {}
static float S2s; // expected-note 2 {{static data member is predetermined as shared}}
- static const float S2sc;
+ static const float S2sc; // expected-note 2 {{'S2sc' declared here}}
};
-const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}}
+const float S2::S2sc = 0;
S2 b; // expected-note 3 {{'b' defined here}}
const S2 ba[5]; // expected-note 2 {{'ba' defined here}}
class S3 {
diff --git a/test/OpenMP/taskloop_ast_print.cpp b/test/OpenMP/taskloop_ast_print.cpp
index dd0af85916cf..891b31dce4db 100644
--- a/test/OpenMP/taskloop_ast_print.cpp
+++ b/test/OpenMP/taskloop_ast_print.cpp
@@ -13,8 +13,10 @@ T tmain(T argc) {
T b = argc, c, d, e, f, g;
static T a;
// CHECK: static T a;
-#pragma omp taskloop if(taskloop: argc > N) default(shared) untied priority(N) grainsize(N) reduction(+:g)
- // CHECK-NEXT: #pragma omp taskloop if(taskloop: argc > N) default(shared) untied priority(N) grainsize(N) reduction(+: g)
+#pragma omp taskgroup task_reduction(+: d)
+#pragma omp taskloop if(taskloop: argc > N) default(shared) untied priority(N) grainsize(N) reduction(+:g) in_reduction(+: d)
+ // CHECK-NEXT: #pragma omp taskgroup task_reduction(+: d)
+ // CHECK-NEXT: #pragma omp taskloop if(taskloop: argc > N) default(shared) untied priority(N) grainsize(N) reduction(+: g) in_reduction(+: d)
for (int i = 0; i < 2; ++i)
a = 2;
// CHECK-NEXT: for (int i = 0; i < 2; ++i)
@@ -53,8 +55,10 @@ int main(int argc, char **argv) {
int b = argc, c, d, e, f, g;
static int a;
// CHECK: static int a;
-#pragma omp taskloop if(taskloop: a) default(none) shared(a) final(b) priority(5) num_tasks(argc) reduction(*: g)
- // CHECK-NEXT: #pragma omp taskloop if(taskloop: a) default(none) shared(a) final(b) priority(5) num_tasks(argc) reduction(*: g)
+#pragma omp taskgroup task_reduction(+: d)
+#pragma omp taskloop if(taskloop: a) default(none) shared(a) final(b) priority(5) num_tasks(argc) reduction(*: g) in_reduction(+:d)
+ // CHECK-NEXT: #pragma omp taskgroup task_reduction(+: d)
+ // CHECK-NEXT: #pragma omp taskloop if(taskloop: a) default(none) shared(a) final(b) priority(5) num_tasks(argc) reduction(*: g) in_reduction(+: d)
for (int i = 0; i < 2; ++i)
a = 2;
// CHECK-NEXT: for (int i = 0; i < 2; ++i)
diff --git a/test/OpenMP/taskloop_firstprivate_messages.cpp b/test/OpenMP/taskloop_firstprivate_messages.cpp
index fe22311f650c..e63d6a678b8d 100644
--- a/test/OpenMP/taskloop_firstprivate_messages.cpp
+++ b/test/OpenMP/taskloop_firstprivate_messages.cpp
@@ -295,9 +295,9 @@ int main(int argc, char **argv) {
#pragma omp taskloop firstprivate(i) // expected-note {{defined as firstprivate}}
for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp taskloop' directive may not be firstprivate, predetermined as private}}
foo();
-#pragma omp parallel reduction(+ : i) // expected-note 4 {{defined as reduction}}
+#pragma omp parallel reduction(+ : i) // expected-note 2 {{defined as reduction}}
#pragma omp taskloop firstprivate(i) //expected-error {{argument of a reduction clause of a parallel construct must not appear in a firstprivate clause on a task construct}}
- for (i = 0; i < argc; ++i) // expected-error 3 {{reduction variables may not be accessed in an explicit task}}
+ for (i = 0; i < argc; ++i) // expected-error {{reduction variables may not be accessed in an explicit task}}
foo();
#pragma omp parallel
#pragma omp taskloop firstprivate(B::x) // expected-error {{threadprivate or thread local variable cannot be firstprivate}}
diff --git a/test/OpenMP/taskloop_in_reduction_codegen.cpp b/test/OpenMP/taskloop_in_reduction_codegen.cpp
new file mode 100644
index 000000000000..e9ee9a32b97b
--- /dev/null
+++ b/test/OpenMP/taskloop_in_reduction_codegen.cpp
@@ -0,0 +1,82 @@
+// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp -x c++ -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-apple-darwin10 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-apple-darwin10 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+// CHECK: [[PRIVATES:%.+]] = type { i8*, i8* }
+
+struct S {
+ int a;
+ S() : a(0) {}
+ S(const S&) {}
+ S& operator=(const S&) {return *this;}
+ ~S() {}
+ friend S operator+(const S&a, const S&b) {return a;}
+};
+
+
+int main(int argc, char **argv) {
+ int a;
+ float b;
+ S c[5];
+ short d[argc];
+#pragma omp taskgroup task_reduction(+: a, b, argc)
+ {
+#pragma omp taskgroup task_reduction(-:c, d)
+#pragma omp parallel
+#pragma omp taskloop in_reduction(+:a) in_reduction(-:d)
+ for (int i = 0; i < 5; ++i)
+ a += d[a];
+ }
+ return 0;
+}
+
+// CHECK-LABEL: @main
+// CHECK: void @__kmpc_taskgroup(%ident_t* @0, i32 [[GTID:%.+]])
+// CHECK: [[TD1:%.+]] = call i8* @__kmpc_task_reduction_init(i32 [[GTID]], i32 3, i8* %
+// CHECK-NEXT: store i8* [[TD1]], i8** [[TD1_ADDR:%[^,]+]],
+// CHECK-NEXT: call void @__kmpc_taskgroup(%ident_t* @0, i32 [[GTID]])
+// CHECK: [[TD2:%.+]] = call i8* @__kmpc_task_reduction_init(i32 [[GTID]], i32 2, i8* %
+// CHECK-NEXT: store i8* [[TD2]], i8** [[TD2_ADDR:%[^,]+]],
+// CHECK-NEXT: call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* @0, i32 5, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*, i64, i16*, i8**, i8**)* [[OMP_PARALLEL:@.+]] to void (i32*, i32*, ...)*), i32* %{{.+}}, i64 %{{.+}}, i16* %{{.+}}, i8** [[TD1_ADDR]], i8** [[TD2_ADDR]])
+// CHECK-NEXT: call void @__kmpc_end_taskgroup(%ident_t* @0, i32 [[GTID]])
+// CHECK-NEXT: call void @__kmpc_end_taskgroup(%ident_t* @0, i32 [[GTID]])
+
+// CHECK: define internal void [[OMP_PARALLEL]](
+// CHECK: [[TASK_T:%.+]] = call i8* @__kmpc_omp_task_alloc(%ident_t* @0, i32 [[GTID:%.+]], i32 1, i64 96, i64 40, i32 (i32, i8*)* bitcast (i32 (i32, [[T:%.+]]*)* [[OMP_TASK:@.+]] to i32 (i32, i8*)*))
+// CHECK-NEXT: [[TASK_T_WITH_PRIVS:%.+]] = bitcast i8* [[TASK_T]] to [[T]]*
+// CHECK: [[PRIVS:%.+]] = getelementptr inbounds [[T]], [[T]]* [[TASK_T_WITH_PRIVS]], i32 0, i32 1
+// CHECK: [[TD1_REF:%.+]] = getelementptr inbounds [[PRIVATES]], [[PRIVATES]]* [[PRIVS]], i32 0, i32 0
+// CHECK-NEXT: [[TD1_SHAR:%.+]] = getelementptr inbounds %
+// CHECK-NEXT: [[TD1_ADDR:%.+]] = load i8**, i8*** [[TD1_SHAR]],
+// CHECK-NEXT: [[TD1:%.+]] = load i8*, i8** [[TD1_ADDR]],
+// CHECK-NEXT: store i8* [[TD1]], i8** [[TD1_REF]],
+// CHECK-NEXT: [[TD2_REF:%.+]] = getelementptr inbounds [[PRIVATES]], [[PRIVATES]]* [[PRIVS]], i32 0, i32 1
+// CHECK-NEXT: [[TD2_SHAR:%.+]] = getelementptr inbounds %
+// CHECK-NEXT: [[TD2_ADDR:%.+]] = load i8**, i8*** [[TD2_SHAR]],
+// CHECK-NEXT: [[TD2:%.+]] = load i8*, i8** [[TD2_ADDR]],
+// CHECK-NEXT: store i8* [[TD2]], i8** [[TD2_REF]],
+// CHECK: call void @__kmpc_taskloop(%ident_t* @0, i32 [[GTID]], i8* [[TASK_T]], i32 1,
+// CHECK: ret void
+// CHECK-NEXT: }
+
+// CHECK: define internal {{.*}} [[OMP_TASK]](
+// CHECK: call void (i8*, ...) %{{[^(]+}}(i8* %{{.+}}, i8*** [[TD1_REF:%[^,]+]], i8*** [[TD2_REF:%[^,]+]])
+// CHECK-NEXT: [[TD1_ADDR:%.+]] = load i8**, i8*** [[TD1_REF]],
+// CHECK-NEXT: [[TD2_ADDR:%.+]] = load i8**, i8*** [[TD2_REF]],
+// CHECK-NEXT: [[A_REF:%.+]] = getelementptr inbounds %
+// CHECK-NEXT: [[A_ADDR:%.+]] = load i32*, i32** [[A_REF]],
+// CHECK-NEXT: [[TD1:%.+]] = load i8*, i8** [[TD1_ADDR]],
+// CHECK-NEXT: [[GTID:%.+]] = load i32, i32* %
+// CHECK-NEXT: [[A_PTR:%.+]] = bitcast i32* [[A_ADDR]] to i8*
+// CHECK-NEXT: call i8* @__kmpc_task_reduction_get_th_data(i32 [[GTID]], i8* [[TD1]], i8* [[A_PTR]])
+// CHECK: [[D_REF:%.+]] = getelementptr inbounds %
+// CHECK-NEXT: [[D_ADDR:%.+]] = load i16*, i16** [[D_REF]],
+// CHECK: [[TD2:%.+]] = load i8*, i8** [[TD2_ADDR]],
+// CHECK-NEXT: [[D_PTR:%.+]] = bitcast i16* [[D_ADDR]] to i8*
+// CHECK-NEXT: call i8* @__kmpc_task_reduction_get_th_data(i32 [[GTID]], i8* [[TD2]], i8* [[D_PTR]])
+// CHECK: add nsw i32
+// CHECK: store i32 %
+#endif
diff --git a/test/OpenMP/taskloop_in_reduction_messages.cpp b/test/OpenMP/taskloop_in_reduction_messages.cpp
new file mode 100644
index 000000000000..409975565a91
--- /dev/null
+++ b/test/OpenMP/taskloop_in_reduction_messages.cpp
@@ -0,0 +1,376 @@
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 150 -o - %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++98 -ferror-limit 150 -o - %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 -ferror-limit 150 -o - %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+void foobar(int &ref) {
+#pragma omp taskgroup task_reduction(+:ref)
+#pragma omp taskloop in_reduction(+:ref)
+ for (int i = 0; i < 10; ++i)
+ foo();
+}
+
+void foobar1(int &ref) {
+#pragma omp taskgroup task_reduction(+:ref)
+#pragma omp taskloop in_reduction(-:ref)
+ for (int i = 0; i < 10; ++i)
+ foo();
+}
+
+#pragma omp declare reduction (red:int:omp_out += omp_in)
+
+void foobar2(int &ref) {
+#pragma omp taskgroup task_reduction(+:ref) // expected-note {{previously marked as task_reduction with different reduction operation}}
+#pragma omp taskloop in_reduction(red:ref) // expected-error{{in_reduction variable must have the same reduction operation as in a task_reduction clause}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+}
+
+void foobar3(int &ref) {
+#pragma omp taskgroup task_reduction(red:ref) // expected-note {{previously marked as task_reduction with different reduction operation}}
+#pragma omp taskloop in_reduction(min:ref) // expected-error{{in_reduction variable must have the same reduction operation as in a task_reduction clause}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+}
+
+void foobar4(int &ref) {
+#pragma omp taskloop in_reduction(min:ref) // expected-error {{in_reduction variable must appear in a task_reduction clause}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+}
+
+struct S1; // expected-note {{declared here}} expected-note 4 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+ mutable int a;
+ S2 &operator+(const S2 &arg) { return (*this); } // expected-note 3 {{implicitly declared private here}}
+
+public:
+ S2() : a(0) {}
+ S2(S2 &s2) : a(s2.a) {}
+ static float S2s; // expected-note 2 {{static data member is predetermined as shared}}
+ static const float S2sc; // expected-note 2 {{'S2sc' declared here}}
+};
+const float S2::S2sc = 0;
+S2 b; // expected-note 3 {{'b' defined here}}
+const S2 ba[5]; // expected-note 2 {{'ba' defined here}}
+class S3 {
+ int a;
+
+public:
+ int b;
+ S3() : a(0) {}
+ S3(const S3 &s3) : a(s3.a) {}
+ S3 operator+(const S3 &arg1) { return arg1; }
+};
+int operator+(const S3 &arg1, const S3 &arg2) { return 5; }
+S3 c; // expected-note 3 {{'c' defined here}}
+const S3 ca[5]; // expected-note 2 {{'ca' defined here}}
+extern const int f; // expected-note 4 {{'f' declared here}}
+class S4 {
+ int a;
+ S4(); // expected-note {{implicitly declared private here}}
+ S4(const S4 &s4);
+ S4 &operator+(const S4 &arg) { return (*this); }
+
+public:
+ S4(int v) : a(v) {}
+};
+S4 &operator&=(S4 &arg1, S4 &arg2) { return arg1; }
+class S5 {
+ int a;
+ S5() : a(0) {} // expected-note {{implicitly declared private here}}
+ S5(const S5 &s5) : a(s5.a) {}
+ S5 &operator+(const S5 &arg);
+
+public:
+ S5(int v) : a(v) {}
+};
+class S6 { // expected-note 3 {{candidate function (the implicit copy assignment operator) not viable: no known conversion from 'int' to 'const S6' for 1st argument}}
+#if __cplusplus >= 201103L // C++11 or later
+// expected-note@-2 3 {{candidate function (the implicit move assignment operator) not viable}}
+#endif
+ int a;
+
+public:
+ S6() : a(6) {}
+ operator int() { return 6; }
+} o;
+
+S3 h, k;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class T> // expected-note {{declared here}}
+T tmain(T argc) {
+ const T d = T(); // expected-note 4 {{'d' defined here}}
+ const T da[5] = {T()}; // expected-note 2 {{'da' defined here}}
+ T qa[5] = {T()};
+ T i;
+ T &j = i; // expected-note 2 {{'j' defined here}}
+ S3 &p = k; // expected-note 2 {{'p' defined here}}
+ const T &r = da[(int)i]; // expected-note 2 {{'r' defined here}}
+ T &q = qa[(int)i];
+ T fl;
+#pragma omp taskgroup task_reduction(+:argc)
+#pragma omp taskloop in_reduction // expected-error {{expected '(' after 'in_reduction'}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskgroup task_reduction(+:argc)
+#pragma omp taskloop in_reduction + // expected-error {{expected '(' after 'in_reduction'}} expected-warning {{extra tokens at the end of '#pragma omp taskloop' are ignored}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskgroup task_reduction(+:argc)
+#pragma omp taskloop in_reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskgroup task_reduction(+:argc)
+#pragma omp taskloop in_reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskgroup task_reduction(+:argc)
+#pragma omp taskloop in_reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskgroup task_reduction(+:argc)
+#pragma omp taskloop in_reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskgroup task_reduction(+:argc)
+#pragma omp taskloop in_reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskgroup task_reduction(&:argc) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
+#pragma omp taskloop in_reduction(& : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{invalid operands to binary expression ('float' and 'float')}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskgroup task_reduction(|:argc) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
+#pragma omp taskloop in_reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{invalid operands to binary expression ('float' and 'float')}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskloop in_reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name, array element or array section}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskloop in_reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskgroup task_reduction(&&:argc)
+#pragma omp taskloop in_reduction(&& : argc)
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskloop in_reduction(^ : T) // expected-error {{'T' does not refer to a value}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskgroup task_reduction(+:c)
+#pragma omp taskloop in_reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}} expected-error 2 {{in_reduction variable must appear in a task_reduction clause}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskloop in_reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'in_reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskloop in_reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskloop in_reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskloop in_reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskloop in_reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskloop in_reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} expected-error {{in_reduction variable must appear in a task_reduction clause}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskloop in_reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskloop in_reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskgroup task_reduction(+:k)
+#pragma omp taskloop in_reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskloop in_reduction(+ : o) // expected-error 2 {{no viable overloaded '='}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp parallel private(k)
+#pragma omp taskloop in_reduction(+ : p), in_reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'in_reduction' must reference the same object in all threads}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskgroup task_reduction(+:p)
+#pragma omp taskloop in_reduction(+ : p), in_reduction(+ : p) // expected-error 2 {{variable can appear only once in OpenMP 'in_reduction' clause}} expected-note 2 {{previously referenced here}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskloop in_reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp parallel shared(i)
+#pragma omp parallel reduction(min : i)
+#pragma omp taskloop in_reduction(max : j) // expected-error 2 {{argument of OpenMP clause 'in_reduction' must reference the same object in all threads}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskgroup task_reduction(+:fl)
+{
+#pragma omp taskloop in_reduction(+ : fl)
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskgroup task_reduction(*:fl) // expected-note 2 {{previously marked as task_reduction with different reduction operation}}
+{
+#pragma omp taskloop in_reduction(+ : fl) // expected-error 2 {{in_reduction variable must have the same reduction operation as in a task_reduction clause}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+}
+}
+#pragma omp parallel
+#pragma omp for reduction(- : fl)
+ for (int i = 0; i < 10; ++i)
+#pragma omp taskgroup task_reduction(+:fl)
+#pragma omp taskloop in_reduction(+ : fl)
+ for (int j = 0; j < 10; ++j)
+ foo();
+
+ return T();
+}
+
+namespace A {
+double x;
+#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}}
+}
+namespace B {
+using A::x;
+}
+
+int main(int argc, char **argv) {
+ const int d = 5; // expected-note 2 {{'d' defined here}}
+ const int da[5] = {0}; // expected-note {{'da' defined here}}
+ int qa[5] = {0};
+ S4 e(4);
+ S5 g(5);
+ int i;
+ int &j = i; // expected-note {{'j' defined here}}
+ S3 &p = k; // expected-note 2 {{'p' defined here}}
+ const int &r = da[i]; // expected-note {{'r' defined here}}
+ int &q = qa[i];
+ float fl;
+#pragma omp taskloop in_reduction // expected-error {{expected '(' after 'in_reduction'}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskloop in_reduction + // expected-error {{expected '(' after 'in_reduction'}} expected-warning {{extra tokens at the end of '#pragma omp taskloop' are ignored}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskloop in_reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskloop in_reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskloop in_reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskloop in_reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskloop in_reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskloop in_reduction(foo : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskgroup task_reduction(|:argc)
+#pragma omp taskloop in_reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskloop in_reduction(|| : argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name, array element or array section}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskloop in_reduction(~ : argc) // expected-error {{expected unqualified-id}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskgroup task_reduction(&&:argc)
+#pragma omp taskloop in_reduction(&& : argc)
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskloop in_reduction(^ : S1) // expected-error {{'S1' does not refer to a value}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskgroup task_reduction(+:c)
+#pragma omp taskloop in_reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified list item cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}} expected-error {{in_reduction variable must appear in a task_reduction clause}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskloop in_reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'in_reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskloop in_reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskloop in_reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskloop in_reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskloop in_reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskloop in_reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskloop in_reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskloop in_reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskloop in_reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{nvalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskgroup task_reduction(+:k)
+#pragma omp taskloop in_reduction(+ : h, k, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskloop in_reduction(+ : o) // expected-error {{no viable overloaded '='}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp parallel private(k)
+#pragma omp taskloop in_reduction(+ : p), in_reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'in_reduction' must reference the same object in all threads}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskgroup task_reduction(+:p)
+#pragma omp taskloop in_reduction(+ : p), in_reduction(+ : p) // expected-error {{variable can appear only once in OpenMP 'in_reduction' clause}} expected-note {{previously referenced here}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskloop in_reduction(+ : r) // expected-error {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp parallel shared(i)
+#pragma omp parallel reduction(min : i)
+#pragma omp taskloop in_reduction(max : j) // expected-error {{argument of OpenMP clause 'in_reduction' must reference the same object in all threads}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp parallel
+#pragma omp for private(fl)
+ for (int i = 0; i < 10; ++i)
+#pragma omp taskgroup task_reduction(+:fl)
+#pragma omp taskloop in_reduction(+ : fl)
+ for (int j = 0; j < 10; ++j)
+ foo();
+#pragma omp taskgroup task_reduction(+:fl)
+#pragma omp taskloop in_reduction(+ : fl)
+ for (int i = 0; i < 10; ++i)
+ foo();
+ static int m;
+#pragma omp taskgroup task_reduction(+:m)
+#pragma omp taskloop in_reduction(+ : m) // OK
+ for (int i = 0; i < 10; ++i)
+ m++;
+
+ return tmain(argc) + tmain(fl); // expected-note {{in instantiation of function template specialization 'tmain<int>' requested here}} expected-note {{in instantiation of function template specialization 'tmain<float>' requested here}}
+}
diff --git a/test/OpenMP/taskloop_lastprivate_messages.cpp b/test/OpenMP/taskloop_lastprivate_messages.cpp
index e4364448159c..1d238ea083e6 100644
--- a/test/OpenMP/taskloop_lastprivate_messages.cpp
+++ b/test/OpenMP/taskloop_lastprivate_messages.cpp
@@ -18,9 +18,9 @@ public:
const S2 &operator =(const S2&) const;
S2 &operator =(const S2&);
static float S2s; // expected-note {{static data member is predetermined as shared}}
- static const float S2sc;
+ static const float S2sc; // expected-note {{static data member is predetermined as shared}}
};
-const float S2::S2sc = 0; // expected-note {{static data member is predetermined as shared}}
+const float S2::S2sc = 0;
const S2 b;
const S2 ba[5];
class S3 {
diff --git a/test/OpenMP/taskloop_reduction_codegen.cpp b/test/OpenMP/taskloop_reduction_codegen.cpp
index af071ae8bd4e..6af067642fea 100644
--- a/test/OpenMP/taskloop_reduction_codegen.cpp
+++ b/test/OpenMP/taskloop_reduction_codegen.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fopenmp -x c++ %s -verify -debug-info-kind=limited -emit-llvm -o - -triple powerpc64le-unknown-linux-gnu | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ %s -verify -debug-info-kind=limited -emit-llvm -o - -triple powerpc64le-unknown-linux-gnu -std=c++98 | FileCheck %s
// expected-no-diagnostics
struct S {
@@ -51,6 +51,7 @@ sum = 0.0;
// CHECK: [[AGG_CAPTURED:%.*]] = alloca [[STRUCT_ANON:%.*]],
// CHECK: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(%ident_t*
// CHECK: [[DOTRD_INPUT_:%.*]] = alloca [4 x %struct.kmp_task_red_input_t],
+// CHECK: alloca i32,
// CHECK: [[DOTCAPTURE_EXPR_:%.*]] = alloca i32,
// CHECK: [[DOTCAPTURE_EXPR_9:%.*]] = alloca i32,
// CHECK: store i32 0, i32* [[RETVAL]],
@@ -143,7 +144,7 @@ sum = 0.0;
// CHECK: [[DIV:%.*]] = sdiv i32 [[ADD11]], 1
// CHECK: [[SUB12:%.*]] = sub nsw i32 [[DIV]], 1
// CHECK: store i32 [[SUB12]], i32* [[DOTCAPTURE_EXPR_9]],
-// CHECK: [[TMP65:%.*]] = call i8* @__kmpc_omp_task_alloc(%ident_t* %{{.+}}, i32 [[TMP0]], i32 1, i64 888, i64 72, i32 (i32, i8*)* bitcast (i32 (i32, %struct.kmp_task_t_with_privates*)* @{{.+}} to i32 (i32, i8*)*))
+// CHECK: [[TMP65:%.*]] = call i8* @__kmpc_omp_task_alloc(%ident_t* %{{.+}}, i32 [[TMP0]], i32 1, i64 888, i64 72, i32 (i32, i8*)* bitcast (i32 (i32, %struct.kmp_task_t_with_privates*)* @[[TASK:.+]] to i32 (i32, i8*)*))
// CHECK: call void @__kmpc_taskloop(%ident_t* %{{.+}}, i32 [[TMP0]], i8* [[TMP65]], i32 1, i64* %{{.+}}, i64* %{{.+}}, i64 %{{.+}}, i32 0, i32 0, i64 0, i8* null)
// CHECK: call void @__kmpc_end_taskgroup(%ident_t*
@@ -195,3 +196,4 @@ sum = 0.0;
// CHECK: store float %{{.+}}, float* %
// CHECK: ret void
+// CHECK: distinct !DISubprogram(linkageName: "[[TASK]]", scope: !
diff --git a/test/OpenMP/taskloop_reduction_messages.cpp b/test/OpenMP/taskloop_reduction_messages.cpp
index 7295075c3cb8..23f70b568525 100644
--- a/test/OpenMP/taskloop_reduction_messages.cpp
+++ b/test/OpenMP/taskloop_reduction_messages.cpp
@@ -25,9 +25,9 @@ public:
S2() : a(0) {}
S2(S2 &s2) : a(s2.a) {}
static float S2s; // expected-note 2 {{static data member is predetermined as shared}}
- static const float S2sc;
+ static const float S2sc; // expected-note 2 {{'S2sc' declared here}}
};
-const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}}
+const float S2::S2sc = 0;
S2 b; // expected-note 3 {{'b' defined here}}
const S2 ba[5]; // expected-note 2 {{'ba' defined here}}
class S3 {
diff --git a/test/OpenMP/taskloop_simd_ast_print.cpp b/test/OpenMP/taskloop_simd_ast_print.cpp
index 8678b9122e29..6f13c7e0baa5 100644
--- a/test/OpenMP/taskloop_simd_ast_print.cpp
+++ b/test/OpenMP/taskloop_simd_ast_print.cpp
@@ -14,8 +14,10 @@ T tmain(T argc) {
T *ptr;
static T a;
// CHECK: static T a;
-#pragma omp taskloop simd if(taskloop: argc > N) default(shared) untied priority(N) safelen(N) linear(c) aligned(ptr) grainsize(N) reduction(+:g)
- // CHECK-NEXT: #pragma omp taskloop simd if(taskloop: argc > N) default(shared) untied priority(N) safelen(N) linear(c) aligned(ptr) grainsize(N) reduction(+: g)
+#pragma omp taskgroup task_reduction(+: d)
+#pragma omp taskloop simd if(taskloop: argc > N) default(shared) untied priority(N) safelen(N) linear(c) aligned(ptr) grainsize(N) reduction(+:g) in_reduction(+: d)
+ // CHECK-NEXT: #pragma omp taskgroup task_reduction(+: d)
+ // CHECK-NEXT: #pragma omp taskloop simd if(taskloop: argc > N) default(shared) untied priority(N) safelen(N) linear(c) aligned(ptr) grainsize(N) reduction(+: g) in_reduction(+: d)
for (int i = 0; i < 2; ++i)
a = 2;
// CHECK-NEXT: for (int i = 0; i < 2; ++i)
@@ -54,8 +56,10 @@ int main(int argc, char **argv) {
int b = argc, c, d, e, f, g;
static int a;
// CHECK: static int a;
-#pragma omp taskloop simd if(taskloop: a) default(none) shared(a) final(b) priority(5) safelen(8) linear(b), aligned(argv) num_tasks(argc) reduction(*: g)
- // CHECK-NEXT: #pragma omp taskloop simd if(taskloop: a) default(none) shared(a) final(b) priority(5) safelen(8) linear(b) aligned(argv) num_tasks(argc) reduction(*: g)
+#pragma omp taskgroup task_reduction(+: d)
+#pragma omp taskloop simd if(taskloop: a) default(none) shared(a) final(b) priority(5) safelen(8) linear(b), aligned(argv) num_tasks(argc) reduction(*: g) in_reduction(+: d)
+ // CHECK-NEXT: #pragma omp taskgroup task_reduction(+: d)
+ // CHECK-NEXT: #pragma omp taskloop simd if(taskloop: a) default(none) shared(a) final(b) priority(5) safelen(8) linear(b) aligned(argv) num_tasks(argc) reduction(*: g) in_reduction(+: d)
for (int i = 0; i < 2; ++i)
a = 2;
// CHECK-NEXT: for (int i = 0; i < 2; ++i)
diff --git a/test/OpenMP/taskloop_simd_codegen.cpp b/test/OpenMP/taskloop_simd_codegen.cpp
index f787689688e3..006fd59af3fa 100644
--- a/test/OpenMP/taskloop_simd_codegen.cpp
+++ b/test/OpenMP/taskloop_simd_codegen.cpp
@@ -158,7 +158,7 @@ struct S {
// CHECK: [[ST_VAL:%.+]] = load i64, i64* [[ST]],
// CHECK: [[NUM_TASKS:%.+]] = zext i32 %{{.+}} to i64
// CHECK: call void @__kmpc_taskloop(%ident_t* [[DEFLOC]], i32 [[GTID]], i8* [[TASKV]], i32 1, i64* [[DOWN]], i64* [[UP]], i64 [[ST_VAL]], i32 0, i32 2, i64 [[NUM_TASKS]], i8* null)
-#pragma omp taskloop simd shared(c) num_tasks(a) simdlen(64) safelen(8)
+#pragma omp taskloop simd shared(c) num_tasks(a) simdlen(8) safelen(64)
for (a = 0; a < c; ++a)
;
}
@@ -201,6 +201,6 @@ struct S {
// CHECK: !{!"llvm.loop.vectorize.enable", i1 true}
// CHECK: !{!"llvm.loop.vectorize.width", i32 4}
// CHECK: !{!"llvm.loop.vectorize.width", i32 32}
-// CHECK: !{!"llvm.loop.vectorize.width", i32 64}
+// CHECK: !{!"llvm.loop.vectorize.width", i32 8}
#endif
diff --git a/test/OpenMP/taskloop_simd_firstprivate_messages.cpp b/test/OpenMP/taskloop_simd_firstprivate_messages.cpp
index 18cefc1beeb2..176dcd7f8f9c 100644
--- a/test/OpenMP/taskloop_simd_firstprivate_messages.cpp
+++ b/test/OpenMP/taskloop_simd_firstprivate_messages.cpp
@@ -295,9 +295,9 @@ int main(int argc, char **argv) {
#pragma omp taskloop simd firstprivate(i) // expected-note {{defined as firstprivate}}
for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp taskloop simd' directive may not be firstprivate, predetermined as linear}}
foo();
-#pragma omp parallel reduction(+ : i) // expected-note 4 {{defined as reduction}}
+#pragma omp parallel reduction(+ : i) // expected-note 2 {{defined as reduction}}
#pragma omp taskloop simd firstprivate(i) // expected-error {{argument of a reduction clause of a parallel construct must not appear in a firstprivate clause on a task construct}}
- for (i = 0; i < argc; ++i) // expected-error 3 {{reduction variables may not be accessed in an explicit task}}
+ for (i = 0; i < argc; ++i) // expected-error {{reduction variables may not be accessed in an explicit task}}
foo();
#pragma omp parallel
#pragma omp taskloop simd firstprivate(B::x) // expected-error {{threadprivate or thread local variable cannot be firstprivate}}
diff --git a/test/OpenMP/taskloop_simd_in_reduction_codegen.cpp b/test/OpenMP/taskloop_simd_in_reduction_codegen.cpp
new file mode 100644
index 000000000000..d894943cc359
--- /dev/null
+++ b/test/OpenMP/taskloop_simd_in_reduction_codegen.cpp
@@ -0,0 +1,82 @@
+// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp -x c++ -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-apple-darwin10 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-apple-darwin10 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+// CHECK: [[PRIVATES:%.+]] = type { i8*, i8* }
+
+struct S {
+ int a;
+ S() : a(0) {}
+ S(const S&) {}
+ S& operator=(const S&) {return *this;}
+ ~S() {}
+ friend S operator+(const S&a, const S&b) {return a;}
+};
+
+
+int main(int argc, char **argv) {
+ int a;
+ float b;
+ S c[5];
+ short d[argc];
+#pragma omp taskgroup task_reduction(+: a, b, argc)
+ {
+#pragma omp taskgroup task_reduction(-:c, d)
+#pragma omp parallel
+#pragma omp taskloop simd in_reduction(+:a) in_reduction(-:d)
+ for (int i = 0; i < 5; ++i)
+ a += d[a];
+ }
+ return 0;
+}
+
+// CHECK-LABEL: @main
+// CHECK: void @__kmpc_taskgroup(%ident_t* @0, i32 [[GTID:%.+]])
+// CHECK: [[TD1:%.+]] = call i8* @__kmpc_task_reduction_init(i32 [[GTID]], i32 3, i8* %
+// CHECK-NEXT: store i8* [[TD1]], i8** [[TD1_ADDR:%[^,]+]],
+// CHECK-NEXT: call void @__kmpc_taskgroup(%ident_t* @0, i32 [[GTID]])
+// CHECK: [[TD2:%.+]] = call i8* @__kmpc_task_reduction_init(i32 [[GTID]], i32 2, i8* %
+// CHECK-NEXT: store i8* [[TD2]], i8** [[TD2_ADDR:%[^,]+]],
+// CHECK-NEXT: call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* @0, i32 5, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*, i64, i16*, i8**, i8**)* [[OMP_PARALLEL:@.+]] to void (i32*, i32*, ...)*), i32* %{{.+}}, i64 %{{.+}}, i16* %{{.+}}, i8** [[TD1_ADDR]], i8** [[TD2_ADDR]])
+// CHECK-NEXT: call void @__kmpc_end_taskgroup(%ident_t* @0, i32 [[GTID]])
+// CHECK-NEXT: call void @__kmpc_end_taskgroup(%ident_t* @0, i32 [[GTID]])
+
+// CHECK: define internal void [[OMP_PARALLEL]](
+// CHECK: [[TASK_T:%.+]] = call i8* @__kmpc_omp_task_alloc(%ident_t* @0, i32 [[GTID:%.+]], i32 1, i64 96, i64 40, i32 (i32, i8*)* bitcast (i32 (i32, [[T:%.+]]*)* [[OMP_TASK:@.+]] to i32 (i32, i8*)*))
+// CHECK-NEXT: [[TASK_T_WITH_PRIVS:%.+]] = bitcast i8* [[TASK_T]] to [[T]]*
+// CHECK: [[PRIVS:%.+]] = getelementptr inbounds [[T]], [[T]]* [[TASK_T_WITH_PRIVS]], i32 0, i32 1
+// CHECK: [[TD1_REF:%.+]] = getelementptr inbounds [[PRIVATES]], [[PRIVATES]]* [[PRIVS]], i32 0, i32 0
+// CHECK-NEXT: [[TD1_SHAR:%.+]] = getelementptr inbounds %
+// CHECK-NEXT: [[TD1_ADDR:%.+]] = load i8**, i8*** [[TD1_SHAR]],
+// CHECK-NEXT: [[TD1:%.+]] = load i8*, i8** [[TD1_ADDR]],
+// CHECK-NEXT: store i8* [[TD1]], i8** [[TD1_REF]],
+// CHECK-NEXT: [[TD2_REF:%.+]] = getelementptr inbounds [[PRIVATES]], [[PRIVATES]]* [[PRIVS]], i32 0, i32 1
+// CHECK-NEXT: [[TD2_SHAR:%.+]] = getelementptr inbounds %
+// CHECK-NEXT: [[TD2_ADDR:%.+]] = load i8**, i8*** [[TD2_SHAR]],
+// CHECK-NEXT: [[TD2:%.+]] = load i8*, i8** [[TD2_ADDR]],
+// CHECK-NEXT: store i8* [[TD2]], i8** [[TD2_REF]],
+// CHECK: call void @__kmpc_taskloop(%ident_t* @0, i32 [[GTID]], i8* [[TASK_T]], i32 1,
+// CHECK: ret void
+// CHECK-NEXT: }
+
+// CHECK: define internal {{.*}} [[OMP_TASK]](
+// CHECK: call void (i8*, ...) %{{[^(]+}}(i8* %{{.+}}, i8*** [[TD1_REF:%[^,]+]], i8*** [[TD2_REF:%[^,]+]])
+// CHECK-NEXT: [[TD1_ADDR:%.+]] = load i8**, i8*** [[TD1_REF]],
+// CHECK-NEXT: [[TD2_ADDR:%.+]] = load i8**, i8*** [[TD2_REF]],
+// CHECK-NEXT: [[A_REF:%.+]] = getelementptr inbounds %
+// CHECK-NEXT: [[A_ADDR:%.+]] = load i32*, i32** [[A_REF]],
+// CHECK-NEXT: [[TD1:%.+]] = load i8*, i8** [[TD1_ADDR]],
+// CHECK-NEXT: [[GTID:%.+]] = load i32, i32* %
+// CHECK-NEXT: [[A_PTR:%.+]] = bitcast i32* [[A_ADDR]] to i8*
+// CHECK-NEXT: call i8* @__kmpc_task_reduction_get_th_data(i32 [[GTID]], i8* [[TD1]], i8* [[A_PTR]])
+// CHECK: [[D_REF:%.+]] = getelementptr inbounds %
+// CHECK-NEXT: [[D_ADDR:%.+]] = load i16*, i16** [[D_REF]],
+// CHECK: [[TD2:%.+]] = load i8*, i8** [[TD2_ADDR]],
+// CHECK-NEXT: [[D_PTR:%.+]] = bitcast i16* [[D_ADDR]] to i8*
+// CHECK-NEXT: call i8* @__kmpc_task_reduction_get_th_data(i32 [[GTID]], i8* [[TD2]], i8* [[D_PTR]])
+// CHECK: add nsw i32
+// CHECK: store i32 %
+#endif
diff --git a/test/OpenMP/taskloop_simd_in_reduction_messages.cpp b/test/OpenMP/taskloop_simd_in_reduction_messages.cpp
new file mode 100644
index 000000000000..f3b1a855e320
--- /dev/null
+++ b/test/OpenMP/taskloop_simd_in_reduction_messages.cpp
@@ -0,0 +1,376 @@
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 150 -o - %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++98 -ferror-limit 150 -o - %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 -ferror-limit 150 -o - %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+void foobar(int &ref) {
+#pragma omp taskgroup task_reduction(+:ref)
+#pragma omp taskloop simd in_reduction(+:ref)
+ for (int i = 0; i < 10; ++i)
+ foo();
+}
+
+void foobar1(int &ref) {
+#pragma omp taskgroup task_reduction(+:ref)
+#pragma omp taskloop simd in_reduction(-:ref)
+ for (int i = 0; i < 10; ++i)
+ foo();
+}
+
+#pragma omp declare reduction (red:int:omp_out += omp_in)
+
+void foobar2(int &ref) {
+#pragma omp taskgroup task_reduction(+:ref) // expected-note {{previously marked as task_reduction with different reduction operation}}
+#pragma omp taskloop simd in_reduction(red:ref) // expected-error{{in_reduction variable must have the same reduction operation as in a task_reduction clause}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+}
+
+void foobar3(int &ref) {
+#pragma omp taskgroup task_reduction(red:ref) // expected-note {{previously marked as task_reduction with different reduction operation}}
+#pragma omp taskloop simd in_reduction(min:ref) // expected-error{{in_reduction variable must have the same reduction operation as in a task_reduction clause}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+}
+
+void foobar4(int &ref) {
+#pragma omp taskloop simd in_reduction(min:ref) // expected-error {{in_reduction variable must appear in a task_reduction clause}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+}
+
+struct S1; // expected-note {{declared here}} expected-note 4 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+ mutable int a;
+ S2 &operator+(const S2 &arg) { return (*this); } // expected-note 3 {{implicitly declared private here}}
+
+public:
+ S2() : a(0) {}
+ S2(S2 &s2) : a(s2.a) {}
+ static float S2s; // expected-note 2 {{static data member is predetermined as shared}}
+ static const float S2sc; // expected-note 2 {{'S2sc' declared here}}
+};
+const float S2::S2sc = 0;
+S2 b; // expected-note 3 {{'b' defined here}}
+const S2 ba[5]; // expected-note 2 {{'ba' defined here}}
+class S3 {
+ int a;
+
+public:
+ int b;
+ S3() : a(0) {}
+ S3(const S3 &s3) : a(s3.a) {}
+ S3 operator+(const S3 &arg1) { return arg1; }
+};
+int operator+(const S3 &arg1, const S3 &arg2) { return 5; }
+S3 c; // expected-note 3 {{'c' defined here}}
+const S3 ca[5]; // expected-note 2 {{'ca' defined here}}
+extern const int f; // expected-note 4 {{'f' declared here}}
+class S4 {
+ int a;
+ S4(); // expected-note {{implicitly declared private here}}
+ S4(const S4 &s4);
+ S4 &operator+(const S4 &arg) { return (*this); }
+
+public:
+ S4(int v) : a(v) {}
+};
+S4 &operator&=(S4 &arg1, S4 &arg2) { return arg1; }
+class S5 {
+ int a;
+ S5() : a(0) {} // expected-note {{implicitly declared private here}}
+ S5(const S5 &s5) : a(s5.a) {}
+ S5 &operator+(const S5 &arg);
+
+public:
+ S5(int v) : a(v) {}
+};
+class S6 { // expected-note 3 {{candidate function (the implicit copy assignment operator) not viable: no known conversion from 'int' to 'const S6' for 1st argument}}
+#if __cplusplus >= 201103L // C++11 or later
+// expected-note@-2 3 {{candidate function (the implicit move assignment operator) not viable}}
+#endif
+ int a;
+
+public:
+ S6() : a(6) {}
+ operator int() { return 6; }
+} o;
+
+S3 h, k;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class T> // expected-note {{declared here}}
+T tmain(T argc) {
+ const T d = T(); // expected-note 4 {{'d' defined here}}
+ const T da[5] = {T()}; // expected-note 2 {{'da' defined here}}
+ T qa[5] = {T()};
+ T i;
+ T &j = i; // expected-note 2 {{'j' defined here}}
+ S3 &p = k; // expected-note 2 {{'p' defined here}}
+ const T &r = da[(int)i]; // expected-note 2 {{'r' defined here}}
+ T &q = qa[(int)i];
+ T fl;
+#pragma omp taskgroup task_reduction(+:argc)
+#pragma omp taskloop simd in_reduction // expected-error {{expected '(' after 'in_reduction'}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskgroup task_reduction(+:argc)
+#pragma omp taskloop simd in_reduction + // expected-error {{expected '(' after 'in_reduction'}} expected-warning {{extra tokens at the end of '#pragma omp taskloop simd' are ignored}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskgroup task_reduction(+:argc)
+#pragma omp taskloop simd in_reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskgroup task_reduction(+:argc)
+#pragma omp taskloop simd in_reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskgroup task_reduction(+:argc)
+#pragma omp taskloop simd in_reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskgroup task_reduction(+:argc)
+#pragma omp taskloop simd in_reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskgroup task_reduction(+:argc)
+#pragma omp taskloop simd in_reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskgroup task_reduction(&:argc) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
+#pragma omp taskloop simd in_reduction(& : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{invalid operands to binary expression ('float' and 'float')}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskgroup task_reduction(|:argc) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
+#pragma omp taskloop simd in_reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{invalid operands to binary expression ('float' and 'float')}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskloop simd in_reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name, array element or array section}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskloop simd in_reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskgroup task_reduction(&&:argc)
+#pragma omp taskloop simd in_reduction(&& : argc)
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskloop simd in_reduction(^ : T) // expected-error {{'T' does not refer to a value}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskgroup task_reduction(+:c)
+#pragma omp taskloop simd in_reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}} expected-error 2 {{in_reduction variable must appear in a task_reduction clause}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskloop simd in_reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'in_reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskloop simd in_reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskloop simd in_reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskloop simd in_reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskloop simd in_reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskloop simd in_reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} expected-error {{in_reduction variable must appear in a task_reduction clause}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskloop simd in_reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskloop simd in_reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskgroup task_reduction(+:k)
+#pragma omp taskloop simd in_reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskloop simd in_reduction(+ : o) // expected-error 2 {{no viable overloaded '='}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp parallel private(k)
+#pragma omp taskloop simd in_reduction(+ : p), in_reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'in_reduction' must reference the same object in all threads}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskgroup task_reduction(+:p)
+#pragma omp taskloop simd in_reduction(+ : p), in_reduction(+ : p) // expected-error 2 {{variable can appear only once in OpenMP 'in_reduction' clause}} expected-note 2 {{previously referenced here}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskloop simd in_reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp parallel shared(i)
+#pragma omp parallel reduction(min : i)
+#pragma omp taskloop simd in_reduction(max : j) // expected-error 2 {{argument of OpenMP clause 'in_reduction' must reference the same object in all threads}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskgroup task_reduction(+:fl)
+{
+#pragma omp taskloop simd in_reduction(+ : fl)
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskgroup task_reduction(*:fl) // expected-note 2 {{previously marked as task_reduction with different reduction operation}}
+{
+#pragma omp taskloop simd in_reduction(+ : fl) // expected-error 2 {{in_reduction variable must have the same reduction operation as in a task_reduction clause}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+}
+}
+#pragma omp parallel
+#pragma omp for reduction(- : fl)
+ for (int i = 0; i < 10; ++i)
+#pragma omp taskgroup task_reduction(+:fl)
+#pragma omp taskloop simd in_reduction(+ : fl)
+ for (int j = 0; j < 10; ++j)
+ foo();
+
+ return T();
+}
+
+namespace A {
+double x;
+#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}}
+}
+namespace B {
+using A::x;
+}
+
+int main(int argc, char **argv) {
+ const int d = 5; // expected-note 2 {{'d' defined here}}
+ const int da[5] = {0}; // expected-note {{'da' defined here}}
+ int qa[5] = {0};
+ S4 e(4);
+ S5 g(5);
+ int i;
+ int &j = i; // expected-note {{'j' defined here}}
+ S3 &p = k; // expected-note 2 {{'p' defined here}}
+ const int &r = da[i]; // expected-note {{'r' defined here}}
+ int &q = qa[i];
+ float fl;
+#pragma omp taskloop simd in_reduction // expected-error {{expected '(' after 'in_reduction'}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskloop simd in_reduction + // expected-error {{expected '(' after 'in_reduction'}} expected-warning {{extra tokens at the end of '#pragma omp taskloop simd' are ignored}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskloop simd in_reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskloop simd in_reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskloop simd in_reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskloop simd in_reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskloop simd in_reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskloop simd in_reduction(foo : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskgroup task_reduction(|:argc)
+#pragma omp taskloop simd in_reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskloop simd in_reduction(|| : argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name, array element or array section}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskloop simd in_reduction(~ : argc) // expected-error {{expected unqualified-id}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskgroup task_reduction(&&:argc)
+#pragma omp taskloop simd in_reduction(&& : argc)
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskloop simd in_reduction(^ : S1) // expected-error {{'S1' does not refer to a value}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskgroup task_reduction(+:c)
+#pragma omp taskloop simd in_reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified list item cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}} expected-error {{in_reduction variable must appear in a task_reduction clause}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskloop simd in_reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'in_reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskloop simd in_reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskloop simd in_reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskloop simd in_reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskloop simd in_reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskloop simd in_reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskloop simd in_reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskloop simd in_reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskloop simd in_reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{nvalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskgroup task_reduction(+:k)
+#pragma omp taskloop simd in_reduction(+ : h, k, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskloop simd in_reduction(+ : o) // expected-error {{no viable overloaded '='}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp parallel private(k)
+#pragma omp taskloop simd in_reduction(+ : p), in_reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'in_reduction' must reference the same object in all threads}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskgroup task_reduction(+:p)
+#pragma omp taskloop simd in_reduction(+ : p), in_reduction(+ : p) // expected-error {{variable can appear only once in OpenMP 'in_reduction' clause}} expected-note {{previously referenced here}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp taskloop simd in_reduction(+ : r) // expected-error {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp parallel shared(i)
+#pragma omp parallel reduction(min : i)
+#pragma omp taskloop simd in_reduction(max : j) // expected-error {{argument of OpenMP clause 'in_reduction' must reference the same object in all threads}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp parallel
+#pragma omp for private(fl)
+ for (int i = 0; i < 10; ++i)
+#pragma omp taskgroup task_reduction(+:fl)
+#pragma omp taskloop simd in_reduction(+ : fl)
+ for (int j = 0; j < 10; ++j)
+ foo();
+#pragma omp taskgroup task_reduction(+:fl)
+#pragma omp taskloop simd in_reduction(+ : fl)
+ for (int i = 0; i < 10; ++i)
+ foo();
+ static int m;
+#pragma omp taskgroup task_reduction(+:m)
+#pragma omp taskloop simd in_reduction(+ : m) // OK
+ for (int i = 0; i < 10; ++i)
+ m++;
+
+ return tmain(argc) + tmain(fl); // expected-note {{in instantiation of function template specialization 'tmain<int>' requested here}} expected-note {{in instantiation of function template specialization 'tmain<float>' requested here}}
+}
diff --git a/test/OpenMP/taskloop_simd_lastprivate_messages.cpp b/test/OpenMP/taskloop_simd_lastprivate_messages.cpp
index ed1bdf5a6e3e..e5cba6c64b6b 100644
--- a/test/OpenMP/taskloop_simd_lastprivate_messages.cpp
+++ b/test/OpenMP/taskloop_simd_lastprivate_messages.cpp
@@ -18,9 +18,9 @@ public:
const S2 &operator =(const S2&) const;
S2 &operator =(const S2&);
static float S2s; // expected-note {{static data member is predetermined as shared}}
- static const float S2sc;
+ static const float S2sc; // expected-note {{static data member is predetermined as shared}}
};
-const float S2::S2sc = 0; // expected-note {{static data member is predetermined as shared}}
+const float S2::S2sc = 0;
const S2 b;
const S2 ba[5];
class S3 {
diff --git a/test/OpenMP/taskloop_simd_misc_messages.c b/test/OpenMP/taskloop_simd_misc_messages.c
index 61c7b107d496..35cc62cad585 100644
--- a/test/OpenMP/taskloop_simd_misc_messages.c
+++ b/test/OpenMP/taskloop_simd_misc_messages.c
@@ -346,6 +346,10 @@ void test_firstprivate() {
#pragma omp taskloop simd lastprivate(x, y, z) firstprivate(x, y, z)
for (i = 0; i < 16; ++i)
;
+// expected-error@+1 {{the value of 'simdlen' parameter must be less than or equal to the value of the 'safelen' parameter}}
+#pragma omp taskloop simd simdlen(64) safelen(8)
+ for (i = 0; i < 16; ++i)
+ ;
}
void test_loop_messages() {
diff --git a/test/OpenMP/taskloop_simd_reduction_codegen.cpp b/test/OpenMP/taskloop_simd_reduction_codegen.cpp
index b96c8d50a3ff..7e8d54a2a1da 100644
--- a/test/OpenMP/taskloop_simd_reduction_codegen.cpp
+++ b/test/OpenMP/taskloop_simd_reduction_codegen.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fopenmp -x c++ %s -verify -debug-info-kind=limited -emit-llvm -o - -triple powerpc64le-unknown-linux-gnu | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ %s -verify -debug-info-kind=limited -emit-llvm -o - -triple powerpc64le-unknown-linux-gnu -std=c++98 | FileCheck %s
// expected-no-diagnostics
struct S {
@@ -51,6 +51,7 @@ sum = 0.0;
// CHECK: [[AGG_CAPTURED:%.*]] = alloca [[STRUCT_ANON:%.*]],
// CHECK: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(%ident_t*
// CHECK: [[DOTRD_INPUT_:%.*]] = alloca [4 x %struct.kmp_task_red_input_t],
+// CHECK: alloca i32,
// CHECK: [[DOTCAPTURE_EXPR_:%.*]] = alloca i32,
// CHECK: [[DOTCAPTURE_EXPR_9:%.*]] = alloca i32,
// CHECK: store i32 0, i32* [[RETVAL]],
diff --git a/test/OpenMP/taskloop_simd_reduction_messages.cpp b/test/OpenMP/taskloop_simd_reduction_messages.cpp
index f9739f708a28..886b685f6325 100644
--- a/test/OpenMP/taskloop_simd_reduction_messages.cpp
+++ b/test/OpenMP/taskloop_simd_reduction_messages.cpp
@@ -25,9 +25,9 @@ public:
S2() : a(0) {}
S2(S2 &s2) : a(s2.a) {}
static float S2s; // expected-note 2 {{static data member is predetermined as shared}}
- static const float S2sc;
+ static const float S2sc; // expected-note 2 {{'S2sc' declared here}}
};
-const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}}
+const float S2::S2sc = 0;
S2 b; // expected-note 3 {{'b' defined here}}
const S2 ba[5]; // expected-note 2 {{'ba' defined here}}
class S3 {
diff --git a/test/OpenMP/teams_codegen.cpp b/test/OpenMP/teams_codegen.cpp
index 8aaa206abc3b..28f6ca0714d4 100644
--- a/test/OpenMP/teams_codegen.cpp
+++ b/test/OpenMP/teams_codegen.cpp
@@ -21,7 +21,7 @@ int teams_argument_global_local(int a){
int la = 23;
float lc = 25.0;
- // CK1: call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 1, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 0)
+ // CK1: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 1, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 0)
// CK1: call void @{{.+}}(i{{64|32}} %{{.+}})
#pragma omp target
#pragma omp teams
@@ -29,7 +29,7 @@ int teams_argument_global_local(int a){
++comp;
}
- // CK1: call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 1, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 0)
+ // CK1: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 1, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 0)
// CK1: call void @{{.+}}(i{{64|32}} %{{.+}})
#pragma omp target
{{{
@@ -39,7 +39,7 @@ int teams_argument_global_local(int a){
}
}}}
- // CK1-DAG: call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 2, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 [[NT:%[^,]+]], i32 0)
+ // CK1-DAG: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 2, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 [[NT:%[^,]+]], i32 0)
// CK1-DAG: [[NT]] = load i32, i32* [[NTA:%[^,]+]],
// CK1: call void @{{.+}}(i{{64|32}} %{{.+}})
@@ -49,7 +49,7 @@ int teams_argument_global_local(int a){
++comp;
}
- // CK1-DAG: call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 2, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 [[NT:%[^,]+]])
+ // CK1-DAG: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 2, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 [[NT:%[^,]+]])
// CK1-DAG: [[NT]] = load i32, i32* [[NTA:%[^,]+]],
// CK1: call void @{{.+}}(i{{64|32}} %{{.+}})
@@ -59,7 +59,7 @@ int teams_argument_global_local(int a){
++comp;
}
- // CK1-DAG: call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 5, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 [[NT:%[^,]+]], i32 [[TL:%[^,]+]])
+ // CK1-DAG: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 5, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 [[NT:%[^,]+]], i32 [[TL:%[^,]+]])
// CK1-DAG: [[NT]] = add nsw i32 [[NTA:%[^,]+]], [[NTB:%[^,]+]]
// CK1-DAG: [[NTA]] = load i32, i32* @Gbla,
@@ -78,7 +78,7 @@ int teams_argument_global_local(int a){
++comp;
}
- // CK1-DAG: call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 {{.+}}, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 [[NT:%[^,]+]], i32 [[TL:%[^,]+]])
+ // CK1-DAG: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 {{.+}}, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 [[NT:%[^,]+]], i32 [[TL:%[^,]+]])
// CK1-DAG: [[NT]] = add nsw i32 [[NTA:%[^,]+]], 1
// CK1-DAG: [[NTA]] = load i32, i32* @Gbla,
@@ -125,7 +125,7 @@ int teams_template_arg(void) {
SS<int> la;
SS<long long> lb;
- // CK2-DAG: call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 3, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 [[NT:%[^,]+]], i32 [[TL:%[^,]+]])
+ // CK2-DAG: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 3, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 [[NT:%[^,]+]], i32 [[TL:%[^,]+]])
// CK2-DAG: [[NT]] = load i32, i32* getelementptr inbounds ([[SSI]], [[SSI]]* @Gbla, i32 0, i32 0)
@@ -141,7 +141,7 @@ int teams_template_arg(void) {
++comp;
}
- // CK2-DAG: call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 3, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 [[NT:%[^,]+]], i32 [[TL:%[^,]+]])
+ // CK2-DAG: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 3, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 [[NT:%[^,]+]], i32 [[TL:%[^,]+]])
// CK2-DAG: [[TL]] = trunc i64 [[TLD:%[^,]+]] to i32
// CK2-DAG: [[TLD]] = load i64, i64* getelementptr inbounds ([[SSL]], [[SSL]]* @Gblb, i32 0, i32 0),
@@ -181,7 +181,7 @@ struct SS{
int foo(void) {
int comp = 1;
- // CK3-DAG: call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 2, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 [[NT:%[^,]+]], i32 123)
+ // CK3-DAG: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 2, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 [[NT:%[^,]+]], i32 123)
// CK3-DAG: [[NT]] = load i32, i32* [[NTA:%[^,]+]],
// CK3-DAG: [[NTA]] = getelementptr inbounds [[SSI]], [[SSI]]* [[NTB:%[^,]+]], i32 0, i32 0
@@ -194,7 +194,7 @@ struct SS{
++comp;
}
- // CK3-DAG: call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 2, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 456, i32 [[TL:%[^,]+]])
+ // CK3-DAG: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 2, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 456, i32 [[TL:%[^,]+]])
// CK3-DAG: [[TL]] = add nsw i32 [[TLA:%[^,]+]], 123
// CK3-DAG: [[TLA]] = fptosi float [[TLB:%[^,]+]] to i32
diff --git a/test/OpenMP/teams_distribute_codegen.cpp b/test/OpenMP/teams_distribute_codegen.cpp
new file mode 100644
index 000000000000..8a2afbd4341d
--- /dev/null
+++ b/test/OpenMP/teams_distribute_codegen.cpp
@@ -0,0 +1,241 @@
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+// Test host codegen.
+// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64
+// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32
+#ifdef CK1
+
+int a[100];
+
+// CK1: define {{.*}}i32 @{{.+}}teams_argument_globali(
+int teams_argument_global(int n){
+ int te = n / 128;
+ int th = 128;
+ // discard n_addr
+ // CK1: alloca i32,
+ // CK1: [[TE:%.+]] = alloca i32,
+ // CK1: [[TH:%.+]] = alloca i32,
+ // CK1: [[TE_CAST:%.+]] = alloca i{{32|64}},
+ // CK1: [[TH_CAST:%.+]] = alloca i{{32|64}},
+ // CK1: [[TE_PAR:%.+]] = load{{.+}}, {{.+}} [[TE_CAST]],
+ // CK1: [[TH_PAR:%.+]] = load{{.+}}, {{.+}} [[TH_CAST]],
+
+ // CK1: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 4, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 {{.+}}, i32 {{.+}})
+
+ // CK1: call void @[[OFFL1:.+]](i{{32|64}} [[TE_PAR]], i{{32|64}} [[TH_PAR]],
+ #pragma omp target
+ #pragma omp teams distribute num_teams(te), thread_limit(th)
+ for(int i = 0; i < n; i++) {
+ a[i] = 0;
+ }
+
+ // CK1: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 2, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 0)
+ // CK1: call void @[[OFFL2:.+]](i{{64|32}} %{{.+}})
+ #pragma omp target
+ {{{
+ #pragma omp teams distribute
+ for(int i = 0; i < n; i++) {
+ a[i] = 0;
+ }
+ }}}
+
+ // outlined target regions
+ // CK1: define internal void @[[OFFL1]](i{{32|64}} [[TE_ARG:%.+]], i{{32|64}} [[TH_ARG:%.+]], i{{32|64}} {{.+}}, {{.+}})
+ // CK1: [[TE_ADDR:%.+]] = alloca i{{32|64}},
+ // CK1: [[TH_ADDR:%.+]] = alloca i{{32|64}},
+ // CK1: store{{.+}} [[TE_ARG]], {{.+}} [[TE_ADDR]],
+ // CK1: store{{.+}} [[TH_ARG]], {{.+}} [[TH_ADDR]],
+ // CK1-64: [[TE_CONV:%.+]] = bitcast{{.+}} [[TE_ADDR]] to
+ // CK1-64: [[TH_CONV:%.+]] = bitcast{{.+}} [[TH_ADDR]] to
+ // CK1-64: [[TE_VAL:%.+]] = load i32, i32* [[TE_CONV]],
+ // CK1-64: [[TH_VAL:%.+]] = load i32, i32* [[TH_CONV]],
+ // CK1-32: [[TE_VAL:%.+]] = load i32, i32* [[TE_ADDR]],
+ // CK1-32: [[TH_VAL:%.+]] = load i32, i32* [[TH_ADDR]],
+ // CK1: {{%.+}} = call i32 @__kmpc_push_num_teams({{.+}}, {{.+}}, i32 [[TE_VAL]], i32 [[TH_VAL]])
+ // CK1: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 2, {{.+}} @[[OUTL1:.+]] to {{.+}}, {{.+}}, {{.+}})
+ // CK1: ret void
+
+ // CK1: define internal void @[[OUTL1]]({{.+}})
+ // CK1: call void @__kmpc_for_static_init_4(
+ // CK1: call void @__kmpc_for_static_fini(
+ // CK1: ret void
+
+ // CK1: define internal void @[[OFFL2]]({{.+}}, {{.+}})
+ // CK1: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 2, {{.+}} @[[OUTL2:.+]] to {{.+}}, {{.+}}, {{.+}})
+ // CK1: ret void
+
+ // CK1: define internal void @[[OUTL2]]({{.+}})
+ // CK1: call void @__kmpc_for_static_init_4(
+ // CK1: call void @__kmpc_for_static_fini(
+ // CK1: ret void
+
+ return a[0];
+}
+
+#endif // CK1
+
+// Test host codegen.
+// RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64
+// RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32
+#ifdef CK2
+
+// CK2: define {{.*}}i32 @{{.+}}teams_local_argv(
+int teams_local_arg(void) {
+ int n = 100;
+ int a[n];
+
+ // CK2: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 3, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}, i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 0)
+ // CK2: call void @[[OFFL1:.+]](i{{64|32}} %{{.+}})
+ #pragma omp target
+ #pragma omp teams distribute
+ for(int i = 0; i < n; i++) {
+ a[i] = 0;
+ }
+
+ // outlined target region
+ // CK2: define internal void @[[OFFL1]]({{.+}}, {{.+}})
+ // CK2: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 3, {{.+}} @[[OUTL1:.+]] to {{.+}}, {{.+}}, {{.+}})
+ // CK2: ret void
+
+ // CK2: define internal void @[[OUTL1]]({{.+}})
+ // CK2: call void @__kmpc_for_static_init_4(
+ // CK2: call void @__kmpc_for_static_fini(
+ // CK2: ret void
+
+ return a[0];
+}
+#endif // CK2
+
+// Test host codegen.
+// RUN: %clang_cc1 -DCK3 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK3 --check-prefix CK3-64
+// RUN: %clang_cc1 -DCK3 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK3 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK3 --check-prefix CK3-64
+// RUN: %clang_cc1 -DCK3 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK3 --check-prefix CK3-32
+// RUN: %clang_cc1 -DCK3 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK3 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK3 --check-prefix CK3-32
+#ifdef CK3
+
+// CK3: [[SSI:%.+]] = type { [{{.+}} x i32], float }
+
+template <typename T, int X, long long Y>
+struct SS{
+ T a[X];
+ float b;
+ // CK3: define {{.*}}i32 @{{.+}}foo{{.+}}(
+ int foo(void) {
+
+ // CK3: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 1, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 0)
+ // CK3: call void @[[OFFL1:.+]]([[SSI]]* %{{.+}})
+ #pragma omp target
+ #pragma omp teams distribute
+ for(int i = 0; i < X; i++) {
+ a[i] = (T)0;
+ }
+
+ // outlined target region
+ // CK3: define internal void @[[OFFL1]]([[SSI]]* {{.+}})
+ // CK3: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTL1:.+]] to {{.+}}, {{.+}}, {{.+}})
+ // CK3: ret void
+
+ // CK3: define internal void @[[OUTL1]]({{.+}})
+ // CK3: call void @__kmpc_for_static_init_4(
+ // CK3: call void @__kmpc_for_static_fini(
+ // CK3: ret void
+
+ return a[0];
+ }
+};
+
+int teams_template_struct(void) {
+ SS<int, 123, 456> V;
+ return V.foo();
+
+}
+#endif // CK3
+
+// Test host codegen.
+// RUN: %clang_cc1 -DCK4 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK4 --check-prefix CK4-64
+// RUN: %clang_cc1 -DCK4 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK4 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK4 --check-prefix CK4-64
+// RUN: %clang_cc1 -DCK4 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK4 --check-prefix CK4-32
+// RUN: %clang_cc1 -DCK4 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK4 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK4 --check-prefix CK4-32
+
+#ifdef CK4
+
+template <typename T, int n>
+int tmain(T argc) {
+ T a[n];
+ int te = n/128;
+ int th = 128;
+#pragma omp target
+#pragma omp teams distribute num_teams(te) thread_limit(th)
+ for(int i = 0; i < n; i++) {
+ a[i] = (T)0;
+ }
+ return 0;
+}
+
+int main (int argc, char **argv) {
+ int n = 100;
+ int a[n];
+#pragma omp target
+#pragma omp teams distribute
+ for(int i = 0; i < n; i++) {
+ a[i] = 0;
+ }
+ return tmain<int, 10>(argc);
+}
+
+// CK4: define {{.*}}i32 @{{[^,]+}}(i{{.+}}{{.+}} %[[ARGC:.+]], {{.+}})
+// CK4: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 3, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}, i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 0)
+// CK4: call void @[[OFFL1:.+]]({{.+}})
+// CK4: {{%.+}} = call{{.*}} i32 @[[TMAIN:.+]]({{.+}})
+// CK4: ret
+
+// CK4: define {{.*}}void @[[OFFL1]]({{.+}})
+// CK4: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 3, {{.+}} @[[OUTL1:.+]] to {{.+}}, {{.+}}, {{.+}})
+// CK4: ret void
+
+// CK4: define internal void @[[OUTL1]]({{.+}})
+// CK4: call void @__kmpc_for_static_init_4(
+// CK4: call void @__kmpc_for_static_fini(
+// CK4: ret void
+
+// CK4: define {{.*}}i32 @[[TMAIN]]({{.+}})
+// CK4: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 3, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 {{.+}}, i32 {{.+}})
+// CK4: call void @[[OFFLT:.+]]({{.+}})
+// CK4: ret
+// CK4-NEXT: }
+
+// CK4: define {{.*}}void @[[OFFLT]](i{{32|64}} [[TE_ARG:%.+]], i{{32|64}} [[TH_ARG:%.+]], {{.+}})
+// CK4: [[TE_ADDR:%.+]] = alloca i{{32|64}},
+// CK4: [[TH_ADDR:%.+]] = alloca i{{32|64}},
+// CK4: store{{.+}} [[TE_ARG]], {{.+}} [[TE_ADDR]],
+// CK4: store{{.+}} [[TH_ARG]], {{.+}} [[TH_ADDR]],
+// CK4-64: [[TE_CONV:%.+]] = bitcast{{.+}} [[TE_ADDR]] to
+// CK4-64: [[TH_CONV:%.+]] = bitcast{{.+}} [[TH_ADDR]] to
+// CK4-64: [[TE_VAL:%.+]] = load i32, i32* [[TE_CONV]],
+// CK4-64: [[TH_VAL:%.+]] = load i32, i32* [[TH_CONV]],
+// CK4-32: [[TE_VAL:%.+]] = load i32, i32* [[TE_ADDR]],
+// CK4-32: [[TH_VAL:%.+]] = load i32, i32* [[TH_ADDR]],
+// CK4: {{%.+}} = call i32 @__kmpc_push_num_teams({{.+}}, {{.+}}, i32 [[TE_VAL]], i32 [[TH_VAL]])
+// CK4: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTLT:.+]] to {{.+}}, {{.+}}, {{.+}})
+// CK4: ret void
+
+// CK4: define internal void @[[OUTLT]]({{.+}})
+// CK4: call void @__kmpc_for_static_init_4(
+// CK4: call void @__kmpc_for_static_fini(
+// CK4: ret void
+
+#endif // CK4
+#endif
diff --git a/test/OpenMP/teams_distribute_collapse_codegen.cpp b/test/OpenMP/teams_distribute_collapse_codegen.cpp
new file mode 100644
index 000000000000..a65c0a2e63f7
--- /dev/null
+++ b/test/OpenMP/teams_distribute_collapse_codegen.cpp
@@ -0,0 +1,128 @@
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+// Test host codegen.
+// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64
+// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32
+#ifdef CK1
+
+template <typename T, int X, long long Y>
+struct SS{
+ T a[X][Y];
+
+ // CK1: define {{.*}}i32 @{{.+}}foo{{.+}}(
+ int foo(void) {
+
+ // CK1: call i32 @__tgt_target_teams(
+ // CK1: call void @[[OFFL1:.+]](
+ #pragma omp target
+ #pragma omp teams distribute collapse(2)
+ for(int i = 0; i < X; i++) {
+ for(int j = 0; j < Y; j++) {
+ a[i][j] = (T)0;
+ }
+ }
+ // CK1: define internal void @[[OFFL1]](
+ // CK1: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTL1:.+]] to {{.+}},
+ // CK1: ret void
+
+ // CK1: define internal void @[[OUTL1]]({{.+}})
+ // discard loop variables not needed here
+ // CK1: = alloca i32,
+ // CK1: = alloca i32,
+ // CK1: = alloca i32,
+ // CK1: = alloca i32,
+ // CK1: [[OMP_UB:%.+]] = alloca i32,
+ // CK1: store i32 56087, i32* [[OMP_UB]],
+ // CK1: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 92, {{.+}}, {{.+}}, i32* [[OMP_UB]],
+ // CK1: call void @__kmpc_for_static_fini(
+ // CK1: ret void
+
+ return a[0][0];
+ }
+};
+
+int teams_template_struct(void) {
+ SS<int, 123, 456> V;
+ return V.foo();
+
+}
+#endif // CK1
+
+// Test host codegen.
+// RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64
+// RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32
+#ifdef CK2
+
+template <typename T, int n, int m>
+int tmain(T argc) {
+ T a[n][m];
+ #pragma omp target
+ #pragma omp teams distribute collapse(2)
+ for(int i = 0; i < n; i++) {
+ for(int j = 0; j < m; j++) {
+ a[i][j] = (T)0;
+ }
+ }
+ return 0;
+}
+
+int main (int argc, char **argv) {
+ int n = 100;
+ int m = 2;
+ int a[n][m];
+ #pragma omp target
+ #pragma omp teams distribute collapse(2)
+ for(int i = 0; i < n; i++) {
+ for(int j = 0; j < m; j++) {
+ a[i][j] = 0;
+ }
+ }
+ return tmain<int, 10, 2>(argc);
+}
+
+// CK2: define {{.*}}i32 @{{[^,]+}}(i{{.+}}{{.+}} %[[ARGC:.+]], {{.+}})
+// CK2: call i32 @__tgt_target_teams(
+// CK2: call void @[[OFFL1:.+]]({{.+}})
+// CK2: {{%.+}} = call{{.*}} i32 @[[TMAIN:.+]]({{.+}})
+// CK2: ret
+
+// CK2: define {{.*}}void @[[OFFL1]]({{.+}})
+// CK2: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 5, {{.+}} @[[OUTL1:.+]] to {{.+}},
+// CK2: ret void
+
+// CK2: define internal void @[[OUTL1]]({{.+}})
+// CK2: [[OMP_UB:%.omp.ub]] = alloca i64,
+// CK2: store i64 {{.+}}, i64* [[OMP_UB]],
+// CK2: call void @__kmpc_for_static_init_8({{.+}}, {{.+}}, i32 92, {{.+}}, {{.+}}, i64* [[OMP_UB]],
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+// CK2: define {{.*}}i32 @[[TMAIN]]({{.+}})
+// CK2: call i32 @__tgt_target_teams(
+// CK2: call void @[[OFFLT1:.+]]({{.+}})
+// CK2: ret
+// CK2-NEXT: }
+
+// CK2: define {{.*}}void @[[OFFLT1]]({{.+}})
+// CK2: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTLT1:.+]] to {{.+}},
+// CK2: ret void
+
+// CK2: define internal void @[[OUTLT1]]({{.+}})
+// discard loop variables not needed here
+// CK2: [[OMP_UB:%.omp.ub]] = alloca i32,
+// CK2: store i32 {{.+}}, i32* [[OMP_UB]],
+// CK2: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 92, {{.+}}, {{.+}}, i32* [[OMP_UB]],
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+#endif // CK2
+#endif // #ifndef HEADER
diff --git a/test/OpenMP/teams_distribute_dist_schedule_codegen.cpp b/test/OpenMP/teams_distribute_dist_schedule_codegen.cpp
new file mode 100644
index 000000000000..8bd8825e00c4
--- /dev/null
+++ b/test/OpenMP/teams_distribute_dist_schedule_codegen.cpp
@@ -0,0 +1,206 @@
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+// Test host codegen.
+// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64
+// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32
+#ifdef CK1
+
+template <typename T, int X, long long Y>
+struct SS{
+ T a[X];
+ float b;
+ // CK1: define {{.*}}i32 @{{.+}}foo{{.+}}(
+ int foo(void) {
+
+ // CK1: call i32 @__tgt_target_teams(
+ // CK1: call void @[[OFFL1:.+]](
+ #pragma omp target
+ #pragma omp teams distribute
+ for(int i = 0; i < X; i++) {
+ a[i] = (T)0;
+ }
+ // CK1: call i32 @__tgt_target_teams(
+ // CK1: call void @[[OFFL2:.+]](
+ #pragma omp target
+ #pragma omp teams distribute dist_schedule(static)
+ for(int i = 0; i < X; i++) {
+ a[i] = (T)0;
+ }
+ // CK1: call i32 @__tgt_target_teams(
+ // CK1: call void @[[OFFL3:.+]](
+ #pragma omp target
+ #pragma omp teams distribute dist_schedule(static, X/2)
+ for(int i = 0; i < X; i++) {
+ a[i] = (T)0;
+ }
+ // CK1: define internal void @[[OFFL1]](
+ // CK1: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTL1:.+]] to {{.+}},
+ // CK1: ret void
+
+ // CK1: define internal void @[[OUTL1]]({{.+}})
+ // CK1: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 92
+ // CK1: call void @__kmpc_for_static_fini(
+ // CK1: ret void
+
+ // CK1: define internal void @[[OFFL2]](
+ // CK1: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTL2:.+]] to {{.+}},
+ // CK1: ret void
+
+ // CK1: define internal void @[[OUTL2]]({{.+}})
+ // CK1: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 92
+ // CK1: call void @__kmpc_for_static_fini(
+ // CK1: ret void
+
+ // CK1: define internal void @[[OFFL3]](
+ // CK1: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTL3:.+]] to {{.+}},
+ // CK1: ret void
+
+ // CK1: define internal void @[[OUTL3]]({{.+}})
+ // CK1: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 91
+ // CK1: call void @__kmpc_for_static_fini(
+ // CK1: ret void
+
+ return a[0];
+ }
+};
+
+int teams_template_struct(void) {
+ SS<int, 123, 456> V;
+ return V.foo();
+
+}
+#endif // CK1
+
+// Test host codegen.
+// RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64
+// RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32
+#ifdef CK2
+
+template <typename T, int n>
+int tmain(T argc) {
+ T a[n];
+#pragma omp target
+#pragma omp teams distribute
+ for(int i = 0; i < n; i++) {
+ a[i] = (T)0;
+ }
+#pragma omp target
+#pragma omp teams distribute dist_schedule(static)
+ for(int i = 0; i < n; i++) {
+ a[i] = (T)0;
+ }
+#pragma omp target
+#pragma omp teams distribute dist_schedule(static, n)
+ for(int i = 0; i < n; i++) {
+ a[i] = (T)0;
+ }
+ return 0;
+}
+
+int main (int argc, char **argv) {
+ int n = 100;
+ int a[n];
+#pragma omp target
+#pragma omp teams distribute
+ for(int i = 0; i < n; i++) {
+ a[i] = 0;
+ }
+#pragma omp target
+#pragma omp teams distribute dist_schedule(static)
+ for(int i = 0; i < n; i++) {
+ a[i] = 0;
+ }
+#pragma omp target
+#pragma omp teams distribute dist_schedule(static, n)
+ for(int i = 0; i < n; i++) {
+ a[i] = 0;
+ }
+ return tmain<int, 10>(argc);
+}
+
+// CK2: define {{.*}}i32 @{{[^,]+}}(i{{.+}}{{.+}} %[[ARGC:.+]], {{.+}})
+// CK2: call i32 @__tgt_target_teams(
+// CK2: call void @[[OFFL1:.+]]({{.+}})
+// CK2: call i32 @__tgt_target_teams(
+// CK2: call void @[[OFFL2:.+]]({{.+}})
+// CK2: call i32 @__tgt_target_teams(
+// CK2: call void @[[OFFL3:.+]]({{.+}})
+// CK2: {{%.+}} = call{{.*}} i32 @[[TMAIN:.+]]({{.+}})
+// CK2: ret
+
+// CK2: define {{.*}}void @[[OFFL1]]({{.+}})
+// CK2: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 3, {{.+}} @[[OUTL1:.+]] to {{.+}},
+// CK2: ret void
+
+// CK2: define internal void @[[OUTL1]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 92
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define {{.*}}void @[[OFFL2]]({{.+}})
+// CK2: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 3, {{.+}} @[[OUTL2:.+]] to {{.+}},
+// CK2: ret void
+
+// CK2: define internal void @[[OUTL2]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 92
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define {{.*}}void @[[OFFL3]]({{.+}})
+// CK2: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 4, {{.+}} @[[OUTL3:.+]] to {{.+}},
+// CK2: ret void
+
+// CK2: define internal void @[[OUTL3]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 91
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define {{.*}}i32 @[[TMAIN]]({{.+}})
+// CK2: call i32 @__tgt_target_teams(
+// CK2: call void @[[OFFLT1:.+]]({{.+}})
+// CK2: call i32 @__tgt_target_teams(
+// CK2: call void @[[OFFLT2:.+]]({{.+}})
+// CK2: call i32 @__tgt_target_teams(
+// CK2: call void @[[OFFLT3:.+]]({{.+}})
+// CK2: ret
+// CK2-NEXT: }
+
+// CK2: define {{.*}}void @[[OFFLT1]]({{.+}})
+// CK2: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTLT1:.+]] to {{.+}},
+// CK2: ret void
+
+// CK2: define internal void @[[OUTLT1]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 92
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define {{.*}}void @[[OFFLT2]]({{.+}})
+// CK2: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTLT2:.+]] to {{.+}},
+// CK2: ret void
+
+// CK2: define internal void @[[OUTLT2]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 92
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define {{.*}}void @[[OFFLT3]]({{.+}})
+// CK2: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTLT3:.+]] to {{.+}},
+// CK2: ret void
+
+// CK2: define internal void @[[OUTLT3]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 91
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+#endif // CK2
+#endif // #ifndef HEADER
diff --git a/test/OpenMP/teams_distribute_firstprivate_codegen.cpp b/test/OpenMP/teams_distribute_firstprivate_codegen.cpp
new file mode 100644
index 000000000000..a126b1d16b77
--- /dev/null
+++ b/test/OpenMP/teams_distribute_firstprivate_codegen.cpp
@@ -0,0 +1,336 @@
+// RUN: %clang_cc1 -DCHECK -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -DCHECK -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+
+// RUN: %clang_cc1 -DLAMBDA -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+struct St {
+ int a, b;
+ St() : a(0), b(0) {}
+ St(const St &st) : a(st.a + st.b), b(0) {}
+ ~St() {}
+};
+
+volatile int g = 1212;
+volatile int &g1 = g;
+
+template <class T>
+struct S {
+ T f;
+ S(T a) : f(a + g) {}
+ S() : f(g) {}
+ S(const S &s, St t = St()) : f(s.f + t.a) {}
+ operator T() { return T(); }
+ ~S() {}
+};
+
+// CHECK-DAG: [[S_FLOAT_TY:%.+]] = type { float }
+// CHECK-DAG: [[S_INT_TY:%.+]] = type { i{{[0-9]+}} }
+// CHECK-DAG: [[ST_TY:%.+]] = type { i{{[0-9]+}}, i{{[0-9]+}} }
+
+template <typename T>
+T tmain() {
+ S<T> test;
+ T t_var = T();
+ T vec[] = {1, 2};
+ S<T> s_arr[] = {1, 2};
+ S<T> &var = test;
+#pragma omp target
+#pragma omp teams distribute firstprivate(t_var, vec, s_arr, var)
+ for (int i = 0; i < 2; ++i) {
+ vec[i] = t_var;
+ s_arr[i] = var;
+ }
+ return T();
+}
+
+// CHECK-DAG: [[TEST:@.+]] = global [[S_FLOAT_TY]] zeroinitializer,
+S<float> test;
+// CHECK-DAG: [[T_VAR:@.+]] = global i{{[0-9]+}} 333,
+int t_var = 333;
+// CHECK-DAG: [[VEC:@.+]] = global [2 x i{{[0-9]+}}] [i{{[0-9]+}} 1, i{{[0-9]+}} 2],
+int vec[] = {1, 2};
+// CHECK-DAG: [[S_ARR:@.+]] = global [2 x [[S_FLOAT_TY]]] zeroinitializer,
+S<float> s_arr[] = {1, 2};
+// CHECK-DAG: [[VAR:@.+]] = global [[S_FLOAT_TY]] zeroinitializer,
+S<float> var(3);
+// CHECK-DAG: [[SIVAR:@.+]] = internal global i{{[0-9]+}} 0,
+
+int main() {
+ static int sivar;
+#ifdef LAMBDA
+ // LAMBDA: [[G:@.+]] = global i{{[0-9]+}} 1212,
+ // LAMBDA-LABEL: @main
+ // LAMBDA: call void [[OUTER_LAMBDA:@.+]](
+ [&]() {
+ // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
+ // LAMBDA: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 3, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 0)
+ // LAMBDA: call void @[[LOFFL1:.+]](i{{64|32}} %{{.+}})
+ // LAMBDA: ret
+#pragma omp target
+#pragma omp teams distribute firstprivate(g, g1, sivar)
+ for (int i = 0; i < 2; ++i) {
+ // LAMBDA: define{{.*}} internal{{.*}} void @[[LOFFL1]](i{{64|32}} {{%.+}}, i{{64|32}} {{%.+}})
+ // LAMBDA: {{%.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: {{%.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: {{%.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: [[G_CAST:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[G1_CAST:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[SIVAR_CAST:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA-DAG: [[G_CAST_VAL:%.+]] = load{{.+}} [[G_CAST]],
+ // LAMBDA-DAG: [[G1_CAST_VAL:%.+]] = load{{.+}} [[G1_CAST]],
+ // LAMBDA-DAG: [[SIVAR_CAST_VAL:%.+]] = load{{.+}} [[SIVAR_CAST]],
+ // LAMBDA: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 3, {{.+}} @[[LOUTL1:.+]] to {{.+}}, {{.+}} [[G_CAST_VAL]], {{.+}} [[G1_CAST_VAL]], {{.+}} [[SIVAR_CAST_VAL]])
+ // LAMBDA: ret void
+
+ // LAMBDA: define internal void @[[LOUTL1]]({{.+}})
+ // Skip global and bound tid vars
+ // LAMBDA: {{.+}} = alloca i32*,
+ // LAMBDA: {{.+}} = alloca i32*,
+ // LAMBDA: [[G_ADDR:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[G1_ADDR:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[SIVAR_ADDR:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[G1_TMP:%.+]] = alloca i32*,
+ // skip loop vars
+ // LAMBDA-DAG: store {{.+}}, {{.+}} [[G_ADDR]],
+ // LAMBDA-DAG: store {{.+}}, {{.+}} [[G1_ADDR]],
+ // LAMBDA-DAG: store {{.+}}, {{.+}} [[SIVAR_ADDR]],
+ // LAMBDA-DAG: [[G_CONV:%.+]] = bitcast {{.+}} [[G_ADDR]] to
+ // LAMBDA-DAG: [[G1_CONV:%.+]] = bitcast {{.+}} [[G1_ADDR]] to
+ // LAMBDA-DAG: [[SIVAR_CONV:%.+]] = bitcast {{.+}} [[SIVAR_ADDR]] to
+ // LAMBDA-DAG: store{{.+}} [[G1_CONV]], {{.+}} [[G1_TMP]],
+ g = 1;
+ g1 = 1;
+ sivar = 2;
+ // LAMBDA: call void @__kmpc_for_static_init_4(
+ // LAMBDA-DAG: store{{.+}} 1, {{.+}} [[G_CONV]],
+ // LAMBDA-DAG: [[G1:%.+]] = load{{.+}}, {{.+}}* [[G1_TMP]]
+ // LAMBDA-DAG: store{{.+}} 1, {{.+}} [[G1]],
+ // LAMBDA-DAG: store{{.+}} 2, {{.+}} [[SIVAR_CONV]],
+ // LAMBDA-DAG: [[G1_REF:%.+]] = load{{.+}}, {{.+}} [[G1_TMP]],
+ // LAMBDA-DAG: store{{.+}} 1, {{.+}} [[G1_REF]],
+ // LAMBDA: call void [[INNER_LAMBDA:@.+]](
+ // LAMBDA: call void @__kmpc_for_static_fini(
+ [&]() {
+ // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]])
+ // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]],
+ g = 2;
+ g1 = 2;
+ sivar = 4;
+ // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]]
+
+ // LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // LAMBDA: [[G_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G_PTR_REF]]
+ // LAMBDA: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[G_REF]]
+ // LAMBDA: [[G1_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // LAMBDA: [[G1_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G1_PTR_REF]]
+ // LAMBDA: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[G1_REF]]
+ // LAMBDA: [[SIVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+ // LAMBDA: [[SIVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SIVAR_PTR_REF]]
+ // LAMBDA: store i{{[0-9]+}} 4, i{{[0-9]+}}* [[SIVAR_REF]]
+ }();
+ }
+ }();
+ return 0;
+#else
+#pragma omp target
+#pragma omp teams distribute firstprivate(t_var, vec, s_arr, var, sivar)
+ for (int i = 0; i < 2; ++i) {
+ vec[i] = t_var;
+ s_arr[i] = var;
+ sivar += i;
+ }
+ return tmain<int>();
+#endif
+}
+
+// CHECK: define {{.*}}i{{[0-9]+}} @main()
+// CHECK: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 5, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 0)
+// CHECK: call void @[[OFFL1:.+]](i{{64|32}} %{{.+}})
+// CHECK: {{%.+}} = call{{.*}} i32 @[[TMAIN_INT:.+]]()
+// CHECK: ret
+
+// CHECK: define{{.*}} void @[[OFFL1]]({{.+}})
+// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}]*,
+// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]]*,
+// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]]*,
+// CHECK: [[SIVAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[T_VAR_CAST:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[SIVAR_CAST:%.+]] = alloca i{{[0-9]+}},
+
+// CHECK-DAG: [[VEC_TE_PAR:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** [[VEC_PRIV]],
+// CHECK-DAG: [[T_VAR_TE_PAR:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_CAST]],
+// CHECK-DAG: [[S_ARR_TE_PAR:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[S_ARR_PRIV]],
+// CHECK-DAG: [[VAR_TE_PAR:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[VAR_PRIV]],
+// CHECK-DAG: [[SIVAR_TE_PAR:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR_CAST]],
+
+// CHECK: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 5, {{.+}} @[[OUTL1:.+]] to {{.+}}, [2 x i{{[0-9]+}}]* [[VEC_TE_PAR]], i{{[0-9]+}} [[T_VAR_TE_PAR]], [2 x [[S_FLOAT_TY]]]* [[S_ARR_TE_PAR]], [[S_FLOAT_TY]]* [[VAR_TE_PAR]], i{{[0-9]+}} [[SIVAR_TE_PAR]])
+// CHECK: ret void
+
+// CHECK: define internal void @[[OUTL1]]({{.+}})
+// Skip global and bound tid vars
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: [[VEC_ADDR:%.+]] = alloca [2 x i{{[0-9]+}}]*,
+// CHECK: [[T_VAR_ADDR:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[S_ARR_ADDR:%.+]] = alloca [2 x [[S_FLOAT_TY]]]*,
+// CHECK: [[VAR_ADDR:%.+]] = alloca [[S_FLOAT_TY]]*,
+// CHECK: [[SIVAR_ADDR:%.+]] = alloca i{{[0-9]+}},
+// Skip temp vars for loop
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]],
+// CHECK: [[AGG_TMP1:%.+]] = alloca [[ST_TY]],
+// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]],
+// CHECK: [[AGG_TMP2:%.+]] = alloca [[ST_TY]],
+
+// param copy
+// CHECK: store [2 x i{{[0-9]+}}]* {{.+}}, [2 x i{{[0-9]+}}]** [[VEC_ADDR]],
+// CHECK: store i{{[0-9]+}} {{.+}}, i{{[0-9]+}}* [[T_VAR_ADDR]],
+// CHECK: store [2 x [[S_FLOAT_TY]]]* {{.+}}, [2 x [[S_FLOAT_TY]]]** [[S_ARR_ADDR]],
+// CHECK: store [[S_FLOAT_TY]]* {{.+}}, [[S_FLOAT_TY]]** [[VAR_ADDR]],
+// CHECK: store i{{[0-9]+}} {{.+}}, i{{[0-9]+}}* [[SIVAR_ADDR]],
+
+// T_VAR and SIVAR
+// CHECK-DAG-64: [[CONV_TVAR:%.+]] = bitcast i64* [[T_VAR_ADDR]] to i32*
+// CHECK-DAG-64: [[CONV_SIVAR:%.+]] = bitcast i64* [[SIVAR_ADDR]] to i32*
+
+// preparation vars
+// CHECK-DAG: [[VEC_ADDR_VAL:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** [[VEC_ADDR]],
+// CHECK-DAG: [[S_ARR_ADDR_REF:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[S_ARR_ADDR]],
+// CHECK-DAG: [[VAR_ADDR_REF:%.+]] = load{{.+}} [[VAR_ADDR]],
+
+// firstprivate vec(vec): copy from *_addr into priv1 and then from priv1 into priv2
+// CHECK-DAG: [[VEC_DEST_PRIV:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV]] to i8*
+// CHECK-DAG: [[VEC_SRC:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_ADDR_VAL]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[VEC_DEST_PRIV]], i8* [[VEC_SRC]], {{.+}})
+
+// firstprivate(s_arr)
+// CHECK-DAG: [[S_ARR_PRIV_BGN:%.+]] = getelementptr{{.*}} [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[S_ARR_PRIV]],
+// CHECK-DAG: [[S_ARR_ADDR_BGN:%.+]] = bitcast [2 x [[S_FLOAT_TY]]]* [[S_ARR_ADDR_REF]] to
+// CHECK-DAG: [[S_ARR_FIN:%.+]] = icmp{{.+}} [[S_ARR_PRIV_BGN]],
+// CHECK-DAG: [[S_ARR_SRC_COPY:%.+]] = phi{{.+}} [ [[S_ARR_ADDR_BGN]], {{.+}} ], [ [[S_ARR_SRC:%.+]], {{.+}} ]
+// CHECK-DAG: [[S_ARR_DST_COPY:%.+]] = phi{{.+}} [ [[S_ARR_PRIV_BGN]], {{.+}}], [ [[S_ARR_DST:%.+]], {{.+}} ]
+// CHECK-DAG: call void @{{.+}}({{.+}} [[AGG_TMP1]])
+// CHECK-DAG: call void @{{.+}}({{.+}} [[S_ARR_DST_COPY]], {{.+}} [[S_ARR_SRC_COPY]], {{.+}} [[AGG_TMP1]])
+// CHECK-DAG: call void @{{.+}}({{.+}} [[AGG_TMP1]])
+// CHECK-DAG: [[S_ARR_DST]] = getelementptr {{.+}} [[S_ARR_DST_COPY]],
+// CHECK-DAG: [[S_ARR_SRC]] = getelementptr {{.+}} [[S_ARR_SRC_COPY]],
+
+// firstprivate(var)
+// CHECK-DAG: call void @{{.+}}({{.+}} [[AGG_TMP2]])
+// CHECK-DAG: call void @{{.+}}({{.+}} [[VAR_PRIV]], {{.+}} [[VAR_ADDR_REF]], {{.+}} [[AGG_TMP2]])
+// CHECK-DAG: call void @{{.+}}({{.+}} [[AGG_TMP2]])
+
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK-DAG-32: {{.+}} = {{.+}} [[T_VAR_ADDR]]
+// CHECK-DAG-64: {{.+}} = {{.+}} [[CONV_TVAR]]
+// CHECK-DAG: {{.+}} = {{.+}} [[VEC_PRIV]]
+// CHECK-DAG: {{.+}} = {{.+}} [[S_ARR_PRIV]]
+// CHECK-DAG: {{.+}} = {{.+}} [[VAR_PRIV]]
+// CHECK-DAG-32: {{.+}} = {{.+}} [[SIVAR_ADDR]]
+// CHECK-DAG-64: {{.+}} = {{.+}} [[CONV_SIVAR]]
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: ret void
+
+// CHECK: define{{.*}} i{{[0-9]+}} @[[TMAIN_INT]]()
+// CHECK: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 4, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 0)
+// CHECK: call void @[[TOFFL1:.+]](i{{64|32}} %{{.+}})
+// CHECK: ret
+
+// CHECK: define {{.*}}void @[[TOFFL1]]({{.+}})
+// CHECK: [[TT_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[TVEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}]*,
+// CHECK: [[TS_ARR_PRIV:%.+]] = alloca [2 x [[S_INT_TY]]]*,
+// CHECK: [[TVAR_PRIV:%.+]] = alloca [[S_INT_TY]]*,
+// CHECK: [[TT_VAR_CAST:%.+]] = alloca i{{[0-9]+}},
+
+// CHECK-DAG: [[TVEC_TE_PAR:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** [[TVEC_PRIV]],
+// CHECK-DAG: [[TT_VAR_TE_PAR:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[TT_VAR_CAST]],
+// CHECK-DAG: [[TS_ARR_TE_PAR:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** [[TS_ARR_PRIV]],
+// CHECK-DAG: [[TVAR_TE_PAR:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[TVAR_PRIV]],
+
+// CHECK: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 4, {{.+}} @[[TOUTL1:.+]] to {{.+}}, [2 x i{{[0-9]+}}]* [[TVEC_TE_PAR]], i{{[0-9]+}} [[TT_VAR_TE_PAR]], [2 x [[S_INT_TY]]]* [[TS_ARR_TE_PAR]], [[S_INT_TY]]* [[TVAR_TE_PAR]])
+// CHECK: ret void
+
+// CHECK: define internal void @[[TOUTL1]]({{.+}})
+// Skip global and bound tid vars
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: [[VEC_ADDR:%.+]] = alloca [2 x i{{[0-9]+}}]*,
+// CHECK: [[T_VAR_ADDR:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[S_ARR_ADDR:%.+]] = alloca [2 x [[S_INT_TY]]]*,
+// CHECK: [[VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*,
+// Skip temp vars for loop
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_INT_TY]]],
+// CHECK: [[AGG_TMP1:%.+]] = alloca [[ST_TY]],
+// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_INT_TY]],
+// CHECK: [[AGG_TMP2:%.+]] = alloca [[ST_TY]],
+// CHECK: [[TMP:%.+]] = alloca [[S_INT_TY]]*,
+
+// param copy
+// CHECK: store [2 x i{{[0-9]+}}]* {{.+}}, [2 x i{{[0-9]+}}]** [[VEC_ADDR]],
+// CHECK: store i{{[0-9]+}} {{.+}}, i{{[0-9]+}}* [[T_VAR_ADDR]],
+// CHECK: store [2 x [[S_INT_TY]]]* {{.+}}, [2 x [[S_INT_TY]]]** [[S_ARR_ADDR]],
+// CHECK: store [[S_INT_TY]]* {{.+}}, [[S_INT_TY]]** [[VAR_ADDR]],
+
+
+// T_VAR and preparation variables
+// CHECK: [[VEC_ADDR_VAL:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** [[VEC_ADDR]],
+// CHECK-64: [[CONV_TVAR:%.+]] = bitcast i64* [[T_VAR_ADDR]] to i32*
+// CHECK: [[S_ARR_ADDR_REF:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** [[S_ARR_ADDR]],
+
+// firstprivate vec(vec): copy from *_addr into priv1 and then from priv1 into priv2
+// CHECK-DAG: [[VEC_DEST_PRIV:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV]] to i8*
+// CHECK-DAG: [[VEC_SRC:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_ADDR_VAL]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[VEC_DEST_PRIV]], i8* [[VEC_SRC]], {{.+}})
+
+// firstprivate(s_arr)
+// CHECK-DAG: [[S_ARR_PRIV_BGN:%.+]] = getelementptr{{.*}} [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[S_ARR_PRIV]],
+// CHECK-DAG: [[S_ARR_ADDR_BGN:%.+]] = bitcast [2 x [[S_INT_TY]]]* [[S_ARR_ADDR_REF]] to
+// CHECK-DAG: [[S_ARR_FIN:%.+]] = icmp{{.+}} [[S_ARR_PRIV_BGN]],
+// CHECK-DAG: [[S_ARR_SRC_COPY:%.+]] = phi{{.+}} [ [[S_ARR_ADDR_BGN]], {{.+}} ], [ [[S_ARR_SRC:%.+]], {{.+}} ]
+// CHECK-DAG: [[S_ARR_DST_COPY:%.+]] = phi{{.+}} [ [[S_ARR_PRIV_BGN]], {{.+}} ], [ [[S_ARR_DST:%.+]], {{.+}} ]
+// CHECK-DAG: call void @{{.+}}({{.+}} [[AGG_TMP1]])
+// CHECK-DAG: call void @{{.+}}({{.+}} [[S_ARR_DST_COPY]], {{.+}} [[S_ARR_SRC_COPY]], {{.+}} [[AGG_TMP1]])
+// CHECK-DAG: call void @{{.+}}({{.+}} [[AGG_TMP1]])
+// CHECK-DAG: [[S_ARR_DST]] = getelementptr {{.+}} [[S_ARR_DST_COPY]],
+// CHECK-DAG: [[S_ARR_SRC]] = getelementptr {{.+}} [[S_ARR_SRC_COPY]],
+
+// firstprivate(var)
+// CHECK-DAG: [[VAR_ADDR_REF:%.+]] = load{{.+}} [[VAR_ADDR]],
+// CHECK-DAG: call void @{{.+}}({{.+}} [[AGG_TMP2]])
+// CHECK-DAG: call void @{{.+}}({{.+}} [[VAR_PRIV]], {{.+}} [[VAR_ADDR_REF]], {{.+}} [[AGG_TMP2]])
+// CHECK-DAG: call void @{{.+}}({{.+}} [[AGG_TMP2]])
+// CHECK-DAG: store [[S_INT_TY]]* [[VAR_PRIV]], [[S_INT_TY]]** [[TMP]],
+
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK-DAG-32: {{.+}} = {{.+}} [[T_VAR_ADDR]]
+// CHECK-DAG-64: {{.+}} = {{.+}} [[CONV_TVAR]]
+// CHECK-DAG: {{.+}} = {{.+}} [[VEC_PRIV]]
+// CHECK-DAG: {{.+}} = {{.+}} [[TMP]]
+// CHECK-DAG: {{.+}} = {{.+}} [[S_ARR_PRIV]]
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: ret void
+
+#endif
diff --git a/test/OpenMP/teams_distribute_firstprivate_messages.cpp b/test/OpenMP/teams_distribute_firstprivate_messages.cpp
index a71080774331..1a2b5f3782f9 100644
--- a/test/OpenMP/teams_distribute_firstprivate_messages.cpp
+++ b/test/OpenMP/teams_distribute_firstprivate_messages.cpp
@@ -144,8 +144,9 @@ int main(int argc, char **argv) {
#pragma omp teams distribute firstprivate(j)
for (i = 0; i < argc; ++i) foo();
+// expected-error@+2 {{lastprivate variable cannot be firstprivate}} expected-note@+2 {{defined as lastprivate}}
#pragma omp target
-#pragma omp teams distribute lastprivate(argc), firstprivate(argc) // OK
+#pragma omp teams distribute lastprivate(argc), firstprivate(argc)
for (i = 0; i < argc; ++i) foo();
return 0;
diff --git a/test/OpenMP/teams_distribute_lastprivate_codegen.cpp b/test/OpenMP/teams_distribute_lastprivate_codegen.cpp
new file mode 100644
index 000000000000..2eab60b9dd3c
--- /dev/null
+++ b/test/OpenMP/teams_distribute_lastprivate_codegen.cpp
@@ -0,0 +1,369 @@
+// RUN: %clang_cc1 -DLAMBDA -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+// RUN: %clang_cc1 -DLAMBDA -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-32
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-32
+
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+template <class T>
+struct S {
+ T f;
+ S(T a) : f(a) {}
+ S() : f() {}
+ operator T() { return T(); }
+ ~S() {}
+};
+
+// CHECK: [[S_FLOAT_TY:%.+]] = type { float }
+// CHECK: [[S_INT_TY:%.+]] = type { i{{[0-9]+}} }
+template <typename T>
+T tmain() {
+ S<T> test;
+ T t_var = T();
+ T vec[] = {1, 2};
+ S<T> s_arr[] = {1, 2};
+ S<T> &var = test;
+ #pragma omp target
+ #pragma omp teams distribute lastprivate(t_var, vec, s_arr, s_arr, var, var)
+ for (int i = 0; i < 2; ++i) {
+ vec[i] = t_var;
+ s_arr[i] = var;
+ }
+ return T();
+}
+
+int main() {
+ static int svar;
+ volatile double g;
+ volatile double &g1 = g;
+
+ #ifdef LAMBDA
+ // LAMBDA-LABEL: @main
+ // LAMBDA: call{{.*}} void [[OUTER_LAMBDA:@.+]](
+ [&]() {
+ static float sfvar;
+ // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
+ // LAMBDA: call i{{[0-9]+}} @__tgt_target_teams(
+ // LAMBDA: call void [[OFFLOADING_FUN:@.+]](
+
+ // LAMBDA: define{{.+}} void [[OFFLOADING_FUN]](
+ // LAMBDA: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, i32 4, {{.+}}* [[OMP_OUTLINED:@.+]] to {{.+}})
+ #pragma omp target
+ #pragma omp teams distribute lastprivate(g, g1, svar, sfvar)
+ for (int i = 0; i < 2; ++i) {
+ // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_OUTLINED]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, double*{{.+}} [[G_IN:%.+]], double*{{.+}} [[G1_IN:%.+]], i{{[0-9]+}}*{{.+}} [[SVAR_IN:%.+]], float*{{.+}} [[SFVAR_IN:%.+]])
+ // LAMBDA: [[G_PRIVATE_ADDR:%.+]] = alloca double*,
+ // LAMBDA: [[G1_PRIVATE_ADDR:%.+]] = alloca double*,
+ // LAMBDA: [[SVAR_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}*,
+ // LAMBDA: [[SFVAR_PRIVATE_ADDR:%.+]] = alloca float*,
+ // loop variables
+ // LAMBDA: {{.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: {{.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: {{.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: {{.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: {{.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: [[OMP_IS_LAST:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[G_PRIVATE:%.+]] = alloca double,
+ // LAMBDA: [[G1_PRIVATE:%.+]] = alloca double,
+ // LAMBDA: [[TMP_G1_PRIVATE:%.+]] = alloca double*,
+ // LAMBDA: [[SVAR_PRIVATE:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[SFVAR_PRIVATE:%.+]] = alloca float,
+ // LAMBDA: store double* [[G_IN]], double** [[G_PRIVATE_ADDR]],
+ // LAMBDA: store double* [[G1_IN]], double** [[G1_PRIVATE_ADDR]],
+ // LAMBDA: store i{{[0-9]+}}* [[SVAR_IN]], i{{[0-9]+}}** [[SVAR_PRIVATE_ADDR]],
+ // LAMBDA: store float* [[SFVAR_IN]], float** [[SFVAR_PRIVATE_ADDR]],
+
+ // init private variables
+ // LAMBDA: [[G_IN_REF:%.+]] = load double*, double** [[G_PRIVATE_ADDR]],
+ // LAMBDA: [[SVAR_IN_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SVAR_PRIVATE_ADDR]],
+ // LAMBDA: [[SFVAR_IN_REF:%.+]] = load float*, float** [[SFVAR_PRIVATE_ADDR]],
+ // LAMBDA: [[G1_IN_REF:%.+]] = load double*, double** [[G1_PRIVATE_ADDR]],
+ // LAMBDA: store double* [[G1_PRIVATE]], double** [[TMP_G1_PRIVATE]],
+ g = 1;
+ g1 = 1;
+ svar = 3;
+ sfvar = 4.0;
+ // LAMBDA: call {{.*}}void @__kmpc_for_static_init_4(
+ // LAMBDA: store double 1.0{{.+}}, double* [[G_PRIVATE]],
+ // LAMBDA: [[TMP_G1_REF:%.+]] = load double*, double** [[TMP_G1_PRIVATE]],
+ // LAMBDA: store{{.+}} double 1.0{{.+}}, double* [[TMP_G1_REF]],
+ // LAMBDA: store i{{[0-9]+}} 3, i{{[0-9]+}}* [[SVAR_PRIVATE]],
+ // LAMBDA: store float 4.0{{.+}}, float* [[SFVAR_PRIVATE]],
+ // LAMBDA: [[G_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // LAMBDA: store double* [[G_PRIVATE]], double** [[G_PRIVATE_ADDR_REF]],
+ // LAMBDA: [[TMP_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // LAMBDA: [[G1_PRIVATE_ADDR_FROM_TMP:%.+]] = load double*, double** [[TMP_G1_PRIVATE]],
+ // LAMBDA: store double* [[G1_PRIVATE_ADDR_FROM_TMP]], double** [[TMP_PRIVATE_ADDR_REF]],
+ // LAMBDA: [[SVAR_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+ // LAMBDA: store i{{[0-9]+}}* [[SVAR_PRIVATE]], i{{[0-9]+}}** [[SVAR_PRIVATE_ADDR_REF]]
+ // LAMBDA: [[SFVAR_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 3
+ // LAMBDA: store float* [[SFVAR_PRIVATE]], float** [[SFVAR_PRIVATE_ADDR_REF]]
+ // LAMBDA: call{{.*}} void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]])
+ // LAMBDA: call {{.*}}void @__kmpc_for_static_fini(
+ // LAMBDA: [[OMP_IS_LAST_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[OMP_IS_LAST]],
+ // LAMBDA: [[IS_LAST_IT:%.+]] = icmp ne i{{[0-9]+}} [[OMP_IS_LAST_VAL]], 0
+ // LAMBDA: br i1 [[IS_LAST_IT]], label %[[OMP_LASTPRIV_BLOCK:.+]], label %[[OMP_LASTPRIV_DONE:.+]]
+
+ // LAMBDA: [[OMP_LASTPRIV_BLOCK]]:
+ // LAMBDA: [[G_PRIV_VAL:%.+]] = load double, double* [[G_PRIVATE]],
+ // LAMBDA: store{{.*}} double [[G_PRIV_VAL]], double* [[G_IN_REF]],
+ // LAMBDA: [[TMP_G1_PRIV_REF:%.+]] = load double*, double** [[TMP_G1_PRIVATE]],
+ // LAMBDA: [[TMP_G1_PRIV_VAL:%.+]] = load double, double* [[TMP_G1_PRIV_REF]],
+ // LAMBDA: store{{.*}} double [[TMP_G1_PRIV_VAL]], double* [[G1_IN_REF]],
+
+ // LAMBDA: [[SVAR_PRIV_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SVAR_PRIVATE]],
+ // LAMBDA: store i{{[0-9]+}} [[SVAR_PRIV_VAL]], i{{[0-9]+}}* [[SVAR_IN_REF]],
+ // LAMBDA: [[SFVAR_PRIV_VAL:%.+]] = load float, float* [[SFVAR_PRIVATE]],
+ // LAMBDA: store float [[SFVAR_PRIV_VAL]], float* [[SFVAR_IN_REF]],
+ // LAMBDA: br label %[[OMP_LASTPRIV_DONE]]
+ // LAMBDA: [[OMP_LASTPRIV_DONE]]:
+ // LAMBDA: ret
+ [&]() {
+ // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]])
+ // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]],
+ g = 2;
+ g1 = 2;
+ svar = 4;
+ sfvar = 8.0;
+ // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]]
+ // LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // LAMBDA: [[G_REF:%.+]] = load double*, double** [[G_PTR_REF]]
+ // LAMBDA: store double 2.0{{.+}}, double* [[G_REF]]
+
+ // LAMBDA: [[TMP_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // LAMBDA: [[G1_REF:%.+]] = load double*, double** [[TMP_PTR_REF]]
+ // LAMBDA: store double 2.0{{.+}}, double* [[G1_REF]],
+ // LAMBDA: [[SVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+ // LAMBDA: [[SVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SVAR_PTR_REF]]
+ // LAMBDA: store i{{[0-9]+}} 4, i{{[0-9]+}}* [[SVAR_REF]]
+ // LAMBDA: [[SFVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 3
+ // LAMBDA: [[SFVAR_REF:%.+]] = load float*, float** [[SFVAR_PTR_REF]]
+ // LAMBDA: store float 8.0{{.+}}, float* [[SFVAR_REF]]
+ }();
+ }
+ }();
+ return 0;
+ #else
+ S<float> test;
+ int t_var = 0;
+ int vec[] = {1, 2};
+ S<float> s_arr[] = {1, 2};
+ S<float> &var = test;
+
+ #pragma omp target
+ #pragma omp teams distribute lastprivate(t_var, vec, s_arr, s_arr, var, var, svar)
+ for (int i = 0; i < 2; ++i) {
+ vec[i] = t_var;
+ s_arr[i] = var;
+ }
+ int i;
+
+ return tmain<int>();
+ #endif
+}
+
+// CHECK: define{{.*}} i{{[0-9]+}} @main()
+// CHECK: [[TEST:%.+]] = alloca [[S_FLOAT_TY]],
+// CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR:@.+]]([[S_FLOAT_TY]]* [[TEST]])
+// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+// CHECK: call void [[OFFLOAD_FUN:@.+]](i{{[0-9]+}} {{.+}}, [2 x i{{[0-9]+}}]* {{.+}}, [2 x [[S_FLOAT_TY]]]* {{.+}}, [[S_FLOAT_TY]]* {{.+}}, i{{[0-9]+}} {{.+}})
+// CHECK: ret
+
+// CHECK: define{{.+}} [[OFFLOAD_FUN]](i{{[0-9]+}} {{.+}}, [2 x i{{[0-9]+}}]*{{.+}} {{.+}}, [2 x [[S_FLOAT_TY]]]*{{.+}} {{.+}}, [[S_FLOAT_TY]]*{{.+}} {{.+}}, i{{[0-9]+}} {{.+}})
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_teams(
+// CHECK: ret
+//
+// CHECK: define internal void [[OMP_OUTLINED:@.+]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [2 x i{{[0-9]+}}]*{{.+}} [[VEC_IN:%.+]], i{{[0-9]+}}*{{.+}} [[T_VAR_IN:%.+]], [2 x [[S_FLOAT_TY]]]*{{.+}} [[S_ARR_IN:%.+]], [[S_FLOAT_TY]]*{{.+}} [[VAR_IN:%.+]], i{{[0-9]+}}*{{.*}} [[S_VAR_IN:%.+]])
+// CHECK: {{.+}} = alloca i{{[0-9]+}}*,
+// CHECK: {{.+}} = alloca i{{[0-9]+}}*,
+// CHECK: [[VEC_ADDR:%.+]] = alloca [2 x i{{[0-9]+}}]*,
+// CHECK: [[T_VAR_ADDR:%.+]] = alloca i{{[0-9]+}}*,
+// CHECK: [[S_ARR_ADDR:%.+]] = alloca [2 x [[S_FLOAT_TY]]]*,
+// CHECK: [[VAR_ADDR:%.+]] = alloca [[S_FLOAT_TY]]*,
+// CHECK: [[SVAR_ADDR:%.+]] = alloca i{{[0-9]+}}*,
+// skip loop variables
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: [[OMP_IS_LAST:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]],
+// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]],
+// CHECK: [[TMP_PRIV:%.+]] = alloca [[S_FLOAT_TY]]*,
+// CHECK: [[S_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+
+// copy from parameters to local address variables
+// CHECK: store [2 x i{{[0-9]+}}]* [[VEC_IN]], [2 x i{{[0-9]+}}]** [[VEC_ADDR]],
+// CHECK: store i{{[0-9]+}}* [[T_VAR_IN]], i{{[0-9]+}}** [[T_VAR_ADDR]],
+// CHECK: store [2 x [[S_FLOAT_TY]]]* [[S_ARR_IN]], [2 x [[S_FLOAT_TY]]]** [[S_ARR_ADDR]],
+// CHECK: store [[S_FLOAT_TY]]* [[VAR_IN]], [[S_FLOAT_TY]]** [[VAR_ADDR]],
+// CHECK: store i{{[0-9]+}}* [[S_VAR_IN]], i{{[0-9]+}}** [[SVAR_ADDR]],
+
+// load content of local address variables
+// CHECK: [[VEC_ADDR_REF:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** [[VEC_ADDR]],
+// CHECK: [[T_VAR_ADDR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[T_VAR_ADDR]],
+// CHECK: [[S_ARR_ADDR_REF:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[S_ARR_ADDR]],
+// CHECK: [[SVAR_ADDR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SVAR_ADDR]],
+// CHECK: store i{{[0-9]+}} 0, i{{[0-9]+}}* [[OMP_IS_LAST]],
+// CHECK: [[VAR_ADDR_REF:%.+]] = load {{.+}}, {{.+}} [[VAR_ADDR]],
+// the distribute loop
+// CHECK: call void @__kmpc_for_static_init_4(
+// assignment: vec[i] = t_var;
+// CHECK: [[T_VAR_PRIV_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_PRIV]],
+// CHECK: [[VEC_PTR:%.+]] = getelementptr inbounds [2 x i{{[0-9]+}}], [2 x i{{[0-9]+}}]* [[VEC_PRIV]], i{{[0-9]+}} 0, i{{[0-9]+}} {{.+}}
+// CHECK: store i{{[0-9]+}} [[T_VAR_PRIV_VAL]], i{{[0-9]+}}* [[VEC_PTR]],
+
+// assignment: s_arr[i] = var;
+// CHECK-DAG: [[S_ARR_PTR:%.+]] = getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[S_ARR_PRIV]],
+// CHECK-DAG: [[TMP_VAL:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[TMP_PRIV]],
+// CHECK-DAG: [[S_ARR_PTR_BCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[S_ARR_PTR]] to i8*
+// CHECK-DAG: [[TMP_VAL_BCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[TMP_VAL]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[S_ARR_PTR_BCAST]], i8* [[TMP_VAL_BCAST]],
+// CHECK: call void @__kmpc_for_static_fini(
+
+// lastprivates
+// CHECK: [[OMP_IS_LAST_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[OMP_IS_LAST]],
+// CHECK: [[IS_LAST_IT:%.+]] = icmp ne i{{[0-9]+}} [[OMP_IS_LAST_VAL]], 0
+// CHECK: br i1 [[IS_LAST_IT]], label %[[OMP_LASTPRIV_BLOCK:.+]], label %[[OMP_LASTPRIV_DONE:.+]]
+
+// CHECK: [[OMP_LASTPRIV_BLOCK]]:
+// CHECK: [[T_VAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_PRIV]],
+// CHECK: store i{{[0-9]+}} [[T_VAR_VAL]], i{{[0-9]+}}* [[T_VAR_ADDR_REF]],
+// CHECK: [[BCAST_VEC_ADDR_REF:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_ADDR_REF]] to i8*
+// CHECK: [[BCAST_VEC_PRIV:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[BCAST_VEC_ADDR_REF]], i8* [[BCAST_VEC_PRIV]],
+// CHECK: [[S_ARR_BEGIN:%.+]] = getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[S_ARR_ADDR_REF]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+// CHECK: [[S_ARR_PRIV_BCAST:%.+]] = bitcast [2 x [[S_FLOAT_TY]]]* [[S_ARR_PRIV]] to [[S_FLOAT_TY]]*
+// CHECK: [[S_ARR_BEGIN_GEP:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[S_ARR_BEGIN]], i{{[0-9]+}} 2
+// CHECK: [[S_ARR_IS_EMPTY:%.+]] = icmp eq [[S_FLOAT_TY]]* [[S_ARR_BEGIN]], [[S_ARR_BEGIN_GEP]]
+// CHECK: br i1 [[S_ARR_IS_EMPTY]], label %[[S_ARR_COPY_DONE:.+]], label %[[S_ARR_COPY_BLOCK:.+]]
+// CHECK: [[S_ARR_COPY_BLOCK]]:
+// CHECK: [[S_ARR_SRC_EL:%.+]] = phi [[S_FLOAT_TY]]*{{.+}}
+// CHECK: [[S_ARR_DST_EL:%.+]] = phi [[S_FLOAT_TY]]*{{.+}}
+// CHECK: [[S_ARR_DST_BCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[S_ARR_DST_EL]] to i8*
+// CHECK: [[S_ARR_SRC_BCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[S_ARR_SRC_EL]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[S_ARR_DST_BCAST]], i8* [[S_ARR_SRC_BCAST]]{{.+}})
+// CHECK: [[S_ARR_DST_NEXT:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[S_ARR_DST_EL]], i{{[0-9]+}} 1
+// CHECK: [[S_ARR_SRC_NEXT:%.+]] = getelementptr{{.+}}
+// CHECK: [[CPY_IS_FINISHED:%.+]] = icmp eq [[S_FLOAT_TY]]* [[S_ARR_DST_NEXT]], [[S_ARR_BEGIN_GEP]]
+// CHECK: br i1 [[CPY_IS_FINISHED]], label %[[S_ARR_COPY_DONE]], label %[[S_ARR_COPY_BLOCK]]
+// CHECK: [[S_ARR_COPY_DONE]]:
+// CHECK: [[TMP_VAL1:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[TMP_PRIV]],
+// CHECK: [[VAR_ADDR_REF_BCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[VAR_ADDR_REF]] to i8*
+// CHECK: [[TMP_VAL1_BCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[TMP_VAL1]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[VAR_ADDR_REF_BCAST]], i8* [[TMP_VAL1_BCAST]],{{.+}})
+// CHECK: [[SVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[S_VAR_PRIV]],
+// CHECK: store i{{[0-9]+}} [[SVAR_VAL]], i{{[0-9]+}}* [[SVAR_ADDR_REF]],
+// CHECK: ret void
+
+// template tmain
+// CHECK: define{{.*}} i{{[0-9]+}} [[TMAIN_INT:@.+]]()
+// CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]],
+// CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR:@.+]]([[S_INT_TY]]* [[TEST]])
+// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+// CHECK: call void [[OFFLOAD_FUN_1:@.+]](i{{[0-9]+}} {{.+}}, [2 x i{{[0-9]+}}]* {{.+}}, [2 x [[S_INT_TY]]]* {{.+}}, [[S_INT_TY]]* {{.+}})
+// CHECK: ret
+
+
+// CHECK: define internal void [[OFFLOAD_FUN_1]](
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_teams(%{{.+}}* @{{.+}}, i{{[0-9]+}} 4,
+// CHECK: ret
+
+// CHECK: define internal void [[OMP_OUTLINED_1:@.+]](i{{[0-9]+}}* noalias [[GTID_ADDR1:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [2 x i{{[0-9]+}}]*{{.+}} [[VEC_IN1:%.+]], i{{[0-9]+}}*{{.+}} [[T_VAR_IN1:%.+]], [2 x [[S_INT_TY]]]*{{.+}} [[S_ARR_IN1:%.+]], [[S_INT_TY]]*{{.+}} [[VAR_IN1:%.+]])
+// skip alloca of global_tid and bound_tid
+// CHECK: {{.+}} = alloca i{{[0-9]+}}*,
+// CHECK: {{.+}} = alloca i{{[0-9]+}}*,
+// CHECK: [[VEC_ADDR1:%.+]] = alloca [2 x i{{[0-9]+}}]*,
+// CHECK: [[T_VAR_ADDR1:%.+]] = alloca i{{[0-9]+}}*,
+// CHECK: [[S_ARR_ADDR1:%.+]] = alloca [2 x [[S_INT_TY]]]*,
+// CHECK: [[VAR_ADDR1:%.+]] = alloca [[S_INT_TY]]*,
+// skip loop variables
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: [[OMP_IS_LAST1:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[T_VAR_PRIV1:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[VEC_PRIV1:%.+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK: [[S_ARR_PRIV1:%.+]] = alloca [2 x [[S_INT_TY]]],
+// CHECK: [[VAR_PRIV1:%.+]] = alloca [[S_INT_TY]],
+// CHECK: [[TMP_PRIV1:%.+]] = alloca [[S_INT_TY]]*,
+
+// skip init of bound and global tid
+// CHECK: store i{{[0-9]+}}* {{.*}},
+// CHECK: store i{{[0-9]+}}* {{.*}},
+// copy from parameters to local address variables
+// CHECK: store [2 x i{{[0-9]+}}]* [[VEC_IN1]], [2 x i{{[0-9]+}}]** [[VEC_ADDR1]],
+// CHECK: store i{{[0-9]+}}* [[T_VAR_IN1]], i{{[0-9]+}}** [[T_VAR_ADDR1]],
+// CHECK: store [2 x [[S_INT_TY]]]* [[S_ARR_IN1]], [2 x [[S_INT_TY]]]** [[S_ARR_ADDR1]],
+// CHECK: store [[S_INT_TY]]* [[VAR_IN1]], [[S_INT_TY]]** [[VAR_ADDR1]],
+
+// load content of local address variables
+// CHECK: [[VEC_ADDR_REF1:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** [[VEC_ADDR1]],
+// CHECK: [[T_VAR_ADDR_REF1:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[T_VAR_ADDR1]],
+// CHECK: [[S_ARR_ADDR_REF1:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** [[S_ARR_ADDR1]],
+// CHECK-DAG: store i{{[0-9]+}} 0, i{{[0-9]+}}* [[OMP_IS_LAST1]],
+// CHECK: [[VAR_ADDR1_REF:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[VAR_ADDR1]],
+// CHECK-DAG: store [[S_INT_TY]]* [[VAR_PRIV1]], [[S_INT_TY]]** [[TMP_PRIV1]],
+// CHECK: call void @__kmpc_for_static_init_4(
+// assignment: vec[i] = t_var;
+// CHECK: [[IV_VAL1:%.+]] =
+// CHECK: [[T_VAR_PRIV_VAL1:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_PRIV1]],
+// CHECK: [[VEC_PTR1:%.+]] = getelementptr inbounds [2 x i{{[0-9]+}}], [2 x i{{[0-9]+}}]* [[VEC_PRIV1]], i{{[0-9]+}} 0, i{{[0-9]+}} {{.+}}
+// CHECK: store i{{[0-9]+}} [[T_VAR_PRIV_VAL1]], i{{[0-9]+}}* [[VEC_PTR1]],
+
+// assignment: s_arr[i] = var;
+// CHECK-DAG: [[S_ARR_PTR1:%.+]] = getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[S_ARR_PRIV1]],
+// CHECK-DAG: [[TMP_VAL1:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[TMP_PRIV1]],
+// CHECK-DAG: [[S_ARR_PTR_BCAST1:%.+]] = bitcast [[S_INT_TY]]* [[S_ARR_PTR1]] to i8*
+// CHECK-DAG: [[TMP_VAL_BCAST1:%.+]] = bitcast [[S_INT_TY]]* [[TMP_VAL1]] to i8*
+// CHECK-DAG: call void @llvm.memcpy.{{.+}}(i8* [[S_ARR_PTR_BCAST1]], i8* [[TMP_VAL_BCAST1]],
+// CHECK: call void @__kmpc_for_static_fini(
+
+// lastprivates
+// CHECK: [[OMP_IS_LAST_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[OMP_IS_LAST1]],
+// CHECK: [[IS_LAST_IT:%.+]] = icmp ne i{{[0-9]+}} [[OMP_IS_LAST_VAL]], 0
+// CHECK: br i1 [[IS_LAST_IT]], label %[[OMP_LASTPRIV_BLOCK:.+]], label %[[OMP_LASTPRIV_DONE:.+]]
+
+// CHECK: [[OMP_LASTPRIV_BLOCK]]:
+// CHECK: [[T_VAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_PRIV1]],
+// CHECK: store i{{[0-9]+}} [[T_VAR_VAL]], i{{[0-9]+}}* [[T_VAR_ADDR_REF1]],
+// CHECK: [[BCAST_VEC_ADDR_REF:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_ADDR_REF1]] to i8*
+// CHECK: [[BCAST_VEC_PRIV:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV1]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[BCAST_VEC_ADDR_REF]], i8* [[BCAST_VEC_PRIV]],
+// CHECK: [[S_ARR_BEGIN:%.+]] = getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[S_ARR_ADDR_REF]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+// CHECK: [[S_ARR_PRIV_BCAST:%.+]] = bitcast [2 x [[S_INT_TY]]]* [[S_ARR_PRIV1]] to [[S_INT_TY]]*
+// CHECK: [[S_ARR_BEGIN_GEP:%.+]] = getelementptr [[S_INT_TY]], [[S_INT_TY]]* [[S_ARR_BEGIN]], i{{[0-9]+}} 2
+// CHECK: [[S_ARR_IS_EMPTY:%.+]] = icmp eq [[S_INT_TY]]* [[S_ARR_BEGIN]], [[S_ARR_BEGIN_GEP]]
+// CHECK: br i1 [[S_ARR_IS_EMPTY]], label %[[S_ARR_COPY_DONE:.+]], label %[[S_ARR_COPY_BLOCK:.+]]
+// CHECK: [[S_ARR_COPY_BLOCK]]:
+// CHECK: [[S_ARR_SRC_EL:%.+]] = phi [[S_INT_TY]]*{{.+}}
+// CHECK: [[S_ARR_DST_EL:%.+]] = phi [[S_INT_TY]]*{{.+}}
+// CHECK: [[S_ARR_DST_BCAST:%.+]] = bitcast [[S_INT_TY]]* [[S_ARR_DST_EL]] to i8*
+// CHECK: [[S_ARR_SRC_BCAST:%.+]] = bitcast [[S_INT_TY]]* [[S_ARR_SRC_EL]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[S_ARR_DST_BCAST]], i8* [[S_ARR_SRC_BCAST]]{{.+}})
+// CHECK: [[S_ARR_DST_NEXT:%.+]] = getelementptr [[S_INT_TY]], [[S_INT_TY]]* [[S_ARR_DST_EL]], i{{[0-9]+}} 1
+// CHECK: [[S_ARR_SRC_NEXT:%.+]] = getelementptr{{.+}}
+// CHECK: [[CPY_IS_FINISHED:%.+]] = icmp eq [[S_INT_TY]]* [[S_ARR_DST_NEXT]], [[S_ARR_BEGIN_GEP]]
+// CHECK: br i1 [[CPY_IS_FINISHED]], label %[[S_ARR_COPY_DONE]], label %[[S_ARR_COPY_BLOCK]]
+// CHECK: [[S_ARR_COPY_DONE]]:
+// CHECK: [[TMP_VAL1:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[TMP_PRIV1]],
+// CHECK: [[VAR_ADDR_REF_BCAST:%.+]] = bitcast [[S_INT_TY]]* [[VAR_ADDR1_REF]] to i8*
+// CHECK: [[TMP_VAL1_BCAST:%.+]] = bitcast [[S_INT_TY]]* [[TMP_VAL1]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[VAR_ADDR_REF_BCAST]], i8* [[TMP_VAL1_BCAST]],{{.+}})
+// CHECK: ret void
+#endif
diff --git a/test/OpenMP/teams_distribute_lastprivate_messages.cpp b/test/OpenMP/teams_distribute_lastprivate_messages.cpp
index b892141d5014..392607ea14ba 100644
--- a/test/OpenMP/teams_distribute_lastprivate_messages.cpp
+++ b/test/OpenMP/teams_distribute_lastprivate_messages.cpp
@@ -18,14 +18,14 @@ public:
const S2 &operator =(const S2&) const;
S2 &operator =(const S2&);
static float S2s; // expected-note {{static data member is predetermined as shared}}
- static const float S2sc;
+ static const float S2sc; // expected-note {{static data member is predetermined as shared}}
};
-const float S2::S2sc = 0; // expected-note {{static data member is predetermined as shared}}
+const float S2::S2sc = 0;
const S2 b;
const S2 ba[5];
class S3 {
int a;
- S3 &operator=(const S3 &s3); // expected-note 2 {{implicitly declared private here}}
+ S3 &operator=(const S3 &s3); // expected-note {{implicitly declared private here}}
public:
S3() : a(0) {}
@@ -52,7 +52,7 @@ public:
};
class S6 {
int a;
- S6() : a(0) {}
+ S6() : a(0) {} // expected-note {{implicitly declared private here}}
public:
S6(const S6 &s6) : a(s6.a) {}
@@ -255,12 +255,14 @@ int main(int argc, char **argv) {
#pragma omp teams distribute lastprivate(j)
for (i = 0; i < argc; ++i) foo();
+// expected-error@+2 {{firstprivate variable cannot be lastprivate}} expected-note@+2 {{defined as firstprivate}}
#pragma omp target
-#pragma omp teams distribute firstprivate(m) lastprivate(m) // expected-error {{'operator=' is a private member of 'S3'}}
+#pragma omp teams distribute firstprivate(m) lastprivate(m)
for (i = 0; i < argc; ++i) foo();
+// expected-error@+2 {{lastprivate variable cannot be firstprivate}} expected-note@+2 {{defined as lastprivate}}
#pragma omp target
-#pragma omp teams distribute lastprivate(n) firstprivate(n) // OK
+#pragma omp teams distribute lastprivate(n) firstprivate(n) // expected-error {{calling a private constructor of class 'S6'}}
for (i = 0; i < argc; ++i) foo();
static int si;
diff --git a/test/OpenMP/teams_distribute_loop_messages.cpp b/test/OpenMP/teams_distribute_loop_messages.cpp
index ea2604eebf0f..acab1f76a2d4 100644
--- a/test/OpenMP/teams_distribute_loop_messages.cpp
+++ b/test/OpenMP/teams_distribute_loop_messages.cpp
@@ -2,7 +2,7 @@
class S {
int a;
- S() : a(0) {}
+ S() : a(0) {} // expected-note {{implicitly declared private here}}
public:
S(int v) : a(v) {}
@@ -689,12 +689,16 @@ void test_loop_eh() {
void g() { throw 0; }
};
}
+ #pragma omp target
+ #pragma omp teams distribute
+ f; // expected-error {{use of undeclared identifier 'f'}}
}
void test_loop_firstprivate_lastprivate() {
S s(4);
+// expected-error@+2 {{lastprivate variable cannot be firstprivate}} expected-note@+2 {{defined as lastprivate}}
#pragma omp target
-#pragma omp teams distribute lastprivate(s) firstprivate(s)
+#pragma omp teams distribute lastprivate(s) firstprivate(s) // expected-error {{calling a private constructor of class 'S'}}
for (int i = 0; i < 16; ++i)
;
}
diff --git a/test/OpenMP/teams_distribute_parallel_for_ast_print.cpp b/test/OpenMP/teams_distribute_parallel_for_ast_print.cpp
index ad14794116ed..68bd424ade01 100644
--- a/test/OpenMP/teams_distribute_parallel_for_ast_print.cpp
+++ b/test/OpenMP/teams_distribute_parallel_for_ast_print.cpp
@@ -8,6 +8,9 @@
void foo() {}
+int x;
+#pragma omp threadprivate(x)
+
struct S {
S(): a(0) {}
S(int v) : a(v) {}
@@ -40,7 +43,7 @@ public:
void foo() {
int b, argv, d, c, e, f;
#pragma omp target
-#pragma omp teams distribute parallel for default(none), private(b) firstprivate(argv) shared(d) reduction(+:c) reduction(max:e) num_teams(f) thread_limit(d)
+#pragma omp teams distribute parallel for default(none), private(b) firstprivate(argv) shared(d) reduction(+:c) reduction(max:e) num_teams(f) thread_limit(d) copyin(x)
for (int k = 0; k < a.a; ++k)
++a.a;
}
@@ -50,7 +53,7 @@ public:
// CHECK: #pragma omp target
// CHECK-NEXT: #pragma omp teams distribute parallel for private(this->a) private(this->a)
// CHECK: #pragma omp target
-// CHECK-NEXT: #pragma omp teams distribute parallel for default(none) private(b) firstprivate(argv) shared(d) reduction(+: c) reduction(max: e) num_teams(f) thread_limit(d)
+// CHECK-NEXT: #pragma omp teams distribute parallel for default(none) private(b) firstprivate(argv) shared(d) reduction(+: c) reduction(max: e) num_teams(f) thread_limit(d) copyin(x)
class S8 : public S7<S> {
S8() {}
@@ -74,7 +77,7 @@ public:
void bar() {
int b, argv, d, c, e, f8;
#pragma omp target
-#pragma omp teams distribute parallel for default(none), private(b) firstprivate(argv) shared(d) reduction(+:c) reduction(max:e) num_teams(f8) thread_limit(d)
+#pragma omp teams distribute parallel for default(none), private(b) firstprivate(argv) shared(d) reduction(+:c) reduction(max:e) num_teams(f8) thread_limit(d) copyin(x)
for (int k = 0; k < a.a; ++k)
++a.a;
}
@@ -86,7 +89,7 @@ public:
// CHECK: #pragma omp target
// CHECK-NEXT: #pragma omp teams distribute parallel for private(this->a) private(this->a)
// CHECK: #pragma omp target
-// CHECK-NEXT: #pragma omp teams distribute parallel for default(none) private(b) firstprivate(argv) shared(d) reduction(+: c) reduction(max: e) num_teams(f8) thread_limit(d)
+// CHECK-NEXT: #pragma omp teams distribute parallel for default(none) private(b) firstprivate(argv) shared(d) reduction(+: c) reduction(max: e) num_teams(f8) thread_limit(d) copyin(x)
template <class T, int N>
T tmain(T argc) {
@@ -127,19 +130,19 @@ T tmain(T argc) {
// CHECK-NEXT: for (int i = 0; i < 10; ++i)
// CHECK-NEXT: foo();
#pragma omp target
-#pragma omp teams distribute parallel for default(none), private(b) firstprivate(argc) shared(d) reduction(+:c) reduction(max:e) num_teams(f) thread_limit(d)
+#pragma omp teams distribute parallel for default(none), private(b) firstprivate(argc) shared(d) reduction(+:c) reduction(max:e) num_teams(f) thread_limit(d) copyin(x)
for (int k = 0; k < 10; ++k)
e += d + argc;
// CHECK: #pragma omp target
-// CHECK-NEXT: #pragma omp teams distribute parallel for default(none) private(b) firstprivate(argc) shared(d) reduction(+: c) reduction(max: e) num_teams(f) thread_limit(d)
+// CHECK-NEXT: #pragma omp teams distribute parallel for default(none) private(b) firstprivate(argc) shared(d) reduction(+: c) reduction(max: e) num_teams(f) thread_limit(d) copyin(x)
// CHECK-NEXT: for (int k = 0; k < 10; ++k)
// CHECK-NEXT: e += d + argc;
#pragma omp target
-#pragma omp teams distribute parallel for linear(d)
+#pragma omp teams distribute parallel for
for (int k = 0; k < 10; ++k)
e += d + argc;
// CHECK: #pragma omp target
-// CHECK-NEXT: #pragma omp teams distribute parallel for linear(d)
+// CHECK-NEXT: #pragma omp teams distribute parallel for
// CHECK-NEXT: for (int k = 0; k < 10; ++k)
// CHECK-NEXT: e += d + argc;
return T();
@@ -182,19 +185,19 @@ int main (int argc, char **argv) {
// CHECK-NEXT: for (int i = 0; i < 10; ++i)
// CHECK-NEXT: foo();
#pragma omp target
-#pragma omp teams distribute parallel for default(none), private(b) firstprivate(argc) shared(d) reduction(+:c) reduction(max:e) num_teams(f) thread_limit(d)
+#pragma omp teams distribute parallel for default(none), private(b) firstprivate(argc) shared(d) reduction(+:c) reduction(max:e) num_teams(f) thread_limit(d) copyin(x)
for (int k = 0; k < 10; ++k)
e += d + argc;
// CHECK: #pragma omp target
-// CHECK-NEXT: #pragma omp teams distribute parallel for default(none) private(b) firstprivate(argc) shared(d) reduction(+: c) reduction(max: e) num_teams(f) thread_limit(d)
+// CHECK-NEXT: #pragma omp teams distribute parallel for default(none) private(b) firstprivate(argc) shared(d) reduction(+: c) reduction(max: e) num_teams(f) thread_limit(d) copyin(x)
// CHECK-NEXT: for (int k = 0; k < 10; ++k)
// CHECK-NEXT: e += d + argc;
#pragma omp target
-#pragma omp teams distribute parallel for linear(d)
+#pragma omp teams distribute parallel for
for (int k = 0; k < 10; ++k)
e += d + argc;
// CHECK: #pragma omp target
-// CHECK-NEXT: #pragma omp teams distribute parallel for linear(d)
+// CHECK-NEXT: #pragma omp teams distribute parallel for
// CHECK-NEXT: for (int k = 0; k < 10; ++k)
// CHECK-NEXT: e += d + argc;
return (0);
diff --git a/test/OpenMP/teams_distribute_parallel_for_codegen.cpp b/test/OpenMP/teams_distribute_parallel_for_codegen.cpp
new file mode 100644
index 000000000000..5711ede87c86
--- /dev/null
+++ b/test/OpenMP/teams_distribute_parallel_for_codegen.cpp
@@ -0,0 +1,247 @@
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+// Test host codegen.
+// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64
+// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32
+#ifdef CK1
+
+int a[100];
+
+// CK1: define {{.*}}i32 @{{.+}}teams_argument_globali(
+int teams_argument_global(int n){
+ int te = n / 128;
+ int th = 128;
+ // discard n_addr
+ // CK1: alloca i32,
+ // CK1: [[TE:%.+]] = alloca i32,
+ // CK1: [[TH:%.+]] = alloca i32,
+ // CK1: [[TE_CAST:%.+]] = alloca i{{32|64}},
+ // CK1: [[TH_CAST:%.+]] = alloca i{{32|64}},
+ // CK1: [[TE_PAR:%.+]] = load{{.+}}, {{.+}} [[TE_CAST]],
+ // CK1: [[TH_PAR:%.+]] = load{{.+}}, {{.+}} [[TH_CAST]],
+ // CK1: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 4, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 {{.+}}, i32 {{.+}})
+
+ // CK1: call void @[[OFFL1:.+]](i{{32|64}} [[TE_PAR]], i{{32|64}} [[TH_PAR]],
+ #pragma omp target
+ #pragma omp teams distribute parallel for num_teams(te), thread_limit(th)
+ for(int i = 0; i < n; i++) {
+ a[i] = 0;
+ #pragma omp cancel for
+ }
+
+ // CK1: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 2, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 0)
+ // CK1: call void @[[OFFL2:.+]](i{{64|32}} %{{.+}})
+ #pragma omp target
+ {{{
+ #pragma omp teams distribute parallel for
+ for(int i = 0; i < n; i++) {
+ a[i] = 0;
+ }
+ }}}
+
+ // outlined target regions
+ // CK1: define internal void @[[OFFL1]](i{{32|64}} [[TE_ARG:%.+]], i{{32|64}} [[TH_ARG:%.+]], i{{32|64}} {{.+}}, {{.+}})
+ // CK1: [[TE_ADDR:%.+]] = alloca i{{32|64}},
+ // CK1: [[TH_ADDR:%.+]] = alloca i{{32|64}},
+ // CK1: store{{.+}} [[TE_ARG]], {{.+}} [[TE_ADDR]],
+ // CK1: store{{.+}} [[TH_ARG]], {{.+}} [[TH_ADDR]],
+ // CK1-64: [[TE_CONV:%.+]] = bitcast{{.+}} [[TE_ADDR]] to
+ // CK1-64: [[TH_CONV:%.+]] = bitcast{{.+}} [[TH_ADDR]] to
+ // CK1-64: [[TE_VAL:%.+]] = load i32, i32* [[TE_CONV]],
+ // CK1-64: [[TH_VAL:%.+]] = load i32, i32* [[TH_CONV]],
+ // CK1-32: [[TE_VAL:%.+]] = load i32, i32* [[TE_ADDR]],
+ // CK1-32: [[TH_VAL:%.+]] = load i32, i32* [[TH_ADDR]],
+ // CK1: {{%.+}} = call i32 @__kmpc_push_num_teams({{.+}}, {{.+}}, i32 [[TE_VAL]], i32 [[TH_VAL]])
+ // CK1: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 2, {{.+}} @[[OUTL1:.+]] to {{.+}}, {{.+}}, {{.+}})
+ // CK1: ret void
+
+ // CK1: define internal void @[[OUTL1]]({{.+}})
+ // CK1: call void @__kmpc_for_static_init_4(
+ // CK1: call void {{.+}} @__kmpc_fork_call(
+ // CK1: call void @__kmpc_for_static_fini(
+ // CK1: ret void
+
+ // CK1: define internal void @[[OFFL2]]({{.+}}, {{.+}})
+ // CK1: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 2, {{.+}} @[[OUTL2:.+]] to {{.+}}, {{.+}}, {{.+}})
+ // CK1: ret void
+
+ // CK1: define internal void @[[OUTL2]]({{.+}})
+ // CK1: call void @__kmpc_for_static_init_4(
+ // CK1: call void {{.+}} @__kmpc_fork_call(
+ // CK1: call void @__kmpc_for_static_fini(
+ // CK1: ret void
+
+ return a[0];
+}
+
+#endif // CK1
+
+// Test host codegen.
+// RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64
+// RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32
+#ifdef CK2
+
+// CK2: define {{.*}}i32 @{{.+}}teams_local_argv(
+int teams_local_arg(void) {
+ int n = 100;
+ int a[n];
+
+ // CK2: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 3, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}, i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 0)
+ // CK2: call void @[[OFFL1:.+]](i{{64|32}} %{{.+}})
+ #pragma omp target
+ #pragma omp teams distribute parallel for
+ for(int i = 0; i < n; i++) {
+ a[i] = 0;
+ }
+
+ // outlined target region
+ // CK2: define internal void @[[OFFL1]]({{.+}}, {{.+}})
+ // CK2: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 3, {{.+}} @[[OUTL1:.+]] to {{.+}}, {{.+}}, {{.+}})
+ // CK2: ret void
+
+ // CK2: define internal void @[[OUTL1]]({{.+}})
+ // CK2: call void @__kmpc_for_static_init_4(
+ // CK2: call void {{.+}} @__kmpc_fork_call(
+ // CK2: call void @__kmpc_for_static_fini(
+ // CK2: ret void
+
+ return a[0];
+}
+#endif // CK2
+
+// Test host codegen.
+// RUN: %clang_cc1 -DCK3 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK3 --check-prefix CK3-64
+// RUN: %clang_cc1 -DCK3 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK3 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK3 --check-prefix CK3-64
+// RUN: %clang_cc1 -DCK3 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK3 --check-prefix CK3-32
+// RUN: %clang_cc1 -DCK3 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK3 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK3 --check-prefix CK3-32
+#ifdef CK3
+
+// CK3: [[SSI:%.+]] = type { [{{.+}} x i32], float }
+
+template <typename T, int X, long long Y>
+struct SS{
+ T a[X];
+ float b;
+ // CK3: define {{.*}}i32 @{{.+}}foo{{.+}}(
+ int foo(void) {
+
+ // CK3: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 1, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 0)
+ // CK3: call void @[[OFFL1:.+]]([[SSI]]* %{{.+}})
+ #pragma omp target
+ #pragma omp teams distribute parallel for
+ for(int i = 0; i < X; i++) {
+ a[i] = (T)0;
+ }
+
+ // outlined target region
+ // CK3: define internal void @[[OFFL1]]([[SSI]]* {{.+}})
+ // CK3: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTL1:.+]] to {{.+}}, {{.+}}, {{.+}})
+ // CK3: ret void
+
+ // CK3: define internal void @[[OUTL1]]({{.+}})
+ // CK3: call void @__kmpc_for_static_init_4(
+ // CK3: call void {{.+}} @__kmpc_fork_call(
+ // CK3: call void @__kmpc_for_static_fini(
+ // CK3: ret void
+
+ return a[0];
+ }
+};
+
+int teams_template_struct(void) {
+ SS<int, 123, 456> V;
+ return V.foo();
+
+}
+#endif // CK3
+
+// Test host codegen.
+// RUN: %clang_cc1 -DCK4 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK4 --check-prefix CK4-64
+// RUN: %clang_cc1 -DCK4 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK4 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK4 --check-prefix CK4-64
+// RUN: %clang_cc1 -DCK4 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK4 --check-prefix CK4-32
+// RUN: %clang_cc1 -DCK4 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK4 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK4 --check-prefix CK4-32
+
+#ifdef CK4
+
+template <typename T, int n>
+int tmain(T argc) {
+ T a[n];
+ int te = n/128;
+ int th = 128;
+#pragma omp target
+#pragma omp teams distribute parallel for num_teams(te) thread_limit(th)
+ for(int i = 0; i < n; i++) {
+ a[i] = (T)0;
+ }
+ return 0;
+}
+
+int main (int argc, char **argv) {
+ int n = 100;
+ int a[n];
+#pragma omp target
+#pragma omp teams distribute parallel for
+ for(int i = 0; i < n; i++) {
+ a[i] = 0;
+ }
+ return tmain<int, 10>(argc);
+}
+
+// CK4: define {{.*}}i32 @{{[^,]+}}(i{{.+}}{{.+}} %[[ARGC:.+]], {{.+}})
+// CK4: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 3, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}, i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 0)
+// CK4: call void @[[OFFL1:.+]]({{.+}})
+// CK4: {{%.+}} = call{{.*}} i32 @[[TMAIN:.+]]({{.+}})
+// CK4: ret
+
+// CK4: define {{.*}}void @[[OFFL1]]({{.+}})
+// CK4: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 3, {{.+}} @[[OUTL1:.+]] to {{.+}}, {{.+}}, {{.+}})
+// CK4: ret void
+
+// CK4: define internal void @[[OUTL1]]({{.+}})
+// CK4: call void @__kmpc_for_static_init_4(
+// CK4: call void {{.+}} @__kmpc_fork_call(
+// CK4: call void @__kmpc_for_static_fini(
+// CK4: ret void
+
+// CK4: define {{.*}}i32 @[[TMAIN]]({{.+}})
+// CK4: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 3, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 {{.+}}, i32 {{.+}})
+// CK4: call void @[[OFFLT:.+]]({{.+}})
+// CK4: ret
+// CK4-NEXT: }
+
+// CK4: define {{.*}}void @[[OFFLT]](i{{32|64}} [[TE_ARG:%.+]], i{{32|64}} [[TH_ARG:%.+]], {{.+}})
+// CK4: [[TE_ADDR:%.+]] = alloca i{{32|64}},
+// CK4: [[TH_ADDR:%.+]] = alloca i{{32|64}},
+// CK4: store{{.+}} [[TE_ARG]], {{.+}} [[TE_ADDR]],
+// CK4: store{{.+}} [[TH_ARG]], {{.+}} [[TH_ADDR]],
+// CK4-64: [[TE_CONV:%.+]] = bitcast{{.+}} [[TE_ADDR]] to
+// CK4-64: [[TH_CONV:%.+]] = bitcast{{.+}} [[TH_ADDR]] to
+// CK4-64: [[TE_VAL:%.+]] = load i32, i32* [[TE_CONV]],
+// CK4-64: [[TH_VAL:%.+]] = load i32, i32* [[TH_CONV]],
+// CK4-32: [[TE_VAL:%.+]] = load i32, i32* [[TE_ADDR]],
+// CK4-32: [[TH_VAL:%.+]] = load i32, i32* [[TH_ADDR]],
+// CK4: {{%.+}} = call i32 @__kmpc_push_num_teams({{.+}}, {{.+}}, i32 [[TE_VAL]], i32 [[TH_VAL]])
+// CK4: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTLT:.+]] to {{.+}}, {{.+}}, {{.+}})
+// CK4: ret void
+
+// CK4: define internal void @[[OUTLT]]({{.+}})
+// CK4: call void @__kmpc_for_static_init_4(
+// CK4: call void {{.+}} @__kmpc_fork_call(
+// CK4: call void @__kmpc_for_static_fini(
+// CK4: ret void
+
+#endif // CK4
+#endif
diff --git a/test/OpenMP/teams_distribute_parallel_for_collapse_codegen.cpp b/test/OpenMP/teams_distribute_parallel_for_collapse_codegen.cpp
new file mode 100644
index 000000000000..7522288f75e2
--- /dev/null
+++ b/test/OpenMP/teams_distribute_parallel_for_collapse_codegen.cpp
@@ -0,0 +1,144 @@
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+// Test host codegen.
+// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64
+// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32
+#ifdef CK1
+
+template <typename T, int X, long long Y>
+struct SS{
+ T a[X][Y];
+
+ // CK1: define {{.*}}i32 @{{.+}}foo{{.+}}(
+ int foo(void) {
+
+ // CK1: call i32 @__tgt_target_teams(
+ // CK1: call void @[[OFFL1:.+]](
+ #pragma omp target
+ #pragma omp teams distribute parallel for collapse(2)
+ for(int i = 0; i < X; i++) {
+ for(int j = 0; j < Y; j++) {
+ a[i][j] = (T)0;
+ }
+ }
+ // CK1: define internal void @[[OFFL1]](
+ // CK1: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTL1:.+]] to {{.+}},
+ // CK1: ret void
+
+ // CK1: define internal void @[[OUTL1]]({{.+}})
+ // discard loop variables not needed here
+ // CK1: [[OMP_UB:%.omp.comb.ub]] = alloca i32,
+ // CK1: store i32 56087, i32* [[OMP_UB]],
+ // CK1: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 92, {{.+}}, {{.+}}, i32* [[OMP_UB]],
+ // CK1: call void {{.*}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[PAR_OUTL1:.+]] to
+ // CK1: call void @__kmpc_for_static_fini(
+ // CK1: ret void
+
+ // CK1: define internal void @[[PAR_OUTL1]]({{.+}})
+ // CK1: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 34, {{.+}}, {{.+}},
+ // CK1: call void @__kmpc_for_static_fini(
+ // CK1: ret void
+
+ return a[0][0];
+ }
+};
+
+int teams_template_struct(void) {
+ SS<int, 123, 456> V;
+ return V.foo();
+
+}
+#endif // CK1
+
+// Test host codegen.
+// RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64
+// RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32
+#ifdef CK2
+
+template <typename T, int n, int m>
+int tmain(T argc) {
+ T a[n][m];
+ #pragma omp target
+ #pragma omp teams distribute parallel for collapse(2)
+ for(int i = 0; i < n; i++) {
+ for(int j = 0; j < m; j++) {
+ a[i][j] = (T)0;
+ }
+ }
+ return 0;
+}
+
+int main (int argc, char **argv) {
+ int n = 100;
+ int m = 2;
+ int a[n][m];
+ #pragma omp target
+ #pragma omp teams distribute parallel for collapse(2)
+ for(int i = 0; i < n; i++) {
+ for(int j = 0; j < m; j++) {
+ a[i][j] = 0;
+ }
+ }
+ return tmain<int, 10, 2>(argc);
+}
+
+// CK2: define {{.*}}i32 @{{[^,]+}}(i{{.+}}{{.+}} %[[ARGC:.+]], {{.+}})
+// CK2: call i32 @__tgt_target_teams(
+// CK2: call void @[[OFFL1:.+]]({{.+}})
+// CK2: {{%.+}} = call{{.*}} i32 @[[TMAIN:.+]]({{.+}})
+// CK2: ret
+
+// CK2: define {{.*}}void @[[OFFL1]]({{.+}})
+// CK2: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 5, {{.+}} @[[OUTL1:.+]] to {{.+}},
+// CK2: ret void
+
+// CK2: define internal void @[[OUTL1]]({{.+}})
+// CK2: [[OMP_UB:%.omp.comb.ub]] = alloca i64,
+// CK2: store i64 {{.+}}, i64* [[OMP_UB]],
+// CK2: call void @__kmpc_for_static_init_8({{.+}}, {{.+}}, i32 92, {{.+}}, {{.+}}, i64* [[OMP_UB]],
+// CK2: call void {{.*}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[PAR_OUTL1:.+]] to
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define internal void @[[PAR_OUTL1]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_{{[4|8]}}({{.+}}, {{.+}}, i32 34, {{.+}}, {{.+}},
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+
+// CK2: define {{.*}}i32 @[[TMAIN]]({{.+}})
+// CK2: call i32 @__tgt_target_teams(
+// CK2: call void @[[OFFLT1:.+]]({{.+}})
+// CK2: ret
+// CK2-NEXT: }
+
+// CK2: define {{.*}}void @[[OFFLT1]]({{.+}})
+// CK2: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTLT1:.+]] to {{.+}},
+// CK2: ret void
+
+// CK2: define internal void @[[OUTLT1]]({{.+}})
+// discard loop variables not needed here
+// CK2: [[OMP_UB:%.omp.comb.ub]] = alloca i32,
+// CK2: store i32 {{.+}}, i32* [[OMP_UB]],
+// CK2: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 92, {{.+}}, {{.+}}, i32* [[OMP_UB]],
+// CK2: call void {{.*}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[TPAR_OUTL1:.+]] to
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define internal void @[[TPAR_OUTL1]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 34, {{.+}}, {{.+}},
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+#endif // CK2
+#endif // #ifndef HEADER
diff --git a/test/OpenMP/teams_distribute_parallel_for_copyin_codegen.cpp b/test/OpenMP/teams_distribute_parallel_for_copyin_codegen.cpp
new file mode 100644
index 000000000000..0202a40002b5
--- /dev/null
+++ b/test/OpenMP/teams_distribute_parallel_for_copyin_codegen.cpp
@@ -0,0 +1,199 @@
+// RUN: %clang_cc1 -DCHECK -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -DCHECK -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+
+// RUN: %clang_cc1 -DLAMBDA -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+int x;
+#pragma omp threadprivate(x)
+
+template <typename T>
+T tmain() {
+ int a[2];
+#pragma omp target
+#pragma omp teams distribute parallel for copyin(x)
+ for (int i = 0; i < 2; ++i) {
+ a[i] = x;
+ }
+ return T();
+}
+
+int main() {
+ int a[2];
+#ifdef LAMBDA
+ // LAMBDA-LABEL: @main
+ // LAMBDA: call void [[OUTER_LAMBDA:@.+]](
+ [&]() {
+ // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
+ // LAMBDA: call i32 @__tgt_target_teams(
+ // LAMBDA: call void @[[LOFFL1:.+]](
+ // LAMBDA: ret
+#pragma omp target
+#pragma omp teams distribute parallel for copyin(x)
+ for (int i = 0; i < 2; ++i) {
+ // LAMBDA: define{{.*}} internal{{.*}} void @[[LOFFL1]](
+ // LAMBDA: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 {{.+}}, {{.+}} @[[LOUTL1:.+]] to {{.+}})
+ // LAMBDA: ret void
+
+ // LAMBDA: define internal void @[[LOUTL1]](
+ // Skip global, bound tid and loop vars
+ // LAMBDA: {{.+}} = alloca i32*,
+ // LAMBDA: {{.+}} = alloca i32*,
+ // LAMBDA: alloca i32,
+ // LAMBDA: alloca i32,
+ // LAMBDA: alloca i32,
+ // LAMBDA: alloca i32,
+ // LAMBDA: alloca i32,
+ a[i] = x;
+
+ // LAMBDA: call void @__kmpc_for_static_init_4(
+ // LAMBDA: call void {{.+}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[LPAR_OUTL:.+]] to
+ // LAMBDA: call void @__kmpc_for_static_fini(
+ // LAMBDA: ret void
+
+ // LAMBDA: define internal void @[[LPAR_OUTL]]({{.+}})
+ // Skip global, bound tid and loop vars
+ // LAMBDA: {{.+}} = alloca i32*,
+ // LAMBDA: {{.+}} = alloca i32*,
+ // LAMBDA: alloca i{{[0-9]+}},
+ // LAMBDA: alloca i{{[0-9]+}},
+ // LAMBDA: {{%.+}} = alloca [2 x i{{[0-9]+}}]*,
+ // LAMBDA: [[X_ADDR:%.+]] = alloca i{{[0-9]+}}*,
+ // LAMBDA: alloca i32,
+ // LAMBDA: alloca i32,
+ // LAMBDA: alloca i32,
+ // LAMBDA: alloca i32,
+ // LAMBDA: alloca i32,
+
+ // LAMBDA: [[X_REF:%.+]] = load {{.+}}, {{.+}} [[X_ADDR]],
+
+ // LAMBDA: call void @__kmpc_for_static_init_4(
+ // LAMBDA: [[X_VAL:%.+]] = load {{.+}}, {{.+}} [[X_REF]],
+ // LAMBDA: store {{.+}} [[X_VAL]],
+ // LAMBDA: call void [[INNER_LAMBDA:@.+]](
+ // LAMBDA: call void @__kmpc_for_static_fini(
+ // LAMBDA: ret void
+ [&]() {
+ // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]])
+ // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]],
+ a[i] = x;
+ }();
+ }
+ }();
+ return 0;
+#else
+#pragma omp target
+#pragma omp teams distribute parallel for copyin(x)
+ for (int i = 0; i < 2; ++i) {
+ a[i] = x;
+ }
+ return tmain<int>();
+ //return 0;
+#endif
+}
+
+// CHECK: define {{.*}}i{{[0-9]+}} @main()
+// CHECK: call i32 @__tgt_target_teams(
+// CHECK: call void @[[OFFL1:.+]](i{{64|32}} %{{.+}})
+// CHECK: {{%.+}} = call{{.*}} i32 @[[TMAIN_INT:.+]]()
+// CHECK: ret
+
+// CHECK: define{{.*}} void @[[OFFL1]]({{.+}})
+// CHECK: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 {{.+}}, {{.+}} @[[OUTL1:.+]] to {{.+}})
+// CHECK: ret void
+
+// CHECK: define internal void @[[OUTL1]]({{.+}})
+// Skip global, bound tid and loop vars
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: {{.+}} = alloca i32,
+// CHECK: {{.+}} = alloca i32,
+// CHECK: {{.+}} = alloca i32,
+// CHECK: {{.+}} = alloca i32,
+// CHECK: {{.+}} = alloca i32,
+
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: call void {{.+}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[PAR_OUTL1:.+]] to
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: ret void
+
+// CHECK: define internal void @[[PAR_OUTL1]]({{.+}})
+// Skip global, bound tid and loop vars
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{%.+}} = alloca [2 x i{{[0-9]+}}]*,
+// CHECK: [[X_ADDR:%.+]] = alloca i{{[0-9]+}}*,
+// CHECK: {{.+}} = alloca i32,
+// CHECK: {{.+}} = alloca i32,
+// CHECK: {{.+}} = alloca i32,
+// CHECK: {{.+}} = alloca i32,
+// CHECK: {{.+}} = alloca i32,
+
+// CHECK: [[X_REF:%.+]] = load {{.+}}, {{.+}} [[X_ADDR]],
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: [[X_VAL:%.+]] = load {{.+}}, {{.+}} [[X_REF]],
+// CHECK: store {{.+}} [[X_VAL]],
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: ret void
+
+// CHECK: define{{.*}} i{{[0-9]+}} @[[TMAIN_INT]]()
+// CHECK: call i32 @__tgt_target_teams(
+// CHECK: call void @[[TOFFL1:.+]](
+// CHECK: ret
+
+// CHECK: define {{.*}}void @[[TOFFL1]](
+// CHECK: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 {{.+}}, {{.+}} @[[TOUTL1:.+]] to {{.+}})
+// CHECK: ret void
+
+// CHECK: define internal void @[[TOUTL1]]({{.+}})
+// Skip global, bound tid and loop vars
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: call void {{.+}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[TPAR_OUTL1:.+]] to
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: ret void
+
+// CHECK: define internal void @[[TPAR_OUTL1]]({{.+}})
+// Skip global, bound tid and loop vars
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: {{.+}} = alloca i32*,
+// prev lb and ub
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+
+// CHECK: {{%.+}} = alloca [2 x i{{[0-9]+}}]*,
+// CHECK: [[X_ADDR:%.+]] = alloca i{{[0-9]+}}*,
+// iter variables
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+
+// CHECK: [[X_REF:%.+]] = load {{.+}}, {{.+}} [[X_ADDR]],
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: [[X_VAL:%.+]] = load {{.+}}, {{.+}} [[X_REF]],
+// CHECK: store {{.+}} [[X_VAL]],
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: ret void
+
+
+#endif
diff --git a/test/OpenMP/teams_distribute_parallel_for_copyin_messages.cpp b/test/OpenMP/teams_distribute_parallel_for_copyin_messages.cpp
new file mode 100644
index 000000000000..30f3e75bf635
--- /dev/null
+++ b/test/OpenMP/teams_distribute_parallel_for_copyin_messages.cpp
@@ -0,0 +1,113 @@
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+class S2 {
+ mutable int a;
+
+public:
+ S2() : a(0) {}
+ S2 &operator=(S2 &s2) { return *this; }
+};
+class S3 {
+ int a;
+
+public:
+ S3() : a(0) {}
+ S3 &operator=(S3 &s3) { return *this; }
+};
+class S4 {
+ int a;
+ S4();
+ S4 &operator=(const S4 &s4); // expected-note {{implicitly declared private here}}
+
+public:
+ S4(int v) : a(v) {}
+};
+class S5 {
+ int a;
+ S5() : a(0) {}
+ S5 &operator=(const S5 &s5) { return *this; } // expected-note {{implicitly declared private here}}
+
+public:
+ S5(int v) : a(v) {}
+};
+template <class T>
+class ST {
+public:
+ static T s;
+};
+
+S2 k;
+S3 h;
+S4 l(3);
+S5 m(4);
+#pragma omp threadprivate(h, k, l, m)
+
+namespace A {
+double x;
+#pragma omp threadprivate(x)
+}
+namespace B {
+using A::x;
+}
+
+int main(int argc, char **argv) {
+ int i;
+#pragma omp target
+#pragma omp teams distribute parallel for copyin // expected-error {{expected '(' after 'copyin'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams distribute parallel for copyin( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams distribute parallel for copyin() // expected-error {{expected expression}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams distribute parallel for copyin(k // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams distribute parallel for copyin(h, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams distribute parallel for copyin(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams distribute parallel for copyin(l) // expected-error {{'operator=' is a private member of 'S4'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams distribute parallel for copyin(S1) // expected-error {{'S1' does not refer to a value}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams distribute parallel for copyin(argv[1]) // expected-error {{expected variable name}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams distribute parallel for copyin(i) // expected-error {{copyin variable must be threadprivate}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams distribute parallel for copyin(m) // expected-error {{'operator=' is a private member of 'S5'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams distribute parallel for copyin(ST<int>::s, B::x) // expected-error {{copyin variable must be threadprivate}}
+ for (i = 0; i < argc; ++i)
+ foo();
+
+ return 0;
+}
diff --git a/test/OpenMP/teams_distribute_parallel_for_dist_schedule_codegen.cpp b/test/OpenMP/teams_distribute_parallel_for_dist_schedule_codegen.cpp
new file mode 100644
index 000000000000..dc48f166b4c0
--- /dev/null
+++ b/test/OpenMP/teams_distribute_parallel_for_dist_schedule_codegen.cpp
@@ -0,0 +1,263 @@
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+// Test host codegen.
+// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64
+// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32
+#ifdef CK1
+
+template <typename T, int X, long long Y>
+struct SS{
+ T a[X];
+ float b;
+ // CK1: define {{.*}}i32 @{{.+}}foo{{.+}}(
+ int foo(void) {
+
+ // CK1: call i32 @__tgt_target_teams(
+ // CK1: call void @[[OFFL1:.+]](
+ #pragma omp target
+ #pragma omp teams distribute parallel for
+ for(int i = 0; i < X; i++) {
+ a[i] = (T)0;
+ }
+ // CK1: call i32 @__tgt_target_teams(
+ // CK1: call void @[[OFFL2:.+]](
+ #pragma omp target
+ #pragma omp teams distribute parallel for dist_schedule(static)
+ for(int i = 0; i < X; i++) {
+ a[i] = (T)0;
+ }
+ // CK1: call i32 @__tgt_target_teams(
+ // CK1: call void @[[OFFL3:.+]](
+ #pragma omp target
+ #pragma omp teams distribute parallel for dist_schedule(static, X/2)
+ for(int i = 0; i < X; i++) {
+ a[i] = (T)0;
+ }
+ // CK1: define internal void @[[OFFL1]](
+ // CK1: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTL1:.+]] to {{.+}},
+ // CK1: ret void
+
+ // CK1: define internal void @[[OUTL1]]({{.+}})
+ // CK1: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 92
+ // CK1: call void {{.*}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[PAR_OUTL1:.+]] to
+ // CK1: call void @__kmpc_for_static_fini(
+ // CK1: ret void
+
+ // CK1: define internal void @[[PAR_OUTL1]]({{.+}})
+ // CK1: call void @__kmpc_for_static_init_4(
+ // CK1: call void @__kmpc_for_static_fini(
+ // CK1: ret void
+
+ // CK1: define internal void @[[OFFL2]](
+ // CK1: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTL2:.+]] to {{.+}},
+ // CK1: ret void
+
+ // CK1: define internal void @[[OUTL2]]({{.+}})
+ // CK1: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 92
+ // CK1: call void {{.*}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[PAR_OUTL2:.+]] to
+ // CK1: call void @__kmpc_for_static_fini(
+ // CK1: ret void
+
+ // CK1: define internal void @[[PAR_OUTL2]]({{.+}})
+ // CK1: call void @__kmpc_for_static_init_4(
+ // CK1: call void @__kmpc_for_static_fini(
+ // CK1: ret void
+
+
+ // CK1: define internal void @[[OFFL3]](
+ // CK1: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTL3:.+]] to {{.+}},
+ // CK1: ret void
+
+ // CK1: define internal void @[[OUTL3]]({{.+}})
+ // CK1: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 91
+ // CK1: call void {{.*}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[PAR_OUTL3:.+]] to
+ // CK1: call void @__kmpc_for_static_fini(
+ // CK1: ret void
+
+ // CK1: define internal void @[[PAR_OUTL3]]({{.+}})
+ // CK1: call void @__kmpc_for_static_init_4(
+ // CK1: call void @__kmpc_for_static_fini(
+ // CK1: ret void
+
+ return a[0];
+ }
+};
+
+int teams_template_struct(void) {
+ SS<int, 123, 456> V;
+ return V.foo();
+
+}
+#endif // CK1
+
+// Test host codegen.
+// RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64
+// RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32
+#ifdef CK2
+
+template <typename T, int n>
+int tmain(T argc) {
+ T a[n];
+ int m = 10;
+#pragma omp target
+#pragma omp teams distribute parallel for
+ for(int i = 0; i < n; i++) {
+ a[i] = (T)0;
+ }
+#pragma omp target
+#pragma omp teams distribute parallel for dist_schedule(static)
+ for(int i = 0; i < n; i++) {
+ a[i] = (T)0;
+ }
+#pragma omp target
+#pragma omp teams distribute parallel for dist_schedule(static, m)
+ for(int i = 0; i < n; i++) {
+ a[i] = (T)0;
+ }
+ return 0;
+}
+
+int main (int argc, char **argv) {
+ int n = 100;
+ int a[n];
+ int m = 10;
+#pragma omp target
+#pragma omp teams distribute parallel for
+ for(int i = 0; i < n; i++) {
+ a[i] = 0;
+ }
+#pragma omp target
+#pragma omp teams distribute parallel for dist_schedule(static)
+ for(int i = 0; i < n; i++) {
+ a[i] = 0;
+ }
+#pragma omp target
+#pragma omp teams distribute parallel for dist_schedule(static, m)
+ for(int i = 0; i < n; i++) {
+ a[i] = 0;
+ }
+ return tmain<int, 10>(argc);
+}
+
+// CK2: define {{.*}}i32 @{{[^,]+}}(i{{.+}}{{.+}} %[[ARGC:.+]], {{.+}})
+// CK2: call i32 @__tgt_target_teams(
+// CK2: call void @[[OFFL1:.+]]({{.+}})
+// CK2: call i32 @__tgt_target_teams(
+// CK2: call void @[[OFFL2:.+]]({{.+}})
+// CK2: call i32 @__tgt_target_teams(
+// CK2: call void @[[OFFL3:.+]]({{.+}})
+// CK2: {{%.+}} = call{{.*}} i32 @[[TMAIN:.+]]({{.+}})
+// CK2: ret
+
+// CK2: define {{.*}}void @[[OFFL1]]({{.+}})
+// CK2: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 3, {{.+}} @[[OUTL1:.+]] to {{.+}},
+// CK2: ret void
+
+// CK2: define internal void @[[OUTL1]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 92
+// CK2: call void {{.*}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[PAR_OUTL1:.+]] to
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define internal void @[[PAR_OUTL1]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4(
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define {{.*}}void @[[OFFL2]]({{.+}})
+// CK2: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 3, {{.+}} @[[OUTL2:.+]] to {{.+}},
+// CK2: ret void
+
+// CK2: define internal void @[[OUTL2]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 92
+// CK2: call void {{.*}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[PAR_OUTL2:.+]] to
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define internal void @[[PAR_OUTL2]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4(
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define {{.*}}void @[[OFFL3]]({{.+}})
+// CK2: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 4, {{.+}} @[[OUTL3:.+]] to {{.+}},
+// CK2: ret void
+
+// CK2: define internal void @[[OUTL3]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 91
+// CK2: call void {{.*}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[PAR_OUTL3:.+]] to
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define internal void @[[PAR_OUTL3]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4(
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define {{.*}}i32 @[[TMAIN]]({{.+}})
+// CK2: call i32 @__tgt_target_teams(
+// CK2: call void @[[OFFLT1:.+]]({{.+}})
+// CK2: call i32 @__tgt_target_teams(
+// CK2: call void @[[OFFLT2:.+]]({{.+}})
+// CK2: call i32 @__tgt_target_teams(
+// CK2: call void @[[OFFLT3:.+]]({{.+}})
+// CK2: ret
+// CK2-NEXT: }
+
+// CK2: define {{.*}}void @[[OFFLT1]]({{.+}})
+// CK2: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTLT1:.+]] to {{.+}},
+// CK2: ret void
+
+// CK2: define internal void @[[OUTLT1]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 92
+// CK2: call void {{.*}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[PAR_OUTLT1:.+]] to
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define internal void @[[PAR_OUTLT1]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4(
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define {{.*}}void @[[OFFLT2]]({{.+}})
+// CK2: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTLT2:.+]] to {{.+}},
+// CK2: ret void
+
+// CK2: define internal void @[[OUTLT2]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 92
+// CK2: call void {{.*}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[PAR_OUTLT2:.+]] to
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define internal void @[[PAR_OUTLT2]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4(
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define {{.*}}void @[[OFFLT3]]({{.+}})
+// CK2: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 {{.+}}, {{.+}} @[[OUTLT3:.+]] to {{.+}},
+// CK2: ret void
+
+// CK2: define internal void @[[OUTLT3]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 91
+// CK2: call void {{.*}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[PAR_OUTLT3:.+]] to
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define internal void @[[PAR_OUTLT3]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4(
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+#endif // CK2
+#endif // #ifndef HEADER
diff --git a/test/OpenMP/teams_distribute_parallel_for_firstprivate_codegen.cpp b/test/OpenMP/teams_distribute_parallel_for_firstprivate_codegen.cpp
new file mode 100644
index 000000000000..fa99f9cfcf1b
--- /dev/null
+++ b/test/OpenMP/teams_distribute_parallel_for_firstprivate_codegen.cpp
@@ -0,0 +1,496 @@
+// RUN: %clang_cc1 -DCHECK -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -DCHECK -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+
+// RUN: %clang_cc1 -DLAMBDA -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+struct St {
+ int a, b;
+ St() : a(0), b(0) {}
+ St(const St &st) : a(st.a + st.b), b(0) {}
+ ~St() {}
+};
+
+volatile int g = 1212;
+volatile int &g1 = g;
+
+template <class T>
+struct S {
+ T f;
+ S(T a) : f(a + g) {}
+ S() : f(g) {}
+ S(const S &s, St t = St()) : f(s.f + t.a) {}
+ operator T() { return T(); }
+ ~S() {}
+};
+
+// CHECK-DAG: [[S_FLOAT_TY:%.+]] = type { float }
+// CHECK-DAG: [[S_INT_TY:%.+]] = type { i{{[0-9]+}} }
+// CHECK-DAG: [[ST_TY:%.+]] = type { i{{[0-9]+}}, i{{[0-9]+}} }
+
+template <typename T>
+T tmain() {
+ S<T> test;
+ T t_var = T();
+ T vec[] = {1, 2};
+ S<T> s_arr[] = {1, 2};
+ S<T> &var = test;
+#pragma omp target
+#pragma omp teams distribute parallel for firstprivate(t_var, vec, s_arr, var)
+ for (int i = 0; i < 2; ++i) {
+ vec[i] = t_var;
+ s_arr[i] = var;
+ }
+ return T();
+}
+
+// CHECK-DAG: [[TEST:@.+]] = global [[S_FLOAT_TY]] zeroinitializer,
+S<float> test;
+// CHECK-DAG: [[T_VAR:@.+]] = global i{{[0-9]+}} 333,
+int t_var = 333;
+// CHECK-DAG: [[VEC:@.+]] = global [2 x i{{[0-9]+}}] [i{{[0-9]+}} 1, i{{[0-9]+}} 2],
+int vec[] = {1, 2};
+// CHECK-DAG: [[S_ARR:@.+]] = global [2 x [[S_FLOAT_TY]]] zeroinitializer,
+S<float> s_arr[] = {1, 2};
+// CHECK-DAG: [[VAR:@.+]] = global [[S_FLOAT_TY]] zeroinitializer,
+S<float> var(3);
+// CHECK-DAG: [[SIVAR:@.+]] = internal global i{{[0-9]+}} 0,
+
+int main() {
+ static int sivar;
+#ifdef LAMBDA
+ // LAMBDA: [[G:@.+]] = global i{{[0-9]+}} 1212,
+ // LAMBDA-LABEL: @main
+ // LAMBDA: call void [[OUTER_LAMBDA:@.+]](
+ [&]() {
+ // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
+ // LAMBDA: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 3, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 0)
+ // LAMBDA: call void @[[LOFFL1:.+]](i{{64|32}} %{{.+}})
+ // LAMBDA: ret
+#pragma omp target
+#pragma omp teams distribute parallel for firstprivate(g, g1, sivar)
+ for (int i = 0; i < 2; ++i) {
+ // LAMBDA: define{{.*}} internal{{.*}} void @[[LOFFL1]](i{{64|32}} {{%.+}}, i{{64|32}} {{%.+}})
+ // LAMBDA: {{%.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: {{%.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: {{%.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: [[G_CAST:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[G1_CAST:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[SIVAR_CAST:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA-DAG: [[G_CAST_VAL:%.+]] = load{{.+}} [[G_CAST]],
+ // LAMBDA-DAG: [[G1_CAST_VAL:%.+]] = load{{.+}} [[G1_CAST]],
+ // LAMBDA-DAG: [[SIVAR_CAST_VAL:%.+]] = load{{.+}} [[SIVAR_CAST]],
+ // LAMBDA: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 3, {{.+}} @[[LOUTL1:.+]] to {{.+}}, {{.+}} [[G_CAST_VAL]], {{.+}} [[G1_CAST_VAL]], {{.+}} [[SIVAR_CAST_VAL]])
+ // LAMBDA: ret void
+
+ // LAMBDA: define internal void @[[LOUTL1]]({{.+}})
+ // Skip global and bound tid vars
+ // LAMBDA: {{.+}} = alloca i32*,
+ // LAMBDA: {{.+}} = alloca i32*,
+ // LAMBDA: [[G_ADDR:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[G1_ADDR:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[SIVAR_ADDR:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[G1_TMP:%.+]] = alloca i32*,
+ // skip loop vars
+ // LAMBDA-DAG: store {{.+}}, {{.+}} [[G_ADDR]],
+ // LAMBDA-DAG: store {{.+}}, {{.+}} [[G1_ADDR]],
+ // LAMBDA-DAG: store {{.+}}, {{.+}} [[SIVAR_ADDR]],
+ // LAMBDA-DAG: [[G_CONV:%.+]] = bitcast {{.+}} [[G_ADDR]] to
+ // LAMBDA-DAG: [[G1_CONV:%.+]] = bitcast {{.+}} [[G1_ADDR]] to
+ // LAMBDA-DAG: [[SIVAR_CONV:%.+]] = bitcast {{.+}} [[SIVAR_ADDR]] to
+ // LAMBDA-DAG: store{{.+}} [[G1_CONV]], {{.+}} [[G1_TMP]],
+ g = 1;
+ g1 = 1;
+ sivar = 2;
+ // LAMBDA: call void @__kmpc_for_static_init_4(
+ // LAMBDA: call void {{.*}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[LPAR_OUTL:.+]] to
+ // LAMBDA: call void @__kmpc_for_static_fini(
+ // LAMBDA: ret void
+
+ // LAMBDA: define internal void @[[LPAR_OUTL]]({{.+}})
+ // Skip global and bound tid vars, and prev lb and ub vars
+ // LAMBDA: {{.+}} = alloca i32*,
+ // LAMBDA: {{.+}} = alloca i32*,
+ // LAMBDA: {{.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: {{.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: [[G_ADDR:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[G1_ADDR:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[SIVAR_ADDR:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[G1_TMP:%.+]] = alloca i32*,
+ // skip loop vars
+ // LAMBDA: alloca i32,
+ // LAMBDA: alloca i32,
+ // LAMBDA: alloca i32,
+ // LAMBDA: alloca i32,
+ // LAMBDA: alloca i32,
+ // LAMBDA: alloca i32,
+ // LAMBDA: [[G_PRIV:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[G1_PRIV:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[G1_TMP_PRIV:%.+]] = alloca i{{[0-9]+}}*,
+ // LAMBDA: [[SIVAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA-DAG: store {{.+}}, {{.+}} [[G_ADDR]],
+ // LAMBDA-DAG: store {{.+}}, {{.+}} [[G1_ADDR]],
+ // LAMBDA-DAG: store {{.+}}, {{.+}} [[SIVAR_ADDR]],
+ // LAMBDA-DAG: [[G_CONV:%.+]] = bitcast {{.+}} [[G_ADDR]] to
+ // LAMBDA-DAG: [[G1_CONV:%.+]] = bitcast {{.+}} [[G1_ADDR]] to
+ // LAMBDA-DAG: [[SIVAR_CONV:%.+]] = bitcast {{.+}} [[SIVAR_ADDR]] to
+ // LAMBDA-DAG: store{{.+}} [[G1_CONV]], {{.+}} [[G1_TMP]],
+
+ // use of private vars
+ // LAMBDA-DAG: store{{.+}} 1, {{.+}} [[G_PRIV]],
+ // LAMBDA-DAG: [[G1:%.+]] = load{{.+}}, {{.+}}* [[G1_TMP_PRIV]]
+ // LAMBDA-DAG: store{{.+}} 1, {{.+}} [[G1]],
+ // LAMBDA-DAG: store{{.+}} 2, {{.+}} [[SIVAR_PRIV]],
+ // LAMBDA-DAG: [[G1_REF:%.+]] = load{{.+}}, {{.+}} [[G1_TMP]],
+ // LAMBDA: call void [[INNER_LAMBDA:@.+]](
+ // LAMBDA: call void @__kmpc_for_static_fini(
+ // LAMBDA: ret void
+ [&]() {
+ // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]])
+ // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]],
+ g = 2;
+ g1 = 2;
+ sivar = 4;
+ // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]]
+
+ // LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // LAMBDA: [[G_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G_PTR_REF]]
+ // LAMBDA: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[G_REF]]
+ // LAMBDA: [[G1_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // LAMBDA: [[G1_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G1_PTR_REF]]
+ // LAMBDA: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[G1_REF]]
+ // LAMBDA: [[SIVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+ // LAMBDA: [[SIVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SIVAR_PTR_REF]]
+ // LAMBDA: store i{{[0-9]+}} 4, i{{[0-9]+}}* [[SIVAR_REF]]
+ }();
+ }
+ }();
+ return 0;
+#else
+#pragma omp target
+#pragma omp teams distribute parallel for firstprivate(t_var, vec, s_arr, var, sivar)
+ for (int i = 0; i < 2; ++i) {
+ vec[i] = t_var;
+ s_arr[i] = var;
+ sivar += i;
+ }
+ return tmain<int>();
+#endif
+}
+
+// CHECK: define {{.*}}i{{[0-9]+}} @main()
+// CHECK: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 5, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 0)
+// CHECK: call void @[[OFFL1:.+]](i{{64|32}} %{{.+}})
+// CHECK: {{%.+}} = call{{.*}} i32 @[[TMAIN_INT:.+]]()
+// CHECK: ret
+
+// CHECK: define{{.*}} void @[[OFFL1]]({{.+}})
+// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}]*,
+// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]]*,
+// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]]*,
+// CHECK: [[SIVAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[T_VAR_CAST:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[SIVAR_CAST:%.+]] = alloca i{{[0-9]+}},
+
+// CHECK-DAG: [[VEC_TE_PAR:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** [[VEC_PRIV]],
+// CHECK-DAG: [[T_VAR_TE_PAR:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_CAST]],
+// CHECK-DAG: [[S_ARR_TE_PAR:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[S_ARR_PRIV]],
+// CHECK-DAG: [[VAR_TE_PAR:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[VAR_PRIV]],
+// CHECK-DAG: [[SIVAR_TE_PAR:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR_CAST]],
+
+// CHECK: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 5, {{.+}} @[[OUTL1:.+]] to {{.+}}, [2 x i{{[0-9]+}}]* [[VEC_TE_PAR]], i{{[0-9]+}} [[T_VAR_TE_PAR]], [2 x [[S_FLOAT_TY]]]* [[S_ARR_TE_PAR]], [[S_FLOAT_TY]]* [[VAR_TE_PAR]], i{{[0-9]+}} [[SIVAR_TE_PAR]])
+// CHECK: ret void
+
+// CHECK: define internal void @[[OUTL1]]({{.+}})
+// Skip global and bound tid vars
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: [[VEC_ADDR:%.+]] = alloca [2 x i{{[0-9]+}}]*,
+// CHECK: [[T_VAR_ADDR:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[S_ARR_ADDR:%.+]] = alloca [2 x [[S_FLOAT_TY]]]*,
+// CHECK: [[VAR_ADDR:%.+]] = alloca [[S_FLOAT_TY]]*,
+// CHECK: [[SIVAR_ADDR:%.+]] = alloca i{{[0-9]+}},
+// Skip temp vars for loop
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]],
+// CHECK: [[AGG_TMP1:%.+]] = alloca [[ST_TY]],
+// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]],
+// CHECK: [[AGG_TMP2:%.+]] = alloca [[ST_TY]],
+
+// param copy
+// CHECK: store [2 x i{{[0-9]+}}]* {{.+}}, [2 x i{{[0-9]+}}]** [[VEC_ADDR]],
+// CHECK: store i{{[0-9]+}} {{.+}}, i{{[0-9]+}}* [[T_VAR_ADDR]],
+// CHECK: store [2 x [[S_FLOAT_TY]]]* {{.+}}, [2 x [[S_FLOAT_TY]]]** [[S_ARR_ADDR]],
+// CHECK: store [[S_FLOAT_TY]]* {{.+}}, [[S_FLOAT_TY]]** [[VAR_ADDR]],
+// CHECK: store i{{[0-9]+}} {{.+}}, i{{[0-9]+}}* [[SIVAR_ADDR]],
+
+// T_VAR and SIVAR
+// CHECK-DAG-64: [[CONV_TVAR:%.+]] = bitcast i64* [[T_VAR_ADDR]] to i32*
+// CHECK-DAG-64: [[CONV_SIVAR:%.+]] = bitcast i64* [[SIVAR_ADDR]] to i32*
+
+// preparation vars
+// CHECK-DAG: [[VEC_ADDR_VAL:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** [[VEC_ADDR]],
+// CHECK-DAG: [[S_ARR_ADDR_REF:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[S_ARR_ADDR]],
+// CHECK-DAG: [[VAR_ADDR_REF:%.+]] = load{{.+}} [[VAR_ADDR]],
+
+// firstprivate vec(vec): copy from *_addr into priv1 and then from priv1 into priv2
+// CHECK-DAG: [[VEC_DEST_PRIV:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV]] to i8*
+// CHECK-DAG: [[VEC_SRC:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_ADDR_VAL]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[VEC_DEST_PRIV]], i8* [[VEC_SRC]], {{.+}})
+
+// firstprivate(s_arr)
+// CHECK-DAG: [[S_ARR_PRIV_BGN:%.+]] = getelementptr{{.*}} [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[S_ARR_PRIV]],
+// CHECK-DAG: [[S_ARR_ADDR_BGN:%.+]] = bitcast [2 x [[S_FLOAT_TY]]]* [[S_ARR_ADDR_REF]] to
+// CHECK-DAG: [[S_ARR_FIN:%.+]] = icmp{{.+}} [[S_ARR_PRIV_BGN]],
+// CHECK-DAG: [[S_ARR_SRC_COPY:%.+]] = phi{{.+}} [ [[S_ARR_ADDR_BGN]], {{.+}} ], [ [[S_ARR_SRC:%.+]], {{.+}} ]
+// CHECK-DAG: [[S_ARR_DST_COPY:%.+]] = phi{{.+}} [ [[S_ARR_PRIV_BGN]], {{.+}}], [ [[S_ARR_DST:%.+]], {{.+}} ]
+// CHECK-DAG: call void @{{.+}}({{.+}} [[AGG_TMP1]])
+// CHECK-DAG: call void @{{.+}}({{.+}} [[S_ARR_DST_COPY]], {{.+}} [[S_ARR_SRC_COPY]], {{.+}} [[AGG_TMP1]])
+// CHECK-DAG: call void @{{.+}}({{.+}} [[AGG_TMP1]])
+// CHECK-DAG: [[S_ARR_DST]] = getelementptr {{.+}} [[S_ARR_DST_COPY]],
+// CHECK-DAG: [[S_ARR_SRC]] = getelementptr {{.+}} [[S_ARR_SRC_COPY]],
+
+// firstprivate(var)
+// CHECK-DAG: call void @{{.+}}({{.+}} [[AGG_TMP2]])
+// CHECK-DAG: call void @{{.+}}({{.+}} [[VAR_PRIV]], {{.+}} [[VAR_ADDR_REF]], {{.+}} [[AGG_TMP2]])
+// CHECK-DAG: call void @{{.+}}({{.+}} [[AGG_TMP2]])
+
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: call void {{.*}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[PAR_OUTL:.+]] to
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: ret void
+
+// CHECK: define internal void @[[PAR_OUTL]]({{.+}})
+// Skip global and bound tid vars, and prev lb ub vars
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: [[VEC_ADDR:%.+]] = alloca [2 x i{{[0-9]+}}]*,
+// CHECK: [[T_VAR_ADDR:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[S_ARR_ADDR:%.+]] = alloca [2 x [[S_FLOAT_TY]]]*,
+// CHECK: [[VAR_ADDR:%.+]] = alloca [[S_FLOAT_TY]]*,
+// CHECK: [[SIVAR_ADDR:%.+]] = alloca i{{[0-9]+}},
+// Skip temp vars for loop
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]],
+// CHECK: [[AGG_TMP1:%.+]] = alloca [[ST_TY]],
+// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]],
+// CHECK: [[AGG_TMP2:%.+]] = alloca [[ST_TY]],
+
+// param copy
+// CHECK: store [2 x i{{[0-9]+}}]* {{.+}}, [2 x i{{[0-9]+}}]** [[VEC_ADDR]],
+// CHECK: store i{{[0-9]+}} {{.+}}, i{{[0-9]+}}* [[T_VAR_ADDR]],
+// CHECK: store [2 x [[S_FLOAT_TY]]]* {{.+}}, [2 x [[S_FLOAT_TY]]]** [[S_ARR_ADDR]],
+// CHECK: store [[S_FLOAT_TY]]* {{.+}}, [[S_FLOAT_TY]]** [[VAR_ADDR]],
+// CHECK: store i{{[0-9]+}} {{.+}}, i{{[0-9]+}}* [[SIVAR_ADDR]],
+
+// T_VAR and SIVAR
+// CHECK-DAG-64: [[CONV_TVAR:%.+]] = bitcast i64* [[T_VAR_ADDR]] to i32*
+// CHECK-DAG-64: [[CONV_SIVAR:%.+]] = bitcast i64* [[SIVAR_ADDR]] to i32*
+
+// preparation vars
+// CHECK-DAG: [[VEC_ADDR_VAL:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** [[VEC_ADDR]],
+// CHECK-DAG: [[S_ARR_ADDR_REF:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[S_ARR_ADDR]],
+// CHECK-DAG: [[VAR_ADDR_REF:%.+]] = load{{.+}} [[VAR_ADDR]],
+
+// firstprivate vec(vec): copy from *_addr into priv1 and then from priv1 into priv2
+// CHECK-DAG: [[VEC_DEST_PRIV:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV]] to i8*
+// CHECK-DAG: [[VEC_SRC:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_ADDR_VAL]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[VEC_DEST_PRIV]], i8* [[VEC_SRC]], {{.+}})
+
+// firstprivate(s_arr)
+// CHECK-DAG: [[S_ARR_PRIV_BGN:%.+]] = getelementptr{{.*}} [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[S_ARR_PRIV]],
+// CHECK-DAG: [[S_ARR_ADDR_BGN:%.+]] = bitcast [2 x [[S_FLOAT_TY]]]* [[S_ARR_ADDR_REF]] to
+// CHECK-DAG: [[S_ARR_FIN:%.+]] = icmp{{.+}} [[S_ARR_PRIV_BGN]],
+// CHECK-DAG: [[S_ARR_SRC_COPY:%.+]] = phi{{.+}} [ [[S_ARR_ADDR_BGN]], {{.+}} ], [ [[S_ARR_SRC:%.+]], {{.+}} ]
+// CHECK-DAG: [[S_ARR_DST_COPY:%.+]] = phi{{.+}} [ [[S_ARR_PRIV_BGN]], {{.+}}], [ [[S_ARR_DST:%.+]], {{.+}} ]
+// CHECK-DAG: call void @{{.+}}({{.+}} [[AGG_TMP1]])
+// CHECK-DAG: call void @{{.+}}({{.+}} [[S_ARR_DST_COPY]], {{.+}} [[S_ARR_SRC_COPY]], {{.+}} [[AGG_TMP1]])
+// CHECK-DAG: call void @{{.+}}({{.+}} [[AGG_TMP1]])
+// CHECK-DAG: [[S_ARR_DST]] = getelementptr {{.+}} [[S_ARR_DST_COPY]],
+// CHECK-DAG: [[S_ARR_SRC]] = getelementptr {{.+}} [[S_ARR_SRC_COPY]],
+
+// firstprivate(var)
+// CHECK-DAG: call void @{{.+}}({{.+}} [[AGG_TMP2]])
+// CHECK-DAG: call void @{{.+}}({{.+}} [[VAR_PRIV]], {{.+}} [[VAR_ADDR_REF]], {{.+}} [[AGG_TMP2]])
+// CHECK-DAG: call void @{{.+}}({{.+}} [[AGG_TMP2]])
+
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK-DAG-32: {{.+}} = {{.+}} [[T_VAR_ADDR]]
+// CHECK-DAG-64: {{.+}} = {{.+}} [[CONV_TVAR]]
+// CHECK-DAG: {{.+}} = {{.+}} [[VEC_PRIV]]
+// CHECK-DAG: {{.+}} = {{.+}} [[S_ARR_PRIV]]
+// CHECK-DAG: {{.+}} = {{.+}} [[VAR_PRIV]]
+// CHECK-DAG-32: {{.+}} = {{.+}} [[SIVAR_ADDR]]
+// CHECK-DAG-64: {{.+}} = {{.+}} [[CONV_SIVAR]]
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: ret void
+
+// CHECK: define{{.*}} i{{[0-9]+}} @[[TMAIN_INT]]()
+// CHECK: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 4, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 0)
+// CHECK: call void @[[TOFFL1:.+]](i{{64|32}} %{{.+}})
+// CHECK: ret
+
+// CHECK: define {{.*}}void @[[TOFFL1]]({{.+}})
+// CHECK: [[TT_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[TVEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}]*,
+// CHECK: [[TS_ARR_PRIV:%.+]] = alloca [2 x [[S_INT_TY]]]*,
+// CHECK: [[TVAR_PRIV:%.+]] = alloca [[S_INT_TY]]*,
+// CHECK: [[TT_VAR_CAST:%.+]] = alloca i{{[0-9]+}},
+
+// CHECK-DAG: [[TVEC_TE_PAR:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** [[TVEC_PRIV]],
+// CHECK-DAG: [[TT_VAR_TE_PAR:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[TT_VAR_CAST]],
+// CHECK-DAG: [[TS_ARR_TE_PAR:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** [[TS_ARR_PRIV]],
+// CHECK-DAG: [[TVAR_TE_PAR:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[TVAR_PRIV]],
+
+// CHECK: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 4, {{.+}} @[[TOUTL1:.+]] to {{.+}}, [2 x i{{[0-9]+}}]* [[TVEC_TE_PAR]], i{{[0-9]+}} [[TT_VAR_TE_PAR]], [2 x [[S_INT_TY]]]* [[TS_ARR_TE_PAR]], [[S_INT_TY]]* [[TVAR_TE_PAR]])
+// CHECK: ret void
+
+// CHECK: define internal void @[[TOUTL1]]({{.+}})
+// Skip global and bound tid vars
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: [[VEC_ADDR:%.+]] = alloca [2 x i{{[0-9]+}}]*,
+// CHECK: [[T_VAR_ADDR:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[S_ARR_ADDR:%.+]] = alloca [2 x [[S_INT_TY]]]*,
+// CHECK: [[VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*,
+// Skip temp vars for loop
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_INT_TY]]],
+// CHECK: [[AGG_TMP1:%.+]] = alloca [[ST_TY]],
+// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_INT_TY]],
+// CHECK: [[AGG_TMP2:%.+]] = alloca [[ST_TY]],
+// CHECK: [[TMP:%.+]] = alloca [[S_INT_TY]]*,
+
+// param copy
+// CHECK: store [2 x i{{[0-9]+}}]* {{.+}}, [2 x i{{[0-9]+}}]** [[VEC_ADDR]],
+// CHECK: store i{{[0-9]+}} {{.+}}, i{{[0-9]+}}* [[T_VAR_ADDR]],
+// CHECK: store [2 x [[S_INT_TY]]]* {{.+}}, [2 x [[S_INT_TY]]]** [[S_ARR_ADDR]],
+// CHECK: store [[S_INT_TY]]* {{.+}}, [[S_INT_TY]]** [[VAR_ADDR]],
+
+// T_VAR and preparation variables
+// CHECK: [[VEC_ADDR_VAL:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** [[VEC_ADDR]],
+// CHECK-64: [[CONV_TVAR:%.+]] = bitcast i64* [[T_VAR_ADDR]] to i32*
+// CHECK: [[S_ARR_ADDR_REF:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** [[S_ARR_ADDR]],
+
+// firstprivate vec(vec): copy from *_addr into priv1 and then from priv1 into priv2
+// CHECK-DAG: [[VEC_DEST_PRIV:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV]] to i8*
+// CHECK-DAG: [[VEC_SRC:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_ADDR_VAL]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[VEC_DEST_PRIV]], i8* [[VEC_SRC]], {{.+}})
+
+// firstprivate(s_arr)
+// CHECK-DAG: [[S_ARR_PRIV_BGN:%.+]] = getelementptr{{.*}} [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[S_ARR_PRIV]],
+// CHECK-DAG: [[S_ARR_ADDR_BGN:%.+]] = bitcast [2 x [[S_INT_TY]]]* [[S_ARR_ADDR_REF]] to
+// CHECK-DAG: [[S_ARR_FIN:%.+]] = icmp{{.+}} [[S_ARR_PRIV_BGN]],
+// CHECK-DAG: [[S_ARR_SRC_COPY:%.+]] = phi{{.+}} [ [[S_ARR_ADDR_BGN]], {{.+}} ], [ [[S_ARR_SRC:%.+]], {{.+}} ]
+// CHECK-DAG: [[S_ARR_DST_COPY:%.+]] = phi{{.+}} [ [[S_ARR_PRIV_BGN]], {{.+}} ], [ [[S_ARR_DST:%.+]], {{.+}} ]
+// CHECK-DAG: call void @{{.+}}({{.+}} [[AGG_TMP1]])
+// CHECK-DAG: call void @{{.+}}({{.+}} [[S_ARR_DST_COPY]], {{.+}} [[S_ARR_SRC_COPY]], {{.+}} [[AGG_TMP1]])
+// CHECK-DAG: call void @{{.+}}({{.+}} [[AGG_TMP1]])
+// CHECK-DAG: [[S_ARR_DST]] = getelementptr {{.+}} [[S_ARR_DST_COPY]],
+// CHECK-DAG: [[S_ARR_SRC]] = getelementptr {{.+}} [[S_ARR_SRC_COPY]],
+
+// firstprivate(var)
+// CHECK-DAG: [[VAR_ADDR_REF:%.+]] = load{{.+}} [[VAR_ADDR]],
+// CHECK-DAG: call void @{{.+}}({{.+}} [[AGG_TMP2]])
+// CHECK-DAG: call void @{{.+}}({{.+}} [[VAR_PRIV]], {{.+}} [[VAR_ADDR_REF]], {{.+}} [[AGG_TMP2]])
+// CHECK-DAG: call void @{{.+}}({{.+}} [[AGG_TMP2]])
+// CHECK-DAG: store [[S_INT_TY]]* [[VAR_PRIV]], [[S_INT_TY]]** [[TMP]],
+
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: call void {{.*}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[TPAR_OUTL:.+]] to
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: ret void
+
+// CHECK: define internal void @[[TPAR_OUTL]]({{.+}})
+// Skip global and bound tid vars
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: [[VEC_ADDR:%.+]] = alloca [2 x i{{[0-9]+}}]*,
+// CHECK: [[T_VAR_ADDR:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[S_ARR_ADDR:%.+]] = alloca [2 x [[S_INT_TY]]]*,
+// CHECK: [[VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*,
+// Skip temp vars for loop
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_INT_TY]]],
+// CHECK: [[AGG_TMP1:%.+]] = alloca [[ST_TY]],
+// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_INT_TY]],
+// CHECK: [[AGG_TMP2:%.+]] = alloca [[ST_TY]],
+// CHECK: [[TMP:%.+]] = alloca [[S_INT_TY]]*,
+
+// param copy
+// CHECK: store [2 x i{{[0-9]+}}]* {{.+}}, [2 x i{{[0-9]+}}]** [[VEC_ADDR]],
+// CHECK: store i{{[0-9]+}} {{.+}}, i{{[0-9]+}}* [[T_VAR_ADDR]],
+// CHECK: store [2 x [[S_INT_TY]]]* {{.+}}, [2 x [[S_INT_TY]]]** [[S_ARR_ADDR]],
+// CHECK: store [[S_INT_TY]]* {{.+}}, [[S_INT_TY]]** [[VAR_ADDR]],
+
+// T_VAR and preparation variables
+// CHECK: [[VEC_ADDR_VAL:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** [[VEC_ADDR]],
+// CHECK-64: [[CONV_TVAR:%.+]] = bitcast i64* [[T_VAR_ADDR]] to i32*
+// CHECK: [[S_ARR_ADDR_REF:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** [[S_ARR_ADDR]],
+
+// firstprivate vec(vec): copy from *_addr into priv1 and then from priv1 into priv2
+// CHECK-DAG: [[VEC_DEST_PRIV:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV]] to i8*
+// CHECK-DAG: [[VEC_SRC:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_ADDR_VAL]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[VEC_DEST_PRIV]], i8* [[VEC_SRC]], {{.+}})
+
+// firstprivate(s_arr)
+// CHECK-DAG: [[S_ARR_PRIV_BGN:%.+]] = getelementptr{{.*}} [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[S_ARR_PRIV]],
+// CHECK-DAG: [[S_ARR_ADDR_BGN:%.+]] = bitcast [2 x [[S_INT_TY]]]* [[S_ARR_ADDR_REF]] to
+// CHECK-DAG: [[S_ARR_FIN:%.+]] = icmp{{.+}} [[S_ARR_PRIV_BGN]],
+// CHECK-DAG: [[S_ARR_SRC_COPY:%.+]] = phi{{.+}} [ [[S_ARR_ADDR_BGN]], {{.+}} ], [ [[S_ARR_SRC:%.+]], {{.+}} ]
+// CHECK-DAG: [[S_ARR_DST_COPY:%.+]] = phi{{.+}} [ [[S_ARR_PRIV_BGN]], {{.+}} ], [ [[S_ARR_DST:%.+]], {{.+}} ]
+// CHECK-DAG: call void @{{.+}}({{.+}} [[AGG_TMP1]])
+// CHECK-DAG: call void @{{.+}}({{.+}} [[S_ARR_DST_COPY]], {{.+}} [[S_ARR_SRC_COPY]], {{.+}} [[AGG_TMP1]])
+// CHECK-DAG: call void @{{.+}}({{.+}} [[AGG_TMP1]])
+// CHECK-DAG: [[S_ARR_DST]] = getelementptr {{.+}} [[S_ARR_DST_COPY]],
+// CHECK-DAG: [[S_ARR_SRC]] = getelementptr {{.+}} [[S_ARR_SRC_COPY]],
+
+// firstprivate(var)
+// CHECK-DAG: [[VAR_ADDR_REF:%.+]] = load{{.+}} [[VAR_ADDR]],
+// CHECK-DAG: call void @{{.+}}({{.+}} [[AGG_TMP2]])
+// CHECK-DAG: call void @{{.+}}({{.+}} [[VAR_PRIV]], {{.+}} [[VAR_ADDR_REF]], {{.+}} [[AGG_TMP2]])
+// CHECK-DAG: call void @{{.+}}({{.+}} [[AGG_TMP2]])
+// CHECK-DAG: store [[S_INT_TY]]* [[VAR_PRIV]], [[S_INT_TY]]** [[TMP]],
+
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK-DAG-32: {{.+}} = {{.+}} [[T_VAR_ADDR]]
+// CHECK-DAG-64: {{.+}} = {{.+}} [[CONV_TVAR]]
+// CHECK-DAG: {{.+}} = {{.+}} [[VEC_PRIV]]
+// CHECK-DAG: {{.+}} = {{.+}} [[TMP]]
+// CHECK-DAG: {{.+}} = {{.+}} [[S_ARR_PRIV]]
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: ret void
+
+#endif
diff --git a/test/OpenMP/teams_distribute_parallel_for_firstprivate_messages.cpp b/test/OpenMP/teams_distribute_parallel_for_firstprivate_messages.cpp
index e6314c210e8f..90e78defc5e2 100644
--- a/test/OpenMP/teams_distribute_parallel_for_firstprivate_messages.cpp
+++ b/test/OpenMP/teams_distribute_parallel_for_firstprivate_messages.cpp
@@ -144,8 +144,9 @@ int main(int argc, char **argv) {
#pragma omp teams distribute parallel for firstprivate(j)
for (i = 0; i < argc; ++i) foo();
+// expected-error@+2 {{lastprivate variable cannot be firstprivate}} expected-note@+2 {{defined as lastprivate}}
#pragma omp target
-#pragma omp teams distribute parallel for lastprivate(argc), firstprivate(argc) // OK
+#pragma omp teams distribute parallel for lastprivate(argc), firstprivate(argc)
for (i = 0; i < argc; ++i) foo();
return 0;
diff --git a/test/OpenMP/teams_distribute_parallel_for_if_codegen.cpp b/test/OpenMP/teams_distribute_parallel_for_if_codegen.cpp
new file mode 100644
index 000000000000..bc40dca83fbe
--- /dev/null
+++ b/test/OpenMP/teams_distribute_parallel_for_if_codegen.cpp
@@ -0,0 +1,184 @@
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple %itanium_abi_triple -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple %itanium_abi_triple -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+void fn1();
+void fn2();
+void fn3();
+void fn4();
+void fn5();
+void fn6();
+
+int Arg;
+
+// CHECK-LABEL: define {{.*}}void @{{.+}}gtid_test
+void gtid_test() {
+#pragma omp target
+// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+// CHECK: call void [[OFFLOADING_FUN_0:@.+]](
+// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+// CHECK: call void [[OFFLOADING_FUN_1:@.+]](
+#pragma omp teams distribute parallel for
+ for(int i = 0 ; i < 100; i++) {}
+ // CHECK: define internal void [[OFFLOADING_FUN_0]](
+ // CHECK: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, i32 0, {{.+}}* [[OMP_TEAMS_OUTLINED_0:@.+]] to {{.+}})
+ // CHECK: define{{.+}} void [[OMP_TEAMS_OUTLINED_0]](
+ // CHECK: call void @__kmpc_for_static_init_4(
+ // CHECK: call void {{.+}} @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{.+}} 2, {{.+}}* [[OMP_OUTLINED_0:@.+]] to void
+ // CHECK: call void @__kmpc_for_static_fini(
+
+ // CHECK: define{{.+}} void [[OMP_OUTLINED_0]](
+ // CHECK: call void @__kmpc_for_static_init_4(
+ // CHECK: call void @__kmpc_for_static_fini(
+ // CHECK: ret
+#pragma omp target
+#pragma omp teams distribute parallel for if (parallel: false)
+ for(int i = 0 ; i < 100; i++) {
+ // CHECK: define internal void [[OFFLOADING_FUN_1]](
+ // CHECK: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, i32 0, {{.+}}* [[OMP_TEAMS_OUTLINED_1:@.+]] to {{.+}})
+ // CHECK: define{{.+}} void [[OMP_TEAMS_OUTLINED_1]](
+ // CHECK: call void @__kmpc_for_static_init_4(
+ // CHECK: call void @__kmpc_serialized_parallel(
+ // CHECK: call void [[OMP_OUTLINED_1:@.+]](
+ // CHECK: call void @__kmpc_end_serialized_parallel(
+ // CHECK: call void @__kmpc_for_static_fini(
+ // CHECK: define{{.+}} void [[OMP_OUTLINED_1]](
+ // CHECK: call void @__kmpc_for_static_init_4(
+ // CHECK: call void @{{.+}}gtid_test
+ // CHECK: call void @__kmpc_for_static_fini(
+ // CHECK: ret
+ gtid_test();
+ }
+}
+
+
+template <typename T>
+int tmain(T Arg) {
+#pragma omp target
+#pragma omp teams distribute parallel for if (true)
+ for(int i = 0 ; i < 100; i++) {
+ fn1();
+ }
+#pragma omp target
+#pragma omp teams distribute parallel for if (false)
+ for(int i = 0 ; i < 100; i++) {
+ fn2();
+ }
+#pragma omp target
+#pragma omp teams distribute parallel for if (parallel: Arg)
+ for(int i = 0 ; i < 100; i++) {
+ fn3();
+ }
+ return 0;
+}
+
+// CHECK-LABEL: define {{.*}}i{{[0-9]+}} @main()
+int main() {
+// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+// CHECK: call void [[OFFLOADING_FUN_0:@.+]](
+// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+// CHECK: call void [[OFFLOADING_FUN_1:@.+]](
+// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+// CHECK: call void [[OFFLOADING_FUN_2:@.+]](
+// CHECK: = call {{.*}}i{{.+}} @{{.+}}tmain
+#pragma omp target
+#pragma omp teams distribute parallel for if (true)
+ for(int i = 0 ; i < 100; i++) {
+ // CHECK: define internal void [[OFFLOADING_FUN_0]](
+ // CHECK: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, i32 0, {{.+}}* [[OMP_TEAMS_OUTLINED_0:@.+]] to {{.+}})
+ // CHECK: define{{.+}} void [[OMP_TEAMS_OUTLINED_0]](
+
+ // CHECK: call void @__kmpc_for_static_init_4(
+ // CHECK: call void {{.+}} @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{.+}} 2, {{.+}}* [[OMP_OUTLINED_2:@.+]] to void
+ // CHECK: call void @__kmpc_for_static_fini(
+ // CHECK: define{{.+}} void [[OMP_OUTLINED_2]](
+ // CHECK: call void @__kmpc_for_static_init_4(
+ // CHECK: call {{.*}}void @{{.+}}fn4
+ // CHECK: call void @__kmpc_for_static_fini(
+
+ fn4();
+ }
+
+#pragma omp target
+#pragma omp teams distribute parallel for if (false)
+ for(int i = 0 ; i < 100; i++) {
+ // CHECK: define internal void [[OFFLOADING_FUN_1]](
+ // CHECK: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, i32 0, {{.+}}* [[OMP_TEAMS_OUTLINED_1:@.+]] to {{.+}})
+ // CHECK: define{{.+}} void [[OMP_TEAMS_OUTLINED_1]](
+
+ // CHECK: call void @__kmpc_for_static_init_4(
+ // CHECK: call void @__kmpc_serialized_parallel(
+ // CHECK: call void [[OMP_OUTLINED_3:@.+]](
+ // CHECK: call void @__kmpc_end_serialized_parallel(
+ // CHECK: call void @__kmpc_for_static_fini(
+
+ // CHECK: define{{.+}} void [[OMP_OUTLINED_3]](
+ // CHECK: call void @__kmpc_for_static_init_4(
+ // CHECK: call {{.*}}void @{{.+}}fn5
+ // CHECK: call void @__kmpc_for_static_fini(
+ fn5();
+ }
+
+#pragma omp target
+#pragma omp teams distribute parallel for if (Arg)
+ for(int i = 0 ; i < 100; i++) {
+ // CHECK: define internal void [[OFFLOADING_FUN_2]](
+ // CHECK: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}}* [[OMP_TEAMS_OUTLINED_2:@.+]] to {{.+}})
+ // CHECK: define{{.+}} void [[OMP_TEAMS_OUTLINED_2]](
+
+ // CHECK: call void @__kmpc_for_static_init_4(
+ // CHECK: call void {{.+}} @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{.+}} 2, {{.+}}* [[OMP_OUTLINED_4:@.+]] to void
+ // CHECK: call void @__kmpc_serialized_parallel(
+ // CHECK: call void [[OMP_OUTLINED_4:@.+]](
+ // CHECK: call void @__kmpc_end_serialized_parallel(
+ // CHECK: call void @__kmpc_for_static_fini(
+
+ // CHECK: define{{.+}} void [[OMP_OUTLINED_4]](
+ // CHECK: call void @__kmpc_for_static_init_4(
+ // CHECK: call {{.*}}void @{{.+}}fn6
+ // CHECK: call void @__kmpc_for_static_fini(
+ fn6();
+ }
+
+ return tmain(Arg);
+}
+
+// CHECK-LABEL: define {{.+}} @{{.+}}tmain
+
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: call {{.*}}void {{.+}} @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{.+}} 2, void {{.+}}* [[T_OUTLINE_FUN_1:@.+]] to void
+// CHECK: call void @__kmpc_for_static_fini(
+
+// CHECK: define internal {{.*}}void [[T_OUTLINE_FUN_1]]
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: call {{.*}}void @{{.+}}fn1
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: ret void
+
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: call {{.*}}void @__kmpc_serialized_parallel(
+// CHECK: call void [[T_OUTLINE_FUN_2:@.+]](
+// CHECK: call {{.*}}void @__kmpc_end_serialized_parallel(
+// CHECK: call void @__kmpc_for_static_fini(
+
+// CHECK: define internal {{.*}}void [[T_OUTLINE_FUN_2]]
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: call {{.*}}void @{{.+}}fn2
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: ret void
+
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: call {{.*}}void {{.+}} @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{.+}} 2, void {{.+}}* [[T_OUTLINE_FUN_3:@.+]] to void
+// CHECK: call {{.*}}void @__kmpc_serialized_parallel(
+// call void [[T_OUTLINE_FUN_3:@.+]](
+// CHECK: call {{.*}}void @__kmpc_end_serialized_parallel(
+
+// CHECK: define internal {{.*}}void [[T_OUTLINE_FUN_3]]
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: call {{.*}}void @{{.+}}fn3
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: ret void
+#endif
diff --git a/test/OpenMP/teams_distribute_parallel_for_lastprivate_codegen.cpp b/test/OpenMP/teams_distribute_parallel_for_lastprivate_codegen.cpp
new file mode 100644
index 000000000000..501abb725b31
--- /dev/null
+++ b/test/OpenMP/teams_distribute_parallel_for_lastprivate_codegen.cpp
@@ -0,0 +1,584 @@
+// RUN: %clang_cc1 -DLAMBDA -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+// RUN: %clang_cc1 -DLAMBDA -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-32
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-32
+
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+template <class T>
+struct S {
+ T f;
+ S(T a) : f(a) {}
+ S() : f() {}
+ operator T() { return T(); }
+ ~S() {}
+};
+
+// CHECK: [[S_FLOAT_TY:%.+]] = type { float }
+// CHECK: [[S_INT_TY:%.+]] = type { i{{[0-9]+}} }
+template <typename T>
+T tmain() {
+ S<T> test;
+ T t_var = T();
+ T vec[] = {1, 2};
+ S<T> s_arr[] = {1, 2};
+ S<T> &var = test;
+ #pragma omp target
+ #pragma omp teams distribute parallel for lastprivate(t_var, vec, s_arr, s_arr, var, var)
+ for (int i = 0; i < 2; ++i) {
+ vec[i] = t_var;
+ s_arr[i] = var;
+ }
+ return T();
+}
+
+int main() {
+ static int svar;
+ volatile double g;
+ volatile double &g1 = g;
+
+ #ifdef LAMBDA
+ // LAMBDA-LABEL: @main
+ // LAMBDA: call{{.*}} void [[OUTER_LAMBDA:@.+]](
+ [&]() {
+ static float sfvar;
+ // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
+ // LAMBDA: call i{{[0-9]+}} @__tgt_target_teams(
+ // LAMBDA: call void [[OFFLOADING_FUN:@.+]](
+
+ // LAMBDA: define{{.+}} void [[OFFLOADING_FUN]](
+ // LAMBDA: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, i32 4, {{.+}}* [[OMP_OUTLINED:@.+]] to {{.+}})
+ #pragma omp target
+ #pragma omp teams distribute parallel for lastprivate(g, g1, svar, sfvar)
+ for (int i = 0; i < 2; ++i) {
+ // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_OUTLINED]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, double*{{.+}} [[G_IN:%.+]], double*{{.+}} [[G1_IN:%.+]], i{{[0-9]+}}*{{.+}} [[SVAR_IN:%.+]], float*{{.+}} [[SFVAR_IN:%.+]])
+ // LAMBDA: [[G_PRIVATE_ADDR:%.+]] = alloca double*,
+ // LAMBDA: [[G1_PRIVATE_ADDR:%.+]] = alloca double*,
+ // LAMBDA: [[SVAR_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}*,
+ // LAMBDA: [[SFVAR_PRIVATE_ADDR:%.+]] = alloca float*,
+ // loop variables
+ // LAMBDA: {{.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: {{.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: {{.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: {{.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: {{.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: [[OMP_IS_LAST:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[G_PRIVATE:%.+]] = alloca double,
+ // LAMBDA: [[G1_PRIVATE:%.+]] = alloca double,
+ // LAMBDA: [[TMP_G1_PRIVATE:%.+]] = alloca double*,
+ // LAMBDA: [[SVAR_PRIVATE:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[SFVAR_PRIVATE:%.+]] = alloca float,
+ // LAMBDA: store double* [[G_IN]], double** [[G_PRIVATE_ADDR]],
+ // LAMBDA: store double* [[G1_IN]], double** [[G1_PRIVATE_ADDR]],
+ // LAMBDA: store i{{[0-9]+}}* [[SVAR_IN]], i{{[0-9]+}}** [[SVAR_PRIVATE_ADDR]],
+ // LAMBDA: store float* [[SFVAR_IN]], float** [[SFVAR_PRIVATE_ADDR]],
+
+ // init private variables
+ // LAMBDA: [[G_IN_REF:%.+]] = load double*, double** [[G_PRIVATE_ADDR]],
+ // LAMBDA: [[SVAR_IN_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SVAR_PRIVATE_ADDR]],
+ // LAMBDA: [[SFVAR_IN_REF:%.+]] = load float*, float** [[SFVAR_PRIVATE_ADDR]],
+ // LAMBDA: [[G1_IN_REF:%.+]] = load double*, double** [[G1_PRIVATE_ADDR]],
+ // LAMBDA: store double* [[G1_PRIVATE]], double** [[TMP_G1_PRIVATE]],
+ g = 1;
+ g1 = 1;
+ svar = 3;
+ sfvar = 4.0;
+ // LAMBDA: call {{.*}}void @__kmpc_for_static_init_4(
+ // LAMBDA: call void {{.*}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[LPAR_OUTL:.+]] to
+ // LAMBDA: call {{.*}}void @__kmpc_for_static_fini(
+
+ // LAMBDA: [[OMP_IS_LAST_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[OMP_IS_LAST]],
+ // LAMBDA: [[IS_LAST_IT:%.+]] = icmp ne i{{[0-9]+}} [[OMP_IS_LAST_VAL]], 0
+ // LAMBDA: br i1 [[IS_LAST_IT]], label %[[OMP_LASTPRIV_BLOCK:.+]], label %[[OMP_LASTPRIV_DONE:.+]]
+
+ // LAMBDA: [[OMP_LASTPRIV_BLOCK]]:
+ // LAMBDA: [[G_PRIV_VAL:%.+]] = load double, double* [[G_PRIVATE]],
+ // LAMBDA: store{{.*}} double [[G_PRIV_VAL]], double* [[G_IN_REF]],
+ // LAMBDA: [[TMP_G1_PRIV_REF:%.+]] = load double*, double** [[TMP_G1_PRIVATE]],
+ // LAMBDA: [[TMP_G1_PRIV_VAL:%.+]] = load double, double* [[TMP_G1_PRIV_REF]],
+ // LAMBDA: store{{.*}} double [[TMP_G1_PRIV_VAL]], double* [[G1_IN_REF]],
+
+ // LAMBDA: [[SVAR_PRIV_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SVAR_PRIVATE]],
+ // LAMBDA: store i{{[0-9]+}} [[SVAR_PRIV_VAL]], i{{[0-9]+}}* [[SVAR_IN_REF]],
+ // LAMBDA: [[SFVAR_PRIV_VAL:%.+]] = load float, float* [[SFVAR_PRIVATE]],
+ // LAMBDA: store float [[SFVAR_PRIV_VAL]], float* [[SFVAR_IN_REF]],
+ // LAMBDA: br label %[[OMP_LASTPRIV_DONE]]
+ // LAMBDA: [[OMP_LASTPRIV_DONE]]:
+ // LAMBDA: ret
+
+ // LAMBDA: define{{.*}} internal{{.*}} void @[[LPAR_OUTL]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, {{.+}}, {{.+}}, double*{{.+}} [[G_IN:%.+]], double*{{.+}} [[G1_IN:%.+]], i{{[0-9]+}}*{{.+}} [[SVAR_IN:%.+]], float*{{.+}} [[SFVAR_IN:%.+]])
+ // LAMBDA: [[G_PRIVATE_ADDR:%.+]] = alloca double*,
+ // LAMBDA: [[G1_PRIVATE_ADDR:%.+]] = alloca double*,
+ // LAMBDA: [[SVAR_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}*,
+ // LAMBDA: [[SFVAR_PRIVATE_ADDR:%.+]] = alloca float*,
+ // loop variables
+ // LAMBDA: {{.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: {{.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: {{.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: {{.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: {{.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: [[OMP_IS_LAST:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[G_PRIVATE:%.+]] = alloca double,
+ // LAMBDA: [[G1_PRIVATE:%.+]] = alloca double,
+ // LAMBDA: [[TMP_G1_PRIVATE:%.+]] = alloca double*,
+ // LAMBDA: [[SVAR_PRIVATE:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[SFVAR_PRIVATE:%.+]] = alloca float,
+ // LAMBDA: store double* [[G_IN]], double** [[G_PRIVATE_ADDR]],
+ // LAMBDA: store double* [[G1_IN]], double** [[G1_PRIVATE_ADDR]],
+ // LAMBDA: store i{{[0-9]+}}* [[SVAR_IN]], i{{[0-9]+}}** [[SVAR_PRIVATE_ADDR]],
+ // LAMBDA: store float* [[SFVAR_IN]], float** [[SFVAR_PRIVATE_ADDR]],
+
+ // init private variables
+ // LAMBDA: [[G_IN_REF:%.+]] = load double*, double** [[G_PRIVATE_ADDR]],
+ // LAMBDA: [[SVAR_IN_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SVAR_PRIVATE_ADDR]],
+ // LAMBDA: [[SFVAR_IN_REF:%.+]] = load float*, float** [[SFVAR_PRIVATE_ADDR]],
+ // LAMBDA: [[G1_IN_REF:%.+]] = load double*, double** [[G1_PRIVATE_ADDR]],
+ // LAMBDA: store double* [[G1_PRIVATE]], double** [[TMP_G1_PRIVATE]],
+
+ // LAMBDA: call {{.*}}void @__kmpc_for_static_init_4(
+ // LAMBDA: store double 1.0{{.+}}, double* [[G_PRIVATE]],
+ // LAMBDA: [[TMP_G1_REF:%.+]] = load double*, double** [[TMP_G1_PRIVATE]],
+ // LAMBDA: store{{.+}} double 1.0{{.+}}, double* [[TMP_G1_REF]],
+ // LAMBDA: store i{{[0-9]+}} 3, i{{[0-9]+}}* [[SVAR_PRIVATE]],
+ // LAMBDA: store float 4.0{{.+}}, float* [[SFVAR_PRIVATE]],
+ // LAMBDA: [[G_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // LAMBDA: store double* [[G_PRIVATE]], double** [[G_PRIVATE_ADDR_REF]],
+ // LAMBDA: [[TMP_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // LAMBDA: [[G1_PRIVATE_ADDR_FROM_TMP:%.+]] = load double*, double** [[TMP_G1_PRIVATE]],
+ // LAMBDA: store double* [[G1_PRIVATE_ADDR_FROM_TMP]], double** [[TMP_PRIVATE_ADDR_REF]],
+ // LAMBDA: [[SVAR_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+ // LAMBDA: store i{{[0-9]+}}* [[SVAR_PRIVATE]], i{{[0-9]+}}** [[SVAR_PRIVATE_ADDR_REF]]
+ // LAMBDA: [[SFVAR_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 3
+ // LAMBDA: store float* [[SFVAR_PRIVATE]], float** [[SFVAR_PRIVATE_ADDR_REF]]
+ // LAMBDA: call{{.*}} void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]])
+ // LAMBDA: call {{.*}}void @__kmpc_for_static_fini(
+
+ // LAMBDA: [[OMP_IS_LAST_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[OMP_IS_LAST]],
+ // LAMBDA: [[IS_LAST_IT:%.+]] = icmp ne i{{[0-9]+}} [[OMP_IS_LAST_VAL]], 0
+ // LAMBDA: br i1 [[IS_LAST_IT]], label %[[OMP_LASTPRIV_BLOCK:.+]], label %[[OMP_LASTPRIV_DONE:.+]]
+
+ // LAMBDA: [[OMP_LASTPRIV_BLOCK]]:
+ // LAMBDA: [[G_PRIV_VAL:%.+]] = load double, double* [[G_PRIVATE]],
+ // LAMBDA: store{{.*}} double [[G_PRIV_VAL]], double* [[G_IN_REF]],
+ // LAMBDA: [[TMP_G1_PRIV_REF:%.+]] = load double*, double** [[TMP_G1_PRIVATE]],
+ // LAMBDA: [[TMP_G1_PRIV_VAL:%.+]] = load double, double* [[TMP_G1_PRIV_REF]],
+ // LAMBDA: store{{.*}} double [[TMP_G1_PRIV_VAL]], double* [[G1_IN_REF]],
+
+ // LAMBDA: [[SVAR_PRIV_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SVAR_PRIVATE]],
+ // LAMBDA: store i{{[0-9]+}} [[SVAR_PRIV_VAL]], i{{[0-9]+}}* [[SVAR_IN_REF]],
+ // LAMBDA: [[SFVAR_PRIV_VAL:%.+]] = load float, float* [[SFVAR_PRIVATE]],
+ // LAMBDA: store float [[SFVAR_PRIV_VAL]], float* [[SFVAR_IN_REF]],
+ // LAMBDA: br label %[[OMP_LASTPRIV_DONE]]
+ // LAMBDA: [[OMP_LASTPRIV_DONE]]:
+ // LAMBDA: ret
+
+ [&]() {
+ // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]])
+ // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]],
+ g = 2;
+ g1 = 2;
+ svar = 4;
+ sfvar = 8.0;
+ // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]]
+ // LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // LAMBDA: [[G_REF:%.+]] = load double*, double** [[G_PTR_REF]]
+ // LAMBDA: store double 2.0{{.+}}, double* [[G_REF]]
+
+ // LAMBDA: [[TMP_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // LAMBDA: [[G1_REF:%.+]] = load double*, double** [[TMP_PTR_REF]]
+ // LAMBDA: store double 2.0{{.+}}, double* [[G1_REF]],
+ // LAMBDA: [[SVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+ // LAMBDA: [[SVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SVAR_PTR_REF]]
+ // LAMBDA: store i{{[0-9]+}} 4, i{{[0-9]+}}* [[SVAR_REF]]
+ // LAMBDA: [[SFVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 3
+ // LAMBDA: [[SFVAR_REF:%.+]] = load float*, float** [[SFVAR_PTR_REF]]
+ // LAMBDA: store float 8.0{{.+}}, float* [[SFVAR_REF]]
+ }();
+ }
+ }();
+ return 0;
+ #else
+ S<float> test;
+ int t_var = 0;
+ int vec[] = {1, 2};
+ S<float> s_arr[] = {1, 2};
+ S<float> &var = test;
+
+ #pragma omp target
+ #pragma omp teams distribute parallel for lastprivate(t_var, vec, s_arr, s_arr, var, var, svar)
+ for (int i = 0; i < 2; ++i) {
+ vec[i] = t_var;
+ s_arr[i] = var;
+ }
+ int i;
+
+ return tmain<int>();
+ #endif
+}
+
+// CHECK: define{{.*}} i{{[0-9]+}} @main()
+// CHECK: [[TEST:%.+]] = alloca [[S_FLOAT_TY]],
+// CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR:@.+]]([[S_FLOAT_TY]]* [[TEST]])
+// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+// CHECK: call void [[OFFLOAD_FUN:@.+]](i{{[0-9]+}} {{.+}}, [2 x i{{[0-9]+}}]* {{.+}}, [2 x [[S_FLOAT_TY]]]* {{.+}}, [[S_FLOAT_TY]]* {{.+}}, i{{[0-9]+}} {{.+}})
+// CHECK: ret
+
+// CHECK: define{{.+}} [[OFFLOAD_FUN]](i{{[0-9]+}} {{.+}}, [2 x i{{[0-9]+}}]*{{.+}} {{.+}}, [2 x [[S_FLOAT_TY]]]*{{.+}} {{.+}}, [[S_FLOAT_TY]]*{{.+}} {{.+}}, i{{[0-9]+}} {{.+}})
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_teams(
+// CHECK: ret
+//
+// CHECK: define internal void [[OMP_OUTLINED:@.+]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [2 x i{{[0-9]+}}]*{{.+}} [[VEC_IN:%.+]], i{{[0-9]+}}*{{.+}} [[T_VAR_IN:%.+]], [2 x [[S_FLOAT_TY]]]*{{.+}} [[S_ARR_IN:%.+]], [[S_FLOAT_TY]]*{{.+}} [[VAR_IN:%.+]], i{{[0-9]+}}*{{.*}} [[S_VAR_IN:%.+]])
+// CHECK: {{.+}} = alloca i{{[0-9]+}}*,
+// CHECK: {{.+}} = alloca i{{[0-9]+}}*,
+// CHECK: [[VEC_ADDR:%.+]] = alloca [2 x i{{[0-9]+}}]*,
+// CHECK: [[T_VAR_ADDR:%.+]] = alloca i{{[0-9]+}}*,
+// CHECK: [[S_ARR_ADDR:%.+]] = alloca [2 x [[S_FLOAT_TY]]]*,
+// CHECK: [[VAR_ADDR:%.+]] = alloca [[S_FLOAT_TY]]*,
+// CHECK: [[SVAR_ADDR:%.+]] = alloca i{{[0-9]+}}*,
+// skip loop variables
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: [[OMP_IS_LAST:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]],
+// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]],
+// CHECK: [[TMP_PRIV:%.+]] = alloca [[S_FLOAT_TY]]*,
+// CHECK: [[S_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+
+// copy from parameters to local address variables
+// CHECK: store [2 x i{{[0-9]+}}]* [[VEC_IN]], [2 x i{{[0-9]+}}]** [[VEC_ADDR]],
+// CHECK: store i{{[0-9]+}}* [[T_VAR_IN]], i{{[0-9]+}}** [[T_VAR_ADDR]],
+// CHECK: store [2 x [[S_FLOAT_TY]]]* [[S_ARR_IN]], [2 x [[S_FLOAT_TY]]]** [[S_ARR_ADDR]],
+// CHECK: store [[S_FLOAT_TY]]* [[VAR_IN]], [[S_FLOAT_TY]]** [[VAR_ADDR]],
+// CHECK: store i{{[0-9]+}}* [[S_VAR_IN]], i{{[0-9]+}}** [[SVAR_ADDR]],
+
+// load content of local address variables
+// CHECK: [[VEC_ADDR_REF:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** [[VEC_ADDR]],
+// CHECK: [[T_VAR_ADDR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[T_VAR_ADDR]],
+// CHECK: [[S_ARR_ADDR_REF:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[S_ARR_ADDR]],
+// CHECK: [[SVAR_ADDR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SVAR_ADDR]],
+// CHECK: store i{{[0-9]+}} 0, i{{[0-9]+}}* [[OMP_IS_LAST]],
+// CHECK: [[VAR_ADDR_REF:%.+]] = load {{.+}}, {{.+}} [[VAR_ADDR]],
+// the distribute loop
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: call void {{.*}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[PAR_OUTL:.+]] to
+// CHECK: call void @__kmpc_for_static_fini(
+
+// lastprivates
+// CHECK: [[OMP_IS_LAST_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[OMP_IS_LAST]],
+// CHECK: [[IS_LAST_IT:%.+]] = icmp ne i{{[0-9]+}} [[OMP_IS_LAST_VAL]], 0
+// CHECK: br i1 [[IS_LAST_IT]], label %[[OMP_LASTPRIV_BLOCK:.+]], label %[[OMP_LASTPRIV_DONE:.+]]
+
+// CHECK: [[OMP_LASTPRIV_BLOCK]]:
+// CHECK: [[T_VAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_PRIV]],
+// CHECK: store i{{[0-9]+}} [[T_VAR_VAL]], i{{[0-9]+}}* [[T_VAR_ADDR_REF]],
+// CHECK: [[BCAST_VEC_ADDR_REF:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_ADDR_REF]] to i8*
+// CHECK: [[BCAST_VEC_PRIV:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[BCAST_VEC_ADDR_REF]], i8* [[BCAST_VEC_PRIV]],
+// CHECK: [[S_ARR_BEGIN:%.+]] = getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[S_ARR_ADDR_REF]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+// CHECK: [[S_ARR_PRIV_BCAST:%.+]] = bitcast [2 x [[S_FLOAT_TY]]]* [[S_ARR_PRIV]] to [[S_FLOAT_TY]]*
+// CHECK: [[S_ARR_BEGIN_GEP:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[S_ARR_BEGIN]], i{{[0-9]+}} 2
+// CHECK: [[S_ARR_IS_EMPTY:%.+]] = icmp eq [[S_FLOAT_TY]]* [[S_ARR_BEGIN]], [[S_ARR_BEGIN_GEP]]
+// CHECK: br i1 [[S_ARR_IS_EMPTY]], label %[[S_ARR_COPY_DONE:.+]], label %[[S_ARR_COPY_BLOCK:.+]]
+// CHECK: [[S_ARR_COPY_BLOCK]]:
+// CHECK: [[S_ARR_SRC_EL:%.+]] = phi [[S_FLOAT_TY]]*{{.+}}
+// CHECK: [[S_ARR_DST_EL:%.+]] = phi [[S_FLOAT_TY]]*{{.+}}
+// CHECK: [[S_ARR_DST_BCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[S_ARR_DST_EL]] to i8*
+// CHECK: [[S_ARR_SRC_BCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[S_ARR_SRC_EL]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[S_ARR_DST_BCAST]], i8* [[S_ARR_SRC_BCAST]]{{.+}})
+// CHECK: [[S_ARR_DST_NEXT:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[S_ARR_DST_EL]], i{{[0-9]+}} 1
+// CHECK: [[S_ARR_SRC_NEXT:%.+]] = getelementptr{{.+}}
+// CHECK: [[CPY_IS_FINISHED:%.+]] = icmp eq [[S_FLOAT_TY]]* [[S_ARR_DST_NEXT]], [[S_ARR_BEGIN_GEP]]
+// CHECK: br i1 [[CPY_IS_FINISHED]], label %[[S_ARR_COPY_DONE]], label %[[S_ARR_COPY_BLOCK]]
+// CHECK: [[S_ARR_COPY_DONE]]:
+// CHECK: [[TMP_VAL1:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[TMP_PRIV]],
+// CHECK: [[VAR_ADDR_REF_BCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[VAR_ADDR_REF]] to i8*
+// CHECK: [[TMP_VAL1_BCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[TMP_VAL1]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[VAR_ADDR_REF_BCAST]], i8* [[TMP_VAL1_BCAST]],{{.+}})
+// CHECK: [[SVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[S_VAR_PRIV]],
+// CHECK: store i{{[0-9]+}} [[SVAR_VAL]], i{{[0-9]+}}* [[SVAR_ADDR_REF]],
+// CHECK: ret void
+
+// CHECK: define internal void [[OMP_OUTLINED:@.+]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, {{.+}}, {{.+}}, [2 x i{{[0-9]+}}]*{{.+}} [[VEC_IN:%.+]], i{{[0-9]+}}*{{.+}} [[T_VAR_IN:%.+]], [2 x [[S_FLOAT_TY]]]*{{.+}} [[S_ARR_IN:%.+]], [[S_FLOAT_TY]]*{{.+}} [[VAR_IN:%.+]], i{{[0-9]+}}*{{.*}} [[S_VAR_IN:%.+]])
+// gbl and bound tid vars, prev lb and ub vars
+// CHECK: {{.+}} = alloca i{{[0-9]+}}*,
+// CHECK: {{.+}} = alloca i{{[0-9]+}}*,
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: [[VEC_ADDR:%.+]] = alloca [2 x i{{[0-9]+}}]*,
+// CHECK: [[T_VAR_ADDR:%.+]] = alloca i{{[0-9]+}}*,
+// CHECK: [[S_ARR_ADDR:%.+]] = alloca [2 x [[S_FLOAT_TY]]]*,
+// CHECK: [[VAR_ADDR:%.+]] = alloca [[S_FLOAT_TY]]*,
+// CHECK: [[SVAR_ADDR:%.+]] = alloca i{{[0-9]+}}*,
+// skip loop variables
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: [[OMP_IS_LAST:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]],
+// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]],
+// CHECK: [[TMP_PRIV:%.+]] = alloca [[S_FLOAT_TY]]*,
+// CHECK: [[S_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+
+// copy from parameters to local address variables
+// CHECK: store [2 x i{{[0-9]+}}]* [[VEC_IN]], [2 x i{{[0-9]+}}]** [[VEC_ADDR]],
+// CHECK: store i{{[0-9]+}}* [[T_VAR_IN]], i{{[0-9]+}}** [[T_VAR_ADDR]],
+// CHECK: store [2 x [[S_FLOAT_TY]]]* [[S_ARR_IN]], [2 x [[S_FLOAT_TY]]]** [[S_ARR_ADDR]],
+// CHECK: store [[S_FLOAT_TY]]* [[VAR_IN]], [[S_FLOAT_TY]]** [[VAR_ADDR]],
+// CHECK: store i{{[0-9]+}}* [[S_VAR_IN]], i{{[0-9]+}}** [[SVAR_ADDR]],
+
+// load content of local address variables
+// CHECK: [[VEC_ADDR_REF:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** [[VEC_ADDR]],
+// CHECK: [[T_VAR_ADDR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[T_VAR_ADDR]],
+// CHECK: [[S_ARR_ADDR_REF:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[S_ARR_ADDR]],
+// CHECK: [[SVAR_ADDR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SVAR_ADDR]],
+// CHECK: store i{{[0-9]+}} 0, i{{[0-9]+}}* [[OMP_IS_LAST]],
+// CHECK: [[VAR_ADDR_REF:%.+]] = load {{.+}}, {{.+}} [[VAR_ADDR]],
+// the distribute loop
+// CHECK: call void @__kmpc_for_static_init_4(
+
+// assignment: vec[i] = t_var;
+// CHECK: [[T_VAR_PRIV_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_PRIV]],
+// CHECK: [[VEC_PTR:%.+]] = getelementptr inbounds [2 x i{{[0-9]+}}], [2 x i{{[0-9]+}}]* [[VEC_PRIV]], i{{[0-9]+}} 0, i{{[0-9]+}} {{.+}}
+// CHECK: store i{{[0-9]+}} [[T_VAR_PRIV_VAL]], i{{[0-9]+}}* [[VEC_PTR]],
+
+// assignment: s_arr[i] = var;
+// CHECK-DAG: [[S_ARR_PTR:%.+]] = getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[S_ARR_PRIV]],
+// CHECK-DAG: [[TMP_VAL:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[TMP_PRIV]],
+// CHECK-DAG: [[S_ARR_PTR_BCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[S_ARR_PTR]] to i8*
+// CHECK-DAG: [[TMP_VAL_BCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[TMP_VAL]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[S_ARR_PTR_BCAST]], i8* [[TMP_VAL_BCAST]],
+
+// CHECK: call void @__kmpc_for_static_fini(
+
+// lastprivates
+// CHECK: [[OMP_IS_LAST_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[OMP_IS_LAST]],
+// CHECK: [[IS_LAST_IT:%.+]] = icmp ne i{{[0-9]+}} [[OMP_IS_LAST_VAL]], 0
+// CHECK: br i1 [[IS_LAST_IT]], label %[[OMP_LASTPRIV_BLOCK:.+]], label %[[OMP_LASTPRIV_DONE:.+]]
+
+// CHECK: [[OMP_LASTPRIV_BLOCK]]:
+// CHECK: [[T_VAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_PRIV]],
+// CHECK: store i{{[0-9]+}} [[T_VAR_VAL]], i{{[0-9]+}}* [[T_VAR_ADDR_REF]],
+// CHECK: [[BCAST_VEC_ADDR_REF:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_ADDR_REF]] to i8*
+// CHECK: [[BCAST_VEC_PRIV:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[BCAST_VEC_ADDR_REF]], i8* [[BCAST_VEC_PRIV]],
+// CHECK: [[S_ARR_BEGIN:%.+]] = getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[S_ARR_ADDR_REF]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+// CHECK: [[S_ARR_PRIV_BCAST:%.+]] = bitcast [2 x [[S_FLOAT_TY]]]* [[S_ARR_PRIV]] to [[S_FLOAT_TY]]*
+// CHECK: [[S_ARR_BEGIN_GEP:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[S_ARR_BEGIN]], i{{[0-9]+}} 2
+// CHECK: [[S_ARR_IS_EMPTY:%.+]] = icmp eq [[S_FLOAT_TY]]* [[S_ARR_BEGIN]], [[S_ARR_BEGIN_GEP]]
+// CHECK: br i1 [[S_ARR_IS_EMPTY]], label %[[S_ARR_COPY_DONE:.+]], label %[[S_ARR_COPY_BLOCK:.+]]
+// CHECK: [[S_ARR_COPY_BLOCK]]:
+// CHECK: [[S_ARR_SRC_EL:%.+]] = phi [[S_FLOAT_TY]]*{{.+}}
+// CHECK: [[S_ARR_DST_EL:%.+]] = phi [[S_FLOAT_TY]]*{{.+}}
+// CHECK: [[S_ARR_DST_BCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[S_ARR_DST_EL]] to i8*
+// CHECK: [[S_ARR_SRC_BCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[S_ARR_SRC_EL]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[S_ARR_DST_BCAST]], i8* [[S_ARR_SRC_BCAST]]{{.+}})
+// CHECK: [[S_ARR_DST_NEXT:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[S_ARR_DST_EL]], i{{[0-9]+}} 1
+// CHECK: [[S_ARR_SRC_NEXT:%.+]] = getelementptr{{.+}}
+// CHECK: [[CPY_IS_FINISHED:%.+]] = icmp eq [[S_FLOAT_TY]]* [[S_ARR_DST_NEXT]], [[S_ARR_BEGIN_GEP]]
+// CHECK: br i1 [[CPY_IS_FINISHED]], label %[[S_ARR_COPY_DONE]], label %[[S_ARR_COPY_BLOCK]]
+// CHECK: [[S_ARR_COPY_DONE]]:
+// CHECK: [[TMP_VAL1:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[TMP_PRIV]],
+// CHECK: [[VAR_ADDR_REF_BCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[VAR_ADDR_REF]] to i8*
+// CHECK: [[TMP_VAL1_BCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[TMP_VAL1]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[VAR_ADDR_REF_BCAST]], i8* [[TMP_VAL1_BCAST]],{{.+}})
+// CHECK: [[SVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[S_VAR_PRIV]],
+// CHECK: store i{{[0-9]+}} [[SVAR_VAL]], i{{[0-9]+}}* [[SVAR_ADDR_REF]],
+// CHECK: ret void
+
+// template tmain
+// CHECK: define{{.*}} i{{[0-9]+}} [[TMAIN_INT:@.+]]()
+// CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]],
+// CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR:@.+]]([[S_INT_TY]]* [[TEST]])
+// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+// CHECK: call void [[OFFLOAD_FUN_1:@.+]](i{{[0-9]+}} {{.+}}, [2 x i{{[0-9]+}}]* {{.+}}, [2 x [[S_INT_TY]]]* {{.+}}, [[S_INT_TY]]* {{.+}})
+// CHECK: ret
+
+// CHECK: define internal void [[OFFLOAD_FUN_1]](
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_teams(%{{.+}}* @{{.+}}, i{{[0-9]+}} 4,
+// CHECK: ret
+
+// CHECK: define internal void [[OMP_OUTLINED_1:@.+]](i{{[0-9]+}}* noalias [[GTID_ADDR1:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [2 x i{{[0-9]+}}]*{{.+}} [[VEC_IN1:%.+]], i{{[0-9]+}}*{{.+}} [[T_VAR_IN1:%.+]], [2 x [[S_INT_TY]]]*{{.+}} [[S_ARR_IN1:%.+]], [[S_INT_TY]]*{{.+}} [[VAR_IN1:%.+]])
+// skip alloca of global_tid and bound_tid
+// CHECK: {{.+}} = alloca i{{[0-9]+}}*,
+// CHECK: {{.+}} = alloca i{{[0-9]+}}*,
+// CHECK: [[VEC_ADDR1:%.+]] = alloca [2 x i{{[0-9]+}}]*,
+// CHECK: [[T_VAR_ADDR1:%.+]] = alloca i{{[0-9]+}}*,
+// CHECK: [[S_ARR_ADDR1:%.+]] = alloca [2 x [[S_INT_TY]]]*,
+// CHECK: [[VAR_ADDR1:%.+]] = alloca [[S_INT_TY]]*,
+// skip loop variables
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: [[OMP_IS_LAST1:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[T_VAR_PRIV1:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[VEC_PRIV1:%.+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK: [[S_ARR_PRIV1:%.+]] = alloca [2 x [[S_INT_TY]]],
+// CHECK: [[VAR_PRIV1:%.+]] = alloca [[S_INT_TY]],
+// CHECK: [[TMP_PRIV1:%.+]] = alloca [[S_INT_TY]]*,
+
+// skip init of bound and global tid
+// CHECK: store i{{[0-9]+}}* {{.*}},
+// CHECK: store i{{[0-9]+}}* {{.*}},
+// copy from parameters to local address variables
+// CHECK: store [2 x i{{[0-9]+}}]* [[VEC_IN1]], [2 x i{{[0-9]+}}]** [[VEC_ADDR1]],
+// CHECK: store i{{[0-9]+}}* [[T_VAR_IN1]], i{{[0-9]+}}** [[T_VAR_ADDR1]],
+// CHECK: store [2 x [[S_INT_TY]]]* [[S_ARR_IN1]], [2 x [[S_INT_TY]]]** [[S_ARR_ADDR1]],
+// CHECK: store [[S_INT_TY]]* [[VAR_IN1]], [[S_INT_TY]]** [[VAR_ADDR1]],
+
+// load content of local address variables
+// CHECK: [[VEC_ADDR_REF1:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** [[VEC_ADDR1]],
+// CHECK: [[T_VAR_ADDR_REF1:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[T_VAR_ADDR1]],
+// CHECK: [[S_ARR_ADDR_REF1:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** [[S_ARR_ADDR1]],
+// CHECK-DAG: store i{{[0-9]+}} 0, i{{[0-9]+}}* [[OMP_IS_LAST1]],
+// CHECK: [[VAR_ADDR1_REF:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[VAR_ADDR1]],
+// CHECK-DAG: store [[S_INT_TY]]* [[VAR_PRIV1]], [[S_INT_TY]]** [[TMP_PRIV1]],
+
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: call void {{.*}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[TPAR_OUTL:.+]] to
+// CHECK: call void @__kmpc_for_static_fini(
+
+// lastprivates
+// CHECK: [[OMP_IS_LAST_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[OMP_IS_LAST1]],
+// CHECK: [[IS_LAST_IT:%.+]] = icmp ne i{{[0-9]+}} [[OMP_IS_LAST_VAL]], 0
+// CHECK: br i1 [[IS_LAST_IT]], label %[[OMP_LASTPRIV_BLOCK:.+]], label %[[OMP_LASTPRIV_DONE:.+]]
+
+// CHECK: [[OMP_LASTPRIV_BLOCK]]:
+// CHECK: [[T_VAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_PRIV1]],
+// CHECK: store i{{[0-9]+}} [[T_VAR_VAL]], i{{[0-9]+}}* [[T_VAR_ADDR_REF1]],
+// CHECK: [[BCAST_VEC_ADDR_REF:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_ADDR_REF1]] to i8*
+// CHECK: [[BCAST_VEC_PRIV:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV1]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[BCAST_VEC_ADDR_REF]], i8* [[BCAST_VEC_PRIV]],
+// CHECK: [[S_ARR_BEGIN:%.+]] = getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[S_ARR_ADDR_REF]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+// CHECK: [[S_ARR_PRIV_BCAST:%.+]] = bitcast [2 x [[S_INT_TY]]]* [[S_ARR_PRIV1]] to [[S_INT_TY]]*
+// CHECK: [[S_ARR_BEGIN_GEP:%.+]] = getelementptr [[S_INT_TY]], [[S_INT_TY]]* [[S_ARR_BEGIN]], i{{[0-9]+}} 2
+// CHECK: [[S_ARR_IS_EMPTY:%.+]] = icmp eq [[S_INT_TY]]* [[S_ARR_BEGIN]], [[S_ARR_BEGIN_GEP]]
+// CHECK: br i1 [[S_ARR_IS_EMPTY]], label %[[S_ARR_COPY_DONE:.+]], label %[[S_ARR_COPY_BLOCK:.+]]
+// CHECK: [[S_ARR_COPY_BLOCK]]:
+// CHECK: [[S_ARR_SRC_EL:%.+]] = phi [[S_INT_TY]]*{{.+}}
+// CHECK: [[S_ARR_DST_EL:%.+]] = phi [[S_INT_TY]]*{{.+}}
+// CHECK: [[S_ARR_DST_BCAST:%.+]] = bitcast [[S_INT_TY]]* [[S_ARR_DST_EL]] to i8*
+// CHECK: [[S_ARR_SRC_BCAST:%.+]] = bitcast [[S_INT_TY]]* [[S_ARR_SRC_EL]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[S_ARR_DST_BCAST]], i8* [[S_ARR_SRC_BCAST]]{{.+}})
+// CHECK: [[S_ARR_DST_NEXT:%.+]] = getelementptr [[S_INT_TY]], [[S_INT_TY]]* [[S_ARR_DST_EL]], i{{[0-9]+}} 1
+// CHECK: [[S_ARR_SRC_NEXT:%.+]] = getelementptr{{.+}}
+// CHECK: [[CPY_IS_FINISHED:%.+]] = icmp eq [[S_INT_TY]]* [[S_ARR_DST_NEXT]], [[S_ARR_BEGIN_GEP]]
+// CHECK: br i1 [[CPY_IS_FINISHED]], label %[[S_ARR_COPY_DONE]], label %[[S_ARR_COPY_BLOCK]]
+// CHECK: [[S_ARR_COPY_DONE]]:
+// CHECK: [[TMP_VAL1:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[TMP_PRIV1]],
+// CHECK: [[VAR_ADDR_REF_BCAST:%.+]] = bitcast [[S_INT_TY]]* [[VAR_ADDR1_REF]] to i8*
+// CHECK: [[TMP_VAL1_BCAST:%.+]] = bitcast [[S_INT_TY]]* [[TMP_VAL1]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[VAR_ADDR_REF_BCAST]], i8* [[TMP_VAL1_BCAST]],{{.+}})
+// CHECK: ret void
+
+// CHECK: define internal void [[TPAR_OUTL:@.+]](i{{[0-9]+}}* noalias [[GTID_ADDR1:%.+]], i{{[0-9]+}}* noalias %{{.+}}, {{.+}}, {{.+}}, [2 x i{{[0-9]+}}]*{{.+}} [[VEC_IN1:%.+]], i{{[0-9]+}}*{{.+}} [[T_VAR_IN1:%.+]], [2 x [[S_INT_TY]]]*{{.+}} [[S_ARR_IN1:%.+]], [[S_INT_TY]]*{{.+}} [[VAR_IN1:%.+]])
+// skip alloca of global_tid and bound_tid, and prev lb and ub vars
+// CHECK: {{.+}} = alloca i{{[0-9]+}}*,
+// CHECK: {{.+}} = alloca i{{[0-9]+}}*,
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: [[VEC_ADDR1:%.+]] = alloca [2 x i{{[0-9]+}}]*,
+// CHECK: [[T_VAR_ADDR1:%.+]] = alloca i{{[0-9]+}}*,
+// CHECK: [[S_ARR_ADDR1:%.+]] = alloca [2 x [[S_INT_TY]]]*,
+// CHECK: [[VAR_ADDR1:%.+]] = alloca [[S_INT_TY]]*,
+// skip loop variables
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: [[OMP_IS_LAST1:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[T_VAR_PRIV1:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[VEC_PRIV1:%.+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK: [[S_ARR_PRIV1:%.+]] = alloca [2 x [[S_INT_TY]]],
+// CHECK: [[VAR_PRIV1:%.+]] = alloca [[S_INT_TY]],
+// CHECK: [[TMP_PRIV1:%.+]] = alloca [[S_INT_TY]]*,
+
+// skip init of bound and global tid
+// CHECK: store i{{[0-9]+}}* {{.*}},
+// CHECK: store i{{[0-9]+}}* {{.*}},
+// copy from parameters to local address variables
+// CHECK: store [2 x i{{[0-9]+}}]* [[VEC_IN1]], [2 x i{{[0-9]+}}]** [[VEC_ADDR1]],
+// CHECK: store i{{[0-9]+}}* [[T_VAR_IN1]], i{{[0-9]+}}** [[T_VAR_ADDR1]],
+// CHECK: store [2 x [[S_INT_TY]]]* [[S_ARR_IN1]], [2 x [[S_INT_TY]]]** [[S_ARR_ADDR1]],
+// CHECK: store [[S_INT_TY]]* [[VAR_IN1]], [[S_INT_TY]]** [[VAR_ADDR1]],
+
+// load content of local address variables
+// CHECK: [[VEC_ADDR_REF1:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** [[VEC_ADDR1]],
+// CHECK: [[T_VAR_ADDR_REF1:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[T_VAR_ADDR1]],
+// CHECK: [[S_ARR_ADDR_REF1:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** [[S_ARR_ADDR1]],
+// CHECK-DAG: store i{{[0-9]+}} 0, i{{[0-9]+}}* [[OMP_IS_LAST1]],
+// CHECK: [[VAR_ADDR1_REF:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[VAR_ADDR1]],
+// CHECK-DAG: store [[S_INT_TY]]* [[VAR_PRIV1]], [[S_INT_TY]]** [[TMP_PRIV1]],
+
+// CHECK: call void @__kmpc_for_static_init_4(
+
+// assignment: vec[i] = t_var;
+// CHECK: [[IV_VAL1:%.+]] =
+// CHECK: [[T_VAR_PRIV_VAL1:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_PRIV1]],
+// CHECK: [[VEC_PTR1:%.+]] = getelementptr inbounds [2 x i{{[0-9]+}}], [2 x i{{[0-9]+}}]* [[VEC_PRIV1]], i{{[0-9]+}} 0, i{{[0-9]+}} {{.+}}
+// CHECK: store i{{[0-9]+}} [[T_VAR_PRIV_VAL1]], i{{[0-9]+}}* [[VEC_PTR1]],
+
+// assignment: s_arr[i] = var;
+// CHECK-DAG: [[S_ARR_PTR1:%.+]] = getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[S_ARR_PRIV1]],
+// CHECK-DAG: [[TMP_VAL1:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[TMP_PRIV1]],
+// CHECK-DAG: [[S_ARR_PTR_BCAST1:%.+]] = bitcast [[S_INT_TY]]* [[S_ARR_PTR1]] to i8*
+// CHECK-DAG: [[TMP_VAL_BCAST1:%.+]] = bitcast [[S_INT_TY]]* [[TMP_VAL1]] to i8*
+// CHECK-DAG: call void @llvm.memcpy.{{.+}}(i8* [[S_ARR_PTR_BCAST1]], i8* [[TMP_VAL_BCAST1]],
+
+// CHECK: call void @__kmpc_for_static_fini(
+
+// lastprivates
+// CHECK: [[OMP_IS_LAST_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[OMP_IS_LAST1]],
+// CHECK: [[IS_LAST_IT:%.+]] = icmp ne i{{[0-9]+}} [[OMP_IS_LAST_VAL]], 0
+// CHECK: br i1 [[IS_LAST_IT]], label %[[OMP_LASTPRIV_BLOCK:.+]], label %[[OMP_LASTPRIV_DONE:.+]]
+
+// CHECK: [[OMP_LASTPRIV_BLOCK]]:
+// CHECK: [[T_VAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_PRIV1]],
+// CHECK: store i{{[0-9]+}} [[T_VAR_VAL]], i{{[0-9]+}}* [[T_VAR_ADDR_REF1]],
+// CHECK: [[BCAST_VEC_ADDR_REF:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_ADDR_REF1]] to i8*
+// CHECK: [[BCAST_VEC_PRIV:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV1]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[BCAST_VEC_ADDR_REF]], i8* [[BCAST_VEC_PRIV]],
+// CHECK: [[S_ARR_BEGIN:%.+]] = getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[S_ARR_ADDR_REF]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+// CHECK: [[S_ARR_PRIV_BCAST:%.+]] = bitcast [2 x [[S_INT_TY]]]* [[S_ARR_PRIV1]] to [[S_INT_TY]]*
+// CHECK: [[S_ARR_BEGIN_GEP:%.+]] = getelementptr [[S_INT_TY]], [[S_INT_TY]]* [[S_ARR_BEGIN]], i{{[0-9]+}} 2
+// CHECK: [[S_ARR_IS_EMPTY:%.+]] = icmp eq [[S_INT_TY]]* [[S_ARR_BEGIN]], [[S_ARR_BEGIN_GEP]]
+// CHECK: br i1 [[S_ARR_IS_EMPTY]], label %[[S_ARR_COPY_DONE:.+]], label %[[S_ARR_COPY_BLOCK:.+]]
+// CHECK: [[S_ARR_COPY_BLOCK]]:
+// CHECK: [[S_ARR_SRC_EL:%.+]] = phi [[S_INT_TY]]*{{.+}}
+// CHECK: [[S_ARR_DST_EL:%.+]] = phi [[S_INT_TY]]*{{.+}}
+// CHECK: [[S_ARR_DST_BCAST:%.+]] = bitcast [[S_INT_TY]]* [[S_ARR_DST_EL]] to i8*
+// CHECK: [[S_ARR_SRC_BCAST:%.+]] = bitcast [[S_INT_TY]]* [[S_ARR_SRC_EL]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[S_ARR_DST_BCAST]], i8* [[S_ARR_SRC_BCAST]]{{.+}})
+// CHECK: [[S_ARR_DST_NEXT:%.+]] = getelementptr [[S_INT_TY]], [[S_INT_TY]]* [[S_ARR_DST_EL]], i{{[0-9]+}} 1
+// CHECK: [[S_ARR_SRC_NEXT:%.+]] = getelementptr{{.+}}
+// CHECK: [[CPY_IS_FINISHED:%.+]] = icmp eq [[S_INT_TY]]* [[S_ARR_DST_NEXT]], [[S_ARR_BEGIN_GEP]]
+// CHECK: br i1 [[CPY_IS_FINISHED]], label %[[S_ARR_COPY_DONE]], label %[[S_ARR_COPY_BLOCK]]
+// CHECK: [[S_ARR_COPY_DONE]]:
+// CHECK: [[TMP_VAL1:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[TMP_PRIV1]],
+// CHECK: [[VAR_ADDR_REF_BCAST:%.+]] = bitcast [[S_INT_TY]]* [[VAR_ADDR1_REF]] to i8*
+// CHECK: [[TMP_VAL1_BCAST:%.+]] = bitcast [[S_INT_TY]]* [[TMP_VAL1]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[VAR_ADDR_REF_BCAST]], i8* [[TMP_VAL1_BCAST]],{{.+}})
+// CHECK: ret void
+
+#endif
diff --git a/test/OpenMP/teams_distribute_parallel_for_lastprivate_messages.cpp b/test/OpenMP/teams_distribute_parallel_for_lastprivate_messages.cpp
index 5691af71f7cd..b58bac4fdfc3 100644
--- a/test/OpenMP/teams_distribute_parallel_for_lastprivate_messages.cpp
+++ b/test/OpenMP/teams_distribute_parallel_for_lastprivate_messages.cpp
@@ -18,14 +18,14 @@ public:
const S2 &operator =(const S2&) const;
S2 &operator =(const S2&);
static float S2s; // expected-note {{static data member is predetermined as shared}}
- static const float S2sc;
+ static const float S2sc; // expected-note {{static data member is predetermined as shared}}
};
-const float S2::S2sc = 0; // expected-note {{static data member is predetermined as shared}}
+const float S2::S2sc = 0;
const S2 b;
const S2 ba[5];
class S3 {
int a;
- S3 &operator=(const S3 &s3); // expected-note 2 {{implicitly declared private here}}
+ S3 &operator=(const S3 &s3); // expected-note {{implicitly declared private here}}
public:
S3() : a(0) {}
@@ -52,7 +52,7 @@ public:
};
class S6 {
int a;
- S6() : a(0) {}
+ S6() : a(0) {} // expected-note {{implicitly declared private here}}
public:
S6(const S6 &s6) : a(s6.a) {}
@@ -255,12 +255,14 @@ int main(int argc, char **argv) {
#pragma omp teams distribute parallel for lastprivate(j)
for (i = 0; i < argc; ++i) foo();
+// expected-error@+2 {{firstprivate variable cannot be lastprivate}} expected-note@+2 {{defined as firstprivate}}
#pragma omp target
-#pragma omp teams distribute parallel for firstprivate(m) lastprivate(m) // expected-error {{'operator=' is a private member of 'S3'}}
+#pragma omp teams distribute parallel for firstprivate(m) lastprivate(m)
for (i = 0; i < argc; ++i) foo();
+// expected-error@+2 {{lastprivate variable cannot be firstprivate}} expected-note@+2 {{defined as lastprivate}}
#pragma omp target
-#pragma omp teams distribute parallel for lastprivate(n) firstprivate(n) // OK
+#pragma omp teams distribute parallel for lastprivate(n) firstprivate(n) // expected-error {{calling a private constructor of class 'S6'}}
for (i = 0; i < argc; ++i) foo();
static int si;
diff --git a/test/OpenMP/teams_distribute_parallel_for_linear_messages.cpp b/test/OpenMP/teams_distribute_parallel_for_linear_messages.cpp
deleted file mode 100644
index b14fb2328b2b..000000000000
--- a/test/OpenMP/teams_distribute_parallel_for_linear_messages.cpp
+++ /dev/null
@@ -1,293 +0,0 @@
-// RUN: %clang_cc1 -verify -fopenmp %s
-
-namespace X {
- int x;
-};
-
-struct B {
- static int ib; // expected-note {{'B::ib' declared here}}
- static int bfoo() { return 8; }
-};
-
-int bfoo() { return 4; }
-
-int z;
-const int C1 = 1;
-const int C2 = 2;
-void test_linear_colons()
-{
- int B = 0;
-
-#pragma omp target
-#pragma omp teams distribute parallel for linear(B:bfoo())
- for (int i = 0; i < 10; ++i) ;
-
-#pragma omp target
-#pragma omp teams distribute parallel for linear(B::ib:B:bfoo()) // expected-error {{unexpected ':' in nested name specifier; did you mean '::'}}
- for (int i = 0; i < 10; ++i) ;
-
-#pragma omp target
-#pragma omp teams distribute parallel for linear(B:ib) // expected-error {{use of undeclared identifier 'ib'; did you mean 'B::ib'}}
- for (int i = 0; i < 10; ++i) ;
-
-#pragma omp target
-#pragma omp teams distribute parallel for linear(z:B:ib) // expected-error {{unexpected ':' in nested name specifier; did you mean '::'?}}
- for (int i = 0; i < 10; ++i) ;
-
-#pragma omp target
-#pragma omp teams distribute parallel for linear(B:B::bfoo())
- for (int i = 0; i < 10; ++i) ;
-
-#pragma omp target
-#pragma omp teams distribute parallel for linear(X::x : ::z)
- for (int i = 0; i < 10; ++i) ;
-
-#pragma omp target
-#pragma omp teams distribute parallel for linear(B,::z, X::x)
- for (int i = 0; i < 10; ++i) ;
-
-#pragma omp target
-#pragma omp teams distribute parallel for linear(::z)
- for (int i = 0; i < 10; ++i) ;
-
-#pragma omp target
-#pragma omp teams distribute parallel for linear(B::bfoo()) // expected-error {{expected variable name}}
- for (int i = 0; i < 10; ++i) ;
-
-#pragma omp target
-#pragma omp teams distribute parallel for linear(B::ib,B:C1+C2)
- for (int i = 0; i < 10; ++i) ;
-}
-
-template<int L, class T, class N> T test_template(T* arr, N num) {
- N i;
- T sum = (T)0;
- T ind2 = - num * L; // expected-note {{'ind2' defined here}}
-
-#pragma omp target
-#pragma omp teams distribute parallel for linear(ind2:L) // expected-error {{argument of a linear clause should be of integral or pointer type}}
- for (i = 0; i < num; ++i) {
- T cur = arr[(int)ind2];
- ind2 += L;
- sum += cur;
- }
- return T();
-}
-
-template<int LEN> int test_warn() {
- int ind2 = 0;
- #pragma omp target
- #pragma omp teams distribute parallel for linear(ind2:LEN) // expected-warning {{zero linear step (ind2 should probably be const)}}
- for (int i = 0; i < 100; i++) {
- ind2 += LEN;
- }
- return ind2;
-}
-
-struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}}
-extern S1 a;
-class S2 {
- mutable int a;
-public:
- S2():a(0) { }
-};
-const S2 b; // expected-note 2 {{'b' defined here}}
-const S2 ba[5];
-class S3 {
- int a;
-public:
- S3():a(0) { }
-};
-const S3 ca[5];
-class S4 {
- int a;
- S4();
-public:
- S4(int v):a(v) { }
-};
-class S5 {
- int a;
- S5():a(0) {}
-public:
- S5(int v):a(v) { }
-};
-
-S3 h;
-#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
-
-template<class I, class C> int foomain(I argc, C **argv) {
- I e(4);
- I g(5);
- int i;
- int &j = i;
-
-#pragma omp target
-#pragma omp teams distribute parallel for linear // expected-error {{expected '(' after 'linear'}}
- for (int k = 0; k < argc; ++k) ++k;
-
-#pragma omp target
-#pragma omp teams distribute parallel for linear ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
- for (int k = 0; k < argc; ++k) ++k;
-
-#pragma omp target
-#pragma omp teams distribute parallel for linear () // expected-error {{expected expression}}
- for (int k = 0; k < argc; ++k) ++k;
-
-#pragma omp target
-#pragma omp teams distribute parallel for linear (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
- for (int k = 0; k < argc; ++k) ++k;
-
-#pragma omp target
-#pragma omp teams distribute parallel for linear (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
- for (int k = 0; k < argc; ++k) ++k;
-
-#pragma omp target
-#pragma omp teams distribute parallel for linear (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
- for (int k = 0; k < argc; ++k) ++k;
-
-#pragma omp target
-#pragma omp teams distribute parallel for linear (argc : 5)
- for (int k = 0; k < argc; ++k) ++k;
-
-#pragma omp target
-#pragma omp teams distribute parallel for linear (S1) // expected-error {{'S1' does not refer to a value}}
- for (int k = 0; k < argc; ++k) ++k;
-
-#pragma omp target
-#pragma omp teams distribute parallel for linear (a, b:B::ib) // expected-error {{linear variable with incomplete type 'S1'}} expected-error {{const-qualified variable cannot be linear}}
- for (int k = 0; k < argc; ++k) ++k;
-
-#pragma omp target
-#pragma omp teams distribute parallel for linear (argv[1]) // expected-error {{expected variable name}}
- for (int k = 0; k < argc; ++k) ++k;
-
-#pragma omp target
-#pragma omp teams distribute parallel for linear(e, g)
- for (int k = 0; k < argc; ++k) ++k;
-
-#pragma omp target
-#pragma omp teams distribute parallel for linear(h) // expected-error {{threadprivate or thread local variable cannot be linear}}
- for (int k = 0; k < argc; ++k) ++k;
-
-#pragma omp target
-#pragma omp teams distribute parallel for linear(i)
- for (int k = 0; k < argc; ++k) ++k;
-
- #pragma omp parallel
- {
- int v = 0;
- int i;
- #pragma omp target
- #pragma omp teams distribute parallel for linear(v:i)
- for (int k = 0; k < argc; ++k) { i = k; v += i; }
- }
-
-#pragma omp target
-#pragma omp teams distribute parallel for linear(j)
- for (int k = 0; k < argc; ++k) ++k;
-
- int v = 0;
-
-#pragma omp target
-#pragma omp teams distribute parallel for linear(v:j)
- for (int k = 0; k < argc; ++k) { ++k; v += j; }
-
-#pragma omp target
-#pragma omp teams distribute parallel for linear(i)
- for (int k = 0; k < argc; ++k) ++k;
- return 0;
-}
-
-namespace A {
-double x;
-#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}}
-}
-namespace C {
-using A::x;
-}
-
-int main(int argc, char **argv) {
- double darr[100];
- // expected-note@+1 {{in instantiation of function template specialization 'test_template<-4, double, int>' requested here}}
- test_template<-4>(darr, 4);
- // expected-note@+1 {{in instantiation of function template specialization 'test_warn<0>' requested here}}
- test_warn<0>();
-
- S4 e(4); // expected-note {{'e' defined here}}
- S5 g(5); // expected-note {{'g' defined here}}
- int i;
- int &j = i;
-
-#pragma omp target
-#pragma omp teams distribute parallel for linear // expected-error {{expected '(' after 'linear'}}
- for (int k = 0; k < argc; ++k) ++k;
-
-#pragma omp target
-#pragma omp teams distribute parallel for linear ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
- for (int k = 0; k < argc; ++k) ++k;
-
-#pragma omp target
-#pragma omp teams distribute parallel for linear () // expected-error {{expected expression}}
- for (int k = 0; k < argc; ++k) ++k;
-
-#pragma omp target
-#pragma omp teams distribute parallel for linear (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
- for (int k = 0; k < argc; ++k) ++k;
-
-#pragma omp target
-#pragma omp teams distribute parallel for linear (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
- for (int k = 0; k < argc; ++k) ++k;
-
-#pragma omp target
-#pragma omp teams distribute parallel for linear (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
- for (int k = 0; k < argc; ++k) ++k;
-
-#pragma omp target
-#pragma omp teams distribute parallel for linear (argc)
- for (int k = 0; k < argc; ++k) ++k;
-
-#pragma omp target
-#pragma omp teams distribute parallel for linear (S1) // expected-error {{'S1' does not refer to a value}}
- for (int k = 0; k < argc; ++k) ++k;
-
-
-#pragma omp target
-#pragma omp teams distribute parallel for linear (a, b) // expected-error {{linear variable with incomplete type 'S1'}} expected-error {{const-qualified variable cannot be linear}}
- for (int k = 0; k < argc; ++k) ++k;
-
-#pragma omp target
-#pragma omp teams distribute parallel for linear (argv[1]) // expected-error {{expected variable name}}
- for (int k = 0; k < argc; ++k) ++k;
-
-#pragma omp target
-#pragma omp teams distribute parallel for linear(e, g) // expected-error {{argument of a linear clause should be of integral or pointer type, not 'S4'}} expected-error {{argument of a linear clause should be of integral or pointer type, not 'S5'}}
- for (int k = 0; k < argc; ++k) ++k;
-
-#pragma omp target
-#pragma omp teams distribute parallel for linear(h, C::x) // expected-error 2 {{threadprivate or thread local variable cannot be linear}}
- for (int k = 0; k < argc; ++k) ++k;
-
- #pragma omp parallel
- {
- int i;
- #pragma omp target
- #pragma omp teams distribute parallel for linear(i)
- for (int k = 0; k < argc; ++k) ++k;
-
- #pragma omp target
- #pragma omp teams distribute parallel for linear(i : 4)
- for (int k = 0; k < argc; ++k) { ++k; i += 4; }
- }
-
-#pragma omp target
-#pragma omp teams distribute parallel for linear(j)
- for (int k = 0; k < argc; ++k) ++k;
-
-#pragma omp target
-#pragma omp teams distribute parallel for linear(i)
- for (int k = 0; k < argc; ++k) ++k;
-
- foomain<int,char>(argc,argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}}
- return 0;
-}
-
diff --git a/test/OpenMP/teams_distribute_parallel_for_loop_messages.cpp b/test/OpenMP/teams_distribute_parallel_for_loop_messages.cpp
index e0c315f513b7..a2f6f679d325 100644
--- a/test/OpenMP/teams_distribute_parallel_for_loop_messages.cpp
+++ b/test/OpenMP/teams_distribute_parallel_for_loop_messages.cpp
@@ -2,7 +2,7 @@
class S {
int a;
- S() : a(0) {}
+ S() : a(0) {} // expected-note {{implicitly declared private here}}
public:
S(int v) : a(v) {}
@@ -691,8 +691,9 @@ void test_loop_eh() {
void test_loop_firstprivate_lastprivate() {
S s(4);
+// expected-error@+2 {{lastprivate variable cannot be firstprivate}} expected-note@+2 {{defined as lastprivate}}
#pragma omp target
-#pragma omp teams distribute parallel for lastprivate(s) firstprivate(s)
+#pragma omp teams distribute parallel for lastprivate(s) firstprivate(s) // expected-error {{calling a private constructor of class 'S'}}
for (int i = 0; i < 16; ++i)
;
}
diff --git a/test/OpenMP/teams_distribute_parallel_for_messages.cpp b/test/OpenMP/teams_distribute_parallel_for_messages.cpp
index c3536cd86167..9843b442e5b4 100644
--- a/test/OpenMP/teams_distribute_parallel_for_messages.cpp
+++ b/test/OpenMP/teams_distribute_parallel_for_messages.cpp
@@ -9,6 +9,9 @@ static int pvt;
#pragma omp teams distribute parallel for // expected-error {{unexpected OpenMP directive '#pragma omp teams distribute parallel for'}}
int main(int argc, char **argv) {
+ #pragma omp target
+ #pragma omp teams distribute parallel for
+ f; // expected-error {{use of undeclared identifier 'f'}}
#pragma omp target
#pragma omp teams distribute parallel for { // expected-warning {{extra tokens at the end of '#pragma omp teams distribute parallel for' are ignored}}
for (int i = 0; i < argc; ++i)
@@ -34,7 +37,7 @@ int main(int argc, char **argv) {
for (int i = 0; i < argc; ++i)
foo();
#pragma omp target
-#pragma omp teams distribute parallel for
+#pragma omp teams distribute parallel for linear(argc) // expected-error {{unexpected OpenMP clause 'linear' in directive '#pragma omp teams distribute parallel for'}}
for (int i = 0; i < argc; ++i)
foo();
// expected-warning@+2 {{extra tokens at the end of '#pragma omp teams distribute parallel for' are ignored}}
@@ -94,7 +97,7 @@ L1:
}
#pragma omp target
-#pragma omp teams distribute parallel for copyin(pvt) // expected-error {{unexpected OpenMP clause 'copyin' in directive '#pragma omp teams distribute parallel for'}}
+#pragma omp teams distribute parallel for copyin(pvt)
for (int n = 0; n < 100; ++n) {}
return 0;
@@ -107,3 +110,12 @@ void test_ordered() {
;
}
+void test_cancel() {
+#pragma omp target
+#pragma omp teams distribute parallel for
+ for (int i = 0; i < 16; ++i) {
+#pragma omp cancel for
+ ;
+ }
+}
+
diff --git a/test/OpenMP/teams_distribute_parallel_for_num_threads_codegen.cpp b/test/OpenMP/teams_distribute_parallel_for_num_threads_codegen.cpp
new file mode 100644
index 000000000000..7c0ac461220d
--- /dev/null
+++ b/test/OpenMP/teams_distribute_parallel_for_num_threads_codegen.cpp
@@ -0,0 +1,120 @@
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple %itanium_abi_triple -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple %itanium_abi_triple -fexceptions -fcxx-exceptions -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple %itanium_abi_triple -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+typedef __INTPTR_TYPE__ intptr_t;
+
+// CHECK-DAG: [[IDENT_T_TY:%.+]] = type { i32, i32, i32, i32, i8* }
+// CHECK-DAG: [[S_TY:%.+]] = type { [[INTPTR_T_TY:i[0-9]+]], [[INTPTR_T_TY]], [[INTPTR_T_TY]] }
+// CHECK-DAG: [[STR:@.+]] = private unnamed_addr constant [23 x i8] c";unknown;unknown;0;0;;\00"
+// CHECK-DAG: [[DEF_LOC_2:@.+]] = private unnamed_addr constant [[IDENT_T_TY]] { i32 0, i32 2, i32 0, i32 0, i8* getelementptr inbounds ([23 x i8], [23 x i8]* [[STR]], i32 0, i32 0) }
+
+void foo();
+
+struct S {
+ intptr_t a, b, c;
+ S(intptr_t a) : a(a) {}
+ operator char() { return a; }
+ ~S() {}
+};
+
+template <typename T, int C>
+int tmain() {
+#pragma omp target
+#pragma omp teams distribute parallel for num_threads(C)
+ for (int i = 0; i < 100; i++)
+ foo();
+#pragma omp target
+#pragma omp teams distribute parallel for num_threads(T(23))
+ for (int i = 0; i < 100; i++)
+ foo();
+ return 0;
+}
+
+int main() {
+ S s(0);
+ char a = s;
+// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+// CHECK: call void [[OFFLOADING_FUN_0:@.+]](
+// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+// CHECK: call void [[OFFLOADING_FUN_1:@.+]](
+// CHECK: invoke{{.+}} [[TMAIN_5:@.+]]()
+// CHECK: invoke{{.+}} [[TMAIN_1:@.+]]()
+#pragma omp target
+ // CHECK: define internal void [[OFFLOADING_FUN_0]](
+ // CHECK: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, i32 0, {{.+}}* [[OMP_TEAMS_OUTLINED_0:@.+]] to {{.+}})
+#pragma omp teams distribute parallel for num_threads(2)
+ for (int i = 0; i < 100; i++) {
+ // CHECK: define{{.+}} void [[OMP_TEAMS_OUTLINED_0]](
+ // CHECK: call {{.*}}void @__kmpc_push_num_threads([[IDENT_T_TY]]* [[DEF_LOC_2]], i32 {{.+}}, i32 2)
+ // CHECK: call {{.*}}void {{.*}} @__kmpc_fork_call(
+ foo();
+ }
+#pragma omp target
+ // CHECK: define internal void [[OFFLOADING_FUN_1]](
+
+ // CHECK: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}}* [[OMP_TEAMS_OUTLINED_1:@.+]] to {{.+}})
+#pragma omp teams distribute parallel for num_threads(a)
+ for (int i = 0; i < 100; i++) {
+ // CHECK: define{{.+}} void [[OMP_TEAMS_OUTLINED_1]](
+ // CHECK-DAG: [[A_ADDR:%.+]] = alloca i8*,
+ // CHECK-DAG: [[A_REF:%.+]] = load i8*, i8** [[A_ADDR]],
+ // CHECK-DAG: [[A_VAL:%.+]] = load i8, i8* [[A_REF]],
+ // CHECK-DAG: [[A_EXT:%.+]] = sext i8 [[A_VAL]] to {{.+}}
+ // CHECK: call {{.*}}void @__kmpc_push_num_threads([[IDENT_T_TY]]* [[DEF_LOC_2]], i32 {{.+}}, i32 [[A_EXT]])
+ // CHECK: call {{.*}}void {{.*}} @__kmpc_fork_call(
+ foo();
+ }
+ return a + tmain<char, 5>() + tmain<S, 1>();
+}
+
+// tmain 5
+// CHECK-DAG: define {{.*}}i{{[0-9]+}} [[TMAIN_5]]()
+// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+// CHECK: call void [[T_OFFLOADING_FUN_0:@.+]](
+// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+// CHECK: call void [[T_OFFLOADING_FUN_1:@.+]](
+
+// tmain 1
+// CHECK-DAG: define {{.*}}i{{[0-9]+}} [[TMAIN_1]]()
+// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+// CHECK: call void [[T_OFFLOADING_FUN_2:@.+]](
+// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+// CHECK: call void [[T_OFFLOADING_FUN_3:@.+]](
+
+// CHECK: define internal void [[T_OFFLOADING_FUN_0]](
+// CHECK: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, i32 0, {{.+}}* [[T_OMP_TEAMS_OUTLINED_0:@.+]] to {{.+}})
+
+// CHECK: define{{.+}} void [[T_OMP_TEAMS_OUTLINED_0]](
+// CHECK: call {{.*}}void @__kmpc_push_num_threads([[IDENT_T_TY]]* [[DEF_LOC_2]], i32 {{.+}}, i32 5)
+// CHECK: call {{.*}}void {{.*}} @__kmpc_fork_call(
+
+// CHECK: define internal void [[T_OFFLOADING_FUN_1]](
+// CHECK: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, i32 0, {{.+}}* [[T_OMP_TEAMS_OUTLINED_1:@.+]] to {{.+}})
+
+// CHECK: define{{.+}} void [[T_OMP_TEAMS_OUTLINED_1]](
+// CHECK: call {{.*}}void @__kmpc_push_num_threads([[IDENT_T_TY]]* [[DEF_LOC_2]], i32 {{.+}}, i32 23)
+// CHECK: call {{.*}}void {{.*}} @__kmpc_fork_call(
+
+// CHECK: define internal void [[T_OFFLOADING_FUN_2]](
+// CHECK: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, i32 0, {{.+}}* [[T_OMP_TEAMS_OUTLINED_2:@.+]] to {{.+}})
+
+// CHECK: define{{.+}} void [[T_OMP_TEAMS_OUTLINED_2]](
+// CHECK: call {{.*}}void @__kmpc_push_num_threads([[IDENT_T_TY]]* [[DEF_LOC_2]], i32 {{.+}}, i32 1)
+// CHECK: call {{.*}}void {{.*}} @__kmpc_fork_call(
+
+// CHECK: define internal void [[T_OFFLOADING_FUN_3]](
+// CHECK: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, i32 {{.+}}, {{.+}}* [[T_OMP_TEAMS_OUTLINED_3:@.+]] to {{.+}})
+
+// CHECK: define{{.+}} void [[T_OMP_TEAMS_OUTLINED_3]]({{.+}}, {{.+}}, {{.+}} [[NUM_TH_CPT_IN:%.+]])
+// CHECK: [[NUM_TH_CPT:%.+]] = alloca i8*,
+// CHECK: store {{.+}} [[NUM_TH_CPT_IN]], {{.+}} [[NUM_TH_CPT]],
+// CHECK: [[NUM_TH_REF:%.+]] = load{{.+}}, {{.+}} [[NUM_TH_CPT]],
+// CHECK-DAG: [[NUM_TH_VAL:%.+]] = load {{.+}}, {{.+}} [[NUM_TH_REF]],
+// CHECK-DAG: [[NUM_TH_SEXT:%.+]] = sext i8 [[NUM_TH_VAL]] to {{.+}}
+// CHECK: call {{.*}}void @__kmpc_push_num_threads([[IDENT_T_TY]]* [[DEF_LOC_2]], i32 {{.+}}, i32 [[NUM_TH_SEXT]])
+// CHECK: call {{.*}}void {{.*}} @__kmpc_fork_call(
+#endif
diff --git a/test/OpenMP/teams_distribute_parallel_for_private_codegen.cpp b/test/OpenMP/teams_distribute_parallel_for_private_codegen.cpp
new file mode 100644
index 000000000000..80a12738cab4
--- /dev/null
+++ b/test/OpenMP/teams_distribute_parallel_for_private_codegen.cpp
@@ -0,0 +1,332 @@
+// RUN: %clang_cc1 -DCHECK -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -DCHECK -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+
+// RUN: %clang_cc1 -DLAMBDA -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+struct St {
+ int a, b;
+ St() : a(0), b(0) {}
+ St(const St &st) : a(st.a + st.b), b(0) {}
+ ~St() {}
+};
+
+volatile int g = 1212;
+volatile int &g1 = g;
+
+template <class T>
+struct S {
+ T f;
+ S(T a) : f(a + g) {}
+ S() : f(g) {}
+ S(const S &s, St t = St()) : f(s.f + t.a) {}
+ operator T() { return T(); }
+ ~S() {}
+};
+
+// CHECK-DAG: [[S_FLOAT_TY:%.+]] = type { float }
+// CHECK-DAG: [[S_INT_TY:%.+]] = type { i{{[0-9]+}} }
+
+template <typename T>
+T tmain() {
+ S<T> test;
+ T t_var = T();
+ T vec[] = {1, 2};
+ S<T> s_arr[] = {1, 2};
+ S<T> &var = test;
+#pragma omp target
+#pragma omp teams distribute parallel for private(t_var, vec, s_arr, var)
+ for (int i = 0; i < 2; ++i) {
+ vec[i] = t_var;
+ s_arr[i] = var;
+ }
+ return T();
+}
+
+// CHECK-DAG: [[TEST:@.+]] = global [[S_FLOAT_TY]] zeroinitializer,
+S<float> test;
+// CHECK-DAG: [[T_VAR:@.+]] = global i{{[0-9]+}} 333,
+int t_var = 333;
+// CHECK-DAG: [[VEC:@.+]] = global [2 x i{{[0-9]+}}] [i{{[0-9]+}} 1, i{{[0-9]+}} 2],
+int vec[] = {1, 2};
+// CHECK-DAG: [[S_ARR:@.+]] = global [2 x [[S_FLOAT_TY]]] zeroinitializer,
+S<float> s_arr[] = {1, 2};
+// CHECK-DAG: [[VAR:@.+]] = global [[S_FLOAT_TY]] zeroinitializer,
+S<float> var(3);
+// CHECK-DAG: [[SIVAR:@.+]] = internal global i{{[0-9]+}} 0,
+
+int main() {
+ static int sivar;
+#ifdef LAMBDA
+ // LAMBDA: [[G:@.+]] = global i{{[0-9]+}} 1212,
+ // LAMBDA-LABEL: @main
+ // LAMBDA: call void [[OUTER_LAMBDA:@.+]](
+ [&]() {
+ // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
+ // LAMBDA: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 1, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 0)
+ // LAMBDA: call void @[[LOFFL1:.+]](
+ // LAMBDA: ret
+#pragma omp target
+#pragma omp teams distribute parallel for private(g, g1, sivar)
+ for (int i = 0; i < 2; ++i) {
+ // LAMBDA: define{{.*}} internal{{.*}} void @[[LOFFL1]](i{{64|32}} {{%.+}})
+ // LAMBDA: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 0, {{.+}} @[[LOUTL1:.+]] to {{.+}})
+ // LAMBDA: ret void
+
+ // LAMBDA: define internal void @[[LOUTL1]]({{.+}})
+ // Skip global, bound tid and loop vars
+ // LAMBDA: {{.+}} = alloca i32*,
+ // LAMBDA: {{.+}} = alloca i32*,
+ // LAMBDA: alloca i32,
+ // LAMBDA: alloca i32,
+ // LAMBDA: alloca i32,
+ // LAMBDA: alloca i32,
+ // LAMBDA: alloca i32,
+ // LAMBDA: alloca i32,
+ // LAMBDA: [[G_PRIV:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[G1_PRIV:%.+]] = alloca i{{[0-9]+}}
+ // LAMBDA: [[TMP:%.+]] = alloca i{{[0-9]+}}*,
+ // LAMBDA: [[SIVAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: store{{.+}} [[G1_PRIV]], {{.+}} [[TMP]],
+
+ g = 1;
+ g1 = 1;
+ sivar = 2;
+ // LAMBDA: call void @__kmpc_for_static_init_4(
+ // LAMBDA: call void {{.+}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[LPAR_OUTL:.+]] to
+ // LAMBDA: call void @__kmpc_for_static_fini(
+ // LAMBDA: ret void
+
+ // LAMBDA: define internal void @[[LPAR_OUTL]]({{.+}})
+ // Skip global, bound tid and loop vars
+ // LAMBDA: {{.+}} = alloca i32*,
+ // LAMBDA: {{.+}} = alloca i32*,
+ // LAMBDA: alloca i{{[0-9]+}},
+ // LAMBDA: alloca i{{[0-9]+}},
+ // LAMBDA: alloca i32,
+ // LAMBDA: alloca i32,
+ // LAMBDA: alloca i32,
+ // LAMBDA: alloca i32,
+ // LAMBDA: alloca i32,
+ // LAMBDA: alloca i32,
+ // LAMBDA: [[G_PRIV:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[G1_PRIV:%.+]] = alloca i{{[0-9]+}}
+ // LAMBDA: [[TMP:%.+]] = alloca i{{[0-9]+}}*,
+ // LAMBDA: [[SIVAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: store{{.+}} [[G1_PRIV]], {{.+}} [[TMP]],
+ // LAMBDA-DAG: store{{.+}} 1, {{.+}} [[G_PRIV]],
+ // LAMBDA-DAG: store{{.+}} 2, {{.+}} [[SIVAR_PRIV]],
+ // LAMBDA-DAG: [[G1_REF:%.+]] = load{{.+}}, {{.+}} [[TMP]],
+ // LAMBDA-DAG: store{{.+}} 1, {{.+}} [[G1_REF]],
+ // LAMBDA: call void [[INNER_LAMBDA:@.+]](
+ // LAMBDA: call void @__kmpc_for_static_fini(
+ // LAMBDA: ret void
+ [&]() {
+ // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]])
+ // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]],
+ g = 2;
+ g1 = 2;
+ sivar = 4;
+ // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]]
+
+ // LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // LAMBDA: [[G_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G_PTR_REF]]
+ // LAMBDA: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[G_REF]]
+ // LAMBDA: [[G1_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // LAMBDA: [[G1_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G1_PTR_REF]]
+ // LAMBDA: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[G1_REF]]
+ // LAMBDA: [[SIVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+ // LAMBDA: [[SIVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SIVAR_PTR_REF]]
+ // LAMBDA: store i{{[0-9]+}} 4, i{{[0-9]+}}* [[SIVAR_REF]]
+ }();
+ }
+ }();
+ return 0;
+#else
+#pragma omp target
+#pragma omp teams distribute parallel for private(t_var, vec, s_arr, var, sivar)
+ for (int i = 0; i < 2; ++i) {
+ vec[i] = t_var;
+ s_arr[i] = var;
+ sivar += i;
+ }
+ return tmain<int>();
+#endif
+}
+
+// CHECK: define {{.*}}i{{[0-9]+}} @main()
+// CHECK: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 0, i8** null, i8** null, i{{64|32}}* null, i64* null, i32 0, i32 0)
+// CHECK: call void @[[OFFL1:.+]]()
+// CHECK: {{%.+}} = call{{.*}} i32 @[[TMAIN_INT:.+]]()
+// CHECK: ret
+
+// CHECK: define{{.*}} void @[[OFFL1]]()
+// CHECK: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 0, {{.+}} @[[OUTL1:.+]] to {{.+}})
+// CHECK: ret void
+
+// CHECK: define internal void @[[OUTL1]]({{.+}})
+// Skip global, bound tid and loop vars
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: {{.+}} = alloca i32,
+// CHECK: {{.+}} = alloca i32,
+// CHECK: {{.+}} = alloca i32,
+// CHECK: {{.+}} = alloca i32,
+// CHECK: {{.+}} = alloca i32,
+// CHECK-DAG: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK-DAG: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK-DAG: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]],
+// CHECK-DAG: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]],
+// CHECK-DAG: [[SIVAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: alloca i32,
+
+// private(s_arr)
+// CHECK-DAG: [[S_ARR_PRIV_BGN:%.+]] = getelementptr{{.*}} [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[S_ARR_PRIV]],
+// CHECK-DAG: [[S_ARR_PTR_ALLOC:%.+]] = phi{{.+}} [ [[S_ARR_PRIV_BGN]], {{.+}} ], [ [[S_ARR_NEXT:%.+]], {{.+}} ]
+// CHECK-DAG: call void @{{.+}}({{.+}} [[S_ARR_PTR_ALLOC]])
+// CHECK-DAG: [[S_ARR_NEXT]] = getelementptr {{.+}} [[S_ARR_PTR_ALLOC]],
+
+// private(var)
+// CHECK-DAG: call void @{{.+}}({{.+}} [[VAR_PRIV]])
+
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: call void {{.+}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[PAR_OUTL1:.+]] to
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: ret void
+
+// CHECK: define internal void @[[PAR_OUTL1]]({{.+}})
+// Skip global, bound tid and loop vars
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i32,
+// CHECK: {{.+}} = alloca i32,
+// CHECK: {{.+}} = alloca i32,
+// CHECK: {{.+}} = alloca i32,
+// CHECK: {{.+}} = alloca i32,
+// CHECK: {{.+}} = alloca i32,
+// CHECK-DAG: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK-DAG: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK-DAG: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]],
+// CHECK-DAG: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]],
+// CHECK-DAG: [[SIVAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: alloca i32,
+
+// private(s_arr)
+// CHECK-DAG: [[S_ARR_PRIV_BGN:%.+]] = getelementptr{{.*}} [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[S_ARR_PRIV]],
+// CHECK-DAG: [[S_ARR_PTR_ALLOC:%.+]] = phi{{.+}} [ [[S_ARR_PRIV_BGN]], {{.+}} ], [ [[S_ARR_NEXT:%.+]], {{.+}} ]
+// CHECK-DAG: call void @{{.+}}({{.+}} [[S_ARR_PTR_ALLOC]])
+// CHECK-DAG: [[S_ARR_NEXT]] = getelementptr {{.+}} [[S_ARR_PTR_ALLOC]],
+
+// private(var)
+// CHECK-DAG: call void @{{.+}}({{.+}} [[VAR_PRIV]])
+
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK-DAG: {{.+}} = {{.+}} [[T_VAR_PRIV]]
+// CHECK-DAG: {{.+}} = {{.+}} [[VEC_PRIV]]
+// CHECK-DAG: {{.+}} = {{.+}} [[S_ARR_PRIV]]
+// CHECK-DAG: {{.+}} = {{.+}} [[VAR_PRIV]]
+// CHECK-DAG: {{.+}} = {{.+}} [[SIVAR_PRIV]]
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: ret void
+
+// CHECK: define{{.*}} i{{[0-9]+}} @[[TMAIN_INT]]()
+// CHECK: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 0,
+// CHECK: call void @[[TOFFL1:.+]]()
+// CHECK: ret
+
+// CHECK: define {{.*}}void @[[TOFFL1]]()
+// CHECK: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 0, {{.+}} @[[TOUTL1:.+]] to {{.+}})
+// CHECK: ret void
+
+// CHECK: define internal void @[[TOUTL1]]({{.+}})
+// Skip global, bound tid and loop vars
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i32,
+// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_INT_TY]]],
+// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_INT_TY]],
+// CHECK: [[TMP:%.+]] = alloca [[S_INT_TY]]*,
+
+// private(s_arr)
+// CHECK-DAG: [[S_ARR_PRIV_BGN:%.+]] = getelementptr{{.*}} [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[S_ARR_PRIV]],
+// CHECK-DAG: [[S_ARR_PTR_ALLOC:%.+]] = phi{{.+}} [ [[S_ARR_PRIV_BGN]], {{.+}} ], [ [[S_ARR_NEXT:%.+]], {{.+}} ]
+// CHECK-DAG: call void @{{.+}}({{.+}} [[S_ARR_PTR_ALLOC]])
+// CHECK-DAG: [[S_ARR_NEXT]] = getelementptr {{.+}} [[S_ARR_PTR_ALLOC]],
+
+// CHECK-DAG: [[S_ARR_PRIV_BGN:%.+]] = getelementptr{{.*}} [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[S_ARR_PRIV]],
+// CHECK-DAG: [[S_ARR_PTR_ALLOC:%.+]] = phi{{.+}} [ [[S_ARR_PRIV_BGN]], {{.+}} ], [ [[S_ARR_NEXT:%.+]], {{.+}} ]
+// CHECK-DAG: call void @{{.+}}({{.+}} [[S_ARR_PTR_ALLOC]])
+// CHECK-DAG: [[S_ARR_NEXT]] = getelementptr {{.+}} [[S_ARR_PTR_ALLOC]],
+
+// private(var)
+// CHECK-DAG: call void @{{.+}}({{.+}} [[VAR_PRIV]])
+// CHECK-DAG: store{{.+}} [[VAR_PRIV]], {{.+}} [[TMP]]
+
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: call void {{.+}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[TPAR_OUTL1:.+]] to
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: ret void
+
+// CHECK: define internal void @[[TPAR_OUTL1]]({{.+}})
+// Skip global, bound tid and loop vars
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: {{.+}} = alloca i32*,
+// prev lb and ub
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// iter variables
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i32,
+// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_INT_TY]]],
+// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_INT_TY]],
+// CHECK: [[TMP:%.+]] = alloca [[S_INT_TY]]*,
+
+// private(s_arr)
+// CHECK-DAG: [[S_ARR_PRIV_BGN:%.+]] = getelementptr{{.*}} [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[S_ARR_PRIV]],
+// CHECK-DAG: [[S_ARR_PTR_ALLOC:%.+]] = phi{{.+}} [ [[S_ARR_PRIV_BGN]], {{.+}} ], [ [[S_ARR_NEXT:%.+]], {{.+}} ]
+// CHECK-DAG: call void @{{.+}}({{.+}} [[S_ARR_PTR_ALLOC]])
+// CHECK-DAG: [[S_ARR_NEXT]] = getelementptr {{.+}} [[S_ARR_PTR_ALLOC]],
+
+// CHECK-DAG: [[S_ARR_PRIV_BGN:%.+]] = getelementptr{{.*}} [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[S_ARR_PRIV]],
+// CHECK-DAG: [[S_ARR_PTR_ALLOC:%.+]] = phi{{.+}} [ [[S_ARR_PRIV_BGN]], {{.+}} ], [ [[S_ARR_NEXT:%.+]], {{.+}} ]
+// CHECK-DAG: call void @{{.+}}({{.+}} [[S_ARR_PTR_ALLOC]])
+// CHECK-DAG: [[S_ARR_NEXT]] = getelementptr {{.+}} [[S_ARR_PTR_ALLOC]],
+
+// private(var)
+// CHECK-DAG: call void @{{.+}}({{.+}} [[VAR_PRIV]])
+// CHECK-DAG: store{{.+}} [[VAR_PRIV]], {{.+}} [[TMP]]
+
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK-DAG: {{.+}} = {{.+}} [[T_VAR_PRIV]]
+// CHECK-DAG: {{.+}} = {{.+}} [[VEC_PRIV]]
+// CHECK-DAG: {{.+}} = {{.+}} [[S_ARR_PRIV]]
+// CHECK-DAG: {{.+}} = {{.+}} [[TMP]]
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: ret void
+
+
+#endif
diff --git a/test/OpenMP/teams_distribute_parallel_for_proc_bind_codegen.cpp b/test/OpenMP/teams_distribute_parallel_for_proc_bind_codegen.cpp
new file mode 100644
index 000000000000..71e92bd5a555
--- /dev/null
+++ b/test/OpenMP/teams_distribute_parallel_for_proc_bind_codegen.cpp
@@ -0,0 +1,90 @@
+// add -fopenmp-targets
+
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+typedef __INTPTR_TYPE__ intptr_t;
+
+// CHECK-DAG: [[IDENT_T_TY:%.+]] = type { i32, i32, i32, i32, i8* }
+// CHECK-DAG: [[STR:@.+]] = private unnamed_addr constant [23 x i8] c";unknown;unknown;0;0;;\00"
+// CHECK-DAG: [[DEF_LOC_2:@.+]] = private unnamed_addr constant [[IDENT_T_TY]] { i32 0, i32 2, i32 0, i32 0, i8* getelementptr inbounds ([23 x i8], [23 x i8]* [[STR]], i32 0, i32 0) }
+
+void foo();
+
+struct S {
+ intptr_t a, b, c;
+ S(intptr_t a) : a(a) {}
+ operator char() { return a; }
+ ~S() {}
+};
+
+template <typename T>
+T tmain() {
+#pragma omp target
+#pragma omp teams distribute parallel for proc_bind(master)
+ for(int i = 0; i < 1000; i++) {}
+ return T();
+}
+
+int main() {
+ // CHECK-LABEL: @main
+#pragma omp target
+#pragma omp teams distribute parallel for proc_bind(spread)
+ for(int i = 0; i < 1000; i++) {}
+#pragma omp target
+#pragma omp teams distribute parallel for proc_bind(close)
+ for(int i = 0; i < 1000; i++) {}
+ return tmain<int>();
+}
+
+// CHECK: call {{.*}}@__tgt_target_teams({{.+}})
+// CHECK: call void [[OFFL1:@.+]]()
+// CHECK: call {{.*}}@__tgt_target_teams({{.+}})
+// CHECK: call void [[OFFL2:@.+]]()
+// CHECK: [[CALL_RET:%.+]] = call{{.+}} i32 [[TMAIN:@.+]]()
+// CHECK: ret i32 [[CALL_RET]]
+
+// CHECK: define{{.+}} void [[OFFL1]](
+// CHECK: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, {{.+}}, {{.+}}* [[OMP_OUTLINED_1:@.+]] to {{.+}})
+
+// CHECK: define{{.+}} [[OMP_OUTLINED_1]](i32* {{.+}} [[GTID_IN:%.+]],
+// CHECK: [[GTID_ADDR:%.+]] = alloca i32*,
+// CHECK: store i32* [[GTID_IN]], i32** [[GTID_ADDR]],
+// CHECK: [[GTID_REF:%.+]] = load i32*, i32** [[GTID_ADDR]],
+// CHECK: [[GTID_VAL:%.+]] = load i32, i32* [[GTID_REF]],
+// CHECK: call {{.*}}void @__kmpc_push_proc_bind([[IDENT_T_TY]]* [[DEF_LOC_2]], i32 [[GTID_VAL]], i32 4)
+// CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(
+// CHECK: ret void
+
+// CHECK: define{{.+}} [[OFFL2]]()
+// CHECK: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, {{.+}}, {{.+}}* [[OMP_OUTLINED_1:@.+]] to {{.+}})
+
+// CHECK: define{{.+}} [[OMP_OUTLINED_1]](i32* {{.+}} [[GTID_IN:%.+]],
+// CHECK: [[GTID_ADDR:%.+]] = alloca i32*,
+// CHECK: store i32* [[GTID_IN]], i32** [[GTID_ADDR]],
+// CHECK: [[GTID_REF:%.+]] = load i32*, i32** [[GTID_ADDR]],
+// CHECK: [[GTID_VAL:%.+]] = load i32, i32* [[GTID_REF]],
+// CHECK: call {{.*}}void @__kmpc_push_proc_bind([[IDENT_T_TY]]* [[DEF_LOC_2]], i32 [[GTID_VAL]], i32 3)
+// CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(
+// CHECK: ret void
+
+// CHECK: define{{.+}} [[TMAIN]]()
+// CHECK: call {{.*}}@__tgt_target_teams({{.+}})
+// CHECK: call void [[OFFL3:@.+]]()
+
+// CHECK: define{{.+}} [[OFFL3]]()
+// CHECK: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, {{.+}}, {{.+}}* [[OMP_OUTLINED_3:@.+]] to {{.+}})
+
+// CHECK: define{{.+}} [[OMP_OUTLINED_3]](i32* {{.+}} [[GTID_IN:%.+]],
+// CHECK: [[GTID_ADDR:%.+]] = alloca i32*,
+// CHECK: store i32* [[GTID_IN]], i32** [[GTID_ADDR]],
+// CHECK: [[GTID_REF:%.+]] = load i32*, i32** [[GTID_ADDR]],
+// CHECK: [[GTID_VAL:%.+]] = load i32, i32* [[GTID_REF]],
+// CHECK: call {{.*}}void @__kmpc_push_proc_bind([[IDENT_T_TY]]* [[DEF_LOC_2]], i32 [[GTID_VAL]], i32 2)
+// CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(
+// CHECK: ret void
+#endif
diff --git a/test/OpenMP/teams_distribute_parallel_for_reduction_codegen.cpp b/test/OpenMP/teams_distribute_parallel_for_reduction_codegen.cpp
new file mode 100644
index 000000000000..55ccfff99a3c
--- /dev/null
+++ b/test/OpenMP/teams_distribute_parallel_for_reduction_codegen.cpp
@@ -0,0 +1,345 @@
+// RUN: %clang_cc1 -DCHECK -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -DCHECK -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+
+// RUN: %clang_cc1 -DLAMBDA -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+template <typename T>
+T tmain() {
+ T t_var = T();
+ T vec[] = {1, 2};
+#pragma omp target
+#pragma omp teams distribute parallel for reduction(+: t_var)
+ for (int i = 0; i < 2; ++i) {
+ t_var += (T) i;
+ }
+ return T();
+}
+
+int main() {
+ static int sivar;
+#ifdef LAMBDA
+ // LAMBDA: [[RED_VAR:@.+]] = common global [8 x {{.+}}] zeroinitializer
+
+ // LAMBDA-LABEL: @main
+ // LAMBDA: call void [[OUTER_LAMBDA:@.+]](
+ [&]() {
+ // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
+ // LAMBDA: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 1, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 0)
+ // LAMBDA: call void @[[LOFFL1:.+]](
+ // LAMBDA: ret
+#pragma omp target
+#pragma omp teams distribute parallel for reduction(+: sivar)
+ for (int i = 0; i < 2; ++i) {
+ // LAMBDA: define{{.*}} internal{{.*}} void @[[LOFFL1]](i{{64|32}} [[SIVAR_ARG:%.+]])
+ // LAMBDA: [[SIVAR_ADDR:%.+]] = alloca i{{.+}},
+ // LAMBDA: store{{.+}} [[SIVAR_ARG]], {{.+}} [[SIVAR_ADDR]],
+ // LAMBDA: [[SIVAR_CONV:%.+]] = bitcast{{.+}} [[SIVAR_ADDR]] to
+ // LAMBDA: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[LOUTL1:.+]] to {{.+}}, {{.+}} [[SIVAR_CONV]])
+ // LAMBDA: ret void
+
+ // LAMBDA: define internal void @[[LOUTL1]]({{.+}}, {{.+}}, {{.+}} [[SIVAR_ARG:%.+]])
+ // Skip global and bound tid vars
+ // LAMBDA: {{.+}} = alloca i32*,
+ // LAMBDA: {{.+}} = alloca i32*,
+ // LAMBDA: [[SIVAR_ADDR:%.+]] = alloca i{{.+}}*,
+ // LAMBDA: [[SIVAR_PRIV:%.+]] = alloca i{{.+}},
+ // LAMBDA: [[RED_LIST:%.+]] = alloca [1 x {{.+}}],
+ // LAMBDA: store{{.+}} [[SIVAR_ARG]], {{.+}} [[SIVAR_ADDR]],
+ // LAMBDA: [[SIVAR_REF:%.+]] = load{{.+}}, {{.+}} [[SIVAR_ADDR]]
+ // LAMBDA: store{{.+}} 0, {{.+}} [[SIVAR_PRIV]],
+
+ // LAMBDA: call void @__kmpc_for_static_init_4(
+ // LAMBDA: call void {{.*}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[LPAR_OUTL:.+]] to
+ // LAMBDA: call void @__kmpc_for_static_fini(
+ // LAMBDA: [[RED_LIST_GEP:%.+]] = getelementptr{{.+}} [[RED_LIST]],
+ // LAMBDA: [[SIVAR_PRIV_CAST:%.+]] = bitcast{{.+}} [[SIVAR_PRIV]] to
+ // LAMBDA: store{{.+}} [[SIVAR_PRIV_CAST]], {{.+}} [[RED_LIST_GEP]],
+ // LAMBDA: [[RED_LIST_BCAST:%.+]] = bitcast{{.+}} [[RED_LIST]] to
+ // LAMBDA: [[K_RED_RET:%.+]] = call{{.+}} @__kmpc_reduce_nowait({{.+}}, {{.+}}, {{.+}}, {{.+}}, {{.+}} [[RED_LIST_BCAST]], {{.+}} [[RED_FUN:@.+]], {{.+}} [[RED_VAR]])
+ // LAMBDA: switch{{.+}} [[K_RED_RET]], label{{.+}} [
+ // LAMBDA: {{.+}}, label %[[CASE1:.+]]
+ // LAMBDA: {{.+}}, label %[[CASE2:.+]]
+ // LAMBDA: ]
+ // LAMBDA: [[CASE1]]:
+ // LAMBDA-DAG: [[SIVAR_VAL:%.+]] = load{{.+}}, {{.+}} [[SIVAR_REF]],
+ // LAMBDA-DAG: [[SIVAR_PRIV_VAL:%.+]] = load{{.+}}, {{.+}} [[SIVAR_PRIV]],
+ // LAMBDA-DAG: [[SIVAR_INC:%.+]] = add{{.+}} [[SIVAR_VAL]], [[SIVAR_PRIV_VAL]]
+ // LAMBDA: store{{.+}} [[SIVAR_INC]], {{.+}} [[SIVAR_REF]],
+ // LAMBDA: call void @__kmpc_end_reduce_nowait({{.+}}, {{.+}}, {{.+}} [[RED_VAR]])
+ // LAMBDA: br
+ // LAMBDA: [[CASE2]]:
+ // LAMBDA-DAG: [[SIVAR_PRIV_VAL:%.+]] = load{{.+}}, {{.+}} [[SIVAR_PRIV]],
+ // LAMBDA-DAG: [[ATOMIC_RES:%.+]] = atomicrmw add{{.+}} [[SIVAR_REF]], {{.+}} [[SIVAR_PRIV_VAL]]
+ // LAMBDA: br
+
+ // LAMBDA: define internal void @[[LPAR_OUTL]]({{.+}}, {{.+}}, {{.+}}, {{.+}}, {{.+}} [[SIVAR_ARG:%.+]])
+
+ // Skip global and bound tid vars, and prev lb and ub vars
+ // LAMBDA: {{.+}} = alloca i32*,
+ // LAMBDA: {{.+}} = alloca i32*,
+ // LAMBDA: alloca i{{[0-9]+}},
+ // LAMBDA: alloca i{{[0-9]+}},
+ // LAMBDA: [[SIVAR_ADDR:%.+]] = alloca i{{.+}}*,
+ // skip loop vars
+ // LAMBDA: alloca i32,
+ // LAMBDA: alloca i32,
+ // LAMBDA: alloca i32,
+ // LAMBDA: alloca i32,
+ // LAMBDA: alloca i32,
+ // LAMBDA: alloca i32,
+ // LAMBDA: [[SIVAR_PRIV:%.+]] = alloca i{{.+}},
+ // LAMBDA: [[RED_LIST:%.+]] = alloca [1 x {{.+}}],
+ // LAMBDA: store{{.+}} [[SIVAR_ARG]], {{.+}} [[SIVAR_ADDR]],
+ // LAMBDA: [[SIVAR_REF:%.+]] = load{{.+}}, {{.+}} [[SIVAR_ADDR]]
+ // LAMBDA: store{{.+}} 0, {{.+}} [[SIVAR_PRIV]],
+
+ // LAMBDA: call void @__kmpc_for_static_init_4(
+ // LAMBDA: store{{.+}}, {{.+}} [[SIVAR_PRIV]],
+ // LAMBDA: call void [[INNER_LAMBDA:@.+]](
+ // LAMBDA: call void @__kmpc_for_static_fini(
+ // LAMBDA: [[RED_LIST_GEP:%.+]] = getelementptr{{.+}} [[RED_LIST]],
+ // LAMBDA: [[SIVAR_PRIV_CAST:%.+]] = bitcast{{.+}} [[SIVAR_PRIV]] to
+ // LAMBDA: store{{.+}} [[SIVAR_PRIV_CAST]], {{.+}} [[RED_LIST_GEP]],
+ // LAMBDA: [[RED_LIST_BCAST:%.+]] = bitcast{{.+}} [[RED_LIST]] to
+ // LAMBDA: [[K_RED_RET:%.+]] = call{{.+}} @__kmpc_reduce_nowait({{.+}}, {{.+}}, {{.+}}, {{.+}}, {{.+}} [[RED_LIST_BCAST]], {{.+}} [[RED_FUN:@.+]], {{.+}} [[RED_VAR]])
+ // LAMBDA: switch{{.+}} [[K_RED_RET]], label{{.+}} [
+ // LAMBDA: {{.+}}, label %[[CASE1:.+]]
+ // LAMBDA: {{.+}}, label %[[CASE2:.+]]
+ // LAMBDA: ]
+ // LAMBDA: [[CASE1]]:
+ // LAMBDA-DAG: [[SIVAR_VAL:%.+]] = load{{.+}}, {{.+}} [[SIVAR_REF]],
+ // LAMBDA-DAG: [[SIVAR_PRIV_VAL:%.+]] = load{{.+}}, {{.+}} [[SIVAR_PRIV]],
+ // LAMBDA-DAG: [[SIVAR_INC:%.+]] = add{{.+}} [[SIVAR_VAL]], [[SIVAR_PRIV_VAL]]
+ // LAMBDA: store{{.+}} [[SIVAR_INC]], {{.+}} [[SIVAR_REF]],
+ // LAMBDA: call void @__kmpc_end_reduce_nowait({{.+}}, {{.+}}, {{.+}} [[RED_VAR]])
+ // LAMBDA: br
+ // LAMBDA: [[CASE2]]:
+ // LAMBDA-DAG: [[SIVAR_PRIV_VAL:%.+]] = load{{.+}}, {{.+}} [[SIVAR_PRIV]],
+ // LAMBDA-DAG: [[ATOMIC_RES:%.+]] = atomicrmw add{{.+}} [[SIVAR_REF]], {{.+}} [[SIVAR_PRIV_VAL]]
+ // LAMBDA: br
+
+ sivar += i;
+
+ [&]() {
+ // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]])
+ // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]],
+
+ sivar += 4;
+ // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]]
+
+ // LAMBDA: [[SIVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // LAMBDA: [[SIVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SIVAR_PTR_REF]]
+ // LAMBDA: [[SIVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR_REF]]
+ // LAMBDA: [[SIVAR_INC:%.+]] = add{{.+}} [[SIVAR_VAL]], 4
+ // LAMBDA: store i{{[0-9]+}} [[SIVAR_INC]], i{{[0-9]+}}* [[SIVAR_REF]]
+ }();
+ }
+ }();
+ return 0;
+#else
+#pragma omp target
+#pragma omp teams distribute parallel for reduction(+: sivar)
+ for (int i = 0; i < 2; ++i) {
+ sivar += i;
+ }
+ return tmain<int>();
+#endif
+}
+
+// CHECK: [[RED_VAR:@.+]] = common global [8 x {{.+}}] zeroinitializer
+
+// CHECK: define {{.*}}i{{[0-9]+}} @main()
+// CHECK: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 1, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 0)
+// CHECK: call void @[[OFFL1:.+]](i{{64|32}} %{{.+}})
+// CHECK: {{%.+}} = call{{.*}} i32 @[[TMAIN_INT:.+]]()
+// CHECK: ret
+
+// CHECK: define{{.*}} void @[[OFFL1]](i{{64|32}} [[SIVAR_ARG:%.+]])
+// CHECK: [[SIVAR_ADDR:%.+]] = alloca i{{.+}},
+// CHECK: store{{.+}} [[SIVAR_ARG]], {{.+}} [[SIVAR_ADDR]],
+// CHECK-64: [[SIVAR_CONV:%.+]] = bitcast{{.+}} [[SIVAR_ADDR]] to
+// CHECK-64: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTL1:.+]] to {{.+}}, {{.+}} [[SIVAR_CONV]])
+// CHECK-32: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTL1:.+]] to {{.+}}, {{.+}} [[SIVAR_ADDR]])
+// CHECK: ret void
+
+// CHECK: define internal void @[[OUTL1]]({{.+}}, {{.+}}, {{.+}} [[SIVAR_ARG:%.+]])
+// Skip global and bound tid vars
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: [[SIVAR_ADDR:%.+]] = alloca i{{.+}}*,
+// CHECK: [[SIVAR_PRIV:%.+]] = alloca i{{.+}},
+// CHECK: [[RED_LIST:%.+]] = alloca [1 x {{.+}}],
+// CHECK: store{{.+}} [[SIVAR_ARG]], {{.+}} [[SIVAR_ADDR]],
+// CHECK: [[SIVAR_REF:%.+]] = load{{.+}}, {{.+}} [[SIVAR_ADDR]]
+// CHECK: store{{.+}} 0, {{.+}} [[SIVAR_PRIV]],
+
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: call void {{.*}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[PAR_OUTL:.+]] to
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: [[RED_LIST_GEP:%.+]] = getelementptr{{.+}} [[RED_LIST]],
+// CHECK: [[SIVAR_PRIV_CAST:%.+]] = bitcast{{.+}} [[SIVAR_PRIV]] to
+// CHECK: store{{.+}} [[SIVAR_PRIV_CAST]], {{.+}} [[RED_LIST_GEP]],
+// CHECK: [[RED_LIST_BCAST:%.+]] = bitcast{{.+}} [[RED_LIST]] to
+// CHECK: [[K_RED_RET:%.+]] = call{{.+}} @__kmpc_reduce_nowait({{.+}}, {{.+}}, {{.+}}, {{.+}}, {{.+}} [[RED_LIST_BCAST]], {{.+}} [[RED_FUN:@.+]], {{.+}} [[RED_VAR]])
+// CHECK: switch{{.+}} [[K_RED_RET]], label{{.+}} [
+// CHECK: {{.+}}, label %[[CASE1:.+]]
+// CHECK: {{.+}}, label %[[CASE2:.+]]
+// CHECK: ]
+// CHECK: [[CASE1]]:
+// CHECK-DAG: [[SIVAR_VAL:%.+]] = load{{.+}}, {{.+}} [[SIVAR_REF]],
+// CHECK-DAG: [[SIVAR_PRIV_VAL:%.+]] = load{{.+}}, {{.+}} [[SIVAR_PRIV]],
+// CHECK-DAG: [[SIVAR_INC:%.+]] = add{{.+}} [[SIVAR_VAL]], [[SIVAR_PRIV_VAL]]
+// CHECK: store{{.+}} [[SIVAR_INC]], {{.+}} [[SIVAR_REF]],
+// CHECK: call void @__kmpc_end_reduce_nowait({{.+}}, {{.+}}, {{.+}} [[RED_VAR]])
+// CHECK: br
+// CHECK: [[CASE2]]:
+// CHECK-DAG: [[SIVAR_PRIV_VAL:%.+]] = load{{.+}}, {{.+}} [[SIVAR_PRIV]],
+// CHECK-DAG: [[ATOMIC_RES:%.+]] = atomicrmw add{{.+}} [[SIVAR_REF]], {{.+}} [[SIVAR_PRIV_VAL]]
+// CHECK: br
+
+// CHECK: define internal void @[[PAR_OUTL]]({{.+}}, {{.+}}, {{.+}}, {{.+}}, {{.+}} [[SIVAR_ARG:%.+]])
+// Skip global and bound tid vars, and prev lb and ub
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: [[SIVAR_ADDR:%.+]] = alloca i{{.+}}*,
+// skip loop vars
+// CHECK: alloca i32,
+// CHECK: alloca i32,
+// CHECK: alloca i32,
+// CHECK: alloca i32,
+// CHECK: alloca i32,
+// CHECK: alloca i32,
+// CHECK: [[SIVAR_PRIV:%.+]] = alloca i{{.+}},
+// CHECK: [[RED_LIST:%.+]] = alloca [1 x {{.+}}],
+// CHECK: store{{.+}} [[SIVAR_ARG]], {{.+}} [[SIVAR_ADDR]],
+// CHECK: [[SIVAR_REF:%.+]] = load{{.+}}, {{.+}} [[SIVAR_ADDR]]
+// CHECK: store{{.+}} 0, {{.+}} [[SIVAR_PRIV]],
+
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: store{{.+}}, {{.+}} [[SIVAR_PRIV]],
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: [[RED_LIST_GEP:%.+]] = getelementptr{{.+}} [[RED_LIST]],
+// CHECK: [[SIVAR_PRIV_CAST:%.+]] = bitcast{{.+}} [[SIVAR_PRIV]] to
+// CHECK: store{{.+}} [[SIVAR_PRIV_CAST]], {{.+}} [[RED_LIST_GEP]],
+// CHECK: [[RED_LIST_BCAST:%.+]] = bitcast{{.+}} [[RED_LIST]] to
+// CHECK: [[K_RED_RET:%.+]] = call{{.+}} @__kmpc_reduce_nowait({{.+}}, {{.+}}, {{.+}}, {{.+}}, {{.+}} [[RED_LIST_BCAST]], {{.+}} [[RED_FUN:@.+]], {{.+}} [[RED_VAR]])
+// CHECK: switch{{.+}} [[K_RED_RET]], label{{.+}} [
+// CHECK: {{.+}}, label %[[CASE1:.+]]
+// CHECK: {{.+}}, label %[[CASE2:.+]]
+// CHECK: ]
+// CHECK: [[CASE1]]:
+// CHECK-DAG: [[SIVAR_VAL:%.+]] = load{{.+}}, {{.+}} [[SIVAR_REF]],
+// CHECK-DAG: [[SIVAR_PRIV_VAL:%.+]] = load{{.+}}, {{.+}} [[SIVAR_PRIV]],
+// CHECK-DAG: [[SIVAR_INC:%.+]] = add{{.+}} [[SIVAR_VAL]], [[SIVAR_PRIV_VAL]]
+// CHECK: store{{.+}} [[SIVAR_INC]], {{.+}} [[SIVAR_REF]],
+// CHECK: call void @__kmpc_end_reduce_nowait({{.+}}, {{.+}}, {{.+}} [[RED_VAR]])
+// CHECK: br
+// CHECK: [[CASE2]]:
+// CHECK-DAG: [[SIVAR_PRIV_VAL:%.+]] = load{{.+}}, {{.+}} [[SIVAR_PRIV]],
+// CHECK-DAG: [[ATOMIC_RES:%.+]] = atomicrmw add{{.+}} [[SIVAR_REF]], {{.+}} [[SIVAR_PRIV_VAL]]
+// CHECK: br
+
+// CHECK: define{{.*}} i{{[0-9]+}} @[[TMAIN_INT]]()
+// CHECK: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 1,
+// CHECK: call void @[[TOFFL1:.+]]({{.+}})
+// CHECK: ret
+
+// CHECK: define{{.*}} void @[[TOFFL1]](i{{64|32}} [[TVAR_ARG:%.+]])
+// CHECK: [[TVAR_ADDR:%.+]] = alloca i{{.+}},
+// CHECK: store{{.+}} [[TVAR_ARG]], {{.+}} [[TVAR_ADDR]],
+// CHECK-64: [[TVAR_CONV:%.+]] = bitcast{{.+}} [[TVAR_ADDR]] to
+// CHECK-64: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[TOUTL1:.+]] to {{.+}}, {{.+}} [[TVAR_CONV]])
+// CHECK-32: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[TOUTL1:.+]] to {{.+}}, {{.+}} [[TVAR_ADDR]])
+// CHECK: ret void
+
+// CHECK: define internal void @[[TOUTL1]]({{.+}}, {{.+}}, {{.+}} [[TVAR_ARG:%.+]])
+// Skip global and bound tid vars
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: [[TVAR_ADDR:%.+]] = alloca i{{.+}}*,
+// CHECK: [[TVAR_PRIV:%.+]] = alloca i{{.+}},
+// CHECK: [[RED_LIST:%.+]] = alloca [1 x {{.+}}],
+// CHECK: store{{.+}} [[TVAR_ARG]], {{.+}} [[TVAR_ADDR]],
+// CHECK: [[TVAR_REF:%.+]] = load{{.+}}, {{.+}} [[TVAR_ADDR]]
+// CHECK: store{{.+}} 0, {{.+}} [[TVAR_PRIV]],
+
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: call void {{.*}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[TPAR_OUTL:.+]] to
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: [[RED_LIST_GEP:%.+]] = getelementptr{{.+}} [[RED_LIST]],
+// CHECK: [[TVAR_PRIV_CAST:%.+]] = bitcast{{.+}} [[TVAR_PRIV]] to
+// CHECK: store{{.+}} [[TVAR_PRIV_CAST]], {{.+}} [[RED_LIST_GEP]],
+// CHECK: [[RED_LIST_BCAST:%.+]] = bitcast{{.+}} [[RED_LIST]] to
+// CHECK: [[K_RED_RET:%.+]] = call{{.+}} @__kmpc_reduce_nowait({{.+}}, {{.+}}, {{.+}}, {{.+}}, {{.+}} [[RED_LIST_BCAST]], {{.+}} [[RED_FUN:@.+]], {{.+}} [[RED_VAR]])
+// CHECK: switch{{.+}} [[K_RED_RET]], label{{.+}} [
+// CHECK: {{.+}}, label %[[CASE1:.+]]
+// CHECK: {{.+}}, label %[[CASE2:.+]]
+// CHECK: ]
+// CHECK: [[CASE1]]:
+// CHECK-DAG: [[TVAR_VAL:%.+]] = load{{.+}}, {{.+}} [[TVAR_REF]],
+// CHECK-DAG: [[TVAR_PRIV_VAL:%.+]] = load{{.+}}, {{.+}} [[TVAR_PRIV]],
+// CHECK-DAG: [[TVAR_INC:%.+]] = add{{.+}} [[TVAR_VAL]], [[TVAR_PRIV_VAL]]
+// CHECK: store{{.+}} [[TVAR_INC]], {{.+}} [[TVAR_REF]],
+// CHECK: call void @__kmpc_end_reduce_nowait({{.+}}, {{.+}}, {{.+}} [[RED_VAR]])
+// CHECK: br
+// CHECK: [[CASE2]]:
+// CHECK-DAG: [[TVAR_PRIV_VAL:%.+]] = load{{.+}}, {{.+}} [[TVAR_PRIV]],
+// CHECK-DAG: [[ATOMIC_RES:%.+]] = atomicrmw add{{.+}} [[TVAR_REF]], {{.+}} [[TVAR_PRIV_VAL]]
+// CHECK: br
+
+// CHECK: define internal void @[[TPAR_OUTL]]({{.+}}, {{.+}}, {{.+}}, {{.+}}, {{.+}} [[TVAR_ARG:%.+]])
+// Skip global and bound tid vars, and prev lb and ub vars
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: [[TVAR_ADDR:%.+]] = alloca i{{.+}}*,
+// skip loop vars
+// CHECK: alloca i32,
+// CHECK: alloca i32,
+// CHECK: alloca i32,
+// CHECK: alloca i32,
+// CHECK: alloca i32,
+// CHECK: alloca i32,
+// CHECK: [[TVAR_PRIV:%.+]] = alloca i{{.+}},
+// CHECK: [[RED_LIST:%.+]] = alloca [1 x {{.+}}],
+// CHECK: store{{.+}} [[TVAR_ARG]], {{.+}} [[TVAR_ADDR]],
+// CHECK: [[TVAR_REF:%.+]] = load{{.+}}, {{.+}} [[TVAR_ADDR]]
+// CHECK: store{{.+}} 0, {{.+}} [[TVAR_PRIV]],
+
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: store{{.+}}, {{.+}} [[TVAR_PRIV]],
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: [[RED_LIST_GEP:%.+]] = getelementptr{{.+}} [[RED_LIST]],
+// CHECK: [[TVAR_PRIV_CAST:%.+]] = bitcast{{.+}} [[TVAR_PRIV]] to
+// CHECK: store{{.+}} [[TVAR_PRIV_CAST]], {{.+}} [[RED_LIST_GEP]],
+// CHECK: [[RED_LIST_BCAST:%.+]] = bitcast{{.+}} [[RED_LIST]] to
+// CHECK: [[K_RED_RET:%.+]] = call{{.+}} @__kmpc_reduce_nowait({{.+}}, {{.+}}, {{.+}}, {{.+}}, {{.+}} [[RED_LIST_BCAST]], {{.+}} [[RED_FUN:@.+]], {{.+}} [[RED_VAR]])
+// CHECK: switch{{.+}} [[K_RED_RET]], label{{.+}} [
+// CHECK: {{.+}}, label %[[CASE1:.+]]
+// CHECK: {{.+}}, label %[[CASE2:.+]]
+// CHECK: ]
+// CHECK: [[CASE1]]:
+// CHECK-DAG: [[TVAR_VAL:%.+]] = load{{.+}}, {{.+}} [[TVAR_REF]],
+// CHECK-DAG: [[TVAR_PRIV_VAL:%.+]] = load{{.+}}, {{.+}} [[TVAR_PRIV]],
+// CHECK-DAG: [[TVAR_INC:%.+]] = add{{.+}} [[TVAR_VAL]], [[TVAR_PRIV_VAL]]
+// CHECK: store{{.+}} [[TVAR_INC]], {{.+}} [[TVAR_REF]],
+// CHECK: call void @__kmpc_end_reduce_nowait({{.+}}, {{.+}}, {{.+}} [[RED_VAR]])
+// CHECK: br
+// CHECK: [[CASE2]]:
+// CHECK-DAG: [[TVAR_PRIV_VAL:%.+]] = load{{.+}}, {{.+}} [[TVAR_PRIV]],
+// CHECK-DAG: [[ATOMIC_RES:%.+]] = atomicrmw add{{.+}} [[TVAR_REF]], {{.+}} [[TVAR_PRIV_VAL]]
+// CHECK: br
+#endif
diff --git a/test/OpenMP/teams_distribute_parallel_for_reduction_messages.cpp b/test/OpenMP/teams_distribute_parallel_for_reduction_messages.cpp
index 73661618d20c..889efd76cc3c 100644
--- a/test/OpenMP/teams_distribute_parallel_for_reduction_messages.cpp
+++ b/test/OpenMP/teams_distribute_parallel_for_reduction_messages.cpp
@@ -19,9 +19,9 @@ public:
S2() : a(0) {}
S2(S2 &s2) : a(s2.a) {}
static float S2s; // expected-note 2 {{static data member is predetermined as shared}}
- static const float S2sc;
+ static const float S2sc; // expected-note 2 {{'S2sc' declared here}}
};
-const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}}
+const float S2::S2sc = 0;
S2 b; // expected-note 3 {{'b' defined here}}
const S2 ba[5]; // expected-note 2 {{'ba' defined here}}
class S3 {
diff --git a/test/OpenMP/teams_distribute_parallel_for_schedule_codegen.cpp b/test/OpenMP/teams_distribute_parallel_for_schedule_codegen.cpp
new file mode 100644
index 000000000000..201a170ccd4a
--- /dev/null
+++ b/test/OpenMP/teams_distribute_parallel_for_schedule_codegen.cpp
@@ -0,0 +1,398 @@
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+// Test host codegen.
+// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64
+// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32
+#ifdef CK1
+
+template <typename T, int X, long long Y>
+struct SS{
+ T a[X];
+ float b;
+ // CK1: define {{.*}}i32 @{{.+}}foo{{.+}}(
+ int foo(void) {
+
+ // CK1: call i32 @__tgt_target_teams(
+ // CK1: call void @[[OFFL1:.+]](
+ #pragma omp target
+ #pragma omp teams distribute parallel for
+ for(int i = 0; i < X; i++) {
+ a[i] = (T)0;
+ }
+ // CK1: call i32 @__tgt_target_teams(
+ // CK1: call void @[[OFFL2:.+]](
+ #pragma omp target
+ #pragma omp teams distribute parallel for schedule(static)
+ for(int i = 0; i < X; i++) {
+ a[i] = (T)0;
+ }
+ // CK1: call i32 @__tgt_target_teams(
+ // CK1: call void @[[OFFL3:.+]](
+ #pragma omp target
+ #pragma omp teams distribute parallel for schedule(static, X/2)
+ for(int i = 0; i < X; i++) {
+ a[i] = (T)0;
+ }
+
+ // CK1: call i32 @__tgt_target_teams(
+ // CK1: call void @[[OFFL4:.+]](
+ #pragma omp target
+ #pragma omp teams distribute parallel for schedule(dynamic)
+ for(int i = 0; i < X; i++) {
+ a[i] = (T)0;
+ }
+
+ // CK1: call i32 @__tgt_target_teams(
+ // CK1: call void @[[OFFL5:.+]](
+ #pragma omp target
+ #pragma omp teams distribute parallel for schedule(dynamic, X/2)
+ for(int i = 0; i < X; i++) {
+ a[i] = (T)0;
+ }
+
+ // CK1: define internal void @[[OFFL1]](
+ // CK1: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTL1:.+]] to {{.+}},
+ // CK1: ret void
+
+ // CK1: define internal void @[[OUTL1]]({{.+}})
+ // CK1: call void @__kmpc_for_static_init_4(
+ // CK1: call void {{.*}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[PAR_OUTL1:.+]] to
+ // CK1: call void @__kmpc_for_static_fini(
+ // CK1: ret void
+
+ // CK1: define internal void @[[PAR_OUTL1]]({{.+}})
+ // CK1: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 34,
+ // CK1: call void @__kmpc_for_static_fini(
+ // CK1: ret void
+
+ // CK1: define internal void @[[OFFL2]](
+ // CK1: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTL2:.+]] to {{.+}},
+ // CK1: ret void
+
+ // CK1: define internal void @[[OUTL2]]({{.+}})
+ // CK1: call void @__kmpc_for_static_init_4(
+ // CK1: call void {{.*}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[PAR_OUTL2:.+]] to
+ // CK1: call void @__kmpc_for_static_fini(
+ // CK1: ret void
+
+ // CK1: define internal void @[[PAR_OUTL2]]({{.+}})
+ // CK1: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 34,
+ // CK1: call void @__kmpc_for_static_fini(
+ // CK1: ret void
+
+ // CK1: define internal void @[[OFFL3]](
+ // CK1: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTL3:.+]] to {{.+}},
+ // CK1: ret void
+
+ // CK1: define internal void @[[OUTL3]]({{.+}})
+ // CK1: call void @__kmpc_for_static_init_4(
+ // CK1: call void {{.*}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[PAR_OUTL3:.+]] to
+ // CK1: call void @__kmpc_for_static_fini(
+ // CK1: ret void
+
+ // CK1: define internal void @[[PAR_OUTL3]]({{.+}})
+ // CK1: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 33,
+ // CK1: call void @__kmpc_for_static_fini(
+ // CK1: ret void
+
+ // CK1: define internal void @[[OFFL4]](
+ // CK1: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTL4:.+]] to {{.+}},
+ // CK1: ret void
+
+ // CK1: define internal void @[[OUTL4]]({{.+}})
+ // CK1: call void @__kmpc_for_static_init_4(
+ // CK1: call void {{.*}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[PAR_OUTL4:.+]] to
+ // CK1: call void @__kmpc_for_static_fini(
+ // CK1: ret void
+
+ // CK1: define internal void @[[PAR_OUTL4]]({{.+}})
+ // CK1: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 35,
+ // CK1: call {{.+}} @__kmpc_dispatch_next_4(
+ // CK1: ret void
+
+ // CK1: define internal void @[[OFFL5]](
+ // CK1: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTL5:.+]] to {{.+}},
+ // CK1: ret void
+
+ // CK1: define internal void @[[OUTL5]]({{.+}})
+ // CK1: call void @__kmpc_for_static_init_4(
+ // CK1: call void {{.*}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[PAR_OUTL5:.+]] to
+ // CK1: call void @__kmpc_for_static_fini(
+ // CK1: ret void
+
+ // CK1: define internal void @[[PAR_OUTL5]]({{.+}})
+ // CK1: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 35,
+ // CK1: call {{.+}} @__kmpc_dispatch_next_4(
+ // CK1: ret void
+
+ return a[0];
+ }
+};
+
+int teams_template_struct(void) {
+ SS<int, 123, 456> V;
+ return V.foo();
+
+}
+#endif // CK1
+
+// Test host codegen.
+// RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64
+// RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32
+#ifdef CK2
+
+template <typename T, int n>
+int tmain(T argc) {
+ T a[n];
+ int m = 10;
+#pragma omp target
+#pragma omp teams distribute parallel for
+ for(int i = 0; i < n; i++) {
+ a[i] = (T)0;
+ }
+#pragma omp target
+#pragma omp teams distribute parallel for schedule(static)
+ for(int i = 0; i < n; i++) {
+ a[i] = (T)0;
+ }
+#pragma omp target
+#pragma omp teams distribute parallel for schedule(static, m)
+ for(int i = 0; i < n; i++) {
+ a[i] = (T)0;
+ }
+#pragma omp target
+#pragma omp teams distribute parallel for schedule(dynamic)
+ for(int i = 0; i < n; i++) {
+ a[i] = (T)0;
+ }
+#pragma omp target
+#pragma omp teams distribute parallel for schedule(dynamic, m)
+ for(int i = 0; i < n; i++) {
+ a[i] = (T)0;
+ }
+ return 0;
+}
+
+int main (int argc, char **argv) {
+ int n = 100;
+ int a[n];
+ int m = 10;
+#pragma omp target
+#pragma omp teams distribute parallel for
+ for(int i = 0; i < n; i++) {
+ a[i] = 0;
+ }
+#pragma omp target
+#pragma omp teams distribute parallel for dist_schedule(static)
+ for(int i = 0; i < n; i++) {
+ a[i] = 0;
+ }
+#pragma omp target
+#pragma omp teams distribute parallel for dist_schedule(static, m)
+ for(int i = 0; i < n; i++) {
+ a[i] = 0;
+ }
+#pragma omp target
+#pragma omp teams distribute parallel for schedule(dynamic)
+ for(int i = 0; i < n; i++) {
+ a[i] = 0;
+ }
+#pragma omp target
+#pragma omp teams distribute parallel for schedule(dynamic, m)
+ for(int i = 0; i < n; i++) {
+ a[i] = 0;
+ }
+ return tmain<int, 10>(argc);
+}
+
+// CK2: define {{.*}}i32 @{{[^,]+}}(i{{.+}}{{.+}} %[[ARGC:.+]], {{.+}})
+// CK2: call i32 @__tgt_target_teams(
+// CK2: call void @[[OFFL1:.+]]({{.+}})
+// CK2: call i32 @__tgt_target_teams(
+// CK2: call void @[[OFFL2:.+]]({{.+}})
+// CK2: call i32 @__tgt_target_teams(
+// CK2: call void @[[OFFL3:.+]]({{.+}})
+// CK2: call i32 @__tgt_target_teams(
+// CK2: call void @[[OFFL4:.+]]({{.+}})
+// CK2: call i32 @__tgt_target_teams(
+// CK2: call void @[[OFFL5:.+]]({{.+}})
+// CK2: {{%.+}} = call{{.*}} i32 @[[TMAIN:.+]]({{.+}})
+// CK2: ret
+
+// CK2: define {{.*}}void @[[OFFL1]]({{.+}})
+// CK2: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 3, {{.+}} @[[OUTL1:.+]] to {{.+}},
+// CK2: ret void
+
+// CK2: define internal void @[[OUTL1]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4(
+// CK2: call void {{.*}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[PAR_OUTL1:.+]] to
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define internal void @[[PAR_OUTL1]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 34,
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define {{.*}}void @[[OFFL2]]({{.+}})
+// CK2: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 3, {{.+}} @[[OUTL2:.+]] to {{.+}},
+// CK2: ret void
+
+// CK2: define internal void @[[OUTL2]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4(
+// CK2: call void {{.*}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[PAR_OUTL2:.+]] to
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define internal void @[[PAR_OUTL2]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 34,
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define {{.*}}void @[[OFFL3]]({{.+}})
+// CK2: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 4, {{.+}} @[[OUTL3:.+]] to {{.+}},
+// CK2: ret void
+
+// CK2: define internal void @[[OUTL3]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4(
+// CK2: call void {{.*}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[PAR_OUTL3:.+]] to
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define internal void @[[PAR_OUTL3]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 34
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define {{.*}}void @[[OFFL4]]({{.+}})
+// CK2: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 {{.+}}, {{.+}} @[[OUTL4:.+]] to {{.+}},
+// CK2: ret void
+
+// CK2: define internal void @[[OUTL4]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4(
+// CK2: call void {{.*}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[PAR_OUTL4:.+]] to
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define internal void @[[PAR_OUTL4]]({{.+}})
+// CK2: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 35,
+// CK2: call {{.+}} @__kmpc_dispatch_next_4(
+// CK2: ret void
+
+
+// CK2: define {{.*}}void @[[OFFL5]]({{.+}})
+// CK2: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 {{.+}}, {{.+}} @[[OUTL5:.+]] to {{.+}},
+// CK2: ret void
+
+// CK2: define internal void @[[OUTL5]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4(
+// CK2: call void {{.*}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[PAR_OUTL5:.+]] to
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define internal void @[[PAR_OUTL5]]({{.+}})
+// CK2: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 35,
+// CK2: call {{.+}} @__kmpc_dispatch_next_4(
+// CK2: ret void
+
+// CK2: define {{.*}}i32 @[[TMAIN]]({{.+}})
+// CK2: call i32 @__tgt_target_teams(
+// CK2: call void @[[OFFLT1:.+]]({{.+}})
+// CK2: call i32 @__tgt_target_teams(
+// CK2: call void @[[OFFLT2:.+]]({{.+}})
+// CK2: call i32 @__tgt_target_teams(
+// CK2: call void @[[OFFLT3:.+]]({{.+}})
+// CK2: call i32 @__tgt_target_teams(
+// CK2: call void @[[OFFLT4:.+]]({{.+}})
+// CK2: call i32 @__tgt_target_teams(
+// CK2: call void @[[OFFLT5:.+]]({{.+}})
+// CK2: ret
+// CK2-NEXT: }
+
+// CK2: define {{.*}}void @[[OFFLT1]]({{.+}})
+// CK2: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTLT1:.+]] to {{.+}},
+// CK2: ret void
+
+// CK2: define internal void @[[OUTLT1]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4(
+// CK2: call void {{.*}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[PAR_OUTLT1:.+]] to
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define internal void @[[PAR_OUTLT1]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 34,
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define {{.*}}void @[[OFFLT2]]({{.+}})
+// CK2: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTLT2:.+]] to {{.+}},
+// CK2: ret void
+
+// CK2: define internal void @[[OUTLT2]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4(
+// CK2: call void {{.*}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[PAR_OUTLT2:.+]] to
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define internal void @[[PAR_OUTLT2]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 34,
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define {{.*}}void @[[OFFLT3]]({{.+}})
+// CK2: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 {{.+}}, {{.+}} @[[OUTLT3:.+]] to {{.+}},
+// CK2: ret void
+
+// CK2: define internal void @[[OUTLT3]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4(
+// CK2: call void {{.*}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[PAR_OUTLT3:.+]] to
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define internal void @[[PAR_OUTLT3]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 33,
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define {{.*}}void @[[OFFLT4]]({{.+}})
+// CK2: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 {{.+}}, {{.+}} @[[OUTLT4:.+]] to {{.+}},
+// CK2: ret void
+
+// CK2: define internal void @[[OUTLT4]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4(
+// CK2: call void {{.*}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[PAR_OUTLT4:.+]] to
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define internal void @[[PAR_OUTLT4]]({{.+}})
+// CK2: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 35,
+// CK2: call {{.+}} @__kmpc_dispatch_next_4(
+// CK2: ret void
+
+// CK2: define {{.*}}void @[[OFFLT5]]({{.+}})
+// CK2: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 {{.+}}, {{.+}} @[[OUTLT5:.+]] to {{.+}},
+// CK2: ret void
+
+// CK2: define internal void @[[OUTLT5]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4(
+// CK2: call void {{.*}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[PAR_OUTLT5:.+]] to
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define internal void @[[PAR_OUTLT5]]({{.+}})
+// CK2: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 35,
+// CK2: call {{.+}} @__kmpc_dispatch_next_4(
+// CK2: ret void
+
+#endif // CK2
+#endif // #ifndef HEADER
diff --git a/test/OpenMP/teams_distribute_parallel_for_shared_messages.cpp b/test/OpenMP/teams_distribute_parallel_for_shared_messages.cpp
index 8edcd3664341..1a1af09aa205 100644
--- a/test/OpenMP/teams_distribute_parallel_for_shared_messages.cpp
+++ b/test/OpenMP/teams_distribute_parallel_for_shared_messages.cpp
@@ -84,7 +84,7 @@ int main(int argc, char **argv) {
#pragma omp teams distribute parallel for shared (S1) // expected-error {{'S1' does not refer to a value}}
for (int j=0; j<100; j++) foo();
#pragma omp target
- #pragma omp teams distribute parallel for shared (a, b, c, d, f)
+ #pragma omp teams distribute parallel for shared (a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}}
for (int j=0; j<100; j++) foo();
#pragma omp target
#pragma omp teams distribute parallel for shared (argv[1]) // expected-error {{expected variable name}}
diff --git a/test/OpenMP/teams_distribute_parallel_for_simd_ast_print.cpp b/test/OpenMP/teams_distribute_parallel_for_simd_ast_print.cpp
index 26cc15822943..7573fdeafa31 100644
--- a/test/OpenMP/teams_distribute_parallel_for_simd_ast_print.cpp
+++ b/test/OpenMP/teams_distribute_parallel_for_simd_ast_print.cpp
@@ -29,9 +29,10 @@ public:
++this->a.a;
}
S7 &operator=(S7 &s) {
+ int k;
#pragma omp target
-#pragma omp teams distribute parallel for simd private(a) private(this->a)
- for (int k = 0; k < s.a.a; ++k)
+#pragma omp teams distribute parallel for simd private(a) private(this->a) linear(k)
+ for (k = 0; k < s.a.a; ++k)
++s.a.a;
foo();
@@ -59,7 +60,7 @@ public:
// CHECK: #pragma omp target
// CHECK-NEXT: #pragma omp teams distribute parallel for simd private(this->a) private(this->a) private(T::a)
// CHECK: #pragma omp target
-// CHECK-NEXT: #pragma omp teams distribute parallel for simd private(this->a) private(this->a)
+// CHECK-NEXT: #pragma omp teams distribute parallel for simd private(this->a) private(this->a) linear(k)
// CHECK: #pragma omp target
// CHECK-NEXT: #pragma omp teams distribute parallel for simd default(none) private(b) firstprivate(argv) shared(d) reduction(+: c) reduction(max: e) num_teams(f) thread_limit(d)
// CHECK: #pragma omp target
@@ -161,11 +162,11 @@ T tmain(T argc) {
// CHECK-NEXT: for (int k = 0; k < 10; ++k)
// CHECK-NEXT: e += d + argc;
#pragma omp target
-#pragma omp teams distribute parallel for simd simdlen(clen-1) linear(d)
+#pragma omp teams distribute parallel for simd simdlen(clen-1)
for (int k = 0; k < 10; ++k)
e += d + argc;
// CHECK: #pragma omp target
-// CHECK-NEXT: #pragma omp teams distribute parallel for simd simdlen(clen - 1) linear(d)
+// CHECK-NEXT: #pragma omp teams distribute parallel for simd simdlen(clen - 1)
// CHECK-NEXT: for (int k = 0; k < 10; ++k)
// CHECK-NEXT: e += d + argc;
#pragma omp target
@@ -224,11 +225,11 @@ int main (int argc, char **argv) {
// CHECK-NEXT: for (int k = 0; k < 10; ++k)
// CHECK-NEXT: e += d + argc;
#pragma omp target
-#pragma omp teams distribute parallel for simd simdlen(clen-1) linear(d)
+#pragma omp teams distribute parallel for simd simdlen(clen-1)
for (int k = 0; k < 10; ++k)
e += d + argc;
// CHECK: #pragma omp target
-// CHECK-NEXT: #pragma omp teams distribute parallel for simd simdlen(clen - 1) linear(d)
+// CHECK-NEXT: #pragma omp teams distribute parallel for simd simdlen(clen - 1)
// CHECK-NEXT: for (int k = 0; k < 10; ++k)
// CHECK-NEXT: e += d + argc;
#pragma omp target
diff --git a/test/OpenMP/teams_distribute_parallel_for_simd_codegen.cpp b/test/OpenMP/teams_distribute_parallel_for_simd_codegen.cpp
new file mode 100644
index 000000000000..00f2844735c9
--- /dev/null
+++ b/test/OpenMP/teams_distribute_parallel_for_simd_codegen.cpp
@@ -0,0 +1,263 @@
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+// Test host codegen.
+// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64
+// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32
+#ifdef CK1
+
+int a[100];
+
+// CK1: define {{.*}}i32 @{{.+}}teams_argument_globali(
+int teams_argument_global(int n){
+ int te = n / 128;
+ int th = 128;
+ // discard n_addr
+ // CK1: alloca i32,
+ // CK1: [[TE:%.+]] = alloca i32,
+ // CK1: [[TH:%.+]] = alloca i32,
+ // CK1: [[TE_CAST:%.+]] = alloca i{{32|64}},
+ // CK1: [[TH_CAST:%.+]] = alloca i{{32|64}},
+ // CK1: [[TE_PAR:%.+]] = load{{.+}}, {{.+}} [[TE_CAST]],
+ // CK1: [[TH_PAR:%.+]] = load{{.+}}, {{.+}} [[TH_CAST]],
+
+ // CK1: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 4, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0)
+
+ // CK1: call void @[[OFFL1:.+]](i{{32|64}} [[TE_PAR]], i{{32|64}} [[TH_PAR]],
+ #pragma omp target
+ #pragma omp teams distribute parallel for simd num_teams(te), thread_limit(th) simdlen(64)
+ for(int i = 0; i < n; i++) {
+ a[i] = 0;
+ }
+
+ int i;
+ // CK1: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 3, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0)
+ // CK1: call void @[[OFFL2:.+]](
+ #pragma omp target
+ {{{
+ #pragma omp teams distribute parallel for simd safelen(4) aligned(a) linear(i)
+ for(i = 0; i < n; i++) {
+ a[i] = 0;
+ }
+ }}}
+ // outlined target regions
+ // CK1: define internal void @[[OFFL1]](i{{32|64}} [[TE_ARG:%.+]], i{{32|64}} [[TH_ARG:%.+]], i{{32|64}} {{.+}}, {{.+}})
+ // CK1: [[TE_ADDR:%.+]] = alloca i{{32|64}},
+ // CK1: [[TH_ADDR:%.+]] = alloca i{{32|64}},
+ // CK1: store{{.+}} [[TE_ARG]], {{.+}} [[TE_ADDR]],
+ // CK1: store{{.+}} [[TH_ARG]], {{.+}} [[TH_ADDR]],
+ // CK1-64: [[TE_CONV:%.+]] = bitcast{{.+}} [[TE_ADDR]] to
+ // CK1-64: [[TH_CONV:%.+]] = bitcast{{.+}} [[TH_ADDR]] to
+ // CK1-64: [[TE_VAL:%.+]] = load i32, i32* [[TE_CONV]],
+ // CK1-64: [[TH_VAL:%.+]] = load i32, i32* [[TH_CONV]],
+ // CK1-32: [[TE_VAL:%.+]] = load i32, i32* [[TE_ADDR]],
+ // CK1-32: [[TH_VAL:%.+]] = load i32, i32* [[TH_ADDR]],
+ // CK1: {{%.+}} = call i32 @__kmpc_push_num_teams({{.+}}, {{.+}}, i32 [[TE_VAL]], i32 [[TH_VAL]])
+ // CK1: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 2, {{.+}} @[[OUTL1:.+]] to {{.+}}, {{.+}}, {{.+}})
+ // CK1: ret void
+
+ // CK1: define internal void @[[OUTL1]]({{.+}})
+ // CK1: call void @__kmpc_for_static_init_4(
+ // CK1: call void {{.+}} @__kmpc_fork_call(
+ // CK1: call void @__kmpc_for_static_fini(
+ // CK1: ret void
+
+ // CK1: define internal void @[[OFFL2]]({{.+}}, {{.+}})
+ // CK1: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 3, {{.+}} @[[OUTL2:.+]] to {{.+}}, {{.+}}, {{.+}})
+ // CK1: ret void
+
+ // CK1: define internal void @[[OUTL2]]({{.+}})
+ // CK1: call void @__kmpc_for_static_init_4(
+ // CK1: call void {{.+}} @__kmpc_fork_call(
+ // CK1: call void @__kmpc_for_static_fini(
+ // CK1: ret void
+
+ return a[0];
+}
+
+// CK1-DAG: !{!"llvm.loop.vectorize.enable", i1 true}
+// CK1-DAG: !{!"llvm.loop.vectorize.width", i32 4}
+// CK1-DAG: !{!"llvm.loop.vectorize.width", i32 64}
+
+#endif // CK1
+
+// Test host codegen.
+// RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64
+// RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32
+#ifdef CK2
+
+// CK2: define {{.*}}i32 @{{.+}}teams_local_argv(
+int teams_local_arg(void) {
+ int n = 100;
+ int a[n], i;
+
+ // CK2: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 4, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}, i64* {{.+}}@{{[^,]+}}, i32 0, i32 0)
+ // CK2: call void @[[OFFL1:.+]](
+ #pragma omp target
+ #pragma omp teams distribute parallel for simd safelen(4) aligned(a) linear(i)
+ for(i = 0; i < n; i++) {
+ a[i] = 0;
+ }
+
+ // outlined target region
+ // CK2: define internal void @[[OFFL1]]({{.+}}, {{.+}})
+ // CK2: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 4, {{.+}} @[[OUTL1:.+]] to {{.+}}, {{.+}}, {{.+}})
+ // CK2: ret void
+
+ // CK2: define internal void @[[OUTL1]]({{.+}})
+ // CK2: call void @__kmpc_for_static_init_4(
+ // CK2: call void {{.+}} @__kmpc_fork_call(
+ // CK2: call void @__kmpc_for_static_fini(
+ // CK2: ret void
+
+ return a[0];
+}
+
+// CK2-DAG: !{!"llvm.loop.vectorize.enable", i1 true}
+// CK2-DAG: !{!"llvm.loop.vectorize.width", i32 4}
+
+#endif // CK2
+
+// Test host codegen.
+// RUN: %clang_cc1 -DCK3 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK3 --check-prefix CK3-64
+// RUN: %clang_cc1 -DCK3 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK3 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK3 --check-prefix CK3-64
+// RUN: %clang_cc1 -DCK3 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK3 --check-prefix CK3-32
+// RUN: %clang_cc1 -DCK3 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK3 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK3 --check-prefix CK3-32
+#ifdef CK3
+
+// CK3: [[SSI:%.+]] = type { [{{.+}} x i32], float }
+
+template <typename T, int X, long long Y>
+struct SS{
+ T a[X];
+ float b;
+ // CK3: define {{.*}}i32 @{{.+}}foo{{.+}}(
+ int foo(void) {
+ int i;
+ // CK3: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 2, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0)
+ // CK3: call void @[[OFFL1:.+]]([[SSI]]* %{{.+}})
+ #pragma omp target
+ #pragma omp teams distribute parallel for simd safelen(4) aligned(a) linear(i)
+ for(i = 0; i < X; i++) {
+ a[i] = (T)0;
+ }
+
+ // outlined target region
+ // CK3: define internal void @[[OFFL1]]([[SSI]]* {{.+}})
+ // CK3: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 2, {{.+}} @[[OUTL1:.+]] to {{.+}}, {{.+}}, {{.+}})
+ // CK3: ret void
+
+ // CK3: define internal void @[[OUTL1]]({{.+}})
+ // CK3: call void @__kmpc_for_static_init_4(
+ // CK3: call void {{.+}} @__kmpc_fork_call(
+ // CK3: call void @__kmpc_for_static_fini(
+ // CK3: ret void
+
+ return a[0];
+ }
+};
+
+int teams_template_struct(void) {
+ SS<int, 123, 456> V;
+ return V.foo();
+
+}
+
+// CK3-DAG: !{!"llvm.loop.vectorize.enable", i1 true}
+// CK3-DAG: !{!"llvm.loop.vectorize.width", i32 4}
+#endif // CK3
+
+// Test host codegen.
+// RUN: %clang_cc1 -DCK4 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK4 --check-prefix CK4-64
+// RUN: %clang_cc1 -DCK4 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK4 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK4 --check-prefix CK4-64
+// RUN: %clang_cc1 -DCK4 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK4 --check-prefix CK4-32
+// RUN: %clang_cc1 -DCK4 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK4 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK4 --check-prefix CK4-32
+
+#ifdef CK4
+
+template <typename T, int n>
+int tmain(T argc) {
+ T a[n];
+ int te = n/128;
+ int th = 128;
+#pragma omp target
+#pragma omp teams distribute parallel for simd num_teams(te) thread_limit(th) simdlen(64)
+ for(int i = 0; i < n; i++) {
+ a[i] = (T)0;
+ }
+ return 0;
+}
+
+int main (int argc, char **argv) {
+ int n = 100;
+ int a[n], i;
+#pragma omp target
+#pragma omp teams distribute parallel for simd safelen(4) aligned(a) linear(i)
+ for(i = 0; i < n; i++) {
+ a[i] = 0;
+ }
+ return tmain<int, 10>(argc);
+}
+
+// CK4: define {{.*}}i32 @{{[^,]+}}(i{{.+}}{{.+}} %[[ARGC:.+]], {{.+}})
+// CK4: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 4, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}, i64* {{.+}}@{{[^,]+}}, i32 0, i32 0)
+// CK4: call void @[[OFFL1:.+]]({{.+}})
+// CK4: {{%.+}} = call{{.*}} i32 @[[TMAIN:.+]]({{.+}})
+// CK4: ret
+
+// CK4: define {{.*}}void @[[OFFL1]]({{.+}})
+// CK4: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 4, {{.+}} @[[OUTL1:.+]] to {{.+}}, {{.+}}, {{.+}})
+// CK4: ret void
+
+// CK4: define internal void @[[OUTL1]]({{.+}})
+// CK4: call void @__kmpc_for_static_init_4(
+// CK4: call void {{.+}} @__kmpc_fork_call(
+// CK4: call void @__kmpc_for_static_fini(
+// CK4: ret void
+
+// CK4: define {{.*}}i32 @[[TMAIN]]({{.+}})
+// CK4: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 3, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0)
+// CK4: call void @[[OFFLT:.+]]({{.+}})
+// CK4: ret
+// CK4-NEXT: }
+
+// CK4: define {{.*}}void @[[OFFLT]](i{{32|64}} [[TE_ARG:%.+]], i{{32|64}} [[TH_ARG:%.+]], {{.+}})
+// CK4: [[TE_ADDR:%.+]] = alloca i{{32|64}},
+// CK4: [[TH_ADDR:%.+]] = alloca i{{32|64}},
+// CK4: store{{.+}} [[TE_ARG]], {{.+}} [[TE_ADDR]],
+// CK4: store{{.+}} [[TH_ARG]], {{.+}} [[TH_ADDR]],
+// CK4-64: [[TE_CONV:%.+]] = bitcast{{.+}} [[TE_ADDR]] to
+// CK4-64: [[TH_CONV:%.+]] = bitcast{{.+}} [[TH_ADDR]] to
+// CK4-64: [[TE_VAL:%.+]] = load i32, i32* [[TE_CONV]],
+// CK4-64: [[TH_VAL:%.+]] = load i32, i32* [[TH_CONV]],
+// CK4-32: [[TE_VAL:%.+]] = load i32, i32* [[TE_ADDR]],
+// CK4-32: [[TH_VAL:%.+]] = load i32, i32* [[TH_ADDR]],
+// CK4: {{%.+}} = call i32 @__kmpc_push_num_teams({{.+}}, {{.+}}, i32 [[TE_VAL]], i32 [[TH_VAL]])
+// CK4: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTLT:.+]] to {{.+}}, {{.+}}, {{.+}})
+// CK4: ret void
+
+// CK4: define internal void @[[OUTLT]]({{.+}})
+// CK4: call void @__kmpc_for_static_init_4(
+// CK4: call void {{.+}} @__kmpc_fork_call(
+// CK4: call void @__kmpc_for_static_fini(
+// CK4: ret void
+
+// CK4-DAG: !{!"llvm.loop.vectorize.enable", i1 true}
+// CK4-DAG: !{!"llvm.loop.vectorize.width", i32 4}
+// CK4-DAG: !{!"llvm.loop.vectorize.width", i32 64}
+
+#endif // CK4
+#endif
+
diff --git a/test/OpenMP/teams_distribute_parallel_for_simd_collapse_codegen.cpp b/test/OpenMP/teams_distribute_parallel_for_simd_collapse_codegen.cpp
new file mode 100644
index 000000000000..91c451d49a08
--- /dev/null
+++ b/test/OpenMP/teams_distribute_parallel_for_simd_collapse_codegen.cpp
@@ -0,0 +1,149 @@
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+// Test host codegen.
+// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64
+// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32
+#ifdef CK1
+
+template <typename T, int X, long long Y>
+struct SS{
+ T a[X][Y];
+
+ // CK1: define {{.*}}i32 @{{.+}}foo{{.+}}(
+ int foo(void) {
+
+ // CK1: call i32 @__tgt_target_teams(
+ // CK1: call void @[[OFFL1:.+]](
+ #pragma omp target
+ #pragma omp teams distribute parallel for simd collapse(2)
+ for(int i = 0; i < X; i++) {
+ for(int j = 0; j < Y; j++) {
+ a[i][j] = (T)0;
+ }
+ }
+ // CK1: define internal void @[[OFFL1]](
+ // CK1: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTL1:.+]] to {{.+}},
+ // CK1: ret void
+
+ // CK1: define internal void @[[OUTL1]]({{.+}})
+ // discard loop variables not needed here
+ // CK1: [[OMP_UB:%.omp.comb.ub]] = alloca i32,
+ // CK1: store i32 56087, i32* [[OMP_UB]],
+ // CK1: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 92, {{.+}}, {{.+}}, i32* [[OMP_UB]],
+ // CK1: call void {{.*}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[PAR_OUTL1:.+]] to
+ // CK1: call void @__kmpc_for_static_fini(
+ // CK1: ret void
+
+ // CK1: define internal void @[[PAR_OUTL1]]({{.+}})
+ // CK1: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 34, {{.+}}, {{.+}},
+ // CK1: call void @__kmpc_for_static_fini(
+ // CK1: ret void
+
+ return a[0][0];
+ }
+};
+
+int teams_template_struct(void) {
+ SS<int, 123, 456> V;
+ return V.foo();
+
+}
+
+// CK4: !{!"llvm.loop.vectorize.enable", i1 true}
+
+#endif // CK1
+
+// Test host codegen.
+// RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64
+// RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32
+#ifdef CK2
+
+template <typename T, int n, int m>
+int tmain(T argc) {
+ T a[n][m];
+ #pragma omp target
+ #pragma omp teams distribute parallel for simd collapse(2)
+ for(int i = 0; i < n; i++) {
+ for(int j = 0; j < m; j++) {
+ a[i][j] = (T)0;
+ }
+ }
+ return 0;
+}
+
+int main (int argc, char **argv) {
+ int n = 100;
+ int m = 2;
+ int a[n][m];
+ #pragma omp target
+ #pragma omp teams distribute parallel for simd collapse(2)
+ for(int i = 0; i < n; i++) {
+ for(int j = 0; j < m; j++) {
+ a[i][j] = 0;
+ }
+ }
+ return tmain<int, 10, 2>(argc);
+}
+
+// CK2: define {{.*}}i32 @{{[^,]+}}(i{{.+}}{{.+}} %[[ARGC:.+]], {{.+}})
+// CK2: call i32 @__tgt_target_teams(
+// CK2: call void @[[OFFL1:.+]]({{.+}})
+// CK2: {{%.+}} = call{{.*}} i32 @[[TMAIN:.+]]({{.+}})
+// CK2: ret
+
+// CK2: define {{.*}}void @[[OFFL1]]({{.+}})
+// CK2: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 5, {{.+}} @[[OUTL1:.+]] to {{.+}},
+// CK2: ret void
+
+// CK2: define internal void @[[OUTL1]]({{.+}})
+// CK2: [[OMP_UB:%.omp.comb.ub]] = alloca i64,
+// CK2: store i64 {{.+}}, i64* [[OMP_UB]],
+// CK2: call void @__kmpc_for_static_init_8({{.+}}, {{.+}}, i32 92, {{.+}}, {{.+}}, i64* [[OMP_UB]],
+// CK2: call void {{.*}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[PAR_OUTL1:.+]] to
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define internal void @[[PAR_OUTL1]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_{{[4|8]}}({{.+}}, {{.+}}, i32 34, {{.+}}, {{.+}},
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+
+// CK2: define {{.*}}i32 @[[TMAIN]]({{.+}})
+// CK2: call i32 @__tgt_target_teams(
+// CK2: call void @[[OFFLT1:.+]]({{.+}})
+// CK2: ret
+// CK2-NEXT: }
+
+// CK2: define {{.*}}void @[[OFFLT1]]({{.+}})
+// CK2: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTLT1:.+]] to {{.+}},
+// CK2: ret void
+
+// CK2: define internal void @[[OUTLT1]]({{.+}})
+// discard loop variables not needed here
+// CK2: [[OMP_UB:%.omp.comb.ub]] = alloca i32,
+// CK2: store i32 {{.+}}, i32* [[OMP_UB]],
+// CK2: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 92, {{.+}}, {{.+}}, i32* [[OMP_UB]],
+// CK2: call void {{.*}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[TPAR_OUTL1:.+]] to
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define internal void @[[TPAR_OUTL1]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 34, {{.+}}, {{.+}},
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK4: !{!"llvm.loop.vectorize.enable", i1 true}
+
+#endif // CK2
+#endif // #ifndef HEADER
diff --git a/test/OpenMP/teams_distribute_parallel_for_simd_dist_schedule_codegen.cpp b/test/OpenMP/teams_distribute_parallel_for_simd_dist_schedule_codegen.cpp
new file mode 100644
index 000000000000..5c1f73066cd4
--- /dev/null
+++ b/test/OpenMP/teams_distribute_parallel_for_simd_dist_schedule_codegen.cpp
@@ -0,0 +1,268 @@
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+// Test host codegen.
+// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64
+// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32
+#ifdef CK1
+
+template <typename T, int X, long long Y>
+struct SS{
+ T a[X];
+ float b;
+ // CK1: define {{.*}}i32 @{{.+}}foo{{.+}}(
+ int foo(void) {
+
+ // CK1: call i32 @__tgt_target_teams(
+ // CK1: call void @[[OFFL1:.+]](
+ #pragma omp target
+ #pragma omp teams distribute parallel for simd
+ for(int i = 0; i < X; i++) {
+ a[i] = (T)0;
+ }
+ // CK1: call i32 @__tgt_target_teams(
+ // CK1: call void @[[OFFL2:.+]](
+ #pragma omp target
+ #pragma omp teams distribute parallel for simd dist_schedule(static)
+ for(int i = 0; i < X; i++) {
+ a[i] = (T)0;
+ }
+ // CK1: call i32 @__tgt_target_teams(
+ // CK1: call void @[[OFFL3:.+]](
+ #pragma omp target
+ #pragma omp teams distribute parallel for simd dist_schedule(static, X/2)
+ for(int i = 0; i < X; i++) {
+ a[i] = (T)0;
+ }
+ // CK1: define internal void @[[OFFL1]](
+ // CK1: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTL1:.+]] to {{.+}},
+ // CK1: ret void
+
+ // CK1: define internal void @[[OUTL1]]({{.+}})
+ // CK1: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 92
+ // CK1: call void {{.*}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[PAR_OUTL1:.+]] to
+ // CK1: call void @__kmpc_for_static_fini(
+ // CK1: ret void
+
+ // CK1: define internal void @[[PAR_OUTL1]]({{.+}})
+ // CK1: call void @__kmpc_for_static_init_4(
+ // CK1: call void @__kmpc_for_static_fini(
+ // CK1: ret void
+
+ // CK1: define internal void @[[OFFL2]](
+ // CK1: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTL2:.+]] to {{.+}},
+ // CK1: ret void
+
+ // CK1: define internal void @[[OUTL2]]({{.+}})
+ // CK1: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 92
+ // CK1: call void {{.*}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[PAR_OUTL2:.+]] to
+ // CK1: call void @__kmpc_for_static_fini(
+ // CK1: ret void
+
+ // CK1: define internal void @[[PAR_OUTL2]]({{.+}})
+ // CK1: call void @__kmpc_for_static_init_4(
+ // CK1: call void @__kmpc_for_static_fini(
+ // CK1: ret void
+
+
+ // CK1: define internal void @[[OFFL3]](
+ // CK1: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTL3:.+]] to {{.+}},
+ // CK1: ret void
+
+ // CK1: define internal void @[[OUTL3]]({{.+}})
+ // CK1: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 91
+ // CK1: call void {{.*}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[PAR_OUTL3:.+]] to
+ // CK1: call void @__kmpc_for_static_fini(
+ // CK1: ret void
+
+ // CK1: define internal void @[[PAR_OUTL3]]({{.+}})
+ // CK1: call void @__kmpc_for_static_init_4(
+ // CK1: call void @__kmpc_for_static_fini(
+ // CK1: ret void
+
+ return a[0];
+ }
+};
+
+int teams_template_struct(void) {
+ SS<int, 123, 456> V;
+ return V.foo();
+
+}
+
+// CK1: !{!"llvm.loop.vectorize.enable", i1 true}
+
+#endif // CK1
+
+// Test host codegen.
+// RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64
+// RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32
+#ifdef CK2
+
+template <typename T, int n>
+int tmain(T argc) {
+ T a[n];
+ int m = 10;
+#pragma omp target
+#pragma omp teams distribute parallel for simd
+ for(int i = 0; i < n; i++) {
+ a[i] = (T)0;
+ }
+#pragma omp target
+#pragma omp teams distribute parallel for simd dist_schedule(static)
+ for(int i = 0; i < n; i++) {
+ a[i] = (T)0;
+ }
+#pragma omp target
+#pragma omp teams distribute parallel for simd dist_schedule(static, m)
+ for(int i = 0; i < n; i++) {
+ a[i] = (T)0;
+ }
+ return 0;
+}
+
+int main (int argc, char **argv) {
+ int n = 100;
+ int a[n];
+ int m = 10;
+#pragma omp target
+#pragma omp teams distribute parallel for simd
+ for(int i = 0; i < n; i++) {
+ a[i] = 0;
+ }
+#pragma omp target
+#pragma omp teams distribute parallel for simd dist_schedule(static)
+ for(int i = 0; i < n; i++) {
+ a[i] = 0;
+ }
+#pragma omp target
+#pragma omp teams distribute parallel for simd dist_schedule(static, m)
+ for(int i = 0; i < n; i++) {
+ a[i] = 0;
+ }
+ return tmain<int, 10>(argc);
+}
+
+// CK2: define {{.*}}i32 @{{[^,]+}}(i{{.+}}{{.+}} %[[ARGC:.+]], {{.+}})
+// CK2: call i32 @__tgt_target_teams(
+// CK2: call void @[[OFFL1:.+]]({{.+}})
+// CK2: call i32 @__tgt_target_teams(
+// CK2: call void @[[OFFL2:.+]]({{.+}})
+// CK2: call i32 @__tgt_target_teams(
+// CK2: call void @[[OFFL3:.+]]({{.+}})
+// CK2: {{%.+}} = call{{.*}} i32 @[[TMAIN:.+]]({{.+}})
+// CK2: ret
+
+// CK2: define {{.*}}void @[[OFFL1]]({{.+}})
+// CK2: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 3, {{.+}} @[[OUTL1:.+]] to {{.+}},
+// CK2: ret void
+
+// CK2: define internal void @[[OUTL1]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 92
+// CK2: call void {{.*}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[PAR_OUTL1:.+]] to
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define internal void @[[PAR_OUTL1]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4(
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define {{.*}}void @[[OFFL2]]({{.+}})
+// CK2: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 3, {{.+}} @[[OUTL2:.+]] to {{.+}},
+// CK2: ret void
+
+// CK2: define internal void @[[OUTL2]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 92
+// CK2: call void {{.*}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[PAR_OUTL2:.+]] to
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define internal void @[[PAR_OUTL2]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4(
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define {{.*}}void @[[OFFL3]]({{.+}})
+// CK2: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 4, {{.+}} @[[OUTL3:.+]] to {{.+}},
+// CK2: ret void
+
+// CK2: define internal void @[[OUTL3]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 91
+// CK2: call void {{.*}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[PAR_OUTL3:.+]] to
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define internal void @[[PAR_OUTL3]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4(
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define {{.*}}i32 @[[TMAIN]]({{.+}})
+// CK2: call i32 @__tgt_target_teams(
+// CK2: call void @[[OFFLT1:.+]]({{.+}})
+// CK2: call i32 @__tgt_target_teams(
+// CK2: call void @[[OFFLT2:.+]]({{.+}})
+// CK2: call i32 @__tgt_target_teams(
+// CK2: call void @[[OFFLT3:.+]]({{.+}})
+// CK2: ret
+// CK2-NEXT: }
+
+// CK2: define {{.*}}void @[[OFFLT1]]({{.+}})
+// CK2: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTLT1:.+]] to {{.+}},
+// CK2: ret void
+
+// CK2: define internal void @[[OUTLT1]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 92
+// CK2: call void {{.*}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[PAR_OUTLT1:.+]] to
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define internal void @[[PAR_OUTLT1]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4(
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define {{.*}}void @[[OFFLT2]]({{.+}})
+// CK2: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTLT2:.+]] to {{.+}},
+// CK2: ret void
+
+// CK2: define internal void @[[OUTLT2]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 92
+// CK2: call void {{.*}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[PAR_OUTLT2:.+]] to
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define internal void @[[PAR_OUTLT2]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4(
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define {{.*}}void @[[OFFLT3]]({{.+}})
+// CK2: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 {{.+}}, {{.+}} @[[OUTLT3:.+]] to {{.+}},
+// CK2: ret void
+
+// CK2: define internal void @[[OUTLT3]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 91
+// CK2: call void {{.*}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[PAR_OUTLT3:.+]] to
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define internal void @[[PAR_OUTLT3]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4(
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: !{!"llvm.loop.vectorize.enable", i1 true}
+
+#endif // CK2
+#endif // #ifndef HEADER
diff --git a/test/OpenMP/teams_distribute_parallel_for_simd_firstprivate_codegen.cpp b/test/OpenMP/teams_distribute_parallel_for_simd_firstprivate_codegen.cpp
new file mode 100644
index 000000000000..1219742c752d
--- /dev/null
+++ b/test/OpenMP/teams_distribute_parallel_for_simd_firstprivate_codegen.cpp
@@ -0,0 +1,501 @@
+// RUN: %clang_cc1 -DCHECK -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -DCHECK -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+
+// RUN: %clang_cc1 -DLAMBDA -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+struct St {
+ int a, b;
+ St() : a(0), b(0) {}
+ St(const St &st) : a(st.a + st.b), b(0) {}
+ ~St() {}
+};
+
+volatile int g = 1212;
+volatile int &g1 = g;
+
+template <class T>
+struct S {
+ T f;
+ S(T a) : f(a + g) {}
+ S() : f(g) {}
+ S(const S &s, St t = St()) : f(s.f + t.a) {}
+ operator T() { return T(); }
+ ~S() {}
+};
+
+// CHECK-DAG: [[S_FLOAT_TY:%.+]] = type { float }
+// CHECK-DAG: [[S_INT_TY:%.+]] = type { i{{[0-9]+}} }
+// CHECK-DAG: [[ST_TY:%.+]] = type { i{{[0-9]+}}, i{{[0-9]+}} }
+
+template <typename T>
+T tmain() {
+ S<T> test;
+ T t_var = T();
+ T vec[] = {1, 2};
+ S<T> s_arr[] = {1, 2};
+ S<T> &var = test;
+#pragma omp target
+#pragma omp teams distribute parallel for simd firstprivate(t_var, vec, s_arr, var)
+ for (int i = 0; i < 2; ++i) {
+ vec[i] = t_var;
+ s_arr[i] = var;
+ }
+ return T();
+}
+
+// CHECK-DAG: [[TEST:@.+]] = global [[S_FLOAT_TY]] zeroinitializer,
+S<float> test;
+// CHECK-DAG: [[T_VAR:@.+]] = global i{{[0-9]+}} 333,
+int t_var = 333;
+// CHECK-DAG: [[VEC:@.+]] = global [2 x i{{[0-9]+}}] [i{{[0-9]+}} 1, i{{[0-9]+}} 2],
+int vec[] = {1, 2};
+// CHECK-DAG: [[S_ARR:@.+]] = global [2 x [[S_FLOAT_TY]]] zeroinitializer,
+S<float> s_arr[] = {1, 2};
+// CHECK-DAG: [[VAR:@.+]] = global [[S_FLOAT_TY]] zeroinitializer,
+S<float> var(3);
+// CHECK-DAG: [[SIVAR:@.+]] = internal global i{{[0-9]+}} 0,
+
+int main() {
+ static int sivar;
+#ifdef LAMBDA
+ // LAMBDA: [[G:@.+]] = global i{{[0-9]+}} 1212,
+ // LAMBDA-LABEL: @main
+ // LAMBDA: call void [[OUTER_LAMBDA:@.+]](
+ [&]() {
+ // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
+ // LAMBDA: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 3, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0)
+ // LAMBDA: call void @[[LOFFL1:.+]](i{{64|32}} %{{.+}})
+ // LAMBDA: ret
+#pragma omp target
+#pragma omp teams distribute parallel for simd firstprivate(g, g1, sivar)
+ for (int i = 0; i < 2; ++i) {
+ // LAMBDA: define{{.*}} internal{{.*}} void @[[LOFFL1]](i{{64|32}} {{%.+}}, i{{64|32}} {{%.+}})
+ // LAMBDA: {{%.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: {{%.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: {{%.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: [[G_CAST:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[G1_CAST:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[SIVAR_CAST:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA-DAG: [[G_CAST_VAL:%.+]] = load{{.+}} [[G_CAST]],
+ // LAMBDA-DAG: [[G1_CAST_VAL:%.+]] = load{{.+}} [[G1_CAST]],
+ // LAMBDA-DAG: [[SIVAR_CAST_VAL:%.+]] = load{{.+}} [[SIVAR_CAST]],
+ // LAMBDA: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 3, {{.+}} @[[LOUTL1:.+]] to {{.+}}, {{.+}} [[G_CAST_VAL]], {{.+}} [[G1_CAST_VAL]], {{.+}} [[SIVAR_CAST_VAL]])
+ // LAMBDA: ret void
+
+ // LAMBDA: define internal void @[[LOUTL1]]({{.+}})
+ // Skip global and bound tid vars
+ // LAMBDA: {{.+}} = alloca i32*,
+ // LAMBDA: {{.+}} = alloca i32*,
+ // LAMBDA: [[G_ADDR:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[G1_ADDR:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[SIVAR_ADDR:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[G1_TMP:%.+]] = alloca i32*,
+ // skip loop vars
+ // LAMBDA-DAG: store {{.+}}, {{.+}} [[G_ADDR]],
+ // LAMBDA-DAG: store {{.+}}, {{.+}} [[G1_ADDR]],
+ // LAMBDA-DAG: store {{.+}}, {{.+}} [[SIVAR_ADDR]],
+ // LAMBDA-DAG: [[G_CONV:%.+]] = bitcast {{.+}} [[G_ADDR]] to
+ // LAMBDA-DAG: [[G1_CONV:%.+]] = bitcast {{.+}} [[G1_ADDR]] to
+ // LAMBDA-DAG: [[SIVAR_CONV:%.+]] = bitcast {{.+}} [[SIVAR_ADDR]] to
+ // LAMBDA-DAG: store{{.+}} [[G1_CONV]], {{.+}} [[G1_TMP]],
+ g = 1;
+ g1 = 1;
+ sivar = 2;
+ // LAMBDA: call void @__kmpc_for_static_init_4(
+ // LAMBDA: call void {{.*}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[LPAR_OUTL:.+]] to
+ // LAMBDA: call void @__kmpc_for_static_fini(
+ // LAMBDA: ret void
+
+ // LAMBDA: define internal void @[[LPAR_OUTL]]({{.+}})
+ // Skip global and bound tid vars, and prev lb and ub vars
+ // LAMBDA: {{.+}} = alloca i32*,
+ // LAMBDA: {{.+}} = alloca i32*,
+ // LAMBDA: {{.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: {{.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: [[G_ADDR:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[G1_ADDR:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[SIVAR_ADDR:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[G1_TMP:%.+]] = alloca i32*,
+ // skip loop vars
+ // LAMBDA: alloca i32,
+ // LAMBDA: alloca i32,
+ // LAMBDA: alloca i32,
+ // LAMBDA: alloca i32,
+ // LAMBDA: alloca i32,
+ // LAMBDA: alloca i32,
+ // LAMBDA: [[G_PRIV:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[G1_PRIV:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[G1_TMP_PRIV:%.+]] = alloca i{{[0-9]+}}*,
+ // LAMBDA: [[SIVAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA-DAG: store {{.+}}, {{.+}} [[G_ADDR]],
+ // LAMBDA-DAG: store {{.+}}, {{.+}} [[G1_ADDR]],
+ // LAMBDA-DAG: store {{.+}}, {{.+}} [[SIVAR_ADDR]],
+ // LAMBDA-DAG: [[G_CONV:%.+]] = bitcast {{.+}} [[G_ADDR]] to
+ // LAMBDA-DAG: [[G1_CONV:%.+]] = bitcast {{.+}} [[G1_ADDR]] to
+ // LAMBDA-DAG: [[SIVAR_CONV:%.+]] = bitcast {{.+}} [[SIVAR_ADDR]] to
+ // LAMBDA-DAG: store{{.+}} [[G1_CONV]], {{.+}} [[G1_TMP]],
+
+ // use of private vars
+ // LAMBDA-DAG: store{{.+}} 1, {{.+}} [[G_PRIV]],
+ // LAMBDA-DAG: [[G1:%.+]] = load{{.+}}, {{.+}}* [[G1_TMP_PRIV]]
+ // LAMBDA-DAG: store{{.+}} 1, {{.+}} [[G1]],
+ // LAMBDA-DAG: store{{.+}} 2, {{.+}} [[SIVAR_PRIV]],
+ // LAMBDA-DAG: [[G1_REF:%.+]] = load{{.+}}, {{.+}} [[G1_TMP]],
+ // LAMBDA: call void [[INNER_LAMBDA:@.+]](
+ // LAMBDA: call void @__kmpc_for_static_fini(
+ // LAMBDA: ret void
+ [&]() {
+ // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]])
+ // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]],
+ g = 2;
+ g1 = 2;
+ sivar = 4;
+ // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]]
+
+ // LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // LAMBDA: [[G_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G_PTR_REF]]
+ // LAMBDA: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[G_REF]]
+ // LAMBDA: [[G1_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // LAMBDA: [[G1_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G1_PTR_REF]]
+ // LAMBDA: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[G1_REF]]
+ // LAMBDA: [[SIVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+ // LAMBDA: [[SIVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SIVAR_PTR_REF]]
+ // LAMBDA: store i{{[0-9]+}} 4, i{{[0-9]+}}* [[SIVAR_REF]]
+ }();
+ }
+ }();
+ return 0;
+
+// LAMBDA: !{!"llvm.loop.vectorize.enable", i1 true}
+
+#else
+#pragma omp target
+#pragma omp teams distribute parallel for simd firstprivate(t_var, vec, s_arr, var, sivar)
+ for (int i = 0; i < 2; ++i) {
+ vec[i] = t_var;
+ s_arr[i] = var;
+ sivar += i;
+ }
+ return tmain<int>();
+#endif
+}
+
+// CHECK: define {{.*}}i{{[0-9]+}} @main()
+// CHECK: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 5, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0)
+// CHECK: call void @[[OFFL1:.+]](i{{64|32}} %{{.+}})
+// CHECK: {{%.+}} = call{{.*}} i32 @[[TMAIN_INT:.+]]()
+// CHECK: ret
+
+// CHECK: define{{.*}} void @[[OFFL1]]({{.+}})
+// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}]*,
+// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]]*,
+// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]]*,
+// CHECK: [[SIVAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[T_VAR_CAST:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[SIVAR_CAST:%.+]] = alloca i{{[0-9]+}},
+
+// CHECK-DAG: [[VEC_TE_PAR:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** [[VEC_PRIV]],
+// CHECK-DAG: [[T_VAR_TE_PAR:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_CAST]],
+// CHECK-DAG: [[S_ARR_TE_PAR:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[S_ARR_PRIV]],
+// CHECK-DAG: [[VAR_TE_PAR:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[VAR_PRIV]],
+// CHECK-DAG: [[SIVAR_TE_PAR:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR_CAST]],
+
+// CHECK: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 5, {{.+}} @[[OUTL1:.+]] to {{.+}}, [2 x i{{[0-9]+}}]* [[VEC_TE_PAR]], i{{[0-9]+}} [[T_VAR_TE_PAR]], [2 x [[S_FLOAT_TY]]]* [[S_ARR_TE_PAR]], [[S_FLOAT_TY]]* [[VAR_TE_PAR]], i{{[0-9]+}} [[SIVAR_TE_PAR]])
+// CHECK: ret void
+
+// CHECK: define internal void @[[OUTL1]]({{.+}})
+// Skip global and bound tid vars
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: [[VEC_ADDR:%.+]] = alloca [2 x i{{[0-9]+}}]*,
+// CHECK: [[T_VAR_ADDR:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[S_ARR_ADDR:%.+]] = alloca [2 x [[S_FLOAT_TY]]]*,
+// CHECK: [[VAR_ADDR:%.+]] = alloca [[S_FLOAT_TY]]*,
+// CHECK: [[SIVAR_ADDR:%.+]] = alloca i{{[0-9]+}},
+// Skip temp vars for loop
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]],
+// CHECK: [[AGG_TMP1:%.+]] = alloca [[ST_TY]],
+// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]],
+// CHECK: [[AGG_TMP2:%.+]] = alloca [[ST_TY]],
+
+// param copy
+// CHECK: store [2 x i{{[0-9]+}}]* {{.+}}, [2 x i{{[0-9]+}}]** [[VEC_ADDR]],
+// CHECK: store i{{[0-9]+}} {{.+}}, i{{[0-9]+}}* [[T_VAR_ADDR]],
+// CHECK: store [2 x [[S_FLOAT_TY]]]* {{.+}}, [2 x [[S_FLOAT_TY]]]** [[S_ARR_ADDR]],
+// CHECK: store [[S_FLOAT_TY]]* {{.+}}, [[S_FLOAT_TY]]** [[VAR_ADDR]],
+// CHECK: store i{{[0-9]+}} {{.+}}, i{{[0-9]+}}* [[SIVAR_ADDR]],
+
+// T_VAR and SIVAR
+// CHECK-DAG-64: [[CONV_TVAR:%.+]] = bitcast i64* [[T_VAR_ADDR]] to i32*
+// CHECK-DAG-64: [[CONV_SIVAR:%.+]] = bitcast i64* [[SIVAR_ADDR]] to i32*
+
+// preparation vars
+// CHECK-DAG: [[VEC_ADDR_VAL:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** [[VEC_ADDR]],
+// CHECK-DAG: [[S_ARR_ADDR_REF:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[S_ARR_ADDR]],
+// CHECK-DAG: [[VAR_ADDR_REF:%.+]] = load{{.+}} [[VAR_ADDR]],
+
+// firstprivate vec(vec): copy from *_addr into priv1 and then from priv1 into priv2
+// CHECK-DAG: [[VEC_DEST_PRIV:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV]] to i8*
+// CHECK-DAG: [[VEC_SRC:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_ADDR_VAL]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[VEC_DEST_PRIV]], i8* [[VEC_SRC]], {{.+}})
+
+// firstprivate(s_arr)
+// CHECK-DAG: [[S_ARR_PRIV_BGN:%.+]] = getelementptr{{.*}} [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[S_ARR_PRIV]],
+// CHECK-DAG: [[S_ARR_ADDR_BGN:%.+]] = bitcast [2 x [[S_FLOAT_TY]]]* [[S_ARR_ADDR_REF]] to
+// CHECK-DAG: [[S_ARR_FIN:%.+]] = icmp{{.+}} [[S_ARR_PRIV_BGN]],
+// CHECK-DAG: [[S_ARR_SRC_COPY:%.+]] = phi{{.+}} [ [[S_ARR_ADDR_BGN]], {{.+}} ], [ [[S_ARR_SRC:%.+]], {{.+}} ]
+// CHECK-DAG: [[S_ARR_DST_COPY:%.+]] = phi{{.+}} [ [[S_ARR_PRIV_BGN]], {{.+}}], [ [[S_ARR_DST:%.+]], {{.+}} ]
+// CHECK-DAG: call void @{{.+}}({{.+}} [[AGG_TMP1]])
+// CHECK-DAG: call void @{{.+}}({{.+}} [[S_ARR_DST_COPY]], {{.+}} [[S_ARR_SRC_COPY]], {{.+}} [[AGG_TMP1]])
+// CHECK-DAG: call void @{{.+}}({{.+}} [[AGG_TMP1]])
+// CHECK-DAG: [[S_ARR_DST]] = getelementptr {{.+}} [[S_ARR_DST_COPY]],
+// CHECK-DAG: [[S_ARR_SRC]] = getelementptr {{.+}} [[S_ARR_SRC_COPY]],
+
+// firstprivate(var)
+// CHECK-DAG: call void @{{.+}}({{.+}} [[AGG_TMP2]])
+// CHECK-DAG: call void @{{.+}}({{.+}} [[VAR_PRIV]], {{.+}} [[VAR_ADDR_REF]], {{.+}} [[AGG_TMP2]])
+// CHECK-DAG: call void @{{.+}}({{.+}} [[AGG_TMP2]])
+
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: call void {{.*}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[PAR_OUTL:.+]] to
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: ret void
+
+// CHECK: define internal void @[[PAR_OUTL]]({{.+}})
+// Skip global and bound tid vars, and prev lb ub vars
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: [[VEC_ADDR:%.+]] = alloca [2 x i{{[0-9]+}}]*,
+// CHECK: [[T_VAR_ADDR:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[S_ARR_ADDR:%.+]] = alloca [2 x [[S_FLOAT_TY]]]*,
+// CHECK: [[VAR_ADDR:%.+]] = alloca [[S_FLOAT_TY]]*,
+// CHECK: [[SIVAR_ADDR:%.+]] = alloca i{{[0-9]+}},
+// Skip temp vars for loop
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]],
+// CHECK: [[AGG_TMP1:%.+]] = alloca [[ST_TY]],
+// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]],
+// CHECK: [[AGG_TMP2:%.+]] = alloca [[ST_TY]],
+
+// param copy
+// CHECK: store [2 x i{{[0-9]+}}]* {{.+}}, [2 x i{{[0-9]+}}]** [[VEC_ADDR]],
+// CHECK: store i{{[0-9]+}} {{.+}}, i{{[0-9]+}}* [[T_VAR_ADDR]],
+// CHECK: store [2 x [[S_FLOAT_TY]]]* {{.+}}, [2 x [[S_FLOAT_TY]]]** [[S_ARR_ADDR]],
+// CHECK: store [[S_FLOAT_TY]]* {{.+}}, [[S_FLOAT_TY]]** [[VAR_ADDR]],
+// CHECK: store i{{[0-9]+}} {{.+}}, i{{[0-9]+}}* [[SIVAR_ADDR]],
+
+// T_VAR and SIVAR
+// CHECK-DAG-64: [[CONV_TVAR:%.+]] = bitcast i64* [[T_VAR_ADDR]] to i32*
+// CHECK-DAG-64: [[CONV_SIVAR:%.+]] = bitcast i64* [[SIVAR_ADDR]] to i32*
+
+// preparation vars
+// CHECK-DAG: [[VEC_ADDR_VAL:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** [[VEC_ADDR]],
+// CHECK-DAG: [[S_ARR_ADDR_REF:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[S_ARR_ADDR]],
+// CHECK-DAG: [[VAR_ADDR_REF:%.+]] = load{{.+}} [[VAR_ADDR]],
+
+// firstprivate vec(vec): copy from *_addr into priv1 and then from priv1 into priv2
+// CHECK-DAG: [[VEC_DEST_PRIV:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV]] to i8*
+// CHECK-DAG: [[VEC_SRC:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_ADDR_VAL]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[VEC_DEST_PRIV]], i8* [[VEC_SRC]], {{.+}})
+
+// firstprivate(s_arr)
+// CHECK-DAG: [[S_ARR_PRIV_BGN:%.+]] = getelementptr{{.*}} [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[S_ARR_PRIV]],
+// CHECK-DAG: [[S_ARR_ADDR_BGN:%.+]] = bitcast [2 x [[S_FLOAT_TY]]]* [[S_ARR_ADDR_REF]] to
+// CHECK-DAG: [[S_ARR_FIN:%.+]] = icmp{{.+}} [[S_ARR_PRIV_BGN]],
+// CHECK-DAG: [[S_ARR_SRC_COPY:%.+]] = phi{{.+}} [ [[S_ARR_ADDR_BGN]], {{.+}} ], [ [[S_ARR_SRC:%.+]], {{.+}} ]
+// CHECK-DAG: [[S_ARR_DST_COPY:%.+]] = phi{{.+}} [ [[S_ARR_PRIV_BGN]], {{.+}}], [ [[S_ARR_DST:%.+]], {{.+}} ]
+// CHECK-DAG: call void @{{.+}}({{.+}} [[AGG_TMP1]])
+// CHECK-DAG: call void @{{.+}}({{.+}} [[S_ARR_DST_COPY]], {{.+}} [[S_ARR_SRC_COPY]], {{.+}} [[AGG_TMP1]])
+// CHECK-DAG: call void @{{.+}}({{.+}} [[AGG_TMP1]])
+// CHECK-DAG: [[S_ARR_DST]] = getelementptr {{.+}} [[S_ARR_DST_COPY]],
+// CHECK-DAG: [[S_ARR_SRC]] = getelementptr {{.+}} [[S_ARR_SRC_COPY]],
+
+// firstprivate(var)
+// CHECK-DAG: call void @{{.+}}({{.+}} [[AGG_TMP2]])
+// CHECK-DAG: call void @{{.+}}({{.+}} [[VAR_PRIV]], {{.+}} [[VAR_ADDR_REF]], {{.+}} [[AGG_TMP2]])
+// CHECK-DAG: call void @{{.+}}({{.+}} [[AGG_TMP2]])
+
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK-DAG-32: {{.+}} = {{.+}} [[T_VAR_ADDR]]
+// CHECK-DAG-64: {{.+}} = {{.+}} [[CONV_TVAR]]
+// CHECK-DAG: {{.+}} = {{.+}} [[VEC_PRIV]]
+// CHECK-DAG: {{.+}} = {{.+}} [[S_ARR_PRIV]]
+// CHECK-DAG: {{.+}} = {{.+}} [[VAR_PRIV]]
+// CHECK-DAG-32: {{.+}} = {{.+}} [[SIVAR_ADDR]]
+// CHECK-DAG-64: {{.+}} = {{.+}} [[CONV_SIVAR]]
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: ret void
+
+// CHECK: define{{.*}} i{{[0-9]+}} @[[TMAIN_INT]]()
+// CHECK: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 4, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0)
+// CHECK: call void @[[TOFFL1:.+]](i{{64|32}} %{{.+}})
+// CHECK: ret
+
+// CHECK: define {{.*}}void @[[TOFFL1]]({{.+}})
+// CHECK: [[TT_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[TVEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}]*,
+// CHECK: [[TS_ARR_PRIV:%.+]] = alloca [2 x [[S_INT_TY]]]*,
+// CHECK: [[TVAR_PRIV:%.+]] = alloca [[S_INT_TY]]*,
+// CHECK: [[TT_VAR_CAST:%.+]] = alloca i{{[0-9]+}},
+
+// CHECK-DAG: [[TVEC_TE_PAR:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** [[TVEC_PRIV]],
+// CHECK-DAG: [[TT_VAR_TE_PAR:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[TT_VAR_CAST]],
+// CHECK-DAG: [[TS_ARR_TE_PAR:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** [[TS_ARR_PRIV]],
+// CHECK-DAG: [[TVAR_TE_PAR:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[TVAR_PRIV]],
+
+// CHECK: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 4, {{.+}} @[[TOUTL1:.+]] to {{.+}}, [2 x i{{[0-9]+}}]* [[TVEC_TE_PAR]], i{{[0-9]+}} [[TT_VAR_TE_PAR]], [2 x [[S_INT_TY]]]* [[TS_ARR_TE_PAR]], [[S_INT_TY]]* [[TVAR_TE_PAR]])
+// CHECK: ret void
+
+// CHECK: define internal void @[[TOUTL1]]({{.+}})
+// Skip global and bound tid vars
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: [[VEC_ADDR:%.+]] = alloca [2 x i{{[0-9]+}}]*,
+// CHECK: [[T_VAR_ADDR:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[S_ARR_ADDR:%.+]] = alloca [2 x [[S_INT_TY]]]*,
+// CHECK: [[VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*,
+// Skip temp vars for loop
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_INT_TY]]],
+// CHECK: [[AGG_TMP1:%.+]] = alloca [[ST_TY]],
+// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_INT_TY]],
+// CHECK: [[AGG_TMP2:%.+]] = alloca [[ST_TY]],
+// CHECK: [[TMP:%.+]] = alloca [[S_INT_TY]]*,
+
+// param copy
+// CHECK: store [2 x i{{[0-9]+}}]* {{.+}}, [2 x i{{[0-9]+}}]** [[VEC_ADDR]],
+// CHECK: store i{{[0-9]+}} {{.+}}, i{{[0-9]+}}* [[T_VAR_ADDR]],
+// CHECK: store [2 x [[S_INT_TY]]]* {{.+}}, [2 x [[S_INT_TY]]]** [[S_ARR_ADDR]],
+// CHECK: store [[S_INT_TY]]* {{.+}}, [[S_INT_TY]]** [[VAR_ADDR]],
+
+// T_VAR and preparation variables
+// CHECK: [[VEC_ADDR_VAL:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** [[VEC_ADDR]],
+// CHECK-64: [[CONV_TVAR:%.+]] = bitcast i64* [[T_VAR_ADDR]] to i32*
+// CHECK: [[S_ARR_ADDR_REF:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** [[S_ARR_ADDR]],
+
+// firstprivate vec(vec): copy from *_addr into priv1 and then from priv1 into priv2
+// CHECK-DAG: [[VEC_DEST_PRIV:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV]] to i8*
+// CHECK-DAG: [[VEC_SRC:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_ADDR_VAL]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[VEC_DEST_PRIV]], i8* [[VEC_SRC]], {{.+}})
+
+// firstprivate(s_arr)
+// CHECK-DAG: [[S_ARR_PRIV_BGN:%.+]] = getelementptr{{.*}} [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[S_ARR_PRIV]],
+// CHECK-DAG: [[S_ARR_ADDR_BGN:%.+]] = bitcast [2 x [[S_INT_TY]]]* [[S_ARR_ADDR_REF]] to
+// CHECK-DAG: [[S_ARR_FIN:%.+]] = icmp{{.+}} [[S_ARR_PRIV_BGN]],
+// CHECK-DAG: [[S_ARR_SRC_COPY:%.+]] = phi{{.+}} [ [[S_ARR_ADDR_BGN]], {{.+}} ], [ [[S_ARR_SRC:%.+]], {{.+}} ]
+// CHECK-DAG: [[S_ARR_DST_COPY:%.+]] = phi{{.+}} [ [[S_ARR_PRIV_BGN]], {{.+}} ], [ [[S_ARR_DST:%.+]], {{.+}} ]
+// CHECK-DAG: call void @{{.+}}({{.+}} [[AGG_TMP1]])
+// CHECK-DAG: call void @{{.+}}({{.+}} [[S_ARR_DST_COPY]], {{.+}} [[S_ARR_SRC_COPY]], {{.+}} [[AGG_TMP1]])
+// CHECK-DAG: call void @{{.+}}({{.+}} [[AGG_TMP1]])
+// CHECK-DAG: [[S_ARR_DST]] = getelementptr {{.+}} [[S_ARR_DST_COPY]],
+// CHECK-DAG: [[S_ARR_SRC]] = getelementptr {{.+}} [[S_ARR_SRC_COPY]],
+
+// firstprivate(var)
+// CHECK-DAG: [[VAR_ADDR_REF:%.+]] = load{{.+}} [[VAR_ADDR]],
+// CHECK-DAG: call void @{{.+}}({{.+}} [[AGG_TMP2]])
+// CHECK-DAG: call void @{{.+}}({{.+}} [[VAR_PRIV]], {{.+}} [[VAR_ADDR_REF]], {{.+}} [[AGG_TMP2]])
+// CHECK-DAG: call void @{{.+}}({{.+}} [[AGG_TMP2]])
+// CHECK-DAG: store [[S_INT_TY]]* [[VAR_PRIV]], [[S_INT_TY]]** [[TMP]],
+
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: call void {{.*}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[TPAR_OUTL:.+]] to
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: ret void
+
+// CHECK: define internal void @[[TPAR_OUTL]]({{.+}})
+// Skip global and bound tid vars
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: [[VEC_ADDR:%.+]] = alloca [2 x i{{[0-9]+}}]*,
+// CHECK: [[T_VAR_ADDR:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[S_ARR_ADDR:%.+]] = alloca [2 x [[S_INT_TY]]]*,
+// CHECK: [[VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*,
+// Skip temp vars for loop
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_INT_TY]]],
+// CHECK: [[AGG_TMP1:%.+]] = alloca [[ST_TY]],
+// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_INT_TY]],
+// CHECK: [[AGG_TMP2:%.+]] = alloca [[ST_TY]],
+// CHECK: [[TMP:%.+]] = alloca [[S_INT_TY]]*,
+
+// param copy
+// CHECK: store [2 x i{{[0-9]+}}]* {{.+}}, [2 x i{{[0-9]+}}]** [[VEC_ADDR]],
+// CHECK: store i{{[0-9]+}} {{.+}}, i{{[0-9]+}}* [[T_VAR_ADDR]],
+// CHECK: store [2 x [[S_INT_TY]]]* {{.+}}, [2 x [[S_INT_TY]]]** [[S_ARR_ADDR]],
+// CHECK: store [[S_INT_TY]]* {{.+}}, [[S_INT_TY]]** [[VAR_ADDR]],
+
+// T_VAR and preparation variables
+// CHECK: [[VEC_ADDR_VAL:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** [[VEC_ADDR]],
+// CHECK-64: [[CONV_TVAR:%.+]] = bitcast i64* [[T_VAR_ADDR]] to i32*
+// CHECK: [[S_ARR_ADDR_REF:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** [[S_ARR_ADDR]],
+
+// firstprivate vec(vec): copy from *_addr into priv1 and then from priv1 into priv2
+// CHECK-DAG: [[VEC_DEST_PRIV:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV]] to i8*
+// CHECK-DAG: [[VEC_SRC:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_ADDR_VAL]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[VEC_DEST_PRIV]], i8* [[VEC_SRC]], {{.+}})
+
+// firstprivate(s_arr)
+// CHECK-DAG: [[S_ARR_PRIV_BGN:%.+]] = getelementptr{{.*}} [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[S_ARR_PRIV]],
+// CHECK-DAG: [[S_ARR_ADDR_BGN:%.+]] = bitcast [2 x [[S_INT_TY]]]* [[S_ARR_ADDR_REF]] to
+// CHECK-DAG: [[S_ARR_FIN:%.+]] = icmp{{.+}} [[S_ARR_PRIV_BGN]],
+// CHECK-DAG: [[S_ARR_SRC_COPY:%.+]] = phi{{.+}} [ [[S_ARR_ADDR_BGN]], {{.+}} ], [ [[S_ARR_SRC:%.+]], {{.+}} ]
+// CHECK-DAG: [[S_ARR_DST_COPY:%.+]] = phi{{.+}} [ [[S_ARR_PRIV_BGN]], {{.+}} ], [ [[S_ARR_DST:%.+]], {{.+}} ]
+// CHECK-DAG: call void @{{.+}}({{.+}} [[AGG_TMP1]])
+// CHECK-DAG: call void @{{.+}}({{.+}} [[S_ARR_DST_COPY]], {{.+}} [[S_ARR_SRC_COPY]], {{.+}} [[AGG_TMP1]])
+// CHECK-DAG: call void @{{.+}}({{.+}} [[AGG_TMP1]])
+// CHECK-DAG: [[S_ARR_DST]] = getelementptr {{.+}} [[S_ARR_DST_COPY]],
+// CHECK-DAG: [[S_ARR_SRC]] = getelementptr {{.+}} [[S_ARR_SRC_COPY]],
+
+// firstprivate(var)
+// CHECK-DAG: [[VAR_ADDR_REF:%.+]] = load{{.+}} [[VAR_ADDR]],
+// CHECK-DAG: call void @{{.+}}({{.+}} [[AGG_TMP2]])
+// CHECK-DAG: call void @{{.+}}({{.+}} [[VAR_PRIV]], {{.+}} [[VAR_ADDR_REF]], {{.+}} [[AGG_TMP2]])
+// CHECK-DAG: call void @{{.+}}({{.+}} [[AGG_TMP2]])
+// CHECK-DAG: store [[S_INT_TY]]* [[VAR_PRIV]], [[S_INT_TY]]** [[TMP]],
+
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK-DAG-32: {{.+}} = {{.+}} [[T_VAR_ADDR]]
+// CHECK-DAG-64: {{.+}} = {{.+}} [[CONV_TVAR]]
+// CHECK-DAG: {{.+}} = {{.+}} [[VEC_PRIV]]
+// CHECK-DAG: {{.+}} = {{.+}} [[TMP]]
+// CHECK-DAG: {{.+}} = {{.+}} [[S_ARR_PRIV]]
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: ret void
+
+// CHECK: !{!"llvm.loop.vectorize.enable", i1 true}
+
+#endif
diff --git a/test/OpenMP/teams_distribute_parallel_for_simd_firstprivate_messages.cpp b/test/OpenMP/teams_distribute_parallel_for_simd_firstprivate_messages.cpp
index cbbb313c06b3..668337db454b 100644
--- a/test/OpenMP/teams_distribute_parallel_for_simd_firstprivate_messages.cpp
+++ b/test/OpenMP/teams_distribute_parallel_for_simd_firstprivate_messages.cpp
@@ -144,8 +144,9 @@ int main(int argc, char **argv) {
#pragma omp teams distribute parallel for simd firstprivate(j)
for (i = 0; i < argc; ++i) foo();
+// expected-error@+2 {{lastprivate variable cannot be firstprivate}} expected-note@+2 {{defined as lastprivate}}
#pragma omp target
-#pragma omp teams distribute parallel for simd lastprivate(argc), firstprivate(argc) // OK
+#pragma omp teams distribute parallel for simd lastprivate(argc), firstprivate(argc)
for (i = 0; i < argc; ++i) foo();
return 0;
diff --git a/test/OpenMP/teams_distribute_parallel_for_simd_if_codegen.cpp b/test/OpenMP/teams_distribute_parallel_for_simd_if_codegen.cpp
new file mode 100644
index 000000000000..6f2cef88cbbc
--- /dev/null
+++ b/test/OpenMP/teams_distribute_parallel_for_simd_if_codegen.cpp
@@ -0,0 +1,187 @@
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple %itanium_abi_triple -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple %itanium_abi_triple -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+void fn1();
+void fn2();
+void fn3();
+void fn4();
+void fn5();
+void fn6();
+
+int Arg;
+
+// CHECK-LABEL: define {{.*}}void @{{.+}}gtid_test
+void gtid_test() {
+#pragma omp target
+// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+// CHECK: call void [[OFFLOADING_FUN_0:@.+]](
+// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+// CHECK: call void [[OFFLOADING_FUN_1:@.+]](
+#pragma omp teams distribute parallel for simd
+ for(int i = 0 ; i < 100; i++) {}
+ // CHECK: define internal void [[OFFLOADING_FUN_0]](
+ // CHECK: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, i32 0, {{.+}}* [[OMP_TEAMS_OUTLINED_0:@.+]] to {{.+}})
+ // CHECK: define{{.+}} void [[OMP_TEAMS_OUTLINED_0]](
+ // CHECK: call void @__kmpc_for_static_init_4(
+ // CHECK: call void {{.+}} @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{.+}} 2, {{.+}}* [[OMP_OUTLINED_0:@.+]] to void
+ // CHECK: call void @__kmpc_for_static_fini(
+
+ // CHECK: define{{.+}} void [[OMP_OUTLINED_0]](
+ // CHECK: call void @__kmpc_for_static_init_4(
+ // CHECK: call void @__kmpc_for_static_fini(
+ // CHECK: ret
+#pragma omp target
+#pragma omp teams distribute parallel for simd if (parallel: false)
+ for(int i = 0 ; i < 100; i++) {
+ // CHECK: define internal void [[OFFLOADING_FUN_1]](
+ // CHECK: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, i32 0, {{.+}}* [[OMP_TEAMS_OUTLINED_1:@.+]] to {{.+}})
+ // CHECK: define{{.+}} void [[OMP_TEAMS_OUTLINED_1]](
+ // CHECK: call void @__kmpc_for_static_init_4(
+ // CHECK: call void @__kmpc_serialized_parallel(
+ // CHECK: call void [[OMP_OUTLINED_1:@.+]](
+ // CHECK: call void @__kmpc_end_serialized_parallel(
+ // CHECK: call void @__kmpc_for_static_fini(
+ // CHECK: define{{.+}} void [[OMP_OUTLINED_1]](
+ // CHECK: call void @__kmpc_for_static_init_4(
+ // CHECK: call void @{{.+}}gtid_test
+ // CHECK: call void @__kmpc_for_static_fini(
+ // CHECK: ret
+ gtid_test();
+ }
+}
+
+
+template <typename T>
+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();
+ }
+ return 0;
+}
+
+// CHECK-LABEL: define {{.*}}i{{[0-9]+}} @main()
+int main() {
+// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+// CHECK: call void [[OFFLOADING_FUN_0:@.+]](
+// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+// CHECK: call void [[OFFLOADING_FUN_1:@.+]](
+// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+// CHECK: call void [[OFFLOADING_FUN_2:@.+]](
+// CHECK: = call {{.*}}i{{.+}} @{{.+}}tmain
+#pragma omp target
+#pragma omp teams distribute parallel for simd if (true)
+ for(int i = 0 ; i < 100; i++) {
+ // CHECK: define internal void [[OFFLOADING_FUN_0]](
+ // CHECK: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, i32 0, {{.+}}* [[OMP_TEAMS_OUTLINED_0:@.+]] to {{.+}})
+ // CHECK: define{{.+}} void [[OMP_TEAMS_OUTLINED_0]](
+
+ // CHECK: call void @__kmpc_for_static_init_4(
+ // CHECK: call void {{.+}} @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{.+}} 2, {{.+}}* [[OMP_OUTLINED_2:@.+]] to void
+ // CHECK: call void @__kmpc_for_static_fini(
+ // CHECK: define{{.+}} void [[OMP_OUTLINED_2]](
+ // CHECK: call void @__kmpc_for_static_init_4(
+ // CHECK: call {{.*}}void @{{.+}}fn4
+ // CHECK: call void @__kmpc_for_static_fini(
+
+ fn4();
+ }
+
+#pragma omp target
+#pragma omp teams distribute parallel for simd if (false)
+ for(int i = 0 ; i < 100; i++) {
+ // CHECK: define internal void [[OFFLOADING_FUN_1]](
+ // CHECK: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, i32 0, {{.+}}* [[OMP_TEAMS_OUTLINED_1:@.+]] to {{.+}})
+ // CHECK: define{{.+}} void [[OMP_TEAMS_OUTLINED_1]](
+
+ // CHECK: call void @__kmpc_for_static_init_4(
+ // CHECK: call void @__kmpc_serialized_parallel(
+ // CHECK: call void [[OMP_OUTLINED_3:@.+]](
+ // CHECK: call void @__kmpc_end_serialized_parallel(
+ // CHECK: call void @__kmpc_for_static_fini(
+
+ // CHECK: define{{.+}} void [[OMP_OUTLINED_3]](
+ // CHECK: call void @__kmpc_for_static_init_4(
+ // CHECK: call {{.*}}void @{{.+}}fn5
+ // CHECK: call void @__kmpc_for_static_fini(
+ fn5();
+ }
+
+#pragma omp target
+#pragma omp teams distribute parallel for simd if (Arg)
+ for(int i = 0 ; i < 100; i++) {
+ // CHECK: define internal void [[OFFLOADING_FUN_2]](
+ // CHECK: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}}* [[OMP_TEAMS_OUTLINED_2:@.+]] to {{.+}})
+ // CHECK: define{{.+}} void [[OMP_TEAMS_OUTLINED_2]](
+
+ // CHECK: call void @__kmpc_for_static_init_4(
+ // CHECK: call void {{.+}} @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{.+}} 2, {{.+}}* [[OMP_OUTLINED_4:@.+]] to void
+ // CHECK: call void @__kmpc_serialized_parallel(
+ // CHECK: call void [[OMP_OUTLINED_4:@.+]](
+ // CHECK: call void @__kmpc_end_serialized_parallel(
+ // CHECK: call void @__kmpc_for_static_fini(
+
+ // CHECK: define{{.+}} void [[OMP_OUTLINED_4]](
+ // CHECK: call void @__kmpc_for_static_init_4(
+ // CHECK: call {{.*}}void @{{.+}}fn6
+ // CHECK: call void @__kmpc_for_static_fini(
+ fn6();
+ }
+
+ return tmain(Arg);
+}
+
+// CHECK-LABEL: define {{.+}} @{{.+}}tmain
+
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: call {{.*}}void {{.+}} @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{.+}} 2, void {{.+}}* [[T_OUTLINE_FUN_1:@.+]] to void
+// CHECK: call void @__kmpc_for_static_fini(
+
+// CHECK: define internal {{.*}}void [[T_OUTLINE_FUN_1]]
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: call {{.*}}void @{{.+}}fn1
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: ret void
+
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: call {{.*}}void @__kmpc_serialized_parallel(
+// CHECK: call void [[T_OUTLINE_FUN_2:@.+]](
+// CHECK: call {{.*}}void @__kmpc_end_serialized_parallel(
+// CHECK: call void @__kmpc_for_static_fini(
+
+// CHECK: define internal {{.*}}void [[T_OUTLINE_FUN_2]]
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: call {{.*}}void @{{.+}}fn2
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: ret void
+
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: call {{.*}}void {{.+}} @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{.+}} 2, void {{.+}}* [[T_OUTLINE_FUN_3:@.+]] to void
+// CHECK: call {{.*}}void @__kmpc_serialized_parallel(
+// call void [[T_OUTLINE_FUN_3:@.+]](
+// CHECK: call {{.*}}void @__kmpc_end_serialized_parallel(
+
+// CHECK: define internal {{.*}}void [[T_OUTLINE_FUN_3]]
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: call {{.*}}void @{{.+}}fn3
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: ret void
+
+// CHECK: !{!"llvm.loop.vectorize.enable", i1 true}
+
+#endif
diff --git a/test/OpenMP/teams_distribute_parallel_for_simd_lastprivate_codegen.cpp b/test/OpenMP/teams_distribute_parallel_for_simd_lastprivate_codegen.cpp
new file mode 100644
index 000000000000..5df893d525f4
--- /dev/null
+++ b/test/OpenMP/teams_distribute_parallel_for_simd_lastprivate_codegen.cpp
@@ -0,0 +1,599 @@
+// RUN: %clang_cc1 -DLAMBDA -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+// RUN: %clang_cc1 -DLAMBDA -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-32
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-32
+
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+template <class T>
+struct S {
+ T f;
+ S(T a) : f(a) {}
+ S() : f() {}
+ operator T() { return T(); }
+ ~S() {}
+};
+
+// CHECK: [[S_FLOAT_TY:%.+]] = type { float }
+// CHECK: [[S_INT_TY:%.+]] = type { i{{[0-9]+}} }
+template <typename T>
+T tmain() {
+ S<T> test;
+ T t_var = T();
+ T vec[] = {1, 2};
+ S<T> s_arr[] = {1, 2};
+ S<T> &var = test;
+ #pragma omp target
+ #pragma omp teams distribute parallel for simd lastprivate(t_var, vec, s_arr, s_arr, var, var)
+ for (int i = 0; i < 2; ++i) {
+ vec[i] = t_var;
+ s_arr[i] = var;
+ }
+ return T();
+}
+
+int main() {
+ static int svar;
+ volatile double g;
+ volatile double &g1 = g;
+
+ #ifdef LAMBDA
+ // LAMBDA-LABEL: @main
+ // LAMBDA: call{{.*}} void [[OUTER_LAMBDA:@.+]](
+ [&]() {
+ static float sfvar;
+ // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
+ // LAMBDA: call i{{[0-9]+}} @__tgt_target_teams(
+ // LAMBDA: call void [[OFFLOADING_FUN:@.+]](
+
+ // LAMBDA: define{{.+}} void [[OFFLOADING_FUN]](
+ // LAMBDA: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, i32 4, {{.+}}* [[OMP_OUTLINED:@.+]] to {{.+}})
+ #pragma omp target
+ #pragma omp teams distribute parallel for simd lastprivate(g, g1, svar, sfvar)
+ for (int i = 0; i < 2; ++i) {
+ // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_OUTLINED]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, double*{{.+}} [[G_IN:%.+]], double*{{.+}} [[G1_IN:%.+]], i{{[0-9]+}}*{{.+}} [[SVAR_IN:%.+]], float*{{.+}} [[SFVAR_IN:%.+]])
+ // LAMBDA: [[G_PRIVATE_ADDR:%.+]] = alloca double*,
+ // LAMBDA: [[G1_PRIVATE_ADDR:%.+]] = alloca double*,
+ // LAMBDA: [[SVAR_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}*,
+ // LAMBDA: [[SFVAR_PRIVATE_ADDR:%.+]] = alloca float*,
+ // loop variables
+ // LAMBDA: {{.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: {{.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: {{.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: {{.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: {{.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: [[OMP_IS_LAST:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[G_PRIVATE:%.+]] = alloca double,
+ // LAMBDA: [[G1_PRIVATE:%.+]] = alloca double,
+ // LAMBDA: [[TMP_G1_PRIVATE:%.+]] = alloca double*,
+ // LAMBDA: [[SVAR_PRIVATE:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[SFVAR_PRIVATE:%.+]] = alloca float,
+ // LAMBDA: store double* [[G_IN]], double** [[G_PRIVATE_ADDR]],
+ // LAMBDA: store double* [[G1_IN]], double** [[G1_PRIVATE_ADDR]],
+ // LAMBDA: store i{{[0-9]+}}* [[SVAR_IN]], i{{[0-9]+}}** [[SVAR_PRIVATE_ADDR]],
+ // LAMBDA: store float* [[SFVAR_IN]], float** [[SFVAR_PRIVATE_ADDR]],
+
+ // init private variables
+ // LAMBDA: [[G_IN_REF:%.+]] = load double*, double** [[G_PRIVATE_ADDR]],
+ // LAMBDA: [[SVAR_IN_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SVAR_PRIVATE_ADDR]],
+ // LAMBDA: [[SFVAR_IN_REF:%.+]] = load float*, float** [[SFVAR_PRIVATE_ADDR]],
+ // LAMBDA: [[G1_IN_REF:%.+]] = load double*, double** [[G1_PRIVATE_ADDR]],
+ // LAMBDA: store double* [[G1_PRIVATE]], double** [[TMP_G1_PRIVATE]],
+ g = 1;
+ g1 = 1;
+ svar = 3;
+ sfvar = 4.0;
+ // LAMBDA: call {{.*}}void @__kmpc_for_static_init_4(
+ // LAMBDA: call void {{.*}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[LPAR_OUTL:.+]] to
+ // LAMBDA: call {{.*}}void @__kmpc_for_static_fini(
+ // skip final branch
+ // LAMBDA: br
+ // LAMBDA: [[OMP_IS_LAST_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[OMP_IS_LAST]],
+ // LAMBDA: [[IS_LAST_IT:%.+]] = icmp ne i{{[0-9]+}} [[OMP_IS_LAST_VAL]], 0
+ // LAMBDA: br i1 [[IS_LAST_IT]], label %[[OMP_LASTPRIV_BLOCK:.+]], label %[[OMP_LASTPRIV_DONE:.+]]
+
+ // LAMBDA: [[OMP_LASTPRIV_BLOCK]]:
+ // LAMBDA: [[G_PRIV_VAL:%.+]] = load double, double* [[G_PRIVATE]],
+ // LAMBDA: store{{.*}} double [[G_PRIV_VAL]], double* [[G_IN_REF]],
+ // LAMBDA: [[TMP_G1_PRIV_REF:%.+]] = load double*, double** [[TMP_G1_PRIVATE]],
+ // LAMBDA: [[TMP_G1_PRIV_VAL:%.+]] = load double, double* [[TMP_G1_PRIV_REF]],
+ // LAMBDA: store{{.*}} double [[TMP_G1_PRIV_VAL]], double* [[G1_IN_REF]],
+
+ // LAMBDA: [[SVAR_PRIV_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SVAR_PRIVATE]],
+ // LAMBDA: store i{{[0-9]+}} [[SVAR_PRIV_VAL]], i{{[0-9]+}}* [[SVAR_IN_REF]],
+ // LAMBDA: [[SFVAR_PRIV_VAL:%.+]] = load float, float* [[SFVAR_PRIVATE]],
+ // LAMBDA: store float [[SFVAR_PRIV_VAL]], float* [[SFVAR_IN_REF]],
+ // LAMBDA: br label %[[OMP_LASTPRIV_DONE]]
+ // LAMBDA: [[OMP_LASTPRIV_DONE]]:
+ // LAMBDA: ret
+
+ // LAMBDA: define{{.*}} internal{{.*}} void @[[LPAR_OUTL]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, {{.+}}, {{.+}}, double*{{.+}} [[G_IN:%.+]], double*{{.+}} [[G1_IN:%.+]], i{{[0-9]+}}*{{.+}} [[SVAR_IN:%.+]], float*{{.+}} [[SFVAR_IN:%.+]])
+ // LAMBDA: [[G_PRIVATE_ADDR:%.+]] = alloca double*,
+ // LAMBDA: [[G1_PRIVATE_ADDR:%.+]] = alloca double*,
+ // LAMBDA: [[SVAR_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}*,
+ // LAMBDA: [[SFVAR_PRIVATE_ADDR:%.+]] = alloca float*,
+ // loop variables
+ // LAMBDA: {{.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: {{.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: {{.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: {{.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: {{.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: [[OMP_IS_LAST:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[G_PRIVATE:%.+]] = alloca double,
+ // LAMBDA: [[G1_PRIVATE:%.+]] = alloca double,
+ // LAMBDA: [[TMP_G1_PRIVATE:%.+]] = alloca double*,
+ // LAMBDA: [[SVAR_PRIVATE:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[SFVAR_PRIVATE:%.+]] = alloca float,
+ // LAMBDA: store double* [[G_IN]], double** [[G_PRIVATE_ADDR]],
+ // LAMBDA: store double* [[G1_IN]], double** [[G1_PRIVATE_ADDR]],
+ // LAMBDA: store i{{[0-9]+}}* [[SVAR_IN]], i{{[0-9]+}}** [[SVAR_PRIVATE_ADDR]],
+ // LAMBDA: store float* [[SFVAR_IN]], float** [[SFVAR_PRIVATE_ADDR]],
+
+ // init private variables
+ // LAMBDA: [[G_IN_REF:%.+]] = load double*, double** [[G_PRIVATE_ADDR]],
+ // LAMBDA: [[SVAR_IN_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SVAR_PRIVATE_ADDR]],
+ // LAMBDA: [[SFVAR_IN_REF:%.+]] = load float*, float** [[SFVAR_PRIVATE_ADDR]],
+ // LAMBDA: [[G1_IN_REF:%.+]] = load double*, double** [[G1_PRIVATE_ADDR]],
+ // LAMBDA: store double* [[G1_PRIVATE]], double** [[TMP_G1_PRIVATE]],
+
+ // LAMBDA: call {{.*}}void @__kmpc_for_static_init_4(
+ // LAMBDA: store double 1.0{{.+}}, double* [[G_PRIVATE]],
+ // LAMBDA: [[TMP_G1_REF:%.+]] = load double*, double** [[TMP_G1_PRIVATE]],
+ // LAMBDA: store{{.+}} double 1.0{{.+}}, double* [[TMP_G1_REF]],
+ // LAMBDA: store i{{[0-9]+}} 3, i{{[0-9]+}}* [[SVAR_PRIVATE]],
+ // LAMBDA: store float 4.0{{.+}}, float* [[SFVAR_PRIVATE]],
+ // LAMBDA: [[G_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // LAMBDA: store double* [[G_PRIVATE]], double** [[G_PRIVATE_ADDR_REF]],
+ // LAMBDA: [[TMP_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // LAMBDA: [[G1_PRIVATE_ADDR_FROM_TMP:%.+]] = load double*, double** [[TMP_G1_PRIVATE]],
+ // LAMBDA: store double* [[G1_PRIVATE_ADDR_FROM_TMP]], double** [[TMP_PRIVATE_ADDR_REF]],
+ // LAMBDA: [[SVAR_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+ // LAMBDA: store i{{[0-9]+}}* [[SVAR_PRIVATE]], i{{[0-9]+}}** [[SVAR_PRIVATE_ADDR_REF]]
+ // LAMBDA: [[SFVAR_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 3
+ // LAMBDA: store float* [[SFVAR_PRIVATE]], float** [[SFVAR_PRIVATE_ADDR_REF]]
+ // LAMBDA: call{{.*}} void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]])
+ // LAMBDA: call {{.*}}void @__kmpc_for_static_fini(
+
+ // skip 'final' simd branch and block (checked as part of simd)
+ // LAMBDA: br
+
+ // LAMBDA: [[OMP_IS_LAST_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[OMP_IS_LAST]],
+ // LAMBDA: [[IS_LAST_IT:%.+]] = icmp ne i{{[0-9]+}} [[OMP_IS_LAST_VAL]], 0
+ // LAMBDA: br i1 [[IS_LAST_IT]], label %[[OMP_LASTPRIV_BLOCK:.+]], label %[[OMP_LASTPRIV_DONE:.+]]
+
+ // LAMBDA: [[OMP_LASTPRIV_BLOCK]]:
+ // LAMBDA: [[G_PRIV_VAL:%.+]] = load double, double* [[G_PRIVATE]],
+ // LAMBDA: store{{.*}} double [[G_PRIV_VAL]], double* [[G_IN_REF]],
+ // LAMBDA: [[TMP_G1_PRIV_REF:%.+]] = load double*, double** [[TMP_G1_PRIVATE]],
+ // LAMBDA: [[TMP_G1_PRIV_VAL:%.+]] = load double, double* [[TMP_G1_PRIV_REF]],
+ // LAMBDA: store{{.*}} double [[TMP_G1_PRIV_VAL]], double* [[G1_IN_REF]],
+
+ // LAMBDA: [[SVAR_PRIV_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SVAR_PRIVATE]],
+ // LAMBDA: store i{{[0-9]+}} [[SVAR_PRIV_VAL]], i{{[0-9]+}}* [[SVAR_IN_REF]],
+ // LAMBDA: [[SFVAR_PRIV_VAL:%.+]] = load float, float* [[SFVAR_PRIVATE]],
+ // LAMBDA: store float [[SFVAR_PRIV_VAL]], float* [[SFVAR_IN_REF]],
+ // LAMBDA: br label %[[OMP_LASTPRIV_DONE]]
+ // LAMBDA: [[OMP_LASTPRIV_DONE]]:
+ // LAMBDA: ret
+
+ [&]() {
+ // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]])
+ // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]],
+ g = 2;
+ g1 = 2;
+ svar = 4;
+ sfvar = 8.0;
+ // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]]
+ // LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // LAMBDA: [[G_REF:%.+]] = load double*, double** [[G_PTR_REF]]
+ // LAMBDA: store double 2.0{{.+}}, double* [[G_REF]]
+
+ // LAMBDA: [[TMP_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // LAMBDA: [[G1_REF:%.+]] = load double*, double** [[TMP_PTR_REF]]
+ // LAMBDA: store double 2.0{{.+}}, double* [[G1_REF]],
+ // LAMBDA: [[SVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+ // LAMBDA: [[SVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SVAR_PTR_REF]]
+ // LAMBDA: store i{{[0-9]+}} 4, i{{[0-9]+}}* [[SVAR_REF]]
+ // LAMBDA: [[SFVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 3
+ // LAMBDA: [[SFVAR_REF:%.+]] = load float*, float** [[SFVAR_PTR_REF]]
+ // LAMBDA: store float 8.0{{.+}}, float* [[SFVAR_REF]]
+ }();
+ }
+ }();
+ return 0;
+
+// LAMBDA: !{!"llvm.loop.vectorize.enable", i1 true}
+
+ #else
+ S<float> test;
+ int t_var = 0;
+ int vec[] = {1, 2};
+ S<float> s_arr[] = {1, 2};
+ S<float> &var = test;
+
+ #pragma omp target
+ #pragma omp teams distribute parallel for simd lastprivate(t_var, vec, s_arr, s_arr, var, var, svar)
+ for (int i = 0; i < 2; ++i) {
+ vec[i] = t_var;
+ s_arr[i] = var;
+ }
+ int i;
+
+ return tmain<int>();
+ #endif
+}
+
+// CHECK: define{{.*}} i{{[0-9]+}} @main()
+// CHECK: [[TEST:%.+]] = alloca [[S_FLOAT_TY]],
+// CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR:@.+]]([[S_FLOAT_TY]]* [[TEST]])
+// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+// CHECK: call void [[OFFLOAD_FUN:@.+]](i{{[0-9]+}} {{.+}}, [2 x i{{[0-9]+}}]* {{.+}}, [2 x [[S_FLOAT_TY]]]* {{.+}}, [[S_FLOAT_TY]]* {{.+}}, i{{[0-9]+}} {{.+}})
+// CHECK: ret
+
+// CHECK: define{{.+}} [[OFFLOAD_FUN]](i{{[0-9]+}} {{.+}}, [2 x i{{[0-9]+}}]*{{.+}} {{.+}}, [2 x [[S_FLOAT_TY]]]*{{.+}} {{.+}}, [[S_FLOAT_TY]]*{{.+}} {{.+}}, i{{[0-9]+}} {{.+}})
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_teams(
+// CHECK: ret
+//
+// CHECK: define internal void [[OMP_OUTLINED:@.+]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [2 x i{{[0-9]+}}]*{{.+}} [[VEC_IN:%.+]], i{{[0-9]+}}*{{.+}} [[T_VAR_IN:%.+]], [2 x [[S_FLOAT_TY]]]*{{.+}} [[S_ARR_IN:%.+]], [[S_FLOAT_TY]]*{{.+}} [[VAR_IN:%.+]], i{{[0-9]+}}*{{.*}} [[S_VAR_IN:%.+]])
+// CHECK: {{.+}} = alloca i{{[0-9]+}}*,
+// CHECK: {{.+}} = alloca i{{[0-9]+}}*,
+// CHECK: [[VEC_ADDR:%.+]] = alloca [2 x i{{[0-9]+}}]*,
+// CHECK: [[T_VAR_ADDR:%.+]] = alloca i{{[0-9]+}}*,
+// CHECK: [[S_ARR_ADDR:%.+]] = alloca [2 x [[S_FLOAT_TY]]]*,
+// CHECK: [[VAR_ADDR:%.+]] = alloca [[S_FLOAT_TY]]*,
+// CHECK: [[SVAR_ADDR:%.+]] = alloca i{{[0-9]+}}*,
+// skip loop variables
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: [[OMP_IS_LAST:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]],
+// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]],
+// CHECK: [[TMP_PRIV:%.+]] = alloca [[S_FLOAT_TY]]*,
+// CHECK: [[S_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+
+// copy from parameters to local address variables
+// CHECK: store [2 x i{{[0-9]+}}]* [[VEC_IN]], [2 x i{{[0-9]+}}]** [[VEC_ADDR]],
+// CHECK: store i{{[0-9]+}}* [[T_VAR_IN]], i{{[0-9]+}}** [[T_VAR_ADDR]],
+// CHECK: store [2 x [[S_FLOAT_TY]]]* [[S_ARR_IN]], [2 x [[S_FLOAT_TY]]]** [[S_ARR_ADDR]],
+// CHECK: store [[S_FLOAT_TY]]* [[VAR_IN]], [[S_FLOAT_TY]]** [[VAR_ADDR]],
+// CHECK: store i{{[0-9]+}}* [[S_VAR_IN]], i{{[0-9]+}}** [[SVAR_ADDR]],
+
+// load content of local address variables
+// CHECK: [[VEC_ADDR_REF:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** [[VEC_ADDR]],
+// CHECK: [[T_VAR_ADDR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[T_VAR_ADDR]],
+// CHECK: [[S_ARR_ADDR_REF:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[S_ARR_ADDR]],
+// CHECK: [[SVAR_ADDR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SVAR_ADDR]],
+// CHECK: store i{{[0-9]+}} 0, i{{[0-9]+}}* [[OMP_IS_LAST]],
+// CHECK: [[VAR_ADDR_REF:%.+]] = load {{.+}}, {{.+}} [[VAR_ADDR]],
+// the distribute loop
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: call void {{.*}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[PAR_OUTL:.+]] to
+// CHECK: call void @__kmpc_for_static_fini(
+
+// lastprivates
+// CHECK: [[OMP_IS_LAST_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[OMP_IS_LAST]],
+// CHECK: [[IS_LAST_IT:%.+]] = icmp ne i{{[0-9]+}} [[OMP_IS_LAST_VAL]], 0
+// CHECK: br i1 [[IS_LAST_IT]], label %[[OMP_LASTPRIV_BLOCK:.+]], label %[[OMP_LASTPRIV_DONE:.+]]
+
+// CHECK: [[OMP_LASTPRIV_BLOCK]]:
+// CHECK: [[T_VAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_PRIV]],
+// CHECK: store i{{[0-9]+}} [[T_VAR_VAL]], i{{[0-9]+}}* [[T_VAR_ADDR_REF]],
+// CHECK: [[BCAST_VEC_ADDR_REF:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_ADDR_REF]] to i8*
+// CHECK: [[BCAST_VEC_PRIV:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[BCAST_VEC_ADDR_REF]], i8* [[BCAST_VEC_PRIV]],
+// CHECK: [[S_ARR_BEGIN:%.+]] = getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[S_ARR_ADDR_REF]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+// CHECK: [[S_ARR_PRIV_BCAST:%.+]] = bitcast [2 x [[S_FLOAT_TY]]]* [[S_ARR_PRIV]] to [[S_FLOAT_TY]]*
+// CHECK: [[S_ARR_BEGIN_GEP:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[S_ARR_BEGIN]], i{{[0-9]+}} 2
+// CHECK: [[S_ARR_IS_EMPTY:%.+]] = icmp eq [[S_FLOAT_TY]]* [[S_ARR_BEGIN]], [[S_ARR_BEGIN_GEP]]
+// CHECK: br i1 [[S_ARR_IS_EMPTY]], label %[[S_ARR_COPY_DONE:.+]], label %[[S_ARR_COPY_BLOCK:.+]]
+// CHECK: [[S_ARR_COPY_BLOCK]]:
+// CHECK: [[S_ARR_SRC_EL:%.+]] = phi [[S_FLOAT_TY]]*{{.+}}
+// CHECK: [[S_ARR_DST_EL:%.+]] = phi [[S_FLOAT_TY]]*{{.+}}
+// CHECK: [[S_ARR_DST_BCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[S_ARR_DST_EL]] to i8*
+// CHECK: [[S_ARR_SRC_BCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[S_ARR_SRC_EL]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[S_ARR_DST_BCAST]], i8* [[S_ARR_SRC_BCAST]]{{.+}})
+// CHECK: [[S_ARR_DST_NEXT:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[S_ARR_DST_EL]], i{{[0-9]+}} 1
+// CHECK: [[S_ARR_SRC_NEXT:%.+]] = getelementptr{{.+}}
+// CHECK: [[CPY_IS_FINISHED:%.+]] = icmp eq [[S_FLOAT_TY]]* [[S_ARR_DST_NEXT]], [[S_ARR_BEGIN_GEP]]
+// CHECK: br i1 [[CPY_IS_FINISHED]], label %[[S_ARR_COPY_DONE]], label %[[S_ARR_COPY_BLOCK]]
+// CHECK: [[S_ARR_COPY_DONE]]:
+// CHECK: [[TMP_VAL1:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[TMP_PRIV]],
+// CHECK: [[VAR_ADDR_REF_BCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[VAR_ADDR_REF]] to i8*
+// CHECK: [[TMP_VAL1_BCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[TMP_VAL1]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[VAR_ADDR_REF_BCAST]], i8* [[TMP_VAL1_BCAST]],{{.+}})
+// CHECK: [[SVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[S_VAR_PRIV]],
+// CHECK: store i{{[0-9]+}} [[SVAR_VAL]], i{{[0-9]+}}* [[SVAR_ADDR_REF]],
+// CHECK: ret void
+
+// CHECK: define internal void [[OMP_OUTLINED:@.+]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, {{.+}}, {{.+}}, [2 x i{{[0-9]+}}]*{{.+}} [[VEC_IN:%.+]], i{{[0-9]+}}*{{.+}} [[T_VAR_IN:%.+]], [2 x [[S_FLOAT_TY]]]*{{.+}} [[S_ARR_IN:%.+]], [[S_FLOAT_TY]]*{{.+}} [[VAR_IN:%.+]], i{{[0-9]+}}*{{.*}} [[S_VAR_IN:%.+]])
+// gbl and bound tid vars, prev lb and ub vars
+// CHECK: {{.+}} = alloca i{{[0-9]+}}*,
+// CHECK: {{.+}} = alloca i{{[0-9]+}}*,
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: [[VEC_ADDR:%.+]] = alloca [2 x i{{[0-9]+}}]*,
+// CHECK: [[T_VAR_ADDR:%.+]] = alloca i{{[0-9]+}}*,
+// CHECK: [[S_ARR_ADDR:%.+]] = alloca [2 x [[S_FLOAT_TY]]]*,
+// CHECK: [[VAR_ADDR:%.+]] = alloca [[S_FLOAT_TY]]*,
+// CHECK: [[SVAR_ADDR:%.+]] = alloca i{{[0-9]+}}*,
+// skip loop variables
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: [[OMP_IS_LAST:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]],
+// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]],
+// CHECK: [[TMP_PRIV:%.+]] = alloca [[S_FLOAT_TY]]*,
+// CHECK: [[S_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+
+// copy from parameters to local address variables
+// CHECK: store [2 x i{{[0-9]+}}]* [[VEC_IN]], [2 x i{{[0-9]+}}]** [[VEC_ADDR]],
+// CHECK: store i{{[0-9]+}}* [[T_VAR_IN]], i{{[0-9]+}}** [[T_VAR_ADDR]],
+// CHECK: store [2 x [[S_FLOAT_TY]]]* [[S_ARR_IN]], [2 x [[S_FLOAT_TY]]]** [[S_ARR_ADDR]],
+// CHECK: store [[S_FLOAT_TY]]* [[VAR_IN]], [[S_FLOAT_TY]]** [[VAR_ADDR]],
+// CHECK: store i{{[0-9]+}}* [[S_VAR_IN]], i{{[0-9]+}}** [[SVAR_ADDR]],
+
+// load content of local address variables
+// CHECK: [[VEC_ADDR_REF:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** [[VEC_ADDR]],
+// CHECK: [[T_VAR_ADDR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[T_VAR_ADDR]],
+// CHECK: [[S_ARR_ADDR_REF:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[S_ARR_ADDR]],
+// CHECK: [[SVAR_ADDR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SVAR_ADDR]],
+// CHECK: store i{{[0-9]+}} 0, i{{[0-9]+}}* [[OMP_IS_LAST]],
+// CHECK: [[VAR_ADDR_REF:%.+]] = load {{.+}}, {{.+}} [[VAR_ADDR]],
+// the distribute loop
+// CHECK: call void @__kmpc_for_static_init_4(
+
+// assignment: vec[i] = t_var;
+// CHECK: [[T_VAR_PRIV_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_PRIV]],
+// CHECK: [[VEC_PTR:%.+]] = getelementptr inbounds [2 x i{{[0-9]+}}], [2 x i{{[0-9]+}}]* [[VEC_PRIV]], i{{[0-9]+}} 0, i{{[0-9]+}} {{.+}}
+// CHECK: store i{{[0-9]+}} [[T_VAR_PRIV_VAL]], i{{[0-9]+}}* [[VEC_PTR]],
+
+// assignment: s_arr[i] = var;
+// CHECK-DAG: [[S_ARR_PTR:%.+]] = getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[S_ARR_PRIV]],
+// CHECK-DAG: [[TMP_VAL:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[TMP_PRIV]],
+// CHECK-DAG: [[S_ARR_PTR_BCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[S_ARR_PTR]] to i8*
+// CHECK-DAG: [[TMP_VAL_BCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[TMP_VAL]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[S_ARR_PTR_BCAST]], i8* [[TMP_VAL_BCAST]],
+
+// CHECK: call void @__kmpc_for_static_fini(
+
+// skip final branch and block
+// CHECK: br
+
+// lastprivates
+// CHECK: [[OMP_IS_LAST_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[OMP_IS_LAST]],
+// CHECK: [[IS_LAST_IT:%.+]] = icmp ne i{{[0-9]+}} [[OMP_IS_LAST_VAL]], 0
+// CHECK: br i1 [[IS_LAST_IT]], label %[[OMP_LASTPRIV_BLOCK:.+]], label %[[OMP_LASTPRIV_DONE:.+]]
+
+// CHECK: [[OMP_LASTPRIV_BLOCK]]:
+// CHECK: [[T_VAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_PRIV]],
+// CHECK: store i{{[0-9]+}} [[T_VAR_VAL]], i{{[0-9]+}}* [[T_VAR_ADDR_REF]],
+// CHECK: [[BCAST_VEC_ADDR_REF:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_ADDR_REF]] to i8*
+// CHECK: [[BCAST_VEC_PRIV:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[BCAST_VEC_ADDR_REF]], i8* [[BCAST_VEC_PRIV]],
+// CHECK: [[S_ARR_BEGIN:%.+]] = getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[S_ARR_ADDR_REF]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+// CHECK: [[S_ARR_PRIV_BCAST:%.+]] = bitcast [2 x [[S_FLOAT_TY]]]* [[S_ARR_PRIV]] to [[S_FLOAT_TY]]*
+// CHECK: [[S_ARR_BEGIN_GEP:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[S_ARR_BEGIN]], i{{[0-9]+}} 2
+// CHECK: [[S_ARR_IS_EMPTY:%.+]] = icmp eq [[S_FLOAT_TY]]* [[S_ARR_BEGIN]], [[S_ARR_BEGIN_GEP]]
+// CHECK: br i1 [[S_ARR_IS_EMPTY]], label %[[S_ARR_COPY_DONE:.+]], label %[[S_ARR_COPY_BLOCK:.+]]
+// CHECK: [[S_ARR_COPY_BLOCK]]:
+// CHECK: [[S_ARR_SRC_EL:%.+]] = phi [[S_FLOAT_TY]]*{{.+}}
+// CHECK: [[S_ARR_DST_EL:%.+]] = phi [[S_FLOAT_TY]]*{{.+}}
+// CHECK: [[S_ARR_DST_BCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[S_ARR_DST_EL]] to i8*
+// CHECK: [[S_ARR_SRC_BCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[S_ARR_SRC_EL]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[S_ARR_DST_BCAST]], i8* [[S_ARR_SRC_BCAST]]{{.+}})
+// CHECK: [[S_ARR_DST_NEXT:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[S_ARR_DST_EL]], i{{[0-9]+}} 1
+// CHECK: [[S_ARR_SRC_NEXT:%.+]] = getelementptr{{.+}}
+// CHECK: [[CPY_IS_FINISHED:%.+]] = icmp eq [[S_FLOAT_TY]]* [[S_ARR_DST_NEXT]], [[S_ARR_BEGIN_GEP]]
+// CHECK: br i1 [[CPY_IS_FINISHED]], label %[[S_ARR_COPY_DONE]], label %[[S_ARR_COPY_BLOCK]]
+// CHECK: [[S_ARR_COPY_DONE]]:
+// CHECK: [[TMP_VAL1:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[TMP_PRIV]],
+// CHECK: [[VAR_ADDR_REF_BCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[VAR_ADDR_REF]] to i8*
+// CHECK: [[TMP_VAL1_BCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[TMP_VAL1]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[VAR_ADDR_REF_BCAST]], i8* [[TMP_VAL1_BCAST]],{{.+}})
+// CHECK: [[SVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[S_VAR_PRIV]],
+// CHECK: store i{{[0-9]+}} [[SVAR_VAL]], i{{[0-9]+}}* [[SVAR_ADDR_REF]],
+// CHECK: ret void
+
+// template tmain
+// CHECK: define{{.*}} i{{[0-9]+}} [[TMAIN_INT:@.+]]()
+// CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]],
+// CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR:@.+]]([[S_INT_TY]]* [[TEST]])
+// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+// CHECK: call void [[OFFLOAD_FUN_1:@.+]](i{{[0-9]+}} {{.+}}, [2 x i{{[0-9]+}}]* {{.+}}, [2 x [[S_INT_TY]]]* {{.+}}, [[S_INT_TY]]* {{.+}})
+// CHECK: ret
+
+// CHECK: define internal void [[OFFLOAD_FUN_1]](
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_teams(%{{.+}}* @{{.+}}, i{{[0-9]+}} 4,
+// CHECK: ret
+
+// CHECK: define internal void [[OMP_OUTLINED_1:@.+]](i{{[0-9]+}}* noalias [[GTID_ADDR1:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [2 x i{{[0-9]+}}]*{{.+}} [[VEC_IN1:%.+]], i{{[0-9]+}}*{{.+}} [[T_VAR_IN1:%.+]], [2 x [[S_INT_TY]]]*{{.+}} [[S_ARR_IN1:%.+]], [[S_INT_TY]]*{{.+}} [[VAR_IN1:%.+]])
+// skip alloca of global_tid and bound_tid
+// CHECK: {{.+}} = alloca i{{[0-9]+}}*,
+// CHECK: {{.+}} = alloca i{{[0-9]+}}*,
+// CHECK: [[VEC_ADDR1:%.+]] = alloca [2 x i{{[0-9]+}}]*,
+// CHECK: [[T_VAR_ADDR1:%.+]] = alloca i{{[0-9]+}}*,
+// CHECK: [[S_ARR_ADDR1:%.+]] = alloca [2 x [[S_INT_TY]]]*,
+// CHECK: [[VAR_ADDR1:%.+]] = alloca [[S_INT_TY]]*,
+// skip loop variables
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: [[OMP_IS_LAST1:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[T_VAR_PRIV1:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[VEC_PRIV1:%.+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK: [[S_ARR_PRIV1:%.+]] = alloca [2 x [[S_INT_TY]]],
+// CHECK: [[VAR_PRIV1:%.+]] = alloca [[S_INT_TY]],
+// CHECK: [[TMP_PRIV1:%.+]] = alloca [[S_INT_TY]]*,
+
+// skip init of bound and global tid
+// CHECK: store i{{[0-9]+}}* {{.*}},
+// CHECK: store i{{[0-9]+}}* {{.*}},
+// copy from parameters to local address variables
+// CHECK: store [2 x i{{[0-9]+}}]* [[VEC_IN1]], [2 x i{{[0-9]+}}]** [[VEC_ADDR1]],
+// CHECK: store i{{[0-9]+}}* [[T_VAR_IN1]], i{{[0-9]+}}** [[T_VAR_ADDR1]],
+// CHECK: store [2 x [[S_INT_TY]]]* [[S_ARR_IN1]], [2 x [[S_INT_TY]]]** [[S_ARR_ADDR1]],
+// CHECK: store [[S_INT_TY]]* [[VAR_IN1]], [[S_INT_TY]]** [[VAR_ADDR1]],
+
+// load content of local address variables
+// CHECK: [[VEC_ADDR_REF1:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** [[VEC_ADDR1]],
+// CHECK: [[T_VAR_ADDR_REF1:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[T_VAR_ADDR1]],
+// CHECK: [[S_ARR_ADDR_REF1:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** [[S_ARR_ADDR1]],
+// CHECK-DAG: store i{{[0-9]+}} 0, i{{[0-9]+}}* [[OMP_IS_LAST1]],
+// CHECK: [[VAR_ADDR1_REF:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[VAR_ADDR1]],
+// CHECK-DAG: store [[S_INT_TY]]* [[VAR_PRIV1]], [[S_INT_TY]]** [[TMP_PRIV1]],
+
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: call void {{.*}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[TPAR_OUTL:.+]] to
+// CHECK: call void @__kmpc_for_static_fini(
+
+// lastprivates
+// CHECK: [[OMP_IS_LAST_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[OMP_IS_LAST1]],
+// CHECK: [[IS_LAST_IT:%.+]] = icmp ne i{{[0-9]+}} [[OMP_IS_LAST_VAL]], 0
+// CHECK: br i1 [[IS_LAST_IT]], label %[[OMP_LASTPRIV_BLOCK:.+]], label %[[OMP_LASTPRIV_DONE:.+]]
+
+// CHECK: [[OMP_LASTPRIV_BLOCK]]:
+// CHECK: [[T_VAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_PRIV1]],
+// CHECK: store i{{[0-9]+}} [[T_VAR_VAL]], i{{[0-9]+}}* [[T_VAR_ADDR_REF1]],
+// CHECK: [[BCAST_VEC_ADDR_REF:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_ADDR_REF1]] to i8*
+// CHECK: [[BCAST_VEC_PRIV:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV1]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[BCAST_VEC_ADDR_REF]], i8* [[BCAST_VEC_PRIV]],
+// CHECK: [[S_ARR_BEGIN:%.+]] = getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[S_ARR_ADDR_REF]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+// CHECK: [[S_ARR_PRIV_BCAST:%.+]] = bitcast [2 x [[S_INT_TY]]]* [[S_ARR_PRIV1]] to [[S_INT_TY]]*
+// CHECK: [[S_ARR_BEGIN_GEP:%.+]] = getelementptr [[S_INT_TY]], [[S_INT_TY]]* [[S_ARR_BEGIN]], i{{[0-9]+}} 2
+// CHECK: [[S_ARR_IS_EMPTY:%.+]] = icmp eq [[S_INT_TY]]* [[S_ARR_BEGIN]], [[S_ARR_BEGIN_GEP]]
+// CHECK: br i1 [[S_ARR_IS_EMPTY]], label %[[S_ARR_COPY_DONE:.+]], label %[[S_ARR_COPY_BLOCK:.+]]
+// CHECK: [[S_ARR_COPY_BLOCK]]:
+// CHECK: [[S_ARR_SRC_EL:%.+]] = phi [[S_INT_TY]]*{{.+}}
+// CHECK: [[S_ARR_DST_EL:%.+]] = phi [[S_INT_TY]]*{{.+}}
+// CHECK: [[S_ARR_DST_BCAST:%.+]] = bitcast [[S_INT_TY]]* [[S_ARR_DST_EL]] to i8*
+// CHECK: [[S_ARR_SRC_BCAST:%.+]] = bitcast [[S_INT_TY]]* [[S_ARR_SRC_EL]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[S_ARR_DST_BCAST]], i8* [[S_ARR_SRC_BCAST]]{{.+}})
+// CHECK: [[S_ARR_DST_NEXT:%.+]] = getelementptr [[S_INT_TY]], [[S_INT_TY]]* [[S_ARR_DST_EL]], i{{[0-9]+}} 1
+// CHECK: [[S_ARR_SRC_NEXT:%.+]] = getelementptr{{.+}}
+// CHECK: [[CPY_IS_FINISHED:%.+]] = icmp eq [[S_INT_TY]]* [[S_ARR_DST_NEXT]], [[S_ARR_BEGIN_GEP]]
+// CHECK: br i1 [[CPY_IS_FINISHED]], label %[[S_ARR_COPY_DONE]], label %[[S_ARR_COPY_BLOCK]]
+// CHECK: [[S_ARR_COPY_DONE]]:
+// CHECK: [[TMP_VAL1:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[TMP_PRIV1]],
+// CHECK: [[VAR_ADDR_REF_BCAST:%.+]] = bitcast [[S_INT_TY]]* [[VAR_ADDR1_REF]] to i8*
+// CHECK: [[TMP_VAL1_BCAST:%.+]] = bitcast [[S_INT_TY]]* [[TMP_VAL1]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[VAR_ADDR_REF_BCAST]], i8* [[TMP_VAL1_BCAST]],{{.+}})
+// CHECK: ret void
+
+// CHECK: define internal void [[TPAR_OUTL:@.+]](i{{[0-9]+}}* noalias [[GTID_ADDR1:%.+]], i{{[0-9]+}}* noalias %{{.+}}, {{.+}}, {{.+}}, [2 x i{{[0-9]+}}]*{{.+}} [[VEC_IN1:%.+]], i{{[0-9]+}}*{{.+}} [[T_VAR_IN1:%.+]], [2 x [[S_INT_TY]]]*{{.+}} [[S_ARR_IN1:%.+]], [[S_INT_TY]]*{{.+}} [[VAR_IN1:%.+]])
+// skip alloca of global_tid and bound_tid, and prev lb and ub vars
+// CHECK: {{.+}} = alloca i{{[0-9]+}}*,
+// CHECK: {{.+}} = alloca i{{[0-9]+}}*,
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: [[VEC_ADDR1:%.+]] = alloca [2 x i{{[0-9]+}}]*,
+// CHECK: [[T_VAR_ADDR1:%.+]] = alloca i{{[0-9]+}}*,
+// CHECK: [[S_ARR_ADDR1:%.+]] = alloca [2 x [[S_INT_TY]]]*,
+// CHECK: [[VAR_ADDR1:%.+]] = alloca [[S_INT_TY]]*,
+// skip loop variables
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: [[OMP_IS_LAST1:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[T_VAR_PRIV1:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[VEC_PRIV1:%.+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK: [[S_ARR_PRIV1:%.+]] = alloca [2 x [[S_INT_TY]]],
+// CHECK: [[VAR_PRIV1:%.+]] = alloca [[S_INT_TY]],
+// CHECK: [[TMP_PRIV1:%.+]] = alloca [[S_INT_TY]]*,
+
+// skip init of bound and global tid
+// CHECK: store i{{[0-9]+}}* {{.*}},
+// CHECK: store i{{[0-9]+}}* {{.*}},
+// copy from parameters to local address variables
+// CHECK: store [2 x i{{[0-9]+}}]* [[VEC_IN1]], [2 x i{{[0-9]+}}]** [[VEC_ADDR1]],
+// CHECK: store i{{[0-9]+}}* [[T_VAR_IN1]], i{{[0-9]+}}** [[T_VAR_ADDR1]],
+// CHECK: store [2 x [[S_INT_TY]]]* [[S_ARR_IN1]], [2 x [[S_INT_TY]]]** [[S_ARR_ADDR1]],
+// CHECK: store [[S_INT_TY]]* [[VAR_IN1]], [[S_INT_TY]]** [[VAR_ADDR1]],
+
+// load content of local address variables
+// CHECK: [[VEC_ADDR_REF1:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** [[VEC_ADDR1]],
+// CHECK: [[T_VAR_ADDR_REF1:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[T_VAR_ADDR1]],
+// CHECK: [[S_ARR_ADDR_REF1:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** [[S_ARR_ADDR1]],
+// CHECK-DAG: store i{{[0-9]+}} 0, i{{[0-9]+}}* [[OMP_IS_LAST1]],
+// CHECK: [[VAR_ADDR1_REF:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[VAR_ADDR1]],
+// CHECK-DAG: store [[S_INT_TY]]* [[VAR_PRIV1]], [[S_INT_TY]]** [[TMP_PRIV1]],
+
+// CHECK: call void @__kmpc_for_static_init_4(
+
+// assignment: vec[i] = t_var;
+// CHECK: [[IV_VAL1:%.+]] =
+// CHECK: [[T_VAR_PRIV_VAL1:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_PRIV1]],
+// CHECK: [[VEC_PTR1:%.+]] = getelementptr inbounds [2 x i{{[0-9]+}}], [2 x i{{[0-9]+}}]* [[VEC_PRIV1]], i{{[0-9]+}} 0, i{{[0-9]+}} {{.+}}
+// CHECK: store i{{[0-9]+}} [[T_VAR_PRIV_VAL1]], i{{[0-9]+}}* [[VEC_PTR1]],
+
+// assignment: s_arr[i] = var;
+// CHECK-DAG: [[S_ARR_PTR1:%.+]] = getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[S_ARR_PRIV1]],
+// CHECK-DAG: [[TMP_VAL1:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[TMP_PRIV1]],
+// CHECK-DAG: [[S_ARR_PTR_BCAST1:%.+]] = bitcast [[S_INT_TY]]* [[S_ARR_PTR1]] to i8*
+// CHECK-DAG: [[TMP_VAL_BCAST1:%.+]] = bitcast [[S_INT_TY]]* [[TMP_VAL1]] to i8*
+// CHECK-DAG: call void @llvm.memcpy.{{.+}}(i8* [[S_ARR_PTR_BCAST1]], i8* [[TMP_VAL_BCAST1]],
+
+// CHECK: call void @__kmpc_for_static_fini(
+
+// skip final branch and block
+// CHECK: br
+
+// lastprivates
+// CHECK: [[OMP_IS_LAST_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[OMP_IS_LAST1]],
+// CHECK: [[IS_LAST_IT:%.+]] = icmp ne i{{[0-9]+}} [[OMP_IS_LAST_VAL]], 0
+// CHECK: br i1 [[IS_LAST_IT]], label %[[OMP_LASTPRIV_BLOCK:.+]], label %[[OMP_LASTPRIV_DONE:.+]]
+
+// CHECK: [[OMP_LASTPRIV_BLOCK]]:
+// CHECK: [[T_VAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_PRIV1]],
+// CHECK: store i{{[0-9]+}} [[T_VAR_VAL]], i{{[0-9]+}}* [[T_VAR_ADDR_REF1]],
+// CHECK: [[BCAST_VEC_ADDR_REF:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_ADDR_REF1]] to i8*
+// CHECK: [[BCAST_VEC_PRIV:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV1]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[BCAST_VEC_ADDR_REF]], i8* [[BCAST_VEC_PRIV]],
+// CHECK: [[S_ARR_BEGIN:%.+]] = getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[S_ARR_ADDR_REF]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+// CHECK: [[S_ARR_PRIV_BCAST:%.+]] = bitcast [2 x [[S_INT_TY]]]* [[S_ARR_PRIV1]] to [[S_INT_TY]]*
+// CHECK: [[S_ARR_BEGIN_GEP:%.+]] = getelementptr [[S_INT_TY]], [[S_INT_TY]]* [[S_ARR_BEGIN]], i{{[0-9]+}} 2
+// CHECK: [[S_ARR_IS_EMPTY:%.+]] = icmp eq [[S_INT_TY]]* [[S_ARR_BEGIN]], [[S_ARR_BEGIN_GEP]]
+// CHECK: br i1 [[S_ARR_IS_EMPTY]], label %[[S_ARR_COPY_DONE:.+]], label %[[S_ARR_COPY_BLOCK:.+]]
+// CHECK: [[S_ARR_COPY_BLOCK]]:
+// CHECK: [[S_ARR_SRC_EL:%.+]] = phi [[S_INT_TY]]*{{.+}}
+// CHECK: [[S_ARR_DST_EL:%.+]] = phi [[S_INT_TY]]*{{.+}}
+// CHECK: [[S_ARR_DST_BCAST:%.+]] = bitcast [[S_INT_TY]]* [[S_ARR_DST_EL]] to i8*
+// CHECK: [[S_ARR_SRC_BCAST:%.+]] = bitcast [[S_INT_TY]]* [[S_ARR_SRC_EL]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[S_ARR_DST_BCAST]], i8* [[S_ARR_SRC_BCAST]]{{.+}})
+// CHECK: [[S_ARR_DST_NEXT:%.+]] = getelementptr [[S_INT_TY]], [[S_INT_TY]]* [[S_ARR_DST_EL]], i{{[0-9]+}} 1
+// CHECK: [[S_ARR_SRC_NEXT:%.+]] = getelementptr{{.+}}
+// CHECK: [[CPY_IS_FINISHED:%.+]] = icmp eq [[S_INT_TY]]* [[S_ARR_DST_NEXT]], [[S_ARR_BEGIN_GEP]]
+// CHECK: br i1 [[CPY_IS_FINISHED]], label %[[S_ARR_COPY_DONE]], label %[[S_ARR_COPY_BLOCK]]
+// CHECK: [[S_ARR_COPY_DONE]]:
+// CHECK: [[TMP_VAL1:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[TMP_PRIV1]],
+// CHECK: [[VAR_ADDR_REF_BCAST:%.+]] = bitcast [[S_INT_TY]]* [[VAR_ADDR1_REF]] to i8*
+// CHECK: [[TMP_VAL1_BCAST:%.+]] = bitcast [[S_INT_TY]]* [[TMP_VAL1]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[VAR_ADDR_REF_BCAST]], i8* [[TMP_VAL1_BCAST]],{{.+}})
+// CHECK: ret void
+
+// CHECK: !{!"llvm.loop.vectorize.enable", i1 true}
+
+#endif
diff --git a/test/OpenMP/teams_distribute_parallel_for_simd_lastprivate_messages.cpp b/test/OpenMP/teams_distribute_parallel_for_simd_lastprivate_messages.cpp
index fce59b924f67..204be4c95e91 100644
--- a/test/OpenMP/teams_distribute_parallel_for_simd_lastprivate_messages.cpp
+++ b/test/OpenMP/teams_distribute_parallel_for_simd_lastprivate_messages.cpp
@@ -18,14 +18,14 @@ public:
const S2 &operator =(const S2&) const;
S2 &operator =(const S2&);
static float S2s; // expected-note {{static data member is predetermined as shared}}
- static const float S2sc;
+ static const float S2sc; // expected-note {{static data member is predetermined as shared}}
};
-const float S2::S2sc = 0; // expected-note {{static data member is predetermined as shared}}
+const float S2::S2sc = 0;
const S2 b;
const S2 ba[5];
class S3 {
int a;
- S3 &operator=(const S3 &s3); // expected-note 2 {{implicitly declared private here}}
+ S3 &operator=(const S3 &s3); // expected-note {{implicitly declared private here}}
public:
S3() : a(0) {}
@@ -52,7 +52,7 @@ public:
};
class S6 {
int a;
- S6() : a(0) {}
+ S6() : a(0) {} // expected-note {{implicitly declared private here}}
public:
S6(const S6 &s6) : a(s6.a) {}
@@ -255,12 +255,14 @@ int main(int argc, char **argv) {
#pragma omp teams distribute parallel for simd lastprivate(j)
for (i = 0; i < argc; ++i) foo();
+// expected-error@+2 {{firstprivate variable cannot be lastprivate}} expected-note@+2 {{defined as firstprivate}}
#pragma omp target
-#pragma omp teams distribute parallel for simd firstprivate(m) lastprivate(m) // expected-error {{'operator=' is a private member of 'S3'}}
+#pragma omp teams distribute parallel for simd firstprivate(m) lastprivate(m)
for (i = 0; i < argc; ++i) foo();
+// expected-error@+2 {{lastprivate variable cannot be firstprivate}} expected-note@+2 {{defined as lastprivate}}
#pragma omp target
-#pragma omp teams distribute parallel for simd lastprivate(n) firstprivate(n) // OK
+#pragma omp teams distribute parallel for simd lastprivate(n) firstprivate(n) // expected-error {{calling a private constructor of class 'S6'}}
for (i = 0; i < argc; ++i) foo();
static int si;
diff --git a/test/OpenMP/teams_distribute_parallel_for_simd_linear_messages.cpp b/test/OpenMP/teams_distribute_parallel_for_simd_linear_messages.cpp
index 5b91a3c4cccc..c0a9baf916dd 100644
--- a/test/OpenMP/teams_distribute_parallel_for_simd_linear_messages.cpp
+++ b/test/OpenMP/teams_distribute_parallel_for_simd_linear_messages.cpp
@@ -18,34 +18,42 @@ void test_linear_colons()
{
int B = 0;
+// expected-error@+2 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
#pragma omp teams distribute parallel for simd linear(B:bfoo())
for (int i = 0; i < 10; ++i) ;
+// expected-error@+2 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
#pragma omp teams distribute parallel for simd linear(B::ib:B:bfoo()) // expected-error {{unexpected ':' in nested name specifier; did you mean '::'}}
for (int i = 0; i < 10; ++i) ;
+// expected-error@+2 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
#pragma omp teams distribute parallel for simd linear(B:ib) // expected-error {{use of undeclared identifier 'ib'; did you mean 'B::ib'}}
for (int i = 0; i < 10; ++i) ;
+// expected-error@+2 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
#pragma omp teams distribute parallel for simd linear(z:B:ib) // expected-error {{unexpected ':' in nested name specifier; did you mean '::'?}}
for (int i = 0; i < 10; ++i) ;
+// expected-error@+2 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
#pragma omp teams distribute parallel for simd linear(B:B::bfoo())
for (int i = 0; i < 10; ++i) ;
+// expected-error@+2 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
#pragma omp teams distribute parallel for simd linear(X::x : ::z)
for (int i = 0; i < 10; ++i) ;
+// expected-error@+2 3 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
#pragma omp teams distribute parallel for simd linear(B,::z, X::x)
for (int i = 0; i < 10; ++i) ;
+// expected-error@+2 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
#pragma omp teams distribute parallel for simd linear(::z)
for (int i = 0; i < 10; ++i) ;
@@ -54,6 +62,7 @@ void test_linear_colons()
#pragma omp teams distribute parallel for simd linear(B::bfoo()) // expected-error {{expected variable name}}
for (int i = 0; i < 10; ++i) ;
+// expected-error@+2 2 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
#pragma omp teams distribute parallel for simd linear(B::ib,B:C1+C2)
for (int i = 0; i < 10; ++i) ;
@@ -76,6 +85,7 @@ template<int L, class T, class N> T test_template(T* arr, N num) {
template<int LEN> int test_warn() {
int ind2 = 0;
+// expected-error@+2 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
#pragma omp teams distribute parallel for simd linear(ind2:LEN) // expected-warning {{zero linear step (ind2 should probably be const)}}
for (int i = 0; i < 100; i++) {
@@ -133,10 +143,12 @@ template<class I, class C> int foomain(I argc, C **argv) {
#pragma omp teams distribute parallel for simd linear () // expected-error {{expected expression}}
for (int k = 0; k < argc; ++k) ++k;
+// expected-error@+2 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
#pragma omp teams distribute parallel for simd linear (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
for (int k = 0; k < argc; ++k) ++k;
+// expected-error@+2 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
#pragma omp teams distribute parallel for simd linear (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
for (int k = 0; k < argc; ++k) ++k;
@@ -145,6 +157,7 @@ template<class I, class C> int foomain(I argc, C **argv) {
#pragma omp teams distribute parallel for simd linear (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
for (int k = 0; k < argc; ++k) ++k;
+// expected-error@+2 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
#pragma omp teams distribute parallel for simd linear (argc : 5)
for (int k = 0; k < argc; ++k) ++k;
@@ -161,6 +174,7 @@ template<class I, class C> int foomain(I argc, C **argv) {
#pragma omp teams distribute parallel for simd linear (argv[1]) // expected-error {{expected variable name}}
for (int k = 0; k < argc; ++k) ++k;
+// expected-error@+2 2 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
#pragma omp teams distribute parallel for simd linear(e, g)
for (int k = 0; k < argc; ++k) ++k;
@@ -169,32 +183,11 @@ template<class I, class C> int foomain(I argc, C **argv) {
#pragma omp teams distribute parallel for simd linear(h) // expected-error {{threadprivate or thread local variable cannot be linear}}
for (int k = 0; k < argc; ++k) ++k;
+// expected-error@+2 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
#pragma omp teams distribute parallel for simd linear(i)
for (int k = 0; k < argc; ++k) ++k;
- #pragma omp parallel
- {
- int v = 0;
- int i;
- #pragma omp target
- #pragma omp teams distribute parallel for simd linear(v:i)
- for (int k = 0; k < argc; ++k) { i = k; v += i; }
- }
-
-#pragma omp target
-#pragma omp teams distribute parallel for simd linear(j)
- for (int k = 0; k < argc; ++k) ++k;
-
- int v = 0;
-
-#pragma omp target
-#pragma omp teams distribute parallel for simd linear(v:j)
- for (int k = 0; k < argc; ++k) { ++k; v += j; }
-
-#pragma omp target
-#pragma omp teams distribute parallel for simd linear(i)
- for (int k = 0; k < argc; ++k) ++k;
return 0;
}
@@ -230,10 +223,12 @@ int main(int argc, char **argv) {
#pragma omp teams distribute parallel for simd linear () // expected-error {{expected expression}}
for (int k = 0; k < argc; ++k) ++k;
+// expected-error@+2 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
#pragma omp teams distribute parallel for simd linear (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
for (int k = 0; k < argc; ++k) ++k;
+// expected-error@+2 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
#pragma omp teams distribute parallel for simd linear (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
for (int k = 0; k < argc; ++k) ++k;
@@ -242,6 +237,7 @@ int main(int argc, char **argv) {
#pragma omp teams distribute parallel for simd linear (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
for (int k = 0; k < argc; ++k) ++k;
+// expected-error@+2 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
#pragma omp teams distribute parallel for simd linear (argc)
for (int k = 0; k < argc; ++k) ++k;
@@ -267,26 +263,6 @@ int main(int argc, char **argv) {
#pragma omp teams distribute parallel for simd linear(h, C::x) // expected-error 2 {{threadprivate or thread local variable cannot be linear}}
for (int k = 0; k < argc; ++k) ++k;
- #pragma omp parallel
- {
- int i;
- #pragma omp target
- #pragma omp teams distribute parallel for simd linear(i)
- for (int k = 0; k < argc; ++k) ++k;
-
- #pragma omp target
- #pragma omp teams distribute parallel for simd linear(i : 4)
- for (int k = 0; k < argc; ++k) { ++k; i += 4; }
- }
-
-#pragma omp target
-#pragma omp teams distribute parallel for simd linear(j)
- for (int k = 0; k < argc; ++k) ++k;
-
-#pragma omp target
-#pragma omp teams distribute parallel for simd linear(i)
- for (int k = 0; k < argc; ++k) ++k;
-
foomain<int,char>(argc,argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}}
return 0;
}
diff --git a/test/OpenMP/teams_distribute_parallel_for_simd_loop_messages.cpp b/test/OpenMP/teams_distribute_parallel_for_simd_loop_messages.cpp
index 03325623502f..66361b64eb84 100644
--- a/test/OpenMP/teams_distribute_parallel_for_simd_loop_messages.cpp
+++ b/test/OpenMP/teams_distribute_parallel_for_simd_loop_messages.cpp
@@ -2,7 +2,7 @@
class S {
int a;
- S() : a(0) {}
+ S() : a(0) {} // expected-note {{implicitly declared private here}}
public:
S(int v) : a(v) {}
@@ -693,8 +693,9 @@ void test_loop_eh() {
void test_loop_firstprivate_lastprivate() {
S s(4);
+// expected-error@+2 {{lastprivate variable cannot be firstprivate}} expected-note@+2 {{defined as lastprivate}}
#pragma omp target
-#pragma omp teams distribute parallel for simd lastprivate(s) firstprivate(s)
+#pragma omp teams distribute parallel for simd lastprivate(s) firstprivate(s) // expected-error {{calling a private constructor of class 'S'}}
for (int i = 0; i < 16; ++i)
;
}
diff --git a/test/OpenMP/teams_distribute_parallel_for_simd_messages.cpp b/test/OpenMP/teams_distribute_parallel_for_simd_messages.cpp
index 7876c38980ee..12ac8f9a9479 100644
--- a/test/OpenMP/teams_distribute_parallel_for_simd_messages.cpp
+++ b/test/OpenMP/teams_distribute_parallel_for_simd_messages.cpp
@@ -9,6 +9,9 @@ static int pvt;
#pragma omp teams distribute parallel for simd // expected-error {{unexpected OpenMP directive '#pragma omp teams distribute parallel for simd'}}
int main(int argc, char **argv) {
+ #pragma omp target
+ #pragma omp teams distribute parallel for simd
+ f; // expected-error {{use of undeclared identifier 'f'}}
#pragma omp target
#pragma omp teams distribute parallel for simd { // expected-warning {{extra tokens at the end of '#pragma omp teams distribute parallel for simd' are ignored}}
for (int i = 0; i < argc; ++i)
diff --git a/test/OpenMP/teams_distribute_parallel_for_simd_num_threads_codegen.cpp b/test/OpenMP/teams_distribute_parallel_for_simd_num_threads_codegen.cpp
new file mode 100644
index 000000000000..93051af6161b
--- /dev/null
+++ b/test/OpenMP/teams_distribute_parallel_for_simd_num_threads_codegen.cpp
@@ -0,0 +1,123 @@
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple %itanium_abi_triple -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple %itanium_abi_triple -fexceptions -fcxx-exceptions -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple %itanium_abi_triple -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+typedef __INTPTR_TYPE__ intptr_t;
+
+// CHECK-DAG: [[IDENT_T_TY:%.+]] = type { i32, i32, i32, i32, i8* }
+// CHECK-DAG: [[S_TY:%.+]] = type { [[INTPTR_T_TY:i[0-9]+]], [[INTPTR_T_TY]], [[INTPTR_T_TY]] }
+// CHECK-DAG: [[STR:@.+]] = private unnamed_addr constant [23 x i8] c";unknown;unknown;0;0;;\00"
+// CHECK-DAG: [[DEF_LOC_2:@.+]] = private unnamed_addr constant [[IDENT_T_TY]] { i32 0, i32 2, i32 0, i32 0, i8* getelementptr inbounds ([23 x i8], [23 x i8]* [[STR]], i32 0, i32 0) }
+
+void foo();
+
+struct S {
+ intptr_t a, b, c;
+ S(intptr_t a) : a(a) {}
+ operator char() { return a; }
+ ~S() {}
+};
+
+template <typename T, int C>
+int tmain() {
+#pragma omp target
+#pragma omp teams distribute parallel for simd num_threads(C)
+ for (int i = 0; i < 100; i++)
+ foo();
+#pragma omp target
+#pragma omp teams distribute parallel for simd num_threads(T(23))
+ for (int i = 0; i < 100; i++)
+ foo();
+ return 0;
+}
+
+int main() {
+ S s(0);
+ char a = s;
+// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+// CHECK: call void [[OFFLOADING_FUN_0:@.+]](
+// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+// CHECK: call void [[OFFLOADING_FUN_1:@.+]](
+// CHECK: invoke{{.+}} [[TMAIN_5:@.+]]()
+// CHECK: invoke{{.+}} [[TMAIN_1:@.+]]()
+#pragma omp target
+ // CHECK: define internal void [[OFFLOADING_FUN_0]](
+ // CHECK: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, i32 0, {{.+}}* [[OMP_TEAMS_OUTLINED_0:@.+]] to {{.+}})
+#pragma omp teams distribute parallel for simd num_threads(2)
+ for (int i = 0; i < 100; i++) {
+ // CHECK: define{{.+}} void [[OMP_TEAMS_OUTLINED_0]](
+ // CHECK: call {{.*}}void @__kmpc_push_num_threads([[IDENT_T_TY]]* [[DEF_LOC_2]], i32 {{.+}}, i32 2)
+ // CHECK: call {{.*}}void {{.*}} @__kmpc_fork_call(
+ foo();
+ }
+#pragma omp target
+ // CHECK: define internal void [[OFFLOADING_FUN_1]](
+
+ // CHECK: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}}* [[OMP_TEAMS_OUTLINED_1:@.+]] to {{.+}})
+#pragma omp teams distribute parallel for simd num_threads(a)
+ for (int i = 0; i < 100; i++) {
+ // CHECK: define{{.+}} void [[OMP_TEAMS_OUTLINED_1]](
+ // CHECK-DAG: [[A_ADDR:%.+]] = alloca i8*,
+ // CHECK-DAG: [[A_REF:%.+]] = load i8*, i8** [[A_ADDR]],
+ // CHECK-DAG: [[A_VAL:%.+]] = load i8, i8* [[A_REF]],
+ // CHECK-DAG: [[A_EXT:%.+]] = sext i8 [[A_VAL]] to {{.+}}
+ // CHECK: call {{.*}}void @__kmpc_push_num_threads([[IDENT_T_TY]]* [[DEF_LOC_2]], i32 {{.+}}, i32 [[A_EXT]])
+ // CHECK: call {{.*}}void {{.*}} @__kmpc_fork_call(
+ foo();
+ }
+ return a + tmain<char, 5>() + tmain<S, 1>();
+}
+
+// tmain 5
+// CHECK-DAG: define {{.*}}i{{[0-9]+}} [[TMAIN_5]]()
+// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+// CHECK: call void [[T_OFFLOADING_FUN_0:@.+]](
+// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+// CHECK: call void [[T_OFFLOADING_FUN_1:@.+]](
+
+// tmain 1
+// CHECK-DAG: define {{.*}}i{{[0-9]+}} [[TMAIN_1]]()
+// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+// CHECK: call void [[T_OFFLOADING_FUN_2:@.+]](
+// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+// CHECK: call void [[T_OFFLOADING_FUN_3:@.+]](
+
+// CHECK: define internal void [[T_OFFLOADING_FUN_0]](
+// CHECK: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, i32 0, {{.+}}* [[T_OMP_TEAMS_OUTLINED_0:@.+]] to {{.+}})
+
+// CHECK: define{{.+}} void [[T_OMP_TEAMS_OUTLINED_0]](
+// CHECK: call {{.*}}void @__kmpc_push_num_threads([[IDENT_T_TY]]* [[DEF_LOC_2]], i32 {{.+}}, i32 5)
+// CHECK: call {{.*}}void {{.*}} @__kmpc_fork_call(
+
+// CHECK: define internal void [[T_OFFLOADING_FUN_1]](
+// CHECK: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, i32 0, {{.+}}* [[T_OMP_TEAMS_OUTLINED_1:@.+]] to {{.+}})
+
+// CHECK: define{{.+}} void [[T_OMP_TEAMS_OUTLINED_1]](
+// CHECK: call {{.*}}void @__kmpc_push_num_threads([[IDENT_T_TY]]* [[DEF_LOC_2]], i32 {{.+}}, i32 23)
+// CHECK: call {{.*}}void {{.*}} @__kmpc_fork_call(
+
+// CHECK: define internal void [[T_OFFLOADING_FUN_2]](
+// CHECK: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, i32 0, {{.+}}* [[T_OMP_TEAMS_OUTLINED_2:@.+]] to {{.+}})
+
+// CHECK: define{{.+}} void [[T_OMP_TEAMS_OUTLINED_2]](
+// CHECK: call {{.*}}void @__kmpc_push_num_threads([[IDENT_T_TY]]* [[DEF_LOC_2]], i32 {{.+}}, i32 1)
+// CHECK: call {{.*}}void {{.*}} @__kmpc_fork_call(
+
+// CHECK: define internal void [[T_OFFLOADING_FUN_3]](
+// CHECK: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, i32 {{.+}}, {{.+}}* [[T_OMP_TEAMS_OUTLINED_3:@.+]] to {{.+}})
+
+// CHECK: define{{.+}} void [[T_OMP_TEAMS_OUTLINED_3]]({{.+}}, {{.+}}, {{.+}} [[NUM_TH_CPT_IN:%.+]])
+// CHECK: [[NUM_TH_CPT:%.+]] = alloca i8*,
+// CHECK: store {{.+}} [[NUM_TH_CPT_IN]], {{.+}} [[NUM_TH_CPT]],
+// CHECK: [[NUM_TH_REF:%.+]] = load{{.+}}, {{.+}} [[NUM_TH_CPT]],
+// CHECK-DAG: [[NUM_TH_VAL:%.+]] = load {{.+}}, {{.+}} [[NUM_TH_REF]],
+// CHECK-DAG: [[NUM_TH_SEXT:%.+]] = sext i8 [[NUM_TH_VAL]] to {{.+}}
+// CHECK: call {{.*}}void @__kmpc_push_num_threads([[IDENT_T_TY]]* [[DEF_LOC_2]], i32 {{.+}}, i32 [[NUM_TH_SEXT]])
+// CHECK: call {{.*}}void {{.*}} @__kmpc_fork_call(
+
+// CHECK: !{!"llvm.loop.vectorize.enable", i1 true}
+
+#endif
diff --git a/test/OpenMP/teams_distribute_parallel_for_simd_private_codegen.cpp b/test/OpenMP/teams_distribute_parallel_for_simd_private_codegen.cpp
new file mode 100644
index 000000000000..a6dbd29a5b96
--- /dev/null
+++ b/test/OpenMP/teams_distribute_parallel_for_simd_private_codegen.cpp
@@ -0,0 +1,336 @@
+// RUN: %clang_cc1 -DCHECK -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -DCHECK -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+
+// RUN: %clang_cc1 -DLAMBDA -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+struct St {
+ int a, b;
+ St() : a(0), b(0) {}
+ St(const St &st) : a(st.a + st.b), b(0) {}
+ ~St() {}
+};
+
+volatile int g = 1212;
+volatile int &g1 = g;
+
+template <class T>
+struct S {
+ T f;
+ S(T a) : f(a + g) {}
+ S() : f(g) {}
+ S(const S &s, St t = St()) : f(s.f + t.a) {}
+ operator T() { return T(); }
+ ~S() {}
+};
+
+// CHECK-DAG: [[S_FLOAT_TY:%.+]] = type { float }
+// CHECK-DAG: [[S_INT_TY:%.+]] = type { i{{[0-9]+}} }
+
+template <typename T>
+T tmain() {
+ S<T> test;
+ T t_var = T();
+ T vec[] = {1, 2};
+ S<T> s_arr[] = {1, 2};
+ S<T> &var = test;
+#pragma omp target
+#pragma omp teams distribute parallel for simd private(t_var, vec, s_arr, var)
+ for (int i = 0; i < 2; ++i) {
+ vec[i] = t_var;
+ s_arr[i] = var;
+ }
+ return T();
+}
+
+// CHECK-DAG: [[TEST:@.+]] = global [[S_FLOAT_TY]] zeroinitializer,
+S<float> test;
+// CHECK-DAG: [[T_VAR:@.+]] = global i{{[0-9]+}} 333,
+int t_var = 333;
+// CHECK-DAG: [[VEC:@.+]] = global [2 x i{{[0-9]+}}] [i{{[0-9]+}} 1, i{{[0-9]+}} 2],
+int vec[] = {1, 2};
+// CHECK-DAG: [[S_ARR:@.+]] = global [2 x [[S_FLOAT_TY]]] zeroinitializer,
+S<float> s_arr[] = {1, 2};
+// CHECK-DAG: [[VAR:@.+]] = global [[S_FLOAT_TY]] zeroinitializer,
+S<float> var(3);
+// CHECK-DAG: [[SIVAR:@.+]] = internal global i{{[0-9]+}} 0,
+
+int main() {
+ static int sivar;
+#ifdef LAMBDA
+ // LAMBDA: [[G:@.+]] = global i{{[0-9]+}} 1212,
+ // LAMBDA-LABEL: @main
+ // LAMBDA: call void [[OUTER_LAMBDA:@.+]](
+ [&]() {
+ // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
+ // LAMBDA: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 1, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0)
+ // LAMBDA: call void @[[LOFFL1:.+]](
+ // LAMBDA: ret
+#pragma omp target
+#pragma omp teams distribute parallel for simd private(g, g1, sivar)
+ for (int i = 0; i < 2; ++i) {
+ // LAMBDA: define{{.*}} internal{{.*}} void @[[LOFFL1]](i{{64|32}} {{%.+}})
+ // LAMBDA: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 0, {{.+}} @[[LOUTL1:.+]] to {{.+}})
+ // LAMBDA: ret void
+
+ // LAMBDA: define internal void @[[LOUTL1]]({{.+}})
+ // Skip global, bound tid and loop vars
+ // LAMBDA: {{.+}} = alloca i32*,
+ // LAMBDA: {{.+}} = alloca i32*,
+ // LAMBDA: alloca i32,
+ // LAMBDA: alloca i32,
+ // LAMBDA: alloca i32,
+ // LAMBDA: alloca i32,
+ // LAMBDA: alloca i32,
+ // LAMBDA: alloca i32,
+ // LAMBDA: [[G_PRIV:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[G1_PRIV:%.+]] = alloca i{{[0-9]+}}
+ // LAMBDA: [[TMP:%.+]] = alloca i{{[0-9]+}}*,
+ // LAMBDA: [[SIVAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: store{{.+}} [[G1_PRIV]], {{.+}} [[TMP]],
+
+ g = 1;
+ g1 = 1;
+ sivar = 2;
+ // LAMBDA: call void @__kmpc_for_static_init_4(
+ // LAMBDA: call void {{.+}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[LPAR_OUTL:.+]] to
+ // LAMBDA: call void @__kmpc_for_static_fini(
+ // LAMBDA: ret void
+
+ // LAMBDA: define internal void @[[LPAR_OUTL]]({{.+}})
+ // Skip global, bound tid and loop vars
+ // LAMBDA: {{.+}} = alloca i32*,
+ // LAMBDA: {{.+}} = alloca i32*,
+ // LAMBDA: alloca i{{[0-9]+}},
+ // LAMBDA: alloca i{{[0-9]+}},
+ // LAMBDA: alloca i32,
+ // LAMBDA: alloca i32,
+ // LAMBDA: alloca i32,
+ // LAMBDA: alloca i32,
+ // LAMBDA: alloca i32,
+ // LAMBDA: alloca i32,
+ // LAMBDA: [[G_PRIV:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[G1_PRIV:%.+]] = alloca i{{[0-9]+}}
+ // LAMBDA: [[TMP:%.+]] = alloca i{{[0-9]+}}*,
+ // LAMBDA: [[SIVAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: store{{.+}} [[G1_PRIV]], {{.+}} [[TMP]],
+ // LAMBDA-DAG: store{{.+}} 1, {{.+}} [[G_PRIV]],
+ // LAMBDA-DAG: store{{.+}} 2, {{.+}} [[SIVAR_PRIV]],
+ // LAMBDA-DAG: [[G1_REF:%.+]] = load{{.+}}, {{.+}} [[TMP]],
+ // LAMBDA-DAG: store{{.+}} 1, {{.+}} [[G1_REF]],
+ // LAMBDA: call void [[INNER_LAMBDA:@.+]](
+ // LAMBDA: call void @__kmpc_for_static_fini(
+ // LAMBDA: ret void
+ [&]() {
+ // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]])
+ // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]],
+ g = 2;
+ g1 = 2;
+ sivar = 4;
+ // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]]
+
+ // LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // LAMBDA: [[G_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G_PTR_REF]]
+ // LAMBDA: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[G_REF]]
+ // LAMBDA: [[G1_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // LAMBDA: [[G1_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G1_PTR_REF]]
+ // LAMBDA: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[G1_REF]]
+ // LAMBDA: [[SIVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+ // LAMBDA: [[SIVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SIVAR_PTR_REF]]
+ // LAMBDA: store i{{[0-9]+}} 4, i{{[0-9]+}}* [[SIVAR_REF]]
+ }();
+ }
+ }();
+ return 0;
+
+// LAMBDA: !{!"llvm.loop.vectorize.enable", i1 true}
+
+#else
+#pragma omp target
+#pragma omp teams distribute parallel for simd private(t_var, vec, s_arr, var, sivar)
+ for (int i = 0; i < 2; ++i) {
+ vec[i] = t_var;
+ s_arr[i] = var;
+ sivar += i;
+ }
+ return tmain<int>();
+#endif
+}
+
+// CHECK: define {{.*}}i{{[0-9]+}} @main()
+// CHECK: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 0, i8** null, i8** null, i{{64|32}}* null, i64* null, i32 0, i32 0)
+// CHECK: call void @[[OFFL1:.+]]()
+// CHECK: {{%.+}} = call{{.*}} i32 @[[TMAIN_INT:.+]]()
+// CHECK: ret
+
+// CHECK: define{{.*}} void @[[OFFL1]]()
+// CHECK: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 0, {{.+}} @[[OUTL1:.+]] to {{.+}})
+// CHECK: ret void
+
+// CHECK: define internal void @[[OUTL1]]({{.+}})
+// Skip global, bound tid and loop vars
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: {{.+}} = alloca i32,
+// CHECK: {{.+}} = alloca i32,
+// CHECK: {{.+}} = alloca i32,
+// CHECK: {{.+}} = alloca i32,
+// CHECK: {{.+}} = alloca i32,
+// CHECK-DAG: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK-DAG: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK-DAG: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]],
+// CHECK-DAG: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]],
+// CHECK-DAG: [[SIVAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: alloca i32,
+
+// private(s_arr)
+// CHECK-DAG: [[S_ARR_PRIV_BGN:%.+]] = getelementptr{{.*}} [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[S_ARR_PRIV]],
+// CHECK-DAG: [[S_ARR_PTR_ALLOC:%.+]] = phi{{.+}} [ [[S_ARR_PRIV_BGN]], {{.+}} ], [ [[S_ARR_NEXT:%.+]], {{.+}} ]
+// CHECK-DAG: call void @{{.+}}({{.+}} [[S_ARR_PTR_ALLOC]])
+// CHECK-DAG: [[S_ARR_NEXT]] = getelementptr {{.+}} [[S_ARR_PTR_ALLOC]],
+
+// private(var)
+// CHECK-DAG: call void @{{.+}}({{.+}} [[VAR_PRIV]])
+
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: call void {{.+}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[PAR_OUTL1:.+]] to
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: ret void
+
+// CHECK: define internal void @[[PAR_OUTL1]]({{.+}})
+// Skip global, bound tid and loop vars
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i32,
+// CHECK: {{.+}} = alloca i32,
+// CHECK: {{.+}} = alloca i32,
+// CHECK: {{.+}} = alloca i32,
+// CHECK: {{.+}} = alloca i32,
+// CHECK: {{.+}} = alloca i32,
+// CHECK-DAG: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK-DAG: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK-DAG: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]],
+// CHECK-DAG: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]],
+// CHECK-DAG: [[SIVAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: alloca i32,
+
+// private(s_arr)
+// CHECK-DAG: [[S_ARR_PRIV_BGN:%.+]] = getelementptr{{.*}} [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[S_ARR_PRIV]],
+// CHECK-DAG: [[S_ARR_PTR_ALLOC:%.+]] = phi{{.+}} [ [[S_ARR_PRIV_BGN]], {{.+}} ], [ [[S_ARR_NEXT:%.+]], {{.+}} ]
+// CHECK-DAG: call void @{{.+}}({{.+}} [[S_ARR_PTR_ALLOC]])
+// CHECK-DAG: [[S_ARR_NEXT]] = getelementptr {{.+}} [[S_ARR_PTR_ALLOC]],
+
+// private(var)
+// CHECK-DAG: call void @{{.+}}({{.+}} [[VAR_PRIV]])
+
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK-DAG: {{.+}} = {{.+}} [[T_VAR_PRIV]]
+// CHECK-DAG: {{.+}} = {{.+}} [[VEC_PRIV]]
+// CHECK-DAG: {{.+}} = {{.+}} [[S_ARR_PRIV]]
+// CHECK-DAG: {{.+}} = {{.+}} [[VAR_PRIV]]
+// CHECK-DAG: {{.+}} = {{.+}} [[SIVAR_PRIV]]
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: ret void
+
+// CHECK: define{{.*}} i{{[0-9]+}} @[[TMAIN_INT]]()
+// CHECK: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 0,
+// CHECK: call void @[[TOFFL1:.+]]()
+// CHECK: ret
+
+// CHECK: define {{.*}}void @[[TOFFL1]]()
+// CHECK: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 0, {{.+}} @[[TOUTL1:.+]] to {{.+}})
+// CHECK: ret void
+
+// CHECK: define internal void @[[TOUTL1]]({{.+}})
+// Skip global, bound tid and loop vars
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_INT_TY]]],
+// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_INT_TY]],
+// CHECK: [[TMP:%.+]] = alloca [[S_INT_TY]]*,
+
+// private(s_arr)
+// CHECK-DAG: [[S_ARR_PRIV_BGN:%.+]] = getelementptr{{.*}} [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[S_ARR_PRIV]],
+// CHECK-DAG: [[S_ARR_PTR_ALLOC:%.+]] = phi{{.+}} [ [[S_ARR_PRIV_BGN]], {{.+}} ], [ [[S_ARR_NEXT:%.+]], {{.+}} ]
+// CHECK-DAG: call void @{{.+}}({{.+}} [[S_ARR_PTR_ALLOC]])
+// CHECK-DAG: [[S_ARR_NEXT]] = getelementptr {{.+}} [[S_ARR_PTR_ALLOC]],
+
+// CHECK-DAG: [[S_ARR_PRIV_BGN:%.+]] = getelementptr{{.*}} [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[S_ARR_PRIV]],
+// CHECK-DAG: [[S_ARR_PTR_ALLOC:%.+]] = phi{{.+}} [ [[S_ARR_PRIV_BGN]], {{.+}} ], [ [[S_ARR_NEXT:%.+]], {{.+}} ]
+// CHECK-DAG: call void @{{.+}}({{.+}} [[S_ARR_PTR_ALLOC]])
+// CHECK-DAG: [[S_ARR_NEXT]] = getelementptr {{.+}} [[S_ARR_PTR_ALLOC]],
+
+// private(var)
+// CHECK-DAG: call void @{{.+}}({{.+}} [[VAR_PRIV]])
+// CHECK-DAG: store{{.+}} [[VAR_PRIV]], {{.+}} [[TMP]]
+
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: call void {{.+}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[TPAR_OUTL1:.+]] to
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: ret void
+
+// CHECK: define internal void @[[TPAR_OUTL1]]({{.+}})
+// Skip global, bound tid and loop vars
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: {{.+}} = alloca i32*,
+// prev lb and ub
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// iter variables
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i32,
+// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_INT_TY]]],
+// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_INT_TY]],
+// CHECK: [[TMP:%.+]] = alloca [[S_INT_TY]]*,
+
+// private(s_arr)
+// CHECK-DAG: [[S_ARR_PRIV_BGN:%.+]] = getelementptr{{.*}} [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[S_ARR_PRIV]],
+// CHECK-DAG: [[S_ARR_PTR_ALLOC:%.+]] = phi{{.+}} [ [[S_ARR_PRIV_BGN]], {{.+}} ], [ [[S_ARR_NEXT:%.+]], {{.+}} ]
+// CHECK-DAG: call void @{{.+}}({{.+}} [[S_ARR_PTR_ALLOC]])
+// CHECK-DAG: [[S_ARR_NEXT]] = getelementptr {{.+}} [[S_ARR_PTR_ALLOC]],
+
+// CHECK-DAG: [[S_ARR_PRIV_BGN:%.+]] = getelementptr{{.*}} [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[S_ARR_PRIV]],
+// CHECK-DAG: [[S_ARR_PTR_ALLOC:%.+]] = phi{{.+}} [ [[S_ARR_PRIV_BGN]], {{.+}} ], [ [[S_ARR_NEXT:%.+]], {{.+}} ]
+// CHECK-DAG: call void @{{.+}}({{.+}} [[S_ARR_PTR_ALLOC]])
+// CHECK-DAG: [[S_ARR_NEXT]] = getelementptr {{.+}} [[S_ARR_PTR_ALLOC]],
+
+// private(var)
+// CHECK-DAG: call void @{{.+}}({{.+}} [[VAR_PRIV]])
+// CHECK-DAG: store{{.+}} [[VAR_PRIV]], {{.+}} [[TMP]]
+
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK-DAG: {{.+}} = {{.+}} [[T_VAR_PRIV]]
+// CHECK-DAG: {{.+}} = {{.+}} [[VEC_PRIV]]
+// CHECK-DAG: {{.+}} = {{.+}} [[S_ARR_PRIV]]
+// CHECK-DAG: {{.+}} = {{.+}} [[TMP]]
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: ret void
+
+// CHECK: !{!"llvm.loop.vectorize.enable", i1 true}
+
+#endif
diff --git a/test/OpenMP/teams_distribute_parallel_for_simd_proc_bind_codegen.cpp b/test/OpenMP/teams_distribute_parallel_for_simd_proc_bind_codegen.cpp
new file mode 100644
index 000000000000..7f95a877ab85
--- /dev/null
+++ b/test/OpenMP/teams_distribute_parallel_for_simd_proc_bind_codegen.cpp
@@ -0,0 +1,93 @@
+// add -fopenmp-targets
+
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+typedef __INTPTR_TYPE__ intptr_t;
+
+// CHECK-DAG: [[IDENT_T_TY:%.+]] = type { i32, i32, i32, i32, i8* }
+// CHECK-DAG: [[STR:@.+]] = private unnamed_addr constant [23 x i8] c";unknown;unknown;0;0;;\00"
+// CHECK-DAG: [[DEF_LOC_2:@.+]] = private unnamed_addr constant [[IDENT_T_TY]] { i32 0, i32 2, i32 0, i32 0, i8* getelementptr inbounds ([23 x i8], [23 x i8]* [[STR]], i32 0, i32 0) }
+
+void foo();
+
+struct S {
+ intptr_t a, b, c;
+ S(intptr_t a) : a(a) {}
+ operator char() { return a; }
+ ~S() {}
+};
+
+template <typename T>
+T tmain() {
+#pragma omp target
+#pragma omp teams distribute parallel for simd proc_bind(master)
+ for(int i = 0; i < 1000; i++) {}
+ return T();
+}
+
+int main() {
+ // CHECK-LABEL: @main
+#pragma omp target
+#pragma omp teams distribute parallel for simd proc_bind(spread)
+ for(int i = 0; i < 1000; i++) {}
+#pragma omp target
+#pragma omp teams distribute parallel for simd proc_bind(close)
+ for(int i = 0; i < 1000; i++) {}
+ return tmain<int>();
+}
+
+// CHECK: call {{.*}}@__tgt_target_teams({{.+}})
+// CHECK: call void [[OFFL1:@.+]]()
+// CHECK: call {{.*}}@__tgt_target_teams({{.+}})
+// CHECK: call void [[OFFL2:@.+]]()
+// CHECK: [[CALL_RET:%.+]] = call{{.+}} i32 [[TMAIN:@.+]]()
+// CHECK: ret i32 [[CALL_RET]]
+
+// CHECK: define{{.+}} void [[OFFL1]](
+// CHECK: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, {{.+}}, {{.+}}* [[OMP_OUTLINED_1:@.+]] to {{.+}})
+
+// CHECK: define{{.+}} [[OMP_OUTLINED_1]](i32* {{.+}} [[GTID_IN:%.+]],
+// CHECK: [[GTID_ADDR:%.+]] = alloca i32*,
+// CHECK: store i32* [[GTID_IN]], i32** [[GTID_ADDR]],
+// CHECK: [[GTID_REF:%.+]] = load i32*, i32** [[GTID_ADDR]],
+// CHECK: [[GTID_VAL:%.+]] = load i32, i32* [[GTID_REF]],
+// CHECK: call {{.*}}void @__kmpc_push_proc_bind([[IDENT_T_TY]]* [[DEF_LOC_2]], i32 [[GTID_VAL]], i32 4)
+// CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(
+// CHECK: ret void
+
+// CHECK: define{{.+}} [[OFFL2]]()
+// CHECK: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, {{.+}}, {{.+}}* [[OMP_OUTLINED_1:@.+]] to {{.+}})
+
+// CHECK: define{{.+}} [[OMP_OUTLINED_1]](i32* {{.+}} [[GTID_IN:%.+]],
+// CHECK: [[GTID_ADDR:%.+]] = alloca i32*,
+// CHECK: store i32* [[GTID_IN]], i32** [[GTID_ADDR]],
+// CHECK: [[GTID_REF:%.+]] = load i32*, i32** [[GTID_ADDR]],
+// CHECK: [[GTID_VAL:%.+]] = load i32, i32* [[GTID_REF]],
+// CHECK: call {{.*}}void @__kmpc_push_proc_bind([[IDENT_T_TY]]* [[DEF_LOC_2]], i32 [[GTID_VAL]], i32 3)
+// CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(
+// CHECK: ret void
+
+// CHECK: define{{.+}} [[TMAIN]]()
+// CHECK: call {{.*}}@__tgt_target_teams({{.+}})
+// CHECK: call void [[OFFL3:@.+]]()
+
+// CHECK: define{{.+}} [[OFFL3]]()
+// CHECK: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, {{.+}}, {{.+}}* [[OMP_OUTLINED_3:@.+]] to {{.+}})
+
+// CHECK: define{{.+}} [[OMP_OUTLINED_3]](i32* {{.+}} [[GTID_IN:%.+]],
+// CHECK: [[GTID_ADDR:%.+]] = alloca i32*,
+// CHECK: store i32* [[GTID_IN]], i32** [[GTID_ADDR]],
+// CHECK: [[GTID_REF:%.+]] = load i32*, i32** [[GTID_ADDR]],
+// CHECK: [[GTID_VAL:%.+]] = load i32, i32* [[GTID_REF]],
+// CHECK: call {{.*}}void @__kmpc_push_proc_bind([[IDENT_T_TY]]* [[DEF_LOC_2]], i32 [[GTID_VAL]], i32 2)
+// CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(
+// CHECK: ret void
+
+// CHECK: !{!"llvm.loop.vectorize.enable", i1 true}
+
+#endif
diff --git a/test/OpenMP/teams_distribute_parallel_for_simd_reduction_codegen.cpp b/test/OpenMP/teams_distribute_parallel_for_simd_reduction_codegen.cpp
new file mode 100644
index 000000000000..384ac4b5f32a
--- /dev/null
+++ b/test/OpenMP/teams_distribute_parallel_for_simd_reduction_codegen.cpp
@@ -0,0 +1,351 @@
+// RUN: %clang_cc1 -DCHECK -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -DCHECK -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+
+// RUN: %clang_cc1 -DLAMBDA -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+template <typename T>
+T tmain() {
+ T t_var = T();
+ T vec[] = {1, 2};
+#pragma omp target
+#pragma omp teams distribute parallel for simd reduction(+: t_var)
+ for (int i = 0; i < 2; ++i) {
+ t_var += (T) i;
+ }
+ return T();
+}
+
+int main() {
+ static int sivar;
+#ifdef LAMBDA
+ // LAMBDA: [[RED_VAR:@.+]] = common global [8 x {{.+}}] zeroinitializer
+
+ // LAMBDA-LABEL: @main
+ // LAMBDA: call void [[OUTER_LAMBDA:@.+]](
+ [&]() {
+ // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
+ // LAMBDA: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 1, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0)
+ // LAMBDA: call void @[[LOFFL1:.+]](
+ // LAMBDA: ret
+#pragma omp target
+#pragma omp teams distribute parallel for simd reduction(+: sivar)
+ for (int i = 0; i < 2; ++i) {
+ // LAMBDA: define{{.*}} internal{{.*}} void @[[LOFFL1]](i{{64|32}} [[SIVAR_ARG:%.+]])
+ // LAMBDA: [[SIVAR_ADDR:%.+]] = alloca i{{.+}},
+ // LAMBDA: store{{.+}} [[SIVAR_ARG]], {{.+}} [[SIVAR_ADDR]],
+ // LAMBDA: [[SIVAR_CONV:%.+]] = bitcast{{.+}} [[SIVAR_ADDR]] to
+ // LAMBDA: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[LOUTL1:.+]] to {{.+}}, {{.+}} [[SIVAR_CONV]])
+ // LAMBDA: ret void
+
+ // LAMBDA: define internal void @[[LOUTL1]]({{.+}}, {{.+}}, {{.+}} [[SIVAR_ARG:%.+]])
+ // Skip global and bound tid vars
+ // LAMBDA: {{.+}} = alloca i32*,
+ // LAMBDA: {{.+}} = alloca i32*,
+ // LAMBDA: [[SIVAR_ADDR:%.+]] = alloca i{{.+}}*,
+ // LAMBDA: [[SIVAR_PRIV:%.+]] = alloca i{{.+}},
+ // LAMBDA: [[RED_LIST:%.+]] = alloca [1 x {{.+}}],
+ // LAMBDA: store{{.+}} [[SIVAR_ARG]], {{.+}} [[SIVAR_ADDR]],
+ // LAMBDA: [[SIVAR_REF:%.+]] = load{{.+}}, {{.+}} [[SIVAR_ADDR]]
+ // LAMBDA: store{{.+}} 0, {{.+}} [[SIVAR_PRIV]],
+
+ // LAMBDA: call void @__kmpc_for_static_init_4(
+ // LAMBDA: call void {{.*}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[LPAR_OUTL:.+]] to
+ // LAMBDA: call void @__kmpc_for_static_fini(
+ // LAMBDA: [[RED_LIST_GEP:%.+]] = getelementptr{{.+}} [[RED_LIST]],
+ // LAMBDA: [[SIVAR_PRIV_CAST:%.+]] = bitcast{{.+}} [[SIVAR_PRIV]] to
+ // LAMBDA: store{{.+}} [[SIVAR_PRIV_CAST]], {{.+}} [[RED_LIST_GEP]],
+ // LAMBDA: [[RED_LIST_BCAST:%.+]] = bitcast{{.+}} [[RED_LIST]] to
+ // LAMBDA: [[K_RED_RET:%.+]] = call{{.+}} @__kmpc_reduce_nowait({{.+}}, {{.+}}, {{.+}}, {{.+}}, {{.+}} [[RED_LIST_BCAST]], {{.+}} [[RED_FUN:@.+]], {{.+}} [[RED_VAR]])
+ // LAMBDA: switch{{.+}} [[K_RED_RET]], label{{.+}} [
+ // LAMBDA: {{.+}}, label %[[CASE1:.+]]
+ // LAMBDA: {{.+}}, label %[[CASE2:.+]]
+ // LAMBDA: ]
+ // LAMBDA: [[CASE1]]:
+ // LAMBDA-DAG: [[SIVAR_VAL:%.+]] = load{{.+}}, {{.+}} [[SIVAR_REF]],
+ // LAMBDA-DAG: [[SIVAR_PRIV_VAL:%.+]] = load{{.+}}, {{.+}} [[SIVAR_PRIV]],
+ // LAMBDA-DAG: [[SIVAR_INC:%.+]] = add{{.+}} [[SIVAR_VAL]], [[SIVAR_PRIV_VAL]]
+ // LAMBDA: store{{.+}} [[SIVAR_INC]], {{.+}} [[SIVAR_REF]],
+ // LAMBDA: call void @__kmpc_end_reduce_nowait({{.+}}, {{.+}}, {{.+}} [[RED_VAR]])
+ // LAMBDA: br
+ // LAMBDA: [[CASE2]]:
+ // LAMBDA-DAG: [[SIVAR_PRIV_VAL:%.+]] = load{{.+}}, {{.+}} [[SIVAR_PRIV]],
+ // LAMBDA-DAG: [[ATOMIC_RES:%.+]] = atomicrmw add{{.+}} [[SIVAR_REF]], {{.+}} [[SIVAR_PRIV_VAL]]
+ // LAMBDA: br
+
+ // LAMBDA: define internal void @[[LPAR_OUTL]]({{.+}}, {{.+}}, {{.+}}, {{.+}}, {{.+}} [[SIVAR_ARG:%.+]])
+
+ // Skip global and bound tid vars, and prev lb and ub vars
+ // LAMBDA: {{.+}} = alloca i32*,
+ // LAMBDA: {{.+}} = alloca i32*,
+ // LAMBDA: alloca i{{[0-9]+}},
+ // LAMBDA: alloca i{{[0-9]+}},
+ // LAMBDA: [[SIVAR_ADDR:%.+]] = alloca i{{.+}}*,
+ // skip loop vars
+ // LAMBDA: alloca i32,
+ // LAMBDA: alloca i32,
+ // LAMBDA: alloca i32,
+ // LAMBDA: alloca i32,
+ // LAMBDA: alloca i32,
+ // LAMBDA: alloca i32,
+ // LAMBDA: [[SIVAR_PRIV:%.+]] = alloca i{{.+}},
+ // LAMBDA: [[RED_LIST:%.+]] = alloca [1 x {{.+}}],
+ // LAMBDA: store{{.+}} [[SIVAR_ARG]], {{.+}} [[SIVAR_ADDR]],
+ // LAMBDA: [[SIVAR_REF:%.+]] = load{{.+}}, {{.+}} [[SIVAR_ADDR]]
+ // LAMBDA: store{{.+}} 0, {{.+}} [[SIVAR_PRIV]],
+
+ // LAMBDA: call void @__kmpc_for_static_init_4(
+ // LAMBDA: store{{.+}}, {{.+}} [[SIVAR_PRIV]],
+ // LAMBDA: call void [[INNER_LAMBDA:@.+]](
+ // LAMBDA: call void @__kmpc_for_static_fini(
+ // LAMBDA: [[RED_LIST_GEP:%.+]] = getelementptr{{.+}} [[RED_LIST]],
+ // LAMBDA: [[SIVAR_PRIV_CAST:%.+]] = bitcast{{.+}} [[SIVAR_PRIV]] to
+ // LAMBDA: store{{.+}} [[SIVAR_PRIV_CAST]], {{.+}} [[RED_LIST_GEP]],
+ // LAMBDA: [[RED_LIST_BCAST:%.+]] = bitcast{{.+}} [[RED_LIST]] to
+ // LAMBDA: [[K_RED_RET:%.+]] = call{{.+}} @__kmpc_reduce_nowait({{.+}}, {{.+}}, {{.+}}, {{.+}}, {{.+}} [[RED_LIST_BCAST]], {{.+}} [[RED_FUN:@.+]], {{.+}} [[RED_VAR]])
+ // LAMBDA: switch{{.+}} [[K_RED_RET]], label{{.+}} [
+ // LAMBDA: {{.+}}, label %[[CASE1:.+]]
+ // LAMBDA: {{.+}}, label %[[CASE2:.+]]
+ // LAMBDA: ]
+ // LAMBDA: [[CASE1]]:
+ // LAMBDA-DAG: [[SIVAR_VAL:%.+]] = load{{.+}}, {{.+}} [[SIVAR_REF]],
+ // LAMBDA-DAG: [[SIVAR_PRIV_VAL:%.+]] = load{{.+}}, {{.+}} [[SIVAR_PRIV]],
+ // LAMBDA-DAG: [[SIVAR_INC:%.+]] = add{{.+}} [[SIVAR_VAL]], [[SIVAR_PRIV_VAL]]
+ // LAMBDA: store{{.+}} [[SIVAR_INC]], {{.+}} [[SIVAR_REF]],
+ // LAMBDA: call void @__kmpc_end_reduce_nowait({{.+}}, {{.+}}, {{.+}} [[RED_VAR]])
+ // LAMBDA: br
+ // LAMBDA: [[CASE2]]:
+ // LAMBDA-DAG: [[SIVAR_PRIV_VAL:%.+]] = load{{.+}}, {{.+}} [[SIVAR_PRIV]],
+ // LAMBDA-DAG: [[ATOMIC_RES:%.+]] = atomicrmw add{{.+}} [[SIVAR_REF]], {{.+}} [[SIVAR_PRIV_VAL]]
+ // LAMBDA: br
+
+ sivar += i;
+
+ [&]() {
+ // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]])
+ // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]],
+
+ sivar += 4;
+ // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]]
+
+ // LAMBDA: [[SIVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // LAMBDA: [[SIVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SIVAR_PTR_REF]]
+ // LAMBDA: [[SIVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR_REF]]
+ // LAMBDA: [[SIVAR_INC:%.+]] = add{{.+}} [[SIVAR_VAL]], 4
+ // LAMBDA: store i{{[0-9]+}} [[SIVAR_INC]], i{{[0-9]+}}* [[SIVAR_REF]]
+ }();
+ }
+ }();
+ return 0;
+
+// LAMBDA: !{!"llvm.loop.vectorize.enable", i1 true}
+
+#else
+#pragma omp target
+#pragma omp teams distribute parallel for simd reduction(+: sivar)
+ for (int i = 0; i < 2; ++i) {
+ sivar += i;
+ }
+ return tmain<int>();
+#endif
+}
+
+// CHECK: [[RED_VAR:@.+]] = common global [8 x {{.+}}] zeroinitializer
+
+// CHECK: define {{.*}}i{{[0-9]+}} @main()
+// CHECK: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 1, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0)
+// CHECK: call void @[[OFFL1:.+]](i{{64|32}} %{{.+}})
+// CHECK: {{%.+}} = call{{.*}} i32 @[[TMAIN_INT:.+]]()
+// CHECK: ret
+
+// CHECK: define{{.*}} void @[[OFFL1]](i{{64|32}} [[SIVAR_ARG:%.+]])
+// CHECK: [[SIVAR_ADDR:%.+]] = alloca i{{.+}},
+// CHECK: store{{.+}} [[SIVAR_ARG]], {{.+}} [[SIVAR_ADDR]],
+// CHECK-64: [[SIVAR_CONV:%.+]] = bitcast{{.+}} [[SIVAR_ADDR]] to
+// CHECK-64: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTL1:.+]] to {{.+}}, {{.+}} [[SIVAR_CONV]])
+// CHECK-32: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTL1:.+]] to {{.+}}, {{.+}} [[SIVAR_ADDR]])
+// CHECK: ret void
+
+// CHECK: define internal void @[[OUTL1]]({{.+}}, {{.+}}, {{.+}} [[SIVAR_ARG:%.+]])
+// Skip global and bound tid vars
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: [[SIVAR_ADDR:%.+]] = alloca i{{.+}}*,
+// CHECK: [[SIVAR_PRIV:%.+]] = alloca i{{.+}},
+// CHECK: [[RED_LIST:%.+]] = alloca [1 x {{.+}}],
+// CHECK: store{{.+}} [[SIVAR_ARG]], {{.+}} [[SIVAR_ADDR]],
+// CHECK: [[SIVAR_REF:%.+]] = load{{.+}}, {{.+}} [[SIVAR_ADDR]]
+// CHECK: store{{.+}} 0, {{.+}} [[SIVAR_PRIV]],
+
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: call void {{.*}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[PAR_OUTL:.+]] to
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: [[RED_LIST_GEP:%.+]] = getelementptr{{.+}} [[RED_LIST]],
+// CHECK: [[SIVAR_PRIV_CAST:%.+]] = bitcast{{.+}} [[SIVAR_PRIV]] to
+// CHECK: store{{.+}} [[SIVAR_PRIV_CAST]], {{.+}} [[RED_LIST_GEP]],
+// CHECK: [[RED_LIST_BCAST:%.+]] = bitcast{{.+}} [[RED_LIST]] to
+// CHECK: [[K_RED_RET:%.+]] = call{{.+}} @__kmpc_reduce_nowait({{.+}}, {{.+}}, {{.+}}, {{.+}}, {{.+}} [[RED_LIST_BCAST]], {{.+}} [[RED_FUN:@.+]], {{.+}} [[RED_VAR]])
+// CHECK: switch{{.+}} [[K_RED_RET]], label{{.+}} [
+// CHECK: {{.+}}, label %[[CASE1:.+]]
+// CHECK: {{.+}}, label %[[CASE2:.+]]
+// CHECK: ]
+// CHECK: [[CASE1]]:
+// CHECK-DAG: [[SIVAR_VAL:%.+]] = load{{.+}}, {{.+}} [[SIVAR_REF]],
+// CHECK-DAG: [[SIVAR_PRIV_VAL:%.+]] = load{{.+}}, {{.+}} [[SIVAR_PRIV]],
+// CHECK-DAG: [[SIVAR_INC:%.+]] = add{{.+}} [[SIVAR_VAL]], [[SIVAR_PRIV_VAL]]
+// CHECK: store{{.+}} [[SIVAR_INC]], {{.+}} [[SIVAR_REF]],
+// CHECK: call void @__kmpc_end_reduce_nowait({{.+}}, {{.+}}, {{.+}} [[RED_VAR]])
+// CHECK: br
+// CHECK: [[CASE2]]:
+// CHECK-DAG: [[SIVAR_PRIV_VAL:%.+]] = load{{.+}}, {{.+}} [[SIVAR_PRIV]],
+// CHECK-DAG: [[ATOMIC_RES:%.+]] = atomicrmw add{{.+}} [[SIVAR_REF]], {{.+}} [[SIVAR_PRIV_VAL]]
+// CHECK: br
+
+// CHECK: define internal void @[[PAR_OUTL]]({{.+}}, {{.+}}, {{.+}}, {{.+}}, {{.+}} [[SIVAR_ARG:%.+]])
+// Skip global and bound tid vars, and prev lb and ub
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: [[SIVAR_ADDR:%.+]] = alloca i{{.+}}*,
+// skip loop vars
+// CHECK: alloca i32,
+// CHECK: alloca i32,
+// CHECK: alloca i32,
+// CHECK: alloca i32,
+// CHECK: alloca i32,
+// CHECK: alloca i32,
+// CHECK: [[SIVAR_PRIV:%.+]] = alloca i{{.+}},
+// CHECK: [[RED_LIST:%.+]] = alloca [1 x {{.+}}],
+// CHECK: store{{.+}} [[SIVAR_ARG]], {{.+}} [[SIVAR_ADDR]],
+// CHECK: [[SIVAR_REF:%.+]] = load{{.+}}, {{.+}} [[SIVAR_ADDR]]
+// CHECK: store{{.+}} 0, {{.+}} [[SIVAR_PRIV]],
+
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: store{{.+}}, {{.+}} [[SIVAR_PRIV]],
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: [[RED_LIST_GEP:%.+]] = getelementptr{{.+}} [[RED_LIST]],
+// CHECK: [[SIVAR_PRIV_CAST:%.+]] = bitcast{{.+}} [[SIVAR_PRIV]] to
+// CHECK: store{{.+}} [[SIVAR_PRIV_CAST]], {{.+}} [[RED_LIST_GEP]],
+// CHECK: [[RED_LIST_BCAST:%.+]] = bitcast{{.+}} [[RED_LIST]] to
+// CHECK: [[K_RED_RET:%.+]] = call{{.+}} @__kmpc_reduce_nowait({{.+}}, {{.+}}, {{.+}}, {{.+}}, {{.+}} [[RED_LIST_BCAST]], {{.+}} [[RED_FUN:@.+]], {{.+}} [[RED_VAR]])
+// CHECK: switch{{.+}} [[K_RED_RET]], label{{.+}} [
+// CHECK: {{.+}}, label %[[CASE1:.+]]
+// CHECK: {{.+}}, label %[[CASE2:.+]]
+// CHECK: ]
+// CHECK: [[CASE1]]:
+// CHECK-DAG: [[SIVAR_VAL:%.+]] = load{{.+}}, {{.+}} [[SIVAR_REF]],
+// CHECK-DAG: [[SIVAR_PRIV_VAL:%.+]] = load{{.+}}, {{.+}} [[SIVAR_PRIV]],
+// CHECK-DAG: [[SIVAR_INC:%.+]] = add{{.+}} [[SIVAR_VAL]], [[SIVAR_PRIV_VAL]]
+// CHECK: store{{.+}} [[SIVAR_INC]], {{.+}} [[SIVAR_REF]],
+// CHECK: call void @__kmpc_end_reduce_nowait({{.+}}, {{.+}}, {{.+}} [[RED_VAR]])
+// CHECK: br
+// CHECK: [[CASE2]]:
+// CHECK-DAG: [[SIVAR_PRIV_VAL:%.+]] = load{{.+}}, {{.+}} [[SIVAR_PRIV]],
+// CHECK-DAG: [[ATOMIC_RES:%.+]] = atomicrmw add{{.+}} [[SIVAR_REF]], {{.+}} [[SIVAR_PRIV_VAL]]
+// CHECK: br
+
+// CHECK: define{{.*}} i{{[0-9]+}} @[[TMAIN_INT]]()
+// CHECK: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 1,
+// CHECK: call void @[[TOFFL1:.+]]({{.+}})
+// CHECK: ret
+
+// CHECK: define{{.*}} void @[[TOFFL1]](i{{64|32}} [[TVAR_ARG:%.+]])
+// CHECK: [[TVAR_ADDR:%.+]] = alloca i{{.+}},
+// CHECK: store{{.+}} [[TVAR_ARG]], {{.+}} [[TVAR_ADDR]],
+// CHECK-64: [[TVAR_CONV:%.+]] = bitcast{{.+}} [[TVAR_ADDR]] to
+// CHECK-64: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[TOUTL1:.+]] to {{.+}}, {{.+}} [[TVAR_CONV]])
+// CHECK-32: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[TOUTL1:.+]] to {{.+}}, {{.+}} [[TVAR_ADDR]])
+// CHECK: ret void
+
+// CHECK: define internal void @[[TOUTL1]]({{.+}}, {{.+}}, {{.+}} [[TVAR_ARG:%.+]])
+// Skip global and bound tid vars
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: [[TVAR_ADDR:%.+]] = alloca i{{.+}}*,
+// CHECK: [[TVAR_PRIV:%.+]] = alloca i{{.+}},
+// CHECK: [[RED_LIST:%.+]] = alloca [1 x {{.+}}],
+// CHECK: store{{.+}} [[TVAR_ARG]], {{.+}} [[TVAR_ADDR]],
+// CHECK: [[TVAR_REF:%.+]] = load{{.+}}, {{.+}} [[TVAR_ADDR]]
+// CHECK: store{{.+}} 0, {{.+}} [[TVAR_PRIV]],
+
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: call void {{.*}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[TPAR_OUTL:.+]] to
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: [[RED_LIST_GEP:%.+]] = getelementptr{{.+}} [[RED_LIST]],
+// CHECK: [[TVAR_PRIV_CAST:%.+]] = bitcast{{.+}} [[TVAR_PRIV]] to
+// CHECK: store{{.+}} [[TVAR_PRIV_CAST]], {{.+}} [[RED_LIST_GEP]],
+// CHECK: [[RED_LIST_BCAST:%.+]] = bitcast{{.+}} [[RED_LIST]] to
+// CHECK: [[K_RED_RET:%.+]] = call{{.+}} @__kmpc_reduce_nowait({{.+}}, {{.+}}, {{.+}}, {{.+}}, {{.+}} [[RED_LIST_BCAST]], {{.+}} [[RED_FUN:@.+]], {{.+}} [[RED_VAR]])
+// CHECK: switch{{.+}} [[K_RED_RET]], label{{.+}} [
+// CHECK: {{.+}}, label %[[CASE1:.+]]
+// CHECK: {{.+}}, label %[[CASE2:.+]]
+// CHECK: ]
+// CHECK: [[CASE1]]:
+// CHECK-DAG: [[TVAR_VAL:%.+]] = load{{.+}}, {{.+}} [[TVAR_REF]],
+// CHECK-DAG: [[TVAR_PRIV_VAL:%.+]] = load{{.+}}, {{.+}} [[TVAR_PRIV]],
+// CHECK-DAG: [[TVAR_INC:%.+]] = add{{.+}} [[TVAR_VAL]], [[TVAR_PRIV_VAL]]
+// CHECK: store{{.+}} [[TVAR_INC]], {{.+}} [[TVAR_REF]],
+// CHECK: call void @__kmpc_end_reduce_nowait({{.+}}, {{.+}}, {{.+}} [[RED_VAR]])
+// CHECK: br
+// CHECK: [[CASE2]]:
+// CHECK-DAG: [[TVAR_PRIV_VAL:%.+]] = load{{.+}}, {{.+}} [[TVAR_PRIV]],
+// CHECK-DAG: [[ATOMIC_RES:%.+]] = atomicrmw add{{.+}} [[TVAR_REF]], {{.+}} [[TVAR_PRIV_VAL]]
+// CHECK: br
+
+// CHECK: define internal void @[[TPAR_OUTL]]({{.+}}, {{.+}}, {{.+}}, {{.+}}, {{.+}} [[TVAR_ARG:%.+]])
+// Skip global and bound tid vars, and prev lb and ub vars
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: [[TVAR_ADDR:%.+]] = alloca i{{.+}}*,
+// skip loop vars
+// CHECK: alloca i32,
+// CHECK: alloca i32,
+// CHECK: alloca i32,
+// CHECK: alloca i32,
+// CHECK: alloca i32,
+// CHECK: alloca i32,
+// CHECK: [[TVAR_PRIV:%.+]] = alloca i{{.+}},
+// CHECK: [[RED_LIST:%.+]] = alloca [1 x {{.+}}],
+// CHECK: store{{.+}} [[TVAR_ARG]], {{.+}} [[TVAR_ADDR]],
+// CHECK: [[TVAR_REF:%.+]] = load{{.+}}, {{.+}} [[TVAR_ADDR]]
+// CHECK: store{{.+}} 0, {{.+}} [[TVAR_PRIV]],
+
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: store{{.+}}, {{.+}} [[TVAR_PRIV]],
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: [[RED_LIST_GEP:%.+]] = getelementptr{{.+}} [[RED_LIST]],
+// CHECK: [[TVAR_PRIV_CAST:%.+]] = bitcast{{.+}} [[TVAR_PRIV]] to
+// CHECK: store{{.+}} [[TVAR_PRIV_CAST]], {{.+}} [[RED_LIST_GEP]],
+// CHECK: [[RED_LIST_BCAST:%.+]] = bitcast{{.+}} [[RED_LIST]] to
+// CHECK: [[K_RED_RET:%.+]] = call{{.+}} @__kmpc_reduce_nowait({{.+}}, {{.+}}, {{.+}}, {{.+}}, {{.+}} [[RED_LIST_BCAST]], {{.+}} [[RED_FUN:@.+]], {{.+}} [[RED_VAR]])
+// CHECK: switch{{.+}} [[K_RED_RET]], label{{.+}} [
+// CHECK: {{.+}}, label %[[CASE1:.+]]
+// CHECK: {{.+}}, label %[[CASE2:.+]]
+// CHECK: ]
+// CHECK: [[CASE1]]:
+// CHECK-DAG: [[TVAR_VAL:%.+]] = load{{.+}}, {{.+}} [[TVAR_REF]],
+// CHECK-DAG: [[TVAR_PRIV_VAL:%.+]] = load{{.+}}, {{.+}} [[TVAR_PRIV]],
+// CHECK-DAG: [[TVAR_INC:%.+]] = add{{.+}} [[TVAR_VAL]], [[TVAR_PRIV_VAL]]
+// CHECK: store{{.+}} [[TVAR_INC]], {{.+}} [[TVAR_REF]],
+// CHECK: call void @__kmpc_end_reduce_nowait({{.+}}, {{.+}}, {{.+}} [[RED_VAR]])
+// CHECK: br
+// CHECK: [[CASE2]]:
+// CHECK-DAG: [[TVAR_PRIV_VAL:%.+]] = load{{.+}}, {{.+}} [[TVAR_PRIV]],
+// CHECK-DAG: [[ATOMIC_RES:%.+]] = atomicrmw add{{.+}} [[TVAR_REF]], {{.+}} [[TVAR_PRIV_VAL]]
+// CHECK: br
+
+// CHECK: !{!"llvm.loop.vectorize.enable", i1 true}
+
+#endif
diff --git a/test/OpenMP/teams_distribute_parallel_for_simd_reduction_messages.cpp b/test/OpenMP/teams_distribute_parallel_for_simd_reduction_messages.cpp
index 47494b94ff0e..b0522e8f69d2 100644
--- a/test/OpenMP/teams_distribute_parallel_for_simd_reduction_messages.cpp
+++ b/test/OpenMP/teams_distribute_parallel_for_simd_reduction_messages.cpp
@@ -19,9 +19,9 @@ public:
S2() : a(0) {}
S2(S2 &s2) : a(s2.a) {}
static float S2s; // expected-note 2 {{static data member is predetermined as shared}}
- static const float S2sc;
+ static const float S2sc; // expected-note 2 {{'S2sc' declared here}}
};
-const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}}
+const float S2::S2sc = 0;
S2 b; // expected-note 3 {{'b' defined here}}
const S2 ba[5]; // expected-note 2 {{'ba' defined here}}
class S3 {
diff --git a/test/OpenMP/teams_distribute_parallel_for_simd_schedule_codegen.cpp b/test/OpenMP/teams_distribute_parallel_for_simd_schedule_codegen.cpp
new file mode 100644
index 000000000000..71e8ee8e8110
--- /dev/null
+++ b/test/OpenMP/teams_distribute_parallel_for_simd_schedule_codegen.cpp
@@ -0,0 +1,402 @@
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+// Test host codegen.
+// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64
+// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32
+#ifdef CK1
+
+template <typename T, int X, long long Y>
+struct SS{
+ T a[X];
+ float b;
+ // CK1: define {{.*}}i32 @{{.+}}foo{{.+}}(
+ int foo(void) {
+
+ // CK1: call i32 @__tgt_target_teams(
+ // CK1: call void @[[OFFL1:.+]](
+ #pragma omp target
+ #pragma omp teams distribute parallel for simd
+ for(int i = 0; i < X; i++) {
+ a[i] = (T)0;
+ }
+ // CK1: call i32 @__tgt_target_teams(
+ // CK1: call void @[[OFFL2:.+]](
+ #pragma omp target
+ #pragma omp teams distribute parallel for simd schedule(static)
+ for(int i = 0; i < X; i++) {
+ a[i] = (T)0;
+ }
+ // CK1: call i32 @__tgt_target_teams(
+ // CK1: call void @[[OFFL3:.+]](
+ #pragma omp target
+ #pragma omp teams distribute parallel for simd schedule(static, X/2)
+ for(int i = 0; i < X; i++) {
+ a[i] = (T)0;
+ }
+
+ // CK1: call i32 @__tgt_target_teams(
+ // CK1: call void @[[OFFL4:.+]](
+ #pragma omp target
+ #pragma omp teams distribute parallel for simd schedule(dynamic)
+ for(int i = 0; i < X; i++) {
+ a[i] = (T)0;
+ }
+
+ // CK1: call i32 @__tgt_target_teams(
+ // CK1: call void @[[OFFL5:.+]](
+ #pragma omp target
+ #pragma omp teams distribute parallel for simd schedule(dynamic, X/2)
+ for(int i = 0; i < X; i++) {
+ a[i] = (T)0;
+ }
+
+ // CK1: define internal void @[[OFFL1]](
+ // CK1: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTL1:.+]] to {{.+}},
+ // CK1: ret void
+
+ // CK1: define internal void @[[OUTL1]]({{.+}})
+ // CK1: call void @__kmpc_for_static_init_4(
+ // CK1: call void {{.*}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[PAR_OUTL1:.+]] to
+ // CK1: call void @__kmpc_for_static_fini(
+ // CK1: ret void
+
+ // CK1: define internal void @[[PAR_OUTL1]]({{.+}})
+ // CK1: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 34,
+ // CK1: call void @__kmpc_for_static_fini(
+ // CK1: ret void
+
+ // CK1: define internal void @[[OFFL2]](
+ // CK1: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTL2:.+]] to {{.+}},
+ // CK1: ret void
+
+ // CK1: define internal void @[[OUTL2]]({{.+}})
+ // CK1: call void @__kmpc_for_static_init_4(
+ // CK1: call void {{.*}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[PAR_OUTL2:.+]] to
+ // CK1: call void @__kmpc_for_static_fini(
+ // CK1: ret void
+
+ // CK1: define internal void @[[PAR_OUTL2]]({{.+}})
+ // CK1: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 34,
+ // CK1: call void @__kmpc_for_static_fini(
+ // CK1: ret void
+
+ // CK1: define internal void @[[OFFL3]](
+ // CK1: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTL3:.+]] to {{.+}},
+ // CK1: ret void
+
+ // CK1: define internal void @[[OUTL3]]({{.+}})
+ // CK1: call void @__kmpc_for_static_init_4(
+ // CK1: call void {{.*}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[PAR_OUTL3:.+]] to
+ // CK1: call void @__kmpc_for_static_fini(
+ // CK1: ret void
+
+ // CK1: define internal void @[[PAR_OUTL3]]({{.+}})
+ // CK1: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 33,
+ // CK1: call void @__kmpc_for_static_fini(
+ // CK1: ret void
+
+ // CK1: define internal void @[[OFFL4]](
+ // CK1: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTL4:.+]] to {{.+}},
+ // CK1: ret void
+
+ // CK1: define internal void @[[OUTL4]]({{.+}})
+ // CK1: call void @__kmpc_for_static_init_4(
+ // CK1: call void {{.*}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[PAR_OUTL4:.+]] to
+ // CK1: call void @__kmpc_for_static_fini(
+ // CK1: ret void
+
+ // CK1: define internal void @[[PAR_OUTL4]]({{.+}})
+ // CK1: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 35,
+ // CK1: call {{.+}} @__kmpc_dispatch_next_4(
+ // CK1: ret void
+
+ // CK1: define internal void @[[OFFL5]](
+ // CK1: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTL5:.+]] to {{.+}},
+ // CK1: ret void
+
+ // CK1: define internal void @[[OUTL5]]({{.+}})
+ // CK1: call void @__kmpc_for_static_init_4(
+ // CK1: call void {{.*}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[PAR_OUTL5:.+]] to
+ // CK1: call void @__kmpc_for_static_fini(
+ // CK1: ret void
+
+ // CK1: define internal void @[[PAR_OUTL5]]({{.+}})
+ // CK1: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 35,
+ // CK1: call {{.+}} @__kmpc_dispatch_next_4(
+ // CK1: ret void
+
+ // CK1: !{!"llvm.loop.vectorize.enable", i1 true}
+
+ return a[0];
+ }
+};
+
+int teams_template_struct(void) {
+ SS<int, 123, 456> V;
+ return V.foo();
+
+}
+#endif // CK1
+
+// Test host codegen.
+// RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64
+// RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32
+#ifdef CK2
+
+template <typename T, int n>
+int tmain(T argc) {
+ T a[n];
+ int m = 10;
+#pragma omp target
+#pragma omp teams distribute parallel for simd
+ for(int i = 0; i < n; i++) {
+ a[i] = (T)0;
+ }
+#pragma omp target
+#pragma omp teams distribute parallel for simd schedule(static)
+ for(int i = 0; i < n; i++) {
+ a[i] = (T)0;
+ }
+#pragma omp target
+#pragma omp teams distribute parallel for simd schedule(static, m)
+ for(int i = 0; i < n; i++) {
+ a[i] = (T)0;
+ }
+#pragma omp target
+#pragma omp teams distribute parallel for simd schedule(dynamic)
+ for(int i = 0; i < n; i++) {
+ a[i] = (T)0;
+ }
+#pragma omp target
+#pragma omp teams distribute parallel for simd schedule(dynamic, m)
+ for(int i = 0; i < n; i++) {
+ a[i] = (T)0;
+ }
+ return 0;
+}
+
+int main (int argc, char **argv) {
+ int n = 100;
+ int a[n];
+ int m = 10;
+#pragma omp target
+#pragma omp teams distribute parallel for simd
+ for(int i = 0; i < n; i++) {
+ a[i] = 0;
+ }
+#pragma omp target
+#pragma omp teams distribute parallel for simd dist_schedule(static)
+ for(int i = 0; i < n; i++) {
+ a[i] = 0;
+ }
+#pragma omp target
+#pragma omp teams distribute parallel for simd dist_schedule(static, m)
+ for(int i = 0; i < n; i++) {
+ a[i] = 0;
+ }
+#pragma omp target
+#pragma omp teams distribute parallel for simd schedule(dynamic)
+ for(int i = 0; i < n; i++) {
+ a[i] = 0;
+ }
+#pragma omp target
+#pragma omp teams distribute parallel for simd schedule(dynamic, m)
+ for(int i = 0; i < n; i++) {
+ a[i] = 0;
+ }
+ return tmain<int, 10>(argc);
+}
+
+// CK2: define {{.*}}i32 @{{[^,]+}}(i{{.+}}{{.+}} %[[ARGC:.+]], {{.+}})
+// CK2: call i32 @__tgt_target_teams(
+// CK2: call void @[[OFFL1:.+]]({{.+}})
+// CK2: call i32 @__tgt_target_teams(
+// CK2: call void @[[OFFL2:.+]]({{.+}})
+// CK2: call i32 @__tgt_target_teams(
+// CK2: call void @[[OFFL3:.+]]({{.+}})
+// CK2: call i32 @__tgt_target_teams(
+// CK2: call void @[[OFFL4:.+]]({{.+}})
+// CK2: call i32 @__tgt_target_teams(
+// CK2: call void @[[OFFL5:.+]]({{.+}})
+// CK2: {{%.+}} = call{{.*}} i32 @[[TMAIN:.+]]({{.+}})
+// CK2: ret
+
+// CK2: define {{.*}}void @[[OFFL1]]({{.+}})
+// CK2: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 3, {{.+}} @[[OUTL1:.+]] to {{.+}},
+// CK2: ret void
+
+// CK2: define internal void @[[OUTL1]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4(
+// CK2: call void {{.*}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[PAR_OUTL1:.+]] to
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define internal void @[[PAR_OUTL1]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 34,
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define {{.*}}void @[[OFFL2]]({{.+}})
+// CK2: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 3, {{.+}} @[[OUTL2:.+]] to {{.+}},
+// CK2: ret void
+
+// CK2: define internal void @[[OUTL2]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4(
+// CK2: call void {{.*}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[PAR_OUTL2:.+]] to
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define internal void @[[PAR_OUTL2]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 34,
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define {{.*}}void @[[OFFL3]]({{.+}})
+// CK2: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 4, {{.+}} @[[OUTL3:.+]] to {{.+}},
+// CK2: ret void
+
+// CK2: define internal void @[[OUTL3]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4(
+// CK2: call void {{.*}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[PAR_OUTL3:.+]] to
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define internal void @[[PAR_OUTL3]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 34
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define {{.*}}void @[[OFFL4]]({{.+}})
+// CK2: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 {{.+}}, {{.+}} @[[OUTL4:.+]] to {{.+}},
+// CK2: ret void
+
+// CK2: define internal void @[[OUTL4]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4(
+// CK2: call void {{.*}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[PAR_OUTL4:.+]] to
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define internal void @[[PAR_OUTL4]]({{.+}})
+// CK2: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 35,
+// CK2: call {{.+}} @__kmpc_dispatch_next_4(
+// CK2: ret void
+
+
+// CK2: define {{.*}}void @[[OFFL5]]({{.+}})
+// CK2: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 {{.+}}, {{.+}} @[[OUTL5:.+]] to {{.+}},
+// CK2: ret void
+
+// CK2: define internal void @[[OUTL5]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4(
+// CK2: call void {{.*}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[PAR_OUTL5:.+]] to
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define internal void @[[PAR_OUTL5]]({{.+}})
+// CK2: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 35,
+// CK2: call {{.+}} @__kmpc_dispatch_next_4(
+// CK2: ret void
+
+// CK2: define {{.*}}i32 @[[TMAIN]]({{.+}})
+// CK2: call i32 @__tgt_target_teams(
+// CK2: call void @[[OFFLT1:.+]]({{.+}})
+// CK2: call i32 @__tgt_target_teams(
+// CK2: call void @[[OFFLT2:.+]]({{.+}})
+// CK2: call i32 @__tgt_target_teams(
+// CK2: call void @[[OFFLT3:.+]]({{.+}})
+// CK2: call i32 @__tgt_target_teams(
+// CK2: call void @[[OFFLT4:.+]]({{.+}})
+// CK2: call i32 @__tgt_target_teams(
+// CK2: call void @[[OFFLT5:.+]]({{.+}})
+// CK2: ret
+// CK2-NEXT: }
+
+// CK2: define {{.*}}void @[[OFFLT1]]({{.+}})
+// CK2: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTLT1:.+]] to {{.+}},
+// CK2: ret void
+
+// CK2: define internal void @[[OUTLT1]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4(
+// CK2: call void {{.*}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[PAR_OUTLT1:.+]] to
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define internal void @[[PAR_OUTLT1]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 34,
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define {{.*}}void @[[OFFLT2]]({{.+}})
+// CK2: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTLT2:.+]] to {{.+}},
+// CK2: ret void
+
+// CK2: define internal void @[[OUTLT2]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4(
+// CK2: call void {{.*}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[PAR_OUTLT2:.+]] to
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define internal void @[[PAR_OUTLT2]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 34,
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define {{.*}}void @[[OFFLT3]]({{.+}})
+// CK2: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 {{.+}}, {{.+}} @[[OUTLT3:.+]] to {{.+}},
+// CK2: ret void
+
+// CK2: define internal void @[[OUTLT3]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4(
+// CK2: call void {{.*}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[PAR_OUTLT3:.+]] to
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define internal void @[[PAR_OUTLT3]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 33,
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define {{.*}}void @[[OFFLT4]]({{.+}})
+// CK2: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 {{.+}}, {{.+}} @[[OUTLT4:.+]] to {{.+}},
+// CK2: ret void
+
+// CK2: define internal void @[[OUTLT4]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4(
+// CK2: call void {{.*}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[PAR_OUTLT4:.+]] to
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define internal void @[[PAR_OUTLT4]]({{.+}})
+// CK2: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 35,
+// CK2: call {{.+}} @__kmpc_dispatch_next_4(
+// CK2: ret void
+
+// CK2: define {{.*}}void @[[OFFLT5]]({{.+}})
+// CK2: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 {{.+}}, {{.+}} @[[OUTLT5:.+]] to {{.+}},
+// CK2: ret void
+
+// CK2: define internal void @[[OUTLT5]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4(
+// CK2: call void {{.*}} @__kmpc_fork_call({{.+}}, {{.+}}, {{.+}} @[[PAR_OUTLT5:.+]] to
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define internal void @[[PAR_OUTLT5]]({{.+}})
+// CK2: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 35,
+// CK2: call {{.+}} @__kmpc_dispatch_next_4(
+// CK2: ret void
+
+// CK2: !{!"llvm.loop.vectorize.enable", i1 true}
+
+#endif // CK2
+#endif // #ifndef HEADER
diff --git a/test/OpenMP/teams_distribute_parallel_for_simd_shared_messages.cpp b/test/OpenMP/teams_distribute_parallel_for_simd_shared_messages.cpp
index f13146641a38..1089555889f0 100644
--- a/test/OpenMP/teams_distribute_parallel_for_simd_shared_messages.cpp
+++ b/test/OpenMP/teams_distribute_parallel_for_simd_shared_messages.cpp
@@ -84,7 +84,7 @@ int main(int argc, char **argv) {
#pragma omp teams distribute parallel for simd shared (S1) // expected-error {{'S1' does not refer to a value}}
for (int j=0; j<100; j++) foo();
#pragma omp target
- #pragma omp teams distribute parallel for simd shared (a, b, c, d, f)
+ #pragma omp teams distribute parallel for simd shared (a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}}
for (int j=0; j<100; j++) foo();
#pragma omp target
#pragma omp teams distribute parallel for simd shared (argv[1]) // expected-error {{expected variable name}}
diff --git a/test/OpenMP/teams_distribute_private_codegen.cpp b/test/OpenMP/teams_distribute_private_codegen.cpp
new file mode 100644
index 000000000000..8e4a61cd7cb1
--- /dev/null
+++ b/test/OpenMP/teams_distribute_private_codegen.cpp
@@ -0,0 +1,236 @@
+// RUN: %clang_cc1 -DCHECK -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -DCHECK -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+
+// RUN: %clang_cc1 -DLAMBDA -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+struct St {
+ int a, b;
+ St() : a(0), b(0) {}
+ St(const St &st) : a(st.a + st.b), b(0) {}
+ ~St() {}
+};
+
+volatile int g = 1212;
+volatile int &g1 = g;
+
+template <class T>
+struct S {
+ T f;
+ S(T a) : f(a + g) {}
+ S() : f(g) {}
+ S(const S &s, St t = St()) : f(s.f + t.a) {}
+ operator T() { return T(); }
+ ~S() {}
+};
+
+// CHECK-DAG: [[S_FLOAT_TY:%.+]] = type { float }
+// CHECK-DAG: [[S_INT_TY:%.+]] = type { i{{[0-9]+}} }
+
+template <typename T>
+T tmain() {
+ S<T> test;
+ T t_var = T();
+ T vec[] = {1, 2};
+ S<T> s_arr[] = {1, 2};
+ S<T> &var = test;
+#pragma omp target
+#pragma omp teams distribute private(t_var, vec, s_arr, var)
+ for (int i = 0; i < 2; ++i) {
+ vec[i] = t_var;
+ s_arr[i] = var;
+ }
+ return T();
+}
+
+// CHECK-DAG: [[TEST:@.+]] = global [[S_FLOAT_TY]] zeroinitializer,
+S<float> test;
+// CHECK-DAG: [[T_VAR:@.+]] = global i{{[0-9]+}} 333,
+int t_var = 333;
+// CHECK-DAG: [[VEC:@.+]] = global [2 x i{{[0-9]+}}] [i{{[0-9]+}} 1, i{{[0-9]+}} 2],
+int vec[] = {1, 2};
+// CHECK-DAG: [[S_ARR:@.+]] = global [2 x [[S_FLOAT_TY]]] zeroinitializer,
+S<float> s_arr[] = {1, 2};
+// CHECK-DAG: [[VAR:@.+]] = global [[S_FLOAT_TY]] zeroinitializer,
+S<float> var(3);
+// CHECK-DAG: [[SIVAR:@.+]] = internal global i{{[0-9]+}} 0,
+
+int main() {
+ static int sivar;
+#ifdef LAMBDA
+ // LAMBDA: [[G:@.+]] = global i{{[0-9]+}} 1212,
+ // LAMBDA-LABEL: @main
+ // LAMBDA: call void [[OUTER_LAMBDA:@.+]](
+ [&]() {
+ // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
+ // LAMBDA: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 1, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 0)
+ // LAMBDA: call void @[[LOFFL1:.+]](
+ // LAMBDA: ret
+#pragma omp target
+#pragma omp teams distribute private(g, g1, sivar)
+ for (int i = 0; i < 2; ++i) {
+ // LAMBDA: define{{.*}} internal{{.*}} void @[[LOFFL1]](i{{64|32}} {{%.+}})
+ // LAMBDA: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 0, {{.+}} @[[LOUTL1:.+]] to {{.+}})
+ // LAMBDA: ret void
+
+ // LAMBDA: define internal void @[[LOUTL1]]({{.+}})
+ // Skip global, bound tid and loop vars
+ // LAMBDA: {{.+}} = alloca i32*,
+ // LAMBDA: {{.+}} = alloca i32*,
+ // LAMBDA: alloca i32,
+ // LAMBDA: alloca i32,
+ // LAMBDA: alloca i32,
+ // LAMBDA: alloca i32,
+ // LAMBDA: alloca i32,
+ // LAMBDA: alloca i32,
+ // LAMBDA: [[G_PRIV:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[G1_PRIV:%.+]] = alloca i{{[0-9]+}}
+ // LAMBDA: [[TMP:%.+]] = alloca i{{[0-9]+}}*,
+ // LAMBDA: [[SIVAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: store{{.+}} [[G1_PRIV]], {{.+}} [[TMP]],
+ g = 1;
+ g1 = 1;
+ sivar = 2;
+ // LAMBDA: call void @__kmpc_for_static_init_4(
+ // LAMBDA-DAG: store{{.+}} 1, {{.+}} [[G_PRIV]],
+ // LAMBDA-DAG: store{{.+}} 2, {{.+}} [[SIVAR_PRIV]],
+ // LAMBDA-DAG: [[G1_REF:%.+]] = load{{.+}}, {{.+}} [[TMP]],
+ // LAMBDA-DAG: store{{.+}} 1, {{.+}} [[G1_REF]],
+ // LAMBDA: call void [[INNER_LAMBDA:@.+]](
+ // LAMBDA: call void @__kmpc_for_static_fini(
+ [&]() {
+ // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]])
+ // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]],
+ g = 2;
+ g1 = 2;
+ sivar = 4;
+ // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]]
+
+ // LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // LAMBDA: [[G_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G_PTR_REF]]
+ // LAMBDA: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[G_REF]]
+ // LAMBDA: [[G1_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // LAMBDA: [[G1_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G1_PTR_REF]]
+ // LAMBDA: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[G1_REF]]
+ // LAMBDA: [[SIVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+ // LAMBDA: [[SIVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SIVAR_PTR_REF]]
+ // LAMBDA: store i{{[0-9]+}} 4, i{{[0-9]+}}* [[SIVAR_REF]]
+ }();
+ }
+ }();
+ return 0;
+#else
+#pragma omp target
+#pragma omp teams distribute private(t_var, vec, s_arr, var, sivar)
+ for (int i = 0; i < 2; ++i) {
+ vec[i] = t_var;
+ s_arr[i] = var;
+ sivar += i;
+ }
+ return tmain<int>();
+#endif
+}
+
+// CHECK: define {{.*}}i{{[0-9]+}} @main()
+// CHECK: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 0, i8** null, i8** null, i{{64|32}}* null, i64* null, i32 0, i32 0)
+// CHECK: call void @[[OFFL1:.+]]()
+// CHECK: {{%.+}} = call{{.*}} i32 @[[TMAIN_INT:.+]]()
+// CHECK: ret
+
+// CHECK: define{{.*}} void @[[OFFL1]]()
+// CHECK: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 0, {{.+}} @[[OUTL1:.+]] to {{.+}})
+// CHECK: ret void
+
+// CHECK: define internal void @[[OUTL1]]({{.+}})
+// Skip global, bound tid and loop vars
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: {{.+}} = alloca i32,
+// CHECK: {{.+}} = alloca i32,
+// CHECK: {{.+}} = alloca i32,
+// CHECK: {{.+}} = alloca i32,
+// CHECK: {{.+}} = alloca i32,
+// CHECK: {{.+}} = alloca i32,
+// CHECK-DAG: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK-DAG: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK-DAG: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]],
+// CHECK-DAG: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]],
+// CHECK-DAG: [[SIVAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+
+// private(s_arr)
+// CHECK-DAG: [[S_ARR_PRIV_BGN:%.+]] = getelementptr{{.*}} [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[S_ARR_PRIV]],
+// CHECK-DAG: [[S_ARR_PTR_ALLOC:%.+]] = phi{{.+}} [ [[S_ARR_PRIV_BGN]], {{.+}} ], [ [[S_ARR_NEXT:%.+]], {{.+}} ]
+// CHECK-DAG: call void @{{.+}}({{.+}} [[S_ARR_PTR_ALLOC]])
+// CHECK-DAG: [[S_ARR_NEXT]] = getelementptr {{.+}} [[S_ARR_PTR_ALLOC]],
+
+// private(var)
+// CHECK-DAG: call void @{{.+}}({{.+}} [[VAR_PRIV]])
+
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK-DAG: {{.+}} = {{.+}} [[T_VAR_PRIV]]
+// CHECK-DAG: {{.+}} = {{.+}} [[VEC_PRIV]]
+// CHECK-DAG: {{.+}} = {{.+}} [[S_ARR_PRIV]]
+// CHECK-DAG: {{.+}} = {{.+}} [[VAR_PRIV]]
+// CHECK-DAG: {{.+}} = {{.+}} [[SIVAR_PRIV]]
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: ret void
+
+
+// CHECK: define{{.*}} i{{[0-9]+}} @[[TMAIN_INT]]()
+// CHECK: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 0,
+// CHECK: call void @[[TOFFL1:.+]]()
+// CHECK: ret
+
+// CHECK: define {{.*}}void @[[TOFFL1]]()
+// CHECK: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 0, {{.+}} @[[TOUTL1:.+]] to {{.+}})
+// CHECK: ret void
+
+// CHECK: define internal void @[[TOUTL1]]({{.+}})
+// Skip global, bound tid and loop vars
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_INT_TY]]],
+// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_INT_TY]],
+// CHECK: [[TMP:%.+]] = alloca [[S_INT_TY]]*,
+
+// private(s_arr)
+// CHECK-DAG: [[S_ARR_PRIV_BGN:%.+]] = getelementptr{{.*}} [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[S_ARR_PRIV]],
+// CHECK-DAG: [[S_ARR_PTR_ALLOC:%.+]] = phi{{.+}} [ [[S_ARR_PRIV_BGN]], {{.+}} ], [ [[S_ARR_NEXT:%.+]], {{.+}} ]
+// CHECK-DAG: call void @{{.+}}({{.+}} [[S_ARR_PTR_ALLOC]])
+// CHECK-DAG: [[S_ARR_NEXT]] = getelementptr {{.+}} [[S_ARR_PTR_ALLOC]],
+
+// CHECK-DAG: [[S_ARR_PRIV_BGN:%.+]] = getelementptr{{.*}} [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[S_ARR_PRIV]],
+// CHECK-DAG: [[S_ARR_PTR_ALLOC:%.+]] = phi{{.+}} [ [[S_ARR_PRIV_BGN]], {{.+}} ], [ [[S_ARR_NEXT:%.+]], {{.+}} ]
+// CHECK-DAG: call void @{{.+}}({{.+}} [[S_ARR_PTR_ALLOC]])
+// CHECK-DAG: [[S_ARR_NEXT]] = getelementptr {{.+}} [[S_ARR_PTR_ALLOC]],
+
+// private(var)
+// CHECK-DAG: call void @{{.+}}({{.+}} [[VAR_PRIV]])
+// CHECK-DAG: store{{.+}} [[VAR_PRIV]], {{.+}} [[TMP]]
+
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK-DAG: {{.+}} = {{.+}} [[T_VAR_PRIV]]
+// CHECK-DAG: {{.+}} = {{.+}} [[VEC_PRIV]]
+// CHECK-DAG: {{.+}} = {{.+}} [[S_ARR_PRIV]]
+// CHECK-DAG: {{.+}} = {{.+}} [[TMP]]
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: ret void
+
+#endif
diff --git a/test/OpenMP/teams_distribute_reduction_codegen.cpp b/test/OpenMP/teams_distribute_reduction_codegen.cpp
new file mode 100644
index 000000000000..961891da98d0
--- /dev/null
+++ b/test/OpenMP/teams_distribute_reduction_codegen.cpp
@@ -0,0 +1,217 @@
+// RUN: %clang_cc1 -DCHECK -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -DCHECK -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+
+// RUN: %clang_cc1 -DLAMBDA -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+template <typename T>
+T tmain() {
+ T t_var = T();
+ T vec[] = {1, 2};
+#pragma omp target
+#pragma omp teams distribute reduction(+: t_var)
+ for (int i = 0; i < 2; ++i) {
+ t_var += (T) i;
+ }
+ return T();
+}
+
+int main() {
+ static int sivar;
+#ifdef LAMBDA
+ // LAMBDA: [[RED_VAR:@.+]] = common global [8 x {{.+}}] zeroinitializer
+
+ // LAMBDA-LABEL: @main
+ // LAMBDA: call void [[OUTER_LAMBDA:@.+]](
+ [&]() {
+ // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
+ // LAMBDA: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 1, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 0)
+ // LAMBDA: call void @[[LOFFL1:.+]](
+ // LAMBDA: ret
+#pragma omp target
+#pragma omp teams distribute reduction(+: sivar)
+ for (int i = 0; i < 2; ++i) {
+ // LAMBDA: define{{.*}} internal{{.*}} void @[[LOFFL1]](i{{64|32}} [[SIVAR_ARG:%.+]])
+ // LAMBDA: [[SIVAR_ADDR:%.+]] = alloca i{{.+}},
+ // LAMBDA: store{{.+}} [[SIVAR_ARG]], {{.+}} [[SIVAR_ADDR]],
+ // LAMBDA: [[SIVAR_CONV:%.+]] = bitcast{{.+}} [[SIVAR_ADDR]] to
+ // LAMBDA: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[LOUTL1:.+]] to {{.+}}, {{.+}} [[SIVAR_CONV]])
+ // LAMBDA: ret void
+
+ // LAMBDA: define internal void @[[LOUTL1]]({{.+}}, {{.+}}, {{.+}} [[SIVAR_ARG:%.+]])
+ // Skip global and bound tid vars
+ // LAMBDA: {{.+}} = alloca i32*,
+ // LAMBDA: {{.+}} = alloca i32*,
+ // LAMBDA: [[SIVAR_ADDR:%.+]] = alloca i{{.+}}*,
+ // LAMBDA: [[SIVAR_PRIV:%.+]] = alloca i{{.+}},
+ // LAMBDA: [[RED_LIST:%.+]] = alloca [1 x {{.+}}],
+ // LAMBDA: store{{.+}} [[SIVAR_ARG]], {{.+}} [[SIVAR_ADDR]],
+ // LAMBDA: [[SIVAR_REF:%.+]] = load{{.+}}, {{.+}} [[SIVAR_ADDR]]
+ // LAMBDA: store{{.+}} 0, {{.+}} [[SIVAR_PRIV]],
+
+ // LAMBDA: call void @__kmpc_for_static_init_4(
+ // LAMBDA: store{{.+}}, {{.+}} [[SIVAR_PRIV]],
+ // LAMBDA: call void [[INNER_LAMBDA:@.+]](
+ // LAMBDA: call void @__kmpc_for_static_fini(
+ // LAMBDA: [[RED_LIST_GEP:%.+]] = getelementptr{{.+}} [[RED_LIST]],
+ // LAMBDA: [[SIVAR_PRIV_CAST:%.+]] = bitcast{{.+}} [[SIVAR_PRIV]] to
+ // LAMBDA: store{{.+}} [[SIVAR_PRIV_CAST]], {{.+}} [[RED_LIST_GEP]],
+ // LAMBDA: [[RED_LIST_BCAST:%.+]] = bitcast{{.+}} [[RED_LIST]] to
+ // LAMBDA: [[K_RED_RET:%.+]] = call{{.+}} @__kmpc_reduce({{.+}}, {{.+}}, {{.+}}, {{.+}}, {{.+}} [[RED_LIST_BCAST]], {{.+}} [[RED_FUN:@.+]], {{.+}} [[RED_VAR]])
+ // LAMBDA: switch{{.+}} [[K_RED_RET]], label{{.+}} [
+ // LAMBDA: {{.+}}, label %[[CASE1:.+]]
+ // LAMBDA: {{.+}}, label %[[CASE2:.+]]
+ // LAMBDA: ]
+ // LAMBDA: [[CASE1]]:
+ // LAMBDA-DAG: [[SIVAR_VAL:%.+]] = load{{.+}}, {{.+}} [[SIVAR_REF]],
+ // LAMBDA-DAG: [[SIVAR_PRIV_VAL:%.+]] = load{{.+}}, {{.+}} [[SIVAR_PRIV]],
+ // LAMBDA-DAG: [[SIVAR_INC:%.+]] = add{{.+}} [[SIVAR_VAL]], [[SIVAR_PRIV_VAL]]
+ // LAMBDA: store{{.+}} [[SIVAR_INC]], {{.+}} [[SIVAR_REF]],
+ // LAMBDA: call void @__kmpc_end_reduce({{.+}}, {{.+}}, {{.+}} [[RED_VAR]])
+ // LAMBDA: br
+ // LAMBDA: [[CASE2]]:
+ // LAMBDA-DAG: [[SIVAR_PRIV_VAL:%.+]] = load{{.+}}, {{.+}} [[SIVAR_PRIV]],
+ // LAMBDA-DAG: [[ATOMIC_RES:%.+]] = atomicrmw add{{.+}} [[SIVAR_REF]], {{.+}} [[SIVAR_PRIV_VAL]]
+ // LAMBDA: call void @__kmpc_end_reduce({{.+}}, {{.+}}, {{.+}} [[RED_VAR]])
+ // LAMBDA: br
+
+ sivar += i;
+
+ [&]() {
+ // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]])
+ // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]],
+
+ sivar += 4;
+ // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]]
+
+ // LAMBDA: [[SIVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // LAMBDA: [[SIVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SIVAR_PTR_REF]]
+ // LAMBDA: [[SIVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR_REF]]
+ // LAMBDA: [[SIVAR_INC:%.+]] = add{{.+}} [[SIVAR_VAL]], 4
+ // LAMBDA: store i{{[0-9]+}} [[SIVAR_INC]], i{{[0-9]+}}* [[SIVAR_REF]]
+ }();
+ }
+ }();
+ return 0;
+#else
+#pragma omp target
+#pragma omp teams distribute reduction(+: sivar)
+ for (int i = 0; i < 2; ++i) {
+ sivar += i;
+ }
+ return tmain<int>();
+#endif
+}
+
+// CHECK: [[RED_VAR:@.+]] = common global [8 x {{.+}}] zeroinitializer
+
+// CHECK: define {{.*}}i{{[0-9]+}} @main()
+// CHECK: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 1, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 0)
+// CHECK: call void @[[OFFL1:.+]](i{{64|32}} %{{.+}})
+// CHECK: {{%.+}} = call{{.*}} i32 @[[TMAIN_INT:.+]]()
+// CHECK: ret
+
+// CHECK: define{{.*}} void @[[OFFL1]](i{{64|32}} [[SIVAR_ARG:%.+]])
+// CHECK: [[SIVAR_ADDR:%.+]] = alloca i{{.+}},
+// CHECK: store{{.+}} [[SIVAR_ARG]], {{.+}} [[SIVAR_ADDR]],
+// CHECK-64: [[SIVAR_CONV:%.+]] = bitcast{{.+}} [[SIVAR_ADDR]] to
+// CHECK-64: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTL1:.+]] to {{.+}}, {{.+}} [[SIVAR_CONV]])
+// CHECK-32: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTL1:.+]] to {{.+}}, {{.+}} [[SIVAR_ADDR]])
+// CHECK: ret void
+
+// CHECK: define internal void @[[OUTL1]]({{.+}}, {{.+}}, {{.+}} [[SIVAR_ARG:%.+]])
+// Skip global and bound tid vars
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: [[SIVAR_ADDR:%.+]] = alloca i{{.+}}*,
+// CHECK: [[SIVAR_PRIV:%.+]] = alloca i{{.+}},
+// CHECK: [[RED_LIST:%.+]] = alloca [1 x {{.+}}],
+// CHECK: store{{.+}} [[SIVAR_ARG]], {{.+}} [[SIVAR_ADDR]],
+// CHECK: [[SIVAR_REF:%.+]] = load{{.+}}, {{.+}} [[SIVAR_ADDR]]
+// CHECK: store{{.+}} 0, {{.+}} [[SIVAR_PRIV]],
+
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: store{{.+}}, {{.+}} [[SIVAR_PRIV]],
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: [[RED_LIST_GEP:%.+]] = getelementptr{{.+}} [[RED_LIST]],
+// CHECK: [[SIVAR_PRIV_CAST:%.+]] = bitcast{{.+}} [[SIVAR_PRIV]] to
+// CHECK: store{{.+}} [[SIVAR_PRIV_CAST]], {{.+}} [[RED_LIST_GEP]],
+// CHECK: [[RED_LIST_BCAST:%.+]] = bitcast{{.+}} [[RED_LIST]] to
+// CHECK: [[K_RED_RET:%.+]] = call{{.+}} @__kmpc_reduce({{.+}}, {{.+}}, {{.+}}, {{.+}}, {{.+}} [[RED_LIST_BCAST]], {{.+}} [[RED_FUN:@.+]], {{.+}} [[RED_VAR]])
+// CHECK: switch{{.+}} [[K_RED_RET]], label{{.+}} [
+// CHECK: {{.+}}, label %[[CASE1:.+]]
+// CHECK: {{.+}}, label %[[CASE2:.+]]
+// CHECK: ]
+// CHECK: [[CASE1]]:
+// CHECK-DAG: [[SIVAR_VAL:%.+]] = load{{.+}}, {{.+}} [[SIVAR_REF]],
+// CHECK-DAG: [[SIVAR_PRIV_VAL:%.+]] = load{{.+}}, {{.+}} [[SIVAR_PRIV]],
+// CHECK-DAG: [[SIVAR_INC:%.+]] = add{{.+}} [[SIVAR_VAL]], [[SIVAR_PRIV_VAL]]
+// CHECK: store{{.+}} [[SIVAR_INC]], {{.+}} [[SIVAR_REF]],
+// CHECK: call void @__kmpc_end_reduce({{.+}}, {{.+}}, {{.+}} [[RED_VAR]])
+// CHECK: br
+// CHECK: [[CASE2]]:
+// CHECK-DAG: [[SIVAR_PRIV_VAL:%.+]] = load{{.+}}, {{.+}} [[SIVAR_PRIV]],
+// CHECK-DAG: [[ATOMIC_RES:%.+]] = atomicrmw add{{.+}} [[SIVAR_REF]], {{.+}} [[SIVAR_PRIV_VAL]]
+// CHECK: call void @__kmpc_end_reduce({{.+}}, {{.+}}, {{.+}} [[RED_VAR]])
+// CHECK: br
+
+
+// CHECK: define{{.*}} i{{[0-9]+}} @[[TMAIN_INT]]()
+// CHECK: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 1,
+// CHECK: call void @[[TOFFL1:.+]]({{.+}})
+// CHECK: ret
+
+// CHECK: define{{.*}} void @[[TOFFL1]](i{{64|32}} [[TVAR_ARG:%.+]])
+// CHECK: [[TVAR_ADDR:%.+]] = alloca i{{.+}},
+// CHECK: store{{.+}} [[TVAR_ARG]], {{.+}} [[TVAR_ADDR]],
+// CHECK-64: [[TVAR_CONV:%.+]] = bitcast{{.+}} [[TVAR_ADDR]] to
+// CHECK-64: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[TOUTL1:.+]] to {{.+}}, {{.+}} [[TVAR_CONV]])
+// CHECK-32: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[TOUTL1:.+]] to {{.+}}, {{.+}} [[TVAR_ADDR]])
+// CHECK: ret void
+
+// CHECK: define internal void @[[TOUTL1]]({{.+}}, {{.+}}, {{.+}} [[TVAR_ARG:%.+]])
+// Skip global and bound tid vars
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: [[TVAR_ADDR:%.+]] = alloca i{{.+}}*,
+// CHECK: [[TVAR_PRIV:%.+]] = alloca i{{.+}},
+// CHECK: [[RED_LIST:%.+]] = alloca [1 x {{.+}}],
+// CHECK: store{{.+}} [[TVAR_ARG]], {{.+}} [[TVAR_ADDR]],
+// CHECK: [[TVAR_REF:%.+]] = load{{.+}}, {{.+}} [[TVAR_ADDR]]
+// CHECK: store{{.+}} 0, {{.+}} [[TVAR_PRIV]],
+
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: store{{.+}}, {{.+}} [[TVAR_PRIV]],
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: [[RED_LIST_GEP:%.+]] = getelementptr{{.+}} [[RED_LIST]],
+// CHECK: [[TVAR_PRIV_CAST:%.+]] = bitcast{{.+}} [[TVAR_PRIV]] to
+// CHECK: store{{.+}} [[TVAR_PRIV_CAST]], {{.+}} [[RED_LIST_GEP]],
+// CHECK: [[RED_LIST_BCAST:%.+]] = bitcast{{.+}} [[RED_LIST]] to
+// CHECK: [[K_RED_RET:%.+]] = call{{.+}} @__kmpc_reduce({{.+}}, {{.+}}, {{.+}}, {{.+}}, {{.+}} [[RED_LIST_BCAST]], {{.+}} [[RED_FUN:@.+]], {{.+}} [[RED_VAR]])
+// CHECK: switch{{.+}} [[K_RED_RET]], label{{.+}} [
+// CHECK: {{.+}}, label %[[CASE1:.+]]
+// CHECK: {{.+}}, label %[[CASE2:.+]]
+// CHECK: ]
+// CHECK: [[CASE1]]:
+// CHECK-DAG: [[TVAR_VAL:%.+]] = load{{.+}}, {{.+}} [[TVAR_REF]],
+// CHECK-DAG: [[TVAR_PRIV_VAL:%.+]] = load{{.+}}, {{.+}} [[TVAR_PRIV]],
+// CHECK-DAG: [[TVAR_INC:%.+]] = add{{.+}} [[TVAR_VAL]], [[TVAR_PRIV_VAL]]
+// CHECK: store{{.+}} [[TVAR_INC]], {{.+}} [[TVAR_REF]],
+// CHECK: call void @__kmpc_end_reduce({{.+}}, {{.+}}, {{.+}} [[RED_VAR]])
+// CHECK: br
+// CHECK: [[CASE2]]:
+// CHECK-DAG: [[TVAR_PRIV_VAL:%.+]] = load{{.+}}, {{.+}} [[TVAR_PRIV]],
+// CHECK-DAG: [[ATOMIC_RES:%.+]] = atomicrmw add{{.+}} [[TVAR_REF]], {{.+}} [[TVAR_PRIV_VAL]]
+// CHECK: call void @__kmpc_end_reduce({{.+}}, {{.+}}, {{.+}} [[RED_VAR]])
+// CHECK: br
+
+#endif
diff --git a/test/OpenMP/teams_distribute_reduction_messages.cpp b/test/OpenMP/teams_distribute_reduction_messages.cpp
index d0a6d296c0f5..f11236f0ce27 100644
--- a/test/OpenMP/teams_distribute_reduction_messages.cpp
+++ b/test/OpenMP/teams_distribute_reduction_messages.cpp
@@ -25,9 +25,9 @@ public:
S2() : a(0) {}
S2(S2 &s2) : a(s2.a) {}
static float S2s; // expected-note 2 {{static data member is predetermined as shared}}
- static const float S2sc;
+ static const float S2sc; // expected-note 2 {{'S2sc' declared here}}
};
-const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}}
+const float S2::S2sc = 0;
S2 b; // expected-note 3 {{'b' defined here}}
const S2 ba[5]; // expected-note 2 {{'ba' defined here}}
class S3 {
diff --git a/test/OpenMP/teams_distribute_shared_messages.cpp b/test/OpenMP/teams_distribute_shared_messages.cpp
index b9e096ce1c24..ecf6f2e03673 100644
--- a/test/OpenMP/teams_distribute_shared_messages.cpp
+++ b/test/OpenMP/teams_distribute_shared_messages.cpp
@@ -84,7 +84,7 @@ int main(int argc, char **argv) {
#pragma omp teams distribute shared (S1) // expected-error {{'S1' does not refer to a value}}
for (int j=0; j<100; j++) foo();
#pragma omp target
- #pragma omp teams distribute shared (a, b, c, d, f)
+ #pragma omp teams distribute shared (a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}}
for (int j=0; j<100; j++) foo();
#pragma omp target
#pragma omp teams distribute shared (argv[1]) // expected-error {{expected variable name}}
diff --git a/test/OpenMP/teams_distribute_simd_ast_print.cpp b/test/OpenMP/teams_distribute_simd_ast_print.cpp
index aaf6745774c5..e751413c4232 100644
--- a/test/OpenMP/teams_distribute_simd_ast_print.cpp
+++ b/test/OpenMP/teams_distribute_simd_ast_print.cpp
@@ -29,9 +29,10 @@ public:
++this->a.a;
}
S7 &operator=(S7 &s) {
+ int k;
#pragma omp target
-#pragma omp teams distribute simd private(a) private(this->a)
- for (int k = 0; k < s.a.a; ++k)
+#pragma omp teams distribute simd private(a) private(this->a) linear(k)
+ for (k = 0; k < s.a.a; ++k)
++s.a.a;
return *this;
}
@@ -56,7 +57,7 @@ public:
// CHECK: #pragma omp target
// CHECK-NEXT: #pragma omp teams distribute simd private(this->a) private(this->a) private(T::a)
// CHECK: #pragma omp target
-// CHECK-NEXT: #pragma omp teams distribute simd private(this->a) private(this->a)
+// CHECK-NEXT: #pragma omp teams distribute simd private(this->a) private(this->a) linear(k)
// CHECK: #pragma omp target
// CHECK-NEXT: #pragma omp teams distribute simd default(none) private(b) firstprivate(argv) shared(d) reduction(+: c) reduction(max: e) num_teams(f) thread_limit(d)
// CHECK: #pragma omp target
@@ -155,11 +156,11 @@ T tmain(T argc) {
// CHECK-NEXT: for (int k = 0; k < 10; ++k)
// CHECK-NEXT: e += d + argc;
#pragma omp target
-#pragma omp teams distribute simd simdlen(clen-1) linear(d)
+#pragma omp teams distribute simd simdlen(clen-1)
for (int k = 0; k < 10; ++k)
e += d + argc;
// CHECK: #pragma omp target
-// CHECK-NEXT: #pragma omp teams distribute simd simdlen(clen - 1) linear(d)
+// CHECK-NEXT: #pragma omp teams distribute simd simdlen(clen - 1)
// CHECK-NEXT: for (int k = 0; k < 10; ++k)
// CHECK-NEXT: e += d + argc;
#pragma omp target
@@ -218,11 +219,11 @@ int main (int argc, char **argv) {
// CHECK-NEXT: for (int k = 0; k < 10; ++k)
// CHECK-NEXT: e += d + argc;
#pragma omp target
-#pragma omp teams distribute simd simdlen(clen-1) linear(d)
+#pragma omp teams distribute simd simdlen(clen-1)
for (int k = 0; k < 10; ++k)
e += d + argc;
// CHECK: #pragma omp target
-// CHECK-NEXT: #pragma omp teams distribute simd simdlen(clen - 1) linear(d)
+// CHECK-NEXT: #pragma omp teams distribute simd simdlen(clen - 1)
// CHECK-NEXT: for (int k = 0; k < 10; ++k)
// CHECK-NEXT: e += d + argc;
#pragma omp target
diff --git a/test/OpenMP/teams_distribute_simd_codegen.cpp b/test/OpenMP/teams_distribute_simd_codegen.cpp
new file mode 100644
index 000000000000..cad5854a2f1e
--- /dev/null
+++ b/test/OpenMP/teams_distribute_simd_codegen.cpp
@@ -0,0 +1,251 @@
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+// Test host codegen.
+// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64
+// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32
+#ifdef CK1
+
+int a[100];
+
+// CK1: define {{.*}}i32 @{{.+}}teams_argument_globali(
+int teams_argument_global(int n) {
+ int i;
+ int te = n / 128;
+ int th = 128;
+ // discard n_addr and i
+ // CK1: alloca i32,
+ // CK1: alloca i32,
+ // CK1: [[TE:%.+]] = alloca i32,
+ // CK1: [[TH:%.+]] = alloca i32,
+ // CK1: [[TE_CAST:%.+]] = alloca i{{32|64}},
+ // CK1: [[TH_CAST:%.+]] = alloca i{{32|64}},
+ // CK1: [[TE_PAR:%.+]] = load{{.+}}, {{.+}} [[TE_CAST]],
+ // CK1: [[TH_PAR:%.+]] = load{{.+}}, {{.+}} [[TH_CAST]],
+
+ // CK1: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 5, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 {{.+}}, i32 {{.+}})
+
+ // CK1: call void @[[OFFL1:.+]](i{{32|64}} [[TE_PAR]], i{{32|64}} [[TH_PAR]],
+ #pragma omp target
+ #pragma omp teams distribute simd num_teams(te), thread_limit(th) aligned(a) simdlen(16) linear(i)
+ for(i = 0; i < n; i++) {
+ a[i] = 0;
+ }
+
+ // CK1: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 2, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 0)
+ // CK1: call void @[[OFFL2:.+]](i{{64|32}} %{{.+}})
+ #pragma omp target
+ {{{
+ #pragma omp teams distribute simd safelen(32)
+ for(int i = 0; i < n; i++) {
+ a[i] = 0;
+ }
+ }}}
+
+ // outlined target regions
+ // CK1: define internal void @[[OFFL1]](i{{32|64}} [[TE_ARG:%.+]], i{{32|64}} [[TH_ARG:%.+]], [100 x i{{32|64}}]* {{.+}}, i{{32|64}} {{.+}}, {{.+}})
+ // CK1: [[TE_ADDR:%.+]] = alloca i{{32|64}},
+ // CK1: [[TH_ADDR:%.+]] = alloca i{{32|64}},
+ // CK1: store{{.+}} [[TE_ARG]], {{.+}} [[TE_ADDR]],
+ // CK1: store{{.+}} [[TH_ARG]], {{.+}} [[TH_ADDR]],
+ // CK1-64: [[TE_CONV:%.+]] = bitcast{{.+}} [[TE_ADDR]] to
+ // CK1-64: [[TH_CONV:%.+]] = bitcast{{.+}} [[TH_ADDR]] to
+ // CK1-64: [[TE_VAL:%.+]] = load i32, i32* [[TE_CONV]],
+ // CK1-64: [[TH_VAL:%.+]] = load i32, i32* [[TH_CONV]],
+ // CK1-32: [[TE_VAL:%.+]] = load i32, i32* [[TE_ADDR]],
+ // CK1-32: [[TH_VAL:%.+]] = load i32, i32* [[TH_ADDR]],
+ // CK1: {{%.+}} = call i32 @__kmpc_push_num_teams({{.+}}, {{.+}}, i32 [[TE_VAL]], i32 [[TH_VAL]])
+ // CK1: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 3, {{.+}} @[[OUTL1:.+]] to {{.+}}, {{.+}}, {{.+}})
+ // CK1: ret void
+
+ // CK1: define internal void @[[OUTL1]]({{.+}})
+ // CK1: call void @__kmpc_for_static_init_4(
+ // CK1: call void @__kmpc_for_static_fini(
+ // CK1: ret void
+
+ // CK1: define internal void @[[OFFL2]]({{.+}}, {{.+}})
+ // CK1: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 2, {{.+}} @[[OUTL2:.+]] to {{.+}}, {{.+}}, {{.+}})
+ // CK1: ret void
+
+ // CK1: define internal void @[[OUTL2]]({{.+}})
+ // CK1: call void @__kmpc_for_static_init_4(
+ // CK1: call void @__kmpc_for_static_fini(
+ // CK1: ret void
+
+ return a[0];
+}
+
+// CK1-DAG: !{!"llvm.loop.vectorize.width", i32 16}
+// CK1-DAG: !{!"llvm.loop.vectorize.enable", i1 true}
+// CK1-DAG: !{!"llvm.loop.vectorize.width", i32 32}
+
+#endif // CK1
+
+// Test host codegen.
+// RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64
+// RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32
+#ifdef CK2
+
+// CK2: define {{.*}}i32 @{{.+}}teams_local_argv(
+int teams_local_arg(void) {
+ int n = 100;
+ int a[n];
+
+ // CK2: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 3, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}, i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 0)
+ // CK2: call void @[[OFFL1:.+]](i{{64|32}} %{{.+}})
+ #pragma omp target
+ #pragma omp teams distribute simd
+ for(int i = 0; i < n; i++) {
+ a[i] = 0;
+ }
+
+ // outlined target region
+ // CK2: define internal void @[[OFFL1]]({{.+}}, {{.+}})
+ // CK2: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 3, {{.+}} @[[OUTL1:.+]] to {{.+}}, {{.+}}, {{.+}})
+ // CK2: ret void
+
+ // CK2: define internal void @[[OUTL1]]({{.+}})
+ // CK2: call void @__kmpc_for_static_init_4(
+ // CK2: call void @__kmpc_for_static_fini(
+ // CK2: ret void
+
+ return a[0];
+}
+// CK2: !{!"llvm.loop.vectorize.enable", i1 true}
+#endif // CK2
+
+// Test host codegen.
+// RUN: %clang_cc1 -DCK3 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK3 --check-prefix CK3-64
+// RUN: %clang_cc1 -DCK3 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK3 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK3 --check-prefix CK3-64
+// RUN: %clang_cc1 -DCK3 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK3 --check-prefix CK3-32
+// RUN: %clang_cc1 -DCK3 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK3 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK3 --check-prefix CK3-32
+#ifdef CK3
+
+// CK3: [[SSI:%.+]] = type { [{{.+}} x i32], float }
+
+template <typename T, int X, long long Y>
+struct SS{
+ T a[X];
+ float b;
+ // CK3: define {{.*}}i32 @{{.+}}foo{{.+}}(
+ int foo(void) {
+
+ // CK3: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 1, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 0)
+ // CK3: call void @[[OFFL1:.+]]([[SSI]]* %{{.+}})
+ #pragma omp target
+ #pragma omp teams distribute simd
+ for(int i = 0; i < X; i++) {
+ a[i] = (T)0;
+ }
+
+ // outlined target region
+ // CK3: define internal void @[[OFFL1]]([[SSI]]* {{.+}})
+ // CK3: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTL1:.+]] to {{.+}}, {{.+}}, {{.+}})
+ // CK3: ret void
+
+ // CK3: define internal void @[[OUTL1]]({{.+}})
+ // CK3: call void @__kmpc_for_static_init_4(
+ // CK3: call void @__kmpc_for_static_fini(
+ // CK3: ret void
+
+ return a[0];
+ }
+};
+
+int teams_template_struct(void) {
+ SS<int, 123, 456> V;
+ return V.foo();
+
+}
+// CK3: !{!"llvm.loop.vectorize.enable", i1 true}
+#endif // CK3
+
+// Test host codegen.
+// RUN: %clang_cc1 -DCK4 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK4 --check-prefix CK4-64
+// RUN: %clang_cc1 -DCK4 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK4 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK4 --check-prefix CK4-64
+// RUN: %clang_cc1 -DCK4 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK4 --check-prefix CK4-32
+// RUN: %clang_cc1 -DCK4 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK4 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK4 --check-prefix CK4-32
+
+#ifdef CK4
+
+template <typename T, int n>
+int tmain(T argc) {
+ T a[n];
+ int te = n/128;
+ int th = 128;
+#pragma omp target
+#pragma omp teams distribute simd num_teams(te) thread_limit(th)
+ for(int i = 0; i < n; i++) {
+ a[i] = (T)0;
+ }
+ return 0;
+}
+
+int main (int argc, char **argv) {
+ int n = 100;
+ int a[n];
+#pragma omp target
+#pragma omp teams distribute simd
+ for(int i = 0; i < n; i++) {
+ a[i] = 0;
+ }
+ return tmain<int, 10>(argc);
+}
+
+// CK4: define {{.*}}i32 @{{[^,]+}}(i{{.+}}{{.+}} %[[ARGC:.+]], {{.+}})
+// CK4: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 3, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}, i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 0)
+// CK4: call void @[[OFFL1:.+]]({{.+}})
+// CK4: {{%.+}} = call{{.*}} i32 @[[TMAIN:.+]]({{.+}})
+// CK4: ret
+
+// CK4: define {{.*}}void @[[OFFL1]]({{.+}})
+// CK4: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 3, {{.+}} @[[OUTL1:.+]] to {{.+}}, {{.+}}, {{.+}})
+// CK4: ret void
+
+// CK4: define internal void @[[OUTL1]]({{.+}})
+// CK4: call void @__kmpc_for_static_init_4(
+// CK4: call void @__kmpc_for_static_fini(
+// CK4: ret void
+
+// CK4: define {{.*}}i32 @[[TMAIN]]({{.+}})
+// CK4: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 3, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 {{.+}}, i32 {{.+}})
+// CK4: call void @[[OFFLT:.+]]({{.+}})
+// CK4: ret
+// CK4-NEXT: }
+
+// CK4: define {{.*}}void @[[OFFLT]](i{{32|64}} [[TE_ARG:%.+]], i{{32|64}} [[TH_ARG:%.+]], {{.+}})
+// CK4: [[TE_ADDR:%.+]] = alloca i{{32|64}},
+// CK4: [[TH_ADDR:%.+]] = alloca i{{32|64}},
+// CK4: store{{.+}} [[TE_ARG]], {{.+}} [[TE_ADDR]],
+// CK4: store{{.+}} [[TH_ARG]], {{.+}} [[TH_ADDR]],
+// CK4-64: [[TE_CONV:%.+]] = bitcast{{.+}} [[TE_ADDR]] to
+// CK4-64: [[TH_CONV:%.+]] = bitcast{{.+}} [[TH_ADDR]] to
+// CK4-64: [[TE_VAL:%.+]] = load i32, i32* [[TE_CONV]],
+// CK4-64: [[TH_VAL:%.+]] = load i32, i32* [[TH_CONV]],
+// CK4-32: [[TE_VAL:%.+]] = load i32, i32* [[TE_ADDR]],
+// CK4-32: [[TH_VAL:%.+]] = load i32, i32* [[TH_ADDR]],
+// CK4: {{%.+}} = call i32 @__kmpc_push_num_teams({{.+}}, {{.+}}, i32 [[TE_VAL]], i32 [[TH_VAL]])
+// CK4: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTLT:.+]] to {{.+}}, {{.+}}, {{.+}})
+// CK4: ret void
+
+// CK4: define internal void @[[OUTLT]]({{.+}})
+// CK4: call void @__kmpc_for_static_init_4(
+// CK4: call void @__kmpc_for_static_fini(
+// CK4: ret void
+
+// CK4: !{!"llvm.loop.vectorize.enable", i1 true}
+#endif // CK4
+#endif
+
diff --git a/test/OpenMP/teams_distribute_simd_collapse_codegen.cpp b/test/OpenMP/teams_distribute_simd_collapse_codegen.cpp
new file mode 100644
index 000000000000..071d1672fad1
--- /dev/null
+++ b/test/OpenMP/teams_distribute_simd_collapse_codegen.cpp
@@ -0,0 +1,131 @@
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+// Test host codegen.
+// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64
+// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32
+#ifdef CK1
+
+template <typename T, int X, long long Y>
+struct SS{
+ T a[X][Y];
+
+ // CK1: define {{.*}}i32 @{{.+}}foo{{.+}}(
+ int foo(void) {
+
+ // CK1: call i32 @__tgt_target_teams(
+ // CK1: call void @[[OFFL1:.+]](
+ #pragma omp target
+ #pragma omp teams distribute simd collapse(2)
+ for(int i = 0; i < X; i++) {
+ for(int j = 0; j < Y; j++) {
+ a[i][j] = (T)0;
+ }
+ }
+ // CK1: define internal void @[[OFFL1]](
+ // CK1: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTL1:.+]] to {{.+}},
+ // CK1: ret void
+
+ // CK1: define internal void @[[OUTL1]]({{.+}})
+ // discard loop variables not needed here
+ // CK1: = alloca i32,
+ // CK1: = alloca i32,
+ // CK1: = alloca i32,
+ // CK1: = alloca i32,
+ // CK1: [[OMP_UB:%.+]] = alloca i32,
+ // CK1: store i32 56087, i32* [[OMP_UB]],
+ // CK1: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 92, {{.+}}, {{.+}}, i32* [[OMP_UB]],
+ // CK1: call void @__kmpc_for_static_fini(
+ // CK1: ret void
+
+ return a[0][0];
+ }
+};
+
+int teams_template_struct(void) {
+ SS<int, 123, 456> V;
+ return V.foo();
+
+}
+
+// CK1: !{!"llvm.loop.vectorize.enable", i1 true}
+#endif // CK1
+
+// Test host codegen.
+// RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64
+// RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32
+#ifdef CK2
+
+template <typename T, int n, int m>
+int tmain(T argc) {
+ T a[n][m];
+ #pragma omp target
+ #pragma omp teams distribute simd collapse(2)
+ for(int i = 0; i < n; i++) {
+ for(int j = 0; j < m; j++) {
+ a[i][j] = (T)0;
+ }
+ }
+ return 0;
+}
+
+int main (int argc, char **argv) {
+ int n = 100;
+ int m = 2;
+ int a[n][m];
+ #pragma omp target
+ #pragma omp teams distribute simd collapse(2)
+ for(int i = 0; i < n; i++) {
+ for(int j = 0; j < m; j++) {
+ a[i][j] = 0;
+ }
+ }
+ return tmain<int, 10, 2>(argc);
+}
+
+// CK2: define {{.*}}i32 @{{[^,]+}}(i{{.+}}{{.+}} %[[ARGC:.+]], {{.+}})
+// CK2: call i32 @__tgt_target_teams(
+// CK2: call void @[[OFFL1:.+]]({{.+}})
+// CK2: {{%.+}} = call{{.*}} i32 @[[TMAIN:.+]]({{.+}})
+// CK2: ret
+
+// CK2: define {{.*}}void @[[OFFL1]]({{.+}})
+// CK2: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 5, {{.+}} @[[OUTL1:.+]] to {{.+}},
+// CK2: ret void
+
+// CK2: define internal void @[[OUTL1]]({{.+}})
+// CK2: [[OMP_UB:%.omp.ub]] = alloca i64,
+// CK2: store i64 {{.+}}, i64* [[OMP_UB]],
+// CK2: call void @__kmpc_for_static_init_8({{.+}}, {{.+}}, i32 92, {{.+}}, {{.+}}, i64* [[OMP_UB]],
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+// CK2: define {{.*}}i32 @[[TMAIN]]({{.+}})
+// CK2: call i32 @__tgt_target_teams(
+// CK2: call void @[[OFFLT1:.+]]({{.+}})
+// CK2: ret
+// CK2-NEXT: }
+
+// CK2: define {{.*}}void @[[OFFLT1]]({{.+}})
+// CK2: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTLT1:.+]] to {{.+}},
+// CK2: ret void
+
+// CK2: define internal void @[[OUTLT1]]({{.+}})
+// discard loop variables not needed here
+// CK2: [[OMP_UB:%.omp.ub]] = alloca i32,
+// CK2: store i32 {{.+}}, i32* [[OMP_UB]],
+// CK2: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 92, {{.+}}, {{.+}}, i32* [[OMP_UB]],
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: !{!"llvm.loop.vectorize.enable", i1 true}
+#endif // CK2
+#endif // #ifndef HEADER
diff --git a/test/OpenMP/teams_distribute_simd_dist_schedule_codegen.cpp b/test/OpenMP/teams_distribute_simd_dist_schedule_codegen.cpp
new file mode 100644
index 000000000000..599e18f58a16
--- /dev/null
+++ b/test/OpenMP/teams_distribute_simd_dist_schedule_codegen.cpp
@@ -0,0 +1,208 @@
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+// Test host codegen.
+// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64
+// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32
+#ifdef CK1
+
+template <typename T, int X, long long Y>
+struct SS{
+ T a[X];
+ float b;
+ // CK1: define {{.*}}i32 @{{.+}}foo{{.+}}(
+ int foo(void) {
+
+ // CK1: call i32 @__tgt_target_teams(
+ // CK1: call void @[[OFFL1:.+]](
+ #pragma omp target
+ #pragma omp teams distribute simd
+ for(int i = 0; i < X; i++) {
+ a[i] = (T)0;
+ }
+ // CK1: call i32 @__tgt_target_teams(
+ // CK1: call void @[[OFFL2:.+]](
+ #pragma omp target
+ #pragma omp teams distribute simd dist_schedule(static)
+ for(int i = 0; i < X; i++) {
+ a[i] = (T)0;
+ }
+ // CK1: call i32 @__tgt_target_teams(
+ // CK1: call void @[[OFFL3:.+]](
+ #pragma omp target
+ #pragma omp teams distribute simd dist_schedule(static, X/2)
+ for(int i = 0; i < X; i++) {
+ a[i] = (T)0;
+ }
+ // CK1: define internal void @[[OFFL1]](
+ // CK1: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTL1:.+]] to {{.+}},
+ // CK1: ret void
+
+ // CK1: define internal void @[[OUTL1]]({{.+}})
+ // CK1: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 92
+ // CK1: call void @__kmpc_for_static_fini(
+ // CK1: ret void
+
+ // CK1: define internal void @[[OFFL2]](
+ // CK1: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTL2:.+]] to {{.+}},
+ // CK1: ret void
+
+ // CK1: define internal void @[[OUTL2]]({{.+}})
+ // CK1: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 92
+ // CK1: call void @__kmpc_for_static_fini(
+ // CK1: ret void
+
+ // CK1: define internal void @[[OFFL3]](
+ // CK1: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTL3:.+]] to {{.+}},
+ // CK1: ret void
+
+ // CK1: define internal void @[[OUTL3]]({{.+}})
+ // CK1: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 91
+ // CK1: call void @__kmpc_for_static_fini(
+ // CK1: ret void
+
+ return a[0];
+ }
+};
+
+int teams_template_struct(void) {
+ SS<int, 123, 456> V;
+ return V.foo();
+
+}
+// CK1: !{!"llvm.loop.vectorize.enable", i1 true}
+#endif // CK1
+
+// Test host codegen.
+// RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64
+// RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32
+#ifdef CK2
+
+template <typename T, int n>
+int tmain(T argc) {
+ T a[n];
+#pragma omp target
+#pragma omp teams distribute simd
+ for(int i = 0; i < n; i++) {
+ a[i] = (T)0;
+ }
+#pragma omp target
+#pragma omp teams distribute simd dist_schedule(static)
+ for(int i = 0; i < n; i++) {
+ a[i] = (T)0;
+ }
+#pragma omp target
+#pragma omp teams distribute simd dist_schedule(static, n)
+ for(int i = 0; i < n; i++) {
+ a[i] = (T)0;
+ }
+ return 0;
+}
+
+int main (int argc, char **argv) {
+ int n = 100;
+ int a[n];
+#pragma omp target
+#pragma omp teams distribute simd
+ for(int i = 0; i < n; i++) {
+ a[i] = 0;
+ }
+#pragma omp target
+#pragma omp teams distribute simd dist_schedule(static)
+ for(int i = 0; i < n; i++) {
+ a[i] = 0;
+ }
+#pragma omp target
+#pragma omp teams distribute simd dist_schedule(static, n)
+ for(int i = 0; i < n; i++) {
+ a[i] = 0;
+ }
+ return tmain<int, 10>(argc);
+}
+
+// CK2: define {{.*}}i32 @{{[^,]+}}(i{{.+}}{{.+}} %[[ARGC:.+]], {{.+}})
+// CK2: call i32 @__tgt_target_teams(
+// CK2: call void @[[OFFL1:.+]]({{.+}})
+// CK2: call i32 @__tgt_target_teams(
+// CK2: call void @[[OFFL2:.+]]({{.+}})
+// CK2: call i32 @__tgt_target_teams(
+// CK2: call void @[[OFFL3:.+]]({{.+}})
+// CK2: {{%.+}} = call{{.*}} i32 @[[TMAIN:.+]]({{.+}})
+// CK2: ret
+
+// CK2: define {{.*}}void @[[OFFL1]]({{.+}})
+// CK2: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 3, {{.+}} @[[OUTL1:.+]] to {{.+}},
+// CK2: ret void
+
+// CK2: define internal void @[[OUTL1]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 92
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define {{.*}}void @[[OFFL2]]({{.+}})
+// CK2: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 3, {{.+}} @[[OUTL2:.+]] to {{.+}},
+// CK2: ret void
+
+// CK2: define internal void @[[OUTL2]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 92
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define {{.*}}void @[[OFFL3]]({{.+}})
+// CK2: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 4, {{.+}} @[[OUTL3:.+]] to {{.+}},
+// CK2: ret void
+
+// CK2: define internal void @[[OUTL3]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 91
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define {{.*}}i32 @[[TMAIN]]({{.+}})
+// CK2: call i32 @__tgt_target_teams(
+// CK2: call void @[[OFFLT1:.+]]({{.+}})
+// CK2: call i32 @__tgt_target_teams(
+// CK2: call void @[[OFFLT2:.+]]({{.+}})
+// CK2: call i32 @__tgt_target_teams(
+// CK2: call void @[[OFFLT3:.+]]({{.+}})
+// CK2: ret
+// CK2-NEXT: }
+
+// CK2: define {{.*}}void @[[OFFLT1]]({{.+}})
+// CK2: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTLT1:.+]] to {{.+}},
+// CK2: ret void
+
+// CK2: define internal void @[[OUTLT1]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 92
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define {{.*}}void @[[OFFLT2]]({{.+}})
+// CK2: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTLT2:.+]] to {{.+}},
+// CK2: ret void
+
+// CK2: define internal void @[[OUTLT2]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 92
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: define {{.*}}void @[[OFFLT3]]({{.+}})
+// CK2: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTLT3:.+]] to {{.+}},
+// CK2: ret void
+
+// CK2: define internal void @[[OUTLT3]]({{.+}})
+// CK2: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, i32 91
+// CK2: call void @__kmpc_for_static_fini(
+// CK2: ret void
+
+// CK2: !{!"llvm.loop.vectorize.enable", i1 true}
+#endif // CK2
+#endif // #ifndef HEADER
diff --git a/test/OpenMP/teams_distribute_simd_firstprivate_codegen.cpp b/test/OpenMP/teams_distribute_simd_firstprivate_codegen.cpp
new file mode 100644
index 000000000000..e503f5267f19
--- /dev/null
+++ b/test/OpenMP/teams_distribute_simd_firstprivate_codegen.cpp
@@ -0,0 +1,337 @@
+// RUN: %clang_cc1 -DCHECK -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -DCHECK -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+
+// RUN: %clang_cc1 -DLAMBDA -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+struct St {
+ int a, b;
+ St() : a(0), b(0) {}
+ St(const St &st) : a(st.a + st.b), b(0) {}
+ ~St() {}
+};
+
+volatile int g = 1212;
+volatile int &g1 = g;
+
+template <class T>
+struct S {
+ T f;
+ S(T a) : f(a + g) {}
+ S() : f(g) {}
+ S(const S &s, St t = St()) : f(s.f + t.a) {}
+ operator T() { return T(); }
+ ~S() {}
+};
+
+// CHECK-DAG: [[S_FLOAT_TY:%.+]] = type { float }
+// CHECK-DAG: [[S_INT_TY:%.+]] = type { i{{[0-9]+}} }
+// CHECK-DAG: [[ST_TY:%.+]] = type { i{{[0-9]+}}, i{{[0-9]+}} }
+
+template <typename T>
+T tmain() {
+ S<T> test;
+ T t_var = T();
+ T vec[] = {1, 2};
+ S<T> s_arr[] = {1, 2};
+ S<T> &var = test;
+#pragma omp target
+#pragma omp teams distribute simd firstprivate(t_var, vec, s_arr, var)
+ for (int i = 0; i < 2; ++i) {
+ vec[i] = t_var;
+ s_arr[i] = var;
+ }
+ return T();
+}
+
+// CHECK-DAG: [[TEST:@.+]] = global [[S_FLOAT_TY]] zeroinitializer,
+S<float> test;
+// CHECK-DAG: [[T_VAR:@.+]] = global i{{[0-9]+}} 333,
+int t_var = 333;
+// CHECK-DAG: [[VEC:@.+]] = global [2 x i{{[0-9]+}}] [i{{[0-9]+}} 1, i{{[0-9]+}} 2],
+int vec[] = {1, 2};
+// CHECK-DAG: [[S_ARR:@.+]] = global [2 x [[S_FLOAT_TY]]] zeroinitializer,
+S<float> s_arr[] = {1, 2};
+// CHECK-DAG: [[VAR:@.+]] = global [[S_FLOAT_TY]] zeroinitializer,
+S<float> var(3);
+// CHECK-DAG: [[SIVAR:@.+]] = internal global i{{[0-9]+}} 0,
+
+int main() {
+ static int sivar;
+#ifdef LAMBDA
+ // LAMBDA: [[G:@.+]] = global i{{[0-9]+}} 1212,
+ // LAMBDA-LABEL: @main
+ // LAMBDA: call void [[OUTER_LAMBDA:@.+]](
+ [&]() {
+ // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
+ // LAMBDA: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 3, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 0)
+ // LAMBDA: call void @[[LOFFL1:.+]](i{{64|32}} %{{.+}})
+ // LAMBDA: ret
+#pragma omp target
+#pragma omp teams distribute simd firstprivate(g, g1, sivar)
+ for (int i = 0; i < 2; ++i) {
+ // LAMBDA: define{{.*}} internal{{.*}} void @[[LOFFL1]](i{{64|32}} {{%.+}}, i{{64|32}} {{%.+}})
+ // LAMBDA: {{%.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: {{%.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: {{%.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: [[G_CAST:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[G1_CAST:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[SIVAR_CAST:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA-DAG: [[G_CAST_VAL:%.+]] = load{{.+}} [[G_CAST]],
+ // LAMBDA-DAG: [[G1_CAST_VAL:%.+]] = load{{.+}} [[G1_CAST]],
+ // LAMBDA-DAG: [[SIVAR_CAST_VAL:%.+]] = load{{.+}} [[SIVAR_CAST]],
+ // LAMBDA: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 3, {{.+}} @[[LOUTL1:.+]] to {{.+}}, {{.+}} [[G_CAST_VAL]], {{.+}} [[G1_CAST_VAL]], {{.+}} [[SIVAR_CAST_VAL]])
+ // LAMBDA: ret void
+
+ // LAMBDA: define internal void @[[LOUTL1]]({{.+}})
+ // Skip global and bound tid vars
+ // LAMBDA: {{.+}} = alloca i32*,
+ // LAMBDA: {{.+}} = alloca i32*,
+ // LAMBDA: [[G_ADDR:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[G1_ADDR:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[SIVAR_ADDR:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[G1_TMP:%.+]] = alloca i32*,
+ // skip loop vars
+ // LAMBDA-DAG: store {{.+}}, {{.+}} [[G_ADDR]],
+ // LAMBDA-DAG: store {{.+}}, {{.+}} [[G1_ADDR]],
+ // LAMBDA-DAG: store {{.+}}, {{.+}} [[SIVAR_ADDR]],
+ // LAMBDA-DAG: [[G_CONV:%.+]] = bitcast {{.+}} [[G_ADDR]] to
+ // LAMBDA-DAG: [[G1_CONV:%.+]] = bitcast {{.+}} [[G1_ADDR]] to
+ // LAMBDA-DAG: [[SIVAR_CONV:%.+]] = bitcast {{.+}} [[SIVAR_ADDR]] to
+ // LAMBDA-DAG: store{{.+}} [[G1_CONV]], {{.+}} [[G1_TMP]],
+ g = 1;
+ g1 = 1;
+ sivar = 2;
+ // LAMBDA: call void @__kmpc_for_static_init_4(
+ // LAMBDA-DAG: store{{.+}} 1, {{.+}} [[G_CONV]],
+ // LAMBDA-DAG: [[G1:%.+]] = load{{.+}}, {{.+}}* [[G1_TMP]]
+ // LAMBDA-DAG: store{{.+}} 1, {{.+}} [[G1]],
+ // LAMBDA-DAG: store{{.+}} 2, {{.+}} [[SIVAR_CONV]],
+ // LAMBDA-DAG: [[G1_REF:%.+]] = load{{.+}}, {{.+}} [[G1_TMP]],
+ // LAMBDA-DAG: store{{.+}} 1, {{.+}} [[G1_REF]],
+ // LAMBDA: call void [[INNER_LAMBDA:@.+]](
+ // LAMBDA: call void @__kmpc_for_static_fini(
+ [&]() {
+ // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]])
+ // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]],
+ g = 2;
+ g1 = 2;
+ sivar = 4;
+ // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]]
+
+ // LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // LAMBDA: [[G_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G_PTR_REF]]
+ // LAMBDA: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[G_REF]]
+ // LAMBDA: [[G1_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // LAMBDA: [[G1_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G1_PTR_REF]]
+ // LAMBDA: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[G1_REF]]
+ // LAMBDA: [[SIVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+ // LAMBDA: [[SIVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SIVAR_PTR_REF]]
+ // LAMBDA: store i{{[0-9]+}} 4, i{{[0-9]+}}* [[SIVAR_REF]]
+ }();
+ }
+ }();
+ return 0;
+#else
+#pragma omp target
+#pragma omp teams distribute simd firstprivate(t_var, vec, s_arr, var, sivar)
+ for (int i = 0; i < 2; ++i) {
+ vec[i] = t_var;
+ s_arr[i] = var;
+ sivar += i;
+ }
+ return tmain<int>();
+#endif
+}
+
+// CHECK: define {{.*}}i{{[0-9]+}} @main()
+// CHECK: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 5, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 0)
+// CHECK: call void @[[OFFL1:.+]](i{{64|32}} %{{.+}})
+// CHECK: {{%.+}} = call{{.*}} i32 @[[TMAIN_INT:.+]]()
+// CHECK: ret
+
+// CHECK: define{{.*}} void @[[OFFL1]]({{.+}})
+// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}]*,
+// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]]*,
+// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]]*,
+// CHECK: [[SIVAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[T_VAR_CAST:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[SIVAR_CAST:%.+]] = alloca i{{[0-9]+}},
+
+// CHECK-DAG: [[VEC_TE_PAR:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** [[VEC_PRIV]],
+// CHECK-DAG: [[T_VAR_TE_PAR:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_CAST]],
+// CHECK-DAG: [[S_ARR_TE_PAR:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[S_ARR_PRIV]],
+// CHECK-DAG: [[VAR_TE_PAR:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[VAR_PRIV]],
+// CHECK-DAG: [[SIVAR_TE_PAR:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR_CAST]],
+
+// CHECK: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 5, {{.+}} @[[OUTL1:.+]] to {{.+}}, [2 x i{{[0-9]+}}]* [[VEC_TE_PAR]], i{{[0-9]+}} [[T_VAR_TE_PAR]], [2 x [[S_FLOAT_TY]]]* [[S_ARR_TE_PAR]], [[S_FLOAT_TY]]* [[VAR_TE_PAR]], i{{[0-9]+}} [[SIVAR_TE_PAR]])
+// CHECK: ret void
+
+// CHECK: define internal void @[[OUTL1]]({{.+}})
+// Skip global and bound tid vars
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: [[VEC_ADDR:%.+]] = alloca [2 x i{{[0-9]+}}]*,
+// CHECK: [[T_VAR_ADDR:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[S_ARR_ADDR:%.+]] = alloca [2 x [[S_FLOAT_TY]]]*,
+// CHECK: [[VAR_ADDR:%.+]] = alloca [[S_FLOAT_TY]]*,
+// CHECK: [[SIVAR_ADDR:%.+]] = alloca i{{[0-9]+}},
+// Skip temp vars for loop
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]],
+// CHECK: [[AGG_TMP1:%.+]] = alloca [[ST_TY]],
+// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]],
+// CHECK: [[AGG_TMP2:%.+]] = alloca [[ST_TY]],
+
+// param copy
+// CHECK: store [2 x i{{[0-9]+}}]* {{.+}}, [2 x i{{[0-9]+}}]** [[VEC_ADDR]],
+// CHECK: store i{{[0-9]+}} {{.+}}, i{{[0-9]+}}* [[T_VAR_ADDR]],
+// CHECK: store [2 x [[S_FLOAT_TY]]]* {{.+}}, [2 x [[S_FLOAT_TY]]]** [[S_ARR_ADDR]],
+// CHECK: store [[S_FLOAT_TY]]* {{.+}}, [[S_FLOAT_TY]]** [[VAR_ADDR]],
+// CHECK: store i{{[0-9]+}} {{.+}}, i{{[0-9]+}}* [[SIVAR_ADDR]],
+
+// T_VAR and SIVAR
+// CHECK-DAG-64: [[CONV_TVAR:%.+]] = bitcast i64* [[T_VAR_ADDR]] to i32*
+// CHECK-DAG-64: [[CONV_SIVAR:%.+]] = bitcast i64* [[SIVAR_ADDR]] to i32*
+
+// preparation vars
+// CHECK-DAG: [[VEC_ADDR_VAL:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** [[VEC_ADDR]],
+// CHECK-DAG: [[S_ARR_ADDR_REF:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[S_ARR_ADDR]],
+// CHECK-DAG: [[VAR_ADDR_REF:%.+]] = load{{.+}} [[VAR_ADDR]],
+
+// firstprivate vec(vec): copy from *_addr into priv1 and then from priv1 into priv2
+// CHECK-DAG: [[VEC_DEST_PRIV:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV]] to i8*
+// CHECK-DAG: [[VEC_SRC:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_ADDR_VAL]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[VEC_DEST_PRIV]], i8* [[VEC_SRC]], {{.+}})
+
+// firstprivate(s_arr)
+// CHECK-DAG: [[S_ARR_PRIV_BGN:%.+]] = getelementptr{{.*}} [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[S_ARR_PRIV]],
+// CHECK-DAG: [[S_ARR_ADDR_BGN:%.+]] = bitcast [2 x [[S_FLOAT_TY]]]* [[S_ARR_ADDR_REF]] to
+// CHECK-DAG: [[S_ARR_FIN:%.+]] = icmp{{.+}} [[S_ARR_PRIV_BGN]],
+// CHECK-DAG: [[S_ARR_SRC_COPY:%.+]] = phi{{.+}} [ [[S_ARR_ADDR_BGN]], {{.+}} ], [ [[S_ARR_SRC:%.+]], {{.+}} ]
+// CHECK-DAG: [[S_ARR_DST_COPY:%.+]] = phi{{.+}} [ [[S_ARR_PRIV_BGN]], {{.+}}], [ [[S_ARR_DST:%.+]], {{.+}} ]
+// CHECK-DAG: call void @{{.+}}({{.+}} [[AGG_TMP1]])
+// CHECK-DAG: call void @{{.+}}({{.+}} [[S_ARR_DST_COPY]], {{.+}} [[S_ARR_SRC_COPY]], {{.+}} [[AGG_TMP1]])
+// CHECK-DAG: call void @{{.+}}({{.+}} [[AGG_TMP1]])
+// CHECK-DAG: [[S_ARR_DST]] = getelementptr {{.+}} [[S_ARR_DST_COPY]],
+// CHECK-DAG: [[S_ARR_SRC]] = getelementptr {{.+}} [[S_ARR_SRC_COPY]],
+
+// firstprivate(var)
+// CHECK-DAG: call void @{{.+}}({{.+}} [[AGG_TMP2]])
+// CHECK-DAG: call void @{{.+}}({{.+}} [[VAR_PRIV]], {{.+}} [[VAR_ADDR_REF]], {{.+}} [[AGG_TMP2]])
+// CHECK-DAG: call void @{{.+}}({{.+}} [[AGG_TMP2]])
+
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK-DAG-32: {{.+}} = {{.+}} [[T_VAR_ADDR]]
+// CHECK-DAG-64: {{.+}} = {{.+}} [[CONV_TVAR]]
+// CHECK-DAG: {{.+}} = {{.+}} [[VEC_PRIV]]
+// CHECK-DAG: {{.+}} = {{.+}} [[S_ARR_PRIV]]
+// CHECK-DAG: {{.+}} = {{.+}} [[VAR_PRIV]]
+// CHECK-DAG-32: {{.+}} = {{.+}} [[SIVAR_ADDR]]
+// CHECK-DAG-64: {{.+}} = {{.+}} [[CONV_SIVAR]]
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: ret void
+
+// CHECK: define{{.*}} i{{[0-9]+}} @[[TMAIN_INT]]()
+// CHECK: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 4, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 0)
+// CHECK: call void @[[TOFFL1:.+]](i{{64|32}} %{{.+}})
+// CHECK: ret
+
+// CHECK: define {{.*}}void @[[TOFFL1]]({{.+}})
+// CHECK: [[TT_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[TVEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}]*,
+// CHECK: [[TS_ARR_PRIV:%.+]] = alloca [2 x [[S_INT_TY]]]*,
+// CHECK: [[TVAR_PRIV:%.+]] = alloca [[S_INT_TY]]*,
+// CHECK: [[TT_VAR_CAST:%.+]] = alloca i{{[0-9]+}},
+
+// CHECK-DAG: [[TVEC_TE_PAR:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** [[TVEC_PRIV]],
+// CHECK-DAG: [[TT_VAR_TE_PAR:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[TT_VAR_CAST]],
+// CHECK-DAG: [[TS_ARR_TE_PAR:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** [[TS_ARR_PRIV]],
+// CHECK-DAG: [[TVAR_TE_PAR:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[TVAR_PRIV]],
+
+// CHECK: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 4, {{.+}} @[[TOUTL1:.+]] to {{.+}}, [2 x i{{[0-9]+}}]* [[TVEC_TE_PAR]], i{{[0-9]+}} [[TT_VAR_TE_PAR]], [2 x [[S_INT_TY]]]* [[TS_ARR_TE_PAR]], [[S_INT_TY]]* [[TVAR_TE_PAR]])
+// CHECK: ret void
+
+// CHECK: define internal void @[[TOUTL1]]({{.+}})
+// Skip global and bound tid vars
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: [[VEC_ADDR:%.+]] = alloca [2 x i{{[0-9]+}}]*,
+// CHECK: [[T_VAR_ADDR:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[S_ARR_ADDR:%.+]] = alloca [2 x [[S_INT_TY]]]*,
+// CHECK: [[VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*,
+// Skip temp vars for loop
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_INT_TY]]],
+// CHECK: [[AGG_TMP1:%.+]] = alloca [[ST_TY]],
+// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_INT_TY]],
+// CHECK: [[AGG_TMP2:%.+]] = alloca [[ST_TY]],
+// CHECK: [[TMP:%.+]] = alloca [[S_INT_TY]]*,
+
+// param copy
+// CHECK: store [2 x i{{[0-9]+}}]* {{.+}}, [2 x i{{[0-9]+}}]** [[VEC_ADDR]],
+// CHECK: store i{{[0-9]+}} {{.+}}, i{{[0-9]+}}* [[T_VAR_ADDR]],
+// CHECK: store [2 x [[S_INT_TY]]]* {{.+}}, [2 x [[S_INT_TY]]]** [[S_ARR_ADDR]],
+// CHECK: store [[S_INT_TY]]* {{.+}}, [[S_INT_TY]]** [[VAR_ADDR]],
+
+
+// T_VAR and preparation variables
+// CHECK: [[VEC_ADDR_VAL:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** [[VEC_ADDR]],
+// CHECK-64: [[CONV_TVAR:%.+]] = bitcast i64* [[T_VAR_ADDR]] to i32*
+// CHECK: [[S_ARR_ADDR_REF:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** [[S_ARR_ADDR]],
+
+// firstprivate vec(vec): copy from *_addr into priv1 and then from priv1 into priv2
+// CHECK-DAG: [[VEC_DEST_PRIV:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV]] to i8*
+// CHECK-DAG: [[VEC_SRC:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_ADDR_VAL]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[VEC_DEST_PRIV]], i8* [[VEC_SRC]], {{.+}})
+
+// firstprivate(s_arr)
+// CHECK-DAG: [[S_ARR_PRIV_BGN:%.+]] = getelementptr{{.*}} [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[S_ARR_PRIV]],
+// CHECK-DAG: [[S_ARR_ADDR_BGN:%.+]] = bitcast [2 x [[S_INT_TY]]]* [[S_ARR_ADDR_REF]] to
+// CHECK-DAG: [[S_ARR_FIN:%.+]] = icmp{{.+}} [[S_ARR_PRIV_BGN]],
+// CHECK-DAG: [[S_ARR_SRC_COPY:%.+]] = phi{{.+}} [ [[S_ARR_ADDR_BGN]], {{.+}} ], [ [[S_ARR_SRC:%.+]], {{.+}} ]
+// CHECK-DAG: [[S_ARR_DST_COPY:%.+]] = phi{{.+}} [ [[S_ARR_PRIV_BGN]], {{.+}} ], [ [[S_ARR_DST:%.+]], {{.+}} ]
+// CHECK-DAG: call void @{{.+}}({{.+}} [[AGG_TMP1]])
+// CHECK-DAG: call void @{{.+}}({{.+}} [[S_ARR_DST_COPY]], {{.+}} [[S_ARR_SRC_COPY]], {{.+}} [[AGG_TMP1]])
+// CHECK-DAG: call void @{{.+}}({{.+}} [[AGG_TMP1]])
+// CHECK-DAG: [[S_ARR_DST]] = getelementptr {{.+}} [[S_ARR_DST_COPY]],
+// CHECK-DAG: [[S_ARR_SRC]] = getelementptr {{.+}} [[S_ARR_SRC_COPY]],
+
+// firstprivate(var)
+// CHECK-DAG: [[VAR_ADDR_REF:%.+]] = load{{.+}} [[VAR_ADDR]],
+// CHECK-DAG: call void @{{.+}}({{.+}} [[AGG_TMP2]])
+// CHECK-DAG: call void @{{.+}}({{.+}} [[VAR_PRIV]], {{.+}} [[VAR_ADDR_REF]], {{.+}} [[AGG_TMP2]])
+// CHECK-DAG: call void @{{.+}}({{.+}} [[AGG_TMP2]])
+// CHECK-DAG: store [[S_INT_TY]]* [[VAR_PRIV]], [[S_INT_TY]]** [[TMP]],
+
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK-DAG-32: {{.+}} = {{.+}} [[T_VAR_ADDR]]
+// CHECK-DAG-64: {{.+}} = {{.+}} [[CONV_TVAR]]
+// CHECK-DAG: {{.+}} = {{.+}} [[VEC_PRIV]]
+// CHECK-DAG: {{.+}} = {{.+}} [[TMP]]
+// CHECK-DAG: {{.+}} = {{.+}} [[S_ARR_PRIV]]
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: ret void
+
+// CHECK: !{!"llvm.loop.vectorize.enable", i1 true}
+#endif
diff --git a/test/OpenMP/teams_distribute_simd_firstprivate_messages.cpp b/test/OpenMP/teams_distribute_simd_firstprivate_messages.cpp
index 324672c14129..bcc0e351c66e 100644
--- a/test/OpenMP/teams_distribute_simd_firstprivate_messages.cpp
+++ b/test/OpenMP/teams_distribute_simd_firstprivate_messages.cpp
@@ -144,6 +144,7 @@ int main(int argc, char **argv) {
#pragma omp teams distribute simd firstprivate(j)
for (i = 0; i < argc; ++i) foo();
+// expected-error@+2 {{lastprivate variable cannot be firstprivate}} expected-note@+2 {{defined as lastprivate}}
#pragma omp target
#pragma omp teams distribute simd lastprivate(argc), firstprivate(argc) // OK
for (i = 0; i < argc; ++i) foo();
diff --git a/test/OpenMP/teams_distribute_simd_lastprivate_codegen.cpp b/test/OpenMP/teams_distribute_simd_lastprivate_codegen.cpp
new file mode 100644
index 000000000000..3a18b75cf405
--- /dev/null
+++ b/test/OpenMP/teams_distribute_simd_lastprivate_codegen.cpp
@@ -0,0 +1,371 @@
+// RUN: %clang_cc1 -DLAMBDA -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+// RUN: %clang_cc1 -DLAMBDA -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-32
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-32
+
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+template <class T>
+struct S {
+ T f;
+ S(T a) : f(a) {}
+ S() : f() {}
+ operator T() { return T(); }
+ ~S() {}
+};
+
+// CHECK: [[S_FLOAT_TY:%.+]] = type { float }
+// CHECK: [[S_INT_TY:%.+]] = type { i{{[0-9]+}} }
+template <typename T>
+T tmain() {
+ S<T> test;
+ T t_var = T();
+ T vec[] = {1, 2};
+ S<T> s_arr[] = {1, 2};
+ S<T> &var = test;
+ #pragma omp target
+ #pragma omp teams distribute simd lastprivate(t_var, vec, s_arr, s_arr, var, var)
+ for (int i = 0; i < 2; ++i) {
+ vec[i] = t_var;
+ s_arr[i] = var;
+ }
+ return T();
+}
+
+int main() {
+ static int svar;
+ volatile double g;
+ volatile double &g1 = g;
+
+ #ifdef LAMBDA
+ // LAMBDA-LABEL: @main
+ // LAMBDA: call{{.*}} void [[OUTER_LAMBDA:@.+]](
+ [&]() {
+ static float sfvar;
+ // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
+ // LAMBDA: call i{{[0-9]+}} @__tgt_target_teams(
+ // LAMBDA: call void [[OFFLOADING_FUN:@.+]](
+
+ // LAMBDA: define{{.+}} void [[OFFLOADING_FUN]](
+ // LAMBDA: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, i32 4, {{.+}}* [[OMP_OUTLINED:@.+]] to {{.+}})
+ #pragma omp target
+ #pragma omp teams distribute simd lastprivate(g, g1, svar, sfvar)
+ for (int i = 0; i < 2; ++i) {
+ // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_OUTLINED]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, double*{{.+}} [[G_IN:%.+]], double*{{.+}} [[G1_IN:%.+]], i{{[0-9]+}}*{{.+}} [[SVAR_IN:%.+]], float*{{.+}} [[SFVAR_IN:%.+]])
+ // LAMBDA: [[G_PRIVATE_ADDR:%.+]] = alloca double*,
+ // LAMBDA: [[G1_PRIVATE_ADDR:%.+]] = alloca double*,
+ // LAMBDA: [[SVAR_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}*,
+ // LAMBDA: [[SFVAR_PRIVATE_ADDR:%.+]] = alloca float*,
+ // loop variables
+ // LAMBDA: {{.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: {{.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: {{.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: {{.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: {{.+}} = alloca i{{[0-9]+}},
+ // LAMBDA: [[OMP_IS_LAST:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[G_PRIVATE:%.+]] = alloca double,
+ // LAMBDA: [[G1_PRIVATE:%.+]] = alloca double,
+ // LAMBDA: [[TMP_G1_PRIVATE:%.+]] = alloca double*,
+ // LAMBDA: [[SVAR_PRIVATE:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[SFVAR_PRIVATE:%.+]] = alloca float,
+ // LAMBDA: store double* [[G_IN]], double** [[G_PRIVATE_ADDR]],
+ // LAMBDA: store double* [[G1_IN]], double** [[G1_PRIVATE_ADDR]],
+ // LAMBDA: store i{{[0-9]+}}* [[SVAR_IN]], i{{[0-9]+}}** [[SVAR_PRIVATE_ADDR]],
+ // LAMBDA: store float* [[SFVAR_IN]], float** [[SFVAR_PRIVATE_ADDR]],
+
+ // init private variables
+ // LAMBDA: [[G_IN_REF:%.+]] = load double*, double** [[G_PRIVATE_ADDR]],
+ // LAMBDA: [[SVAR_IN_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SVAR_PRIVATE_ADDR]],
+ // LAMBDA: [[SFVAR_IN_REF:%.+]] = load float*, float** [[SFVAR_PRIVATE_ADDR]],
+ // LAMBDA: [[G1_IN_REF:%.+]] = load double*, double** [[G1_PRIVATE_ADDR]],
+ // LAMBDA: store double* [[G1_PRIVATE]], double** [[TMP_G1_PRIVATE]],
+ g = 1;
+ g1 = 1;
+ svar = 3;
+ sfvar = 4.0;
+ // LAMBDA: call {{.*}}void @__kmpc_for_static_init_4(
+ // LAMBDA: store double 1.0{{.+}}, double* [[G_PRIVATE]],
+ // LAMBDA: [[TMP_G1_REF:%.+]] = load double*, double** [[TMP_G1_PRIVATE]],
+ // LAMBDA: store{{.+}} double 1.0{{.+}}, double* [[TMP_G1_REF]],
+ // LAMBDA: store i{{[0-9]+}} 3, i{{[0-9]+}}* [[SVAR_PRIVATE]],
+ // LAMBDA: store float 4.0{{.+}}, float* [[SFVAR_PRIVATE]],
+ // LAMBDA: [[G_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // LAMBDA: store double* [[G_PRIVATE]], double** [[G_PRIVATE_ADDR_REF]],
+ // LAMBDA: [[TMP_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // LAMBDA: [[G1_PRIVATE_ADDR_FROM_TMP:%.+]] = load double*, double** [[TMP_G1_PRIVATE]],
+ // LAMBDA: store double* [[G1_PRIVATE_ADDR_FROM_TMP]], double** [[TMP_PRIVATE_ADDR_REF]],
+ // LAMBDA: [[SVAR_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+ // LAMBDA: store i{{[0-9]+}}* [[SVAR_PRIVATE]], i{{[0-9]+}}** [[SVAR_PRIVATE_ADDR_REF]]
+ // LAMBDA: [[SFVAR_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 3
+ // LAMBDA: store float* [[SFVAR_PRIVATE]], float** [[SFVAR_PRIVATE_ADDR_REF]]
+ // LAMBDA: call{{.*}} void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]])
+ // LAMBDA: call {{.*}}void @__kmpc_for_static_fini(
+ // LAMBDA: store i32 2, i32* %
+ // LAMBDA: [[OMP_IS_LAST_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[OMP_IS_LAST]],
+ // LAMBDA: [[IS_LAST_IT:%.+]] = icmp ne i{{[0-9]+}} [[OMP_IS_LAST_VAL]], 0
+ // LAMBDA: br i1 [[IS_LAST_IT]], label %[[OMP_LASTPRIV_BLOCK:.+]], label %[[OMP_LASTPRIV_DONE:.+]]
+
+ // LAMBDA: [[OMP_LASTPRIV_BLOCK]]:
+ // LAMBDA: [[G_PRIV_VAL:%.+]] = load double, double* [[G_PRIVATE]],
+ // LAMBDA: store{{.*}} double [[G_PRIV_VAL]], double* [[G_IN_REF]],
+ // LAMBDA: [[TMP_G1_PRIV_REF:%.+]] = load double*, double** [[TMP_G1_PRIVATE]],
+ // LAMBDA: [[TMP_G1_PRIV_VAL:%.+]] = load double, double* [[TMP_G1_PRIV_REF]],
+ // LAMBDA: store{{.*}} double [[TMP_G1_PRIV_VAL]], double* [[G1_IN_REF]],
+
+ // LAMBDA: [[SVAR_PRIV_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SVAR_PRIVATE]],
+ // LAMBDA: store i{{[0-9]+}} [[SVAR_PRIV_VAL]], i{{[0-9]+}}* [[SVAR_IN_REF]],
+ // LAMBDA: [[SFVAR_PRIV_VAL:%.+]] = load float, float* [[SFVAR_PRIVATE]],
+ // LAMBDA: store float [[SFVAR_PRIV_VAL]], float* [[SFVAR_IN_REF]],
+ // LAMBDA: br label %[[OMP_LASTPRIV_DONE]]
+ // LAMBDA: [[OMP_LASTPRIV_DONE]]:
+ // LAMBDA: ret
+ [&]() {
+ // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]])
+ // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]],
+ g = 2;
+ g1 = 2;
+ svar = 4;
+ sfvar = 8.0;
+ // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]]
+ // LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // LAMBDA: [[G_REF:%.+]] = load double*, double** [[G_PTR_REF]]
+ // LAMBDA: store double 2.0{{.+}}, double* [[G_REF]]
+
+ // LAMBDA: [[TMP_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // LAMBDA: [[G1_REF:%.+]] = load double*, double** [[TMP_PTR_REF]]
+ // LAMBDA: store double 2.0{{.+}}, double* [[G1_REF]],
+ // LAMBDA: [[SVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+ // LAMBDA: [[SVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SVAR_PTR_REF]]
+ // LAMBDA: store i{{[0-9]+}} 4, i{{[0-9]+}}* [[SVAR_REF]]
+ // LAMBDA: [[SFVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 3
+ // LAMBDA: [[SFVAR_REF:%.+]] = load float*, float** [[SFVAR_PTR_REF]]
+ // LAMBDA: store float 8.0{{.+}}, float* [[SFVAR_REF]]
+ }();
+ }
+ }();
+ return 0;
+ #else
+ S<float> test;
+ int t_var = 0;
+ int vec[] = {1, 2};
+ S<float> s_arr[] = {1, 2};
+ S<float> &var = test;
+
+ #pragma omp target
+ #pragma omp teams distribute simd lastprivate(t_var, vec, s_arr, s_arr, var, var, svar)
+ for (int i = 0; i < 2; ++i) {
+ vec[i] = t_var;
+ s_arr[i] = var;
+ }
+ int i;
+
+ return tmain<int>();
+ #endif
+}
+
+// CHECK: define{{.*}} i{{[0-9]+}} @main()
+// CHECK: [[TEST:%.+]] = alloca [[S_FLOAT_TY]],
+// CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR:@.+]]([[S_FLOAT_TY]]* [[TEST]])
+// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+// CHECK: call void [[OFFLOAD_FUN:@.+]](i{{[0-9]+}} {{.+}}, [2 x i{{[0-9]+}}]* {{.+}}, [2 x [[S_FLOAT_TY]]]* {{.+}}, [[S_FLOAT_TY]]* {{.+}}, i{{[0-9]+}} {{.+}})
+// CHECK: ret
+
+// CHECK: define{{.+}} [[OFFLOAD_FUN]](i{{[0-9]+}} {{.+}}, [2 x i{{[0-9]+}}]*{{.+}} {{.+}}, [2 x [[S_FLOAT_TY]]]*{{.+}} {{.+}}, [[S_FLOAT_TY]]*{{.+}} {{.+}}, i{{[0-9]+}} {{.+}})
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_teams(
+// CHECK: ret
+//
+// CHECK: define internal void [[OMP_OUTLINED:@.+]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [2 x i{{[0-9]+}}]*{{.+}} [[VEC_IN:%.+]], i{{[0-9]+}}*{{.+}} [[T_VAR_IN:%.+]], [2 x [[S_FLOAT_TY]]]*{{.+}} [[S_ARR_IN:%.+]], [[S_FLOAT_TY]]*{{.+}} [[VAR_IN:%.+]], i{{[0-9]+}}*{{.*}} [[S_VAR_IN:%.+]])
+// CHECK: {{.+}} = alloca i{{[0-9]+}}*,
+// CHECK: {{.+}} = alloca i{{[0-9]+}}*,
+// CHECK: [[VEC_ADDR:%.+]] = alloca [2 x i{{[0-9]+}}]*,
+// CHECK: [[T_VAR_ADDR:%.+]] = alloca i{{[0-9]+}}*,
+// CHECK: [[S_ARR_ADDR:%.+]] = alloca [2 x [[S_FLOAT_TY]]]*,
+// CHECK: [[VAR_ADDR:%.+]] = alloca [[S_FLOAT_TY]]*,
+// CHECK: [[SVAR_ADDR:%.+]] = alloca i{{[0-9]+}}*,
+// skip loop variables
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: [[OMP_IS_LAST:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]],
+// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]],
+// CHECK: [[TMP_PRIV:%.+]] = alloca [[S_FLOAT_TY]]*,
+// CHECK: [[S_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+
+// copy from parameters to local address variables
+// CHECK: store [2 x i{{[0-9]+}}]* [[VEC_IN]], [2 x i{{[0-9]+}}]** [[VEC_ADDR]],
+// CHECK: store i{{[0-9]+}}* [[T_VAR_IN]], i{{[0-9]+}}** [[T_VAR_ADDR]],
+// CHECK: store [2 x [[S_FLOAT_TY]]]* [[S_ARR_IN]], [2 x [[S_FLOAT_TY]]]** [[S_ARR_ADDR]],
+// CHECK: store [[S_FLOAT_TY]]* [[VAR_IN]], [[S_FLOAT_TY]]** [[VAR_ADDR]],
+// CHECK: store i{{[0-9]+}}* [[S_VAR_IN]], i{{[0-9]+}}** [[SVAR_ADDR]],
+
+// load content of local address variables
+// CHECK: [[VEC_ADDR_REF:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** [[VEC_ADDR]],
+// CHECK: [[T_VAR_ADDR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[T_VAR_ADDR]],
+// CHECK: [[S_ARR_ADDR_REF:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[S_ARR_ADDR]],
+// CHECK: [[SVAR_ADDR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SVAR_ADDR]],
+// CHECK: store i{{[0-9]+}} 0, i{{[0-9]+}}* [[OMP_IS_LAST]],
+// CHECK: [[VAR_ADDR_REF:%.+]] = load {{.+}}, {{.+}} [[VAR_ADDR]],
+// the distribute loop
+// CHECK: call void @__kmpc_for_static_init_4(
+// assignment: vec[i] = t_var;
+// CHECK: [[T_VAR_PRIV_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_PRIV]],
+// CHECK: [[VEC_PTR:%.+]] = getelementptr inbounds [2 x i{{[0-9]+}}], [2 x i{{[0-9]+}}]* [[VEC_PRIV]], i{{[0-9]+}} 0, i{{[0-9]+}} {{.+}}
+// CHECK: store i{{[0-9]+}} [[T_VAR_PRIV_VAL]], i{{[0-9]+}}* [[VEC_PTR]],
+
+// assignment: s_arr[i] = var;
+// CHECK-DAG: [[S_ARR_PTR:%.+]] = getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[S_ARR_PRIV]],
+// CHECK-DAG: [[TMP_VAL:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[TMP_PRIV]],
+// CHECK-DAG: [[S_ARR_PTR_BCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[S_ARR_PTR]] to i8*
+// CHECK-DAG: [[TMP_VAL_BCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[TMP_VAL]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[S_ARR_PTR_BCAST]], i8* [[TMP_VAL_BCAST]],
+// CHECK: call void @__kmpc_for_static_fini(
+
+// lastprivates
+// CHECK: [[OMP_IS_LAST_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[OMP_IS_LAST]],
+// CHECK: [[IS_LAST_IT:%.+]] = icmp ne i{{[0-9]+}} [[OMP_IS_LAST_VAL]], 0
+// CHECK: br i1 [[IS_LAST_IT]], label %[[OMP_LASTPRIV_BLOCK:.+]], label %[[OMP_LASTPRIV_DONE:.+]]
+
+// CHECK: [[OMP_LASTPRIV_BLOCK]]:
+// CHECK: [[T_VAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_PRIV]],
+// CHECK: store i{{[0-9]+}} [[T_VAR_VAL]], i{{[0-9]+}}* [[T_VAR_ADDR_REF]],
+// CHECK: [[BCAST_VEC_ADDR_REF:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_ADDR_REF]] to i8*
+// CHECK: [[BCAST_VEC_PRIV:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[BCAST_VEC_ADDR_REF]], i8* [[BCAST_VEC_PRIV]],
+// CHECK: [[S_ARR_BEGIN:%.+]] = getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[S_ARR_ADDR_REF]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+// CHECK: [[S_ARR_PRIV_BCAST:%.+]] = bitcast [2 x [[S_FLOAT_TY]]]* [[S_ARR_PRIV]] to [[S_FLOAT_TY]]*
+// CHECK: [[S_ARR_BEGIN_GEP:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[S_ARR_BEGIN]], i{{[0-9]+}} 2
+// CHECK: [[S_ARR_IS_EMPTY:%.+]] = icmp eq [[S_FLOAT_TY]]* [[S_ARR_BEGIN]], [[S_ARR_BEGIN_GEP]]
+// CHECK: br i1 [[S_ARR_IS_EMPTY]], label %[[S_ARR_COPY_DONE:.+]], label %[[S_ARR_COPY_BLOCK:.+]]
+// CHECK: [[S_ARR_COPY_BLOCK]]:
+// CHECK: [[S_ARR_SRC_EL:%.+]] = phi [[S_FLOAT_TY]]*{{.+}}
+// CHECK: [[S_ARR_DST_EL:%.+]] = phi [[S_FLOAT_TY]]*{{.+}}
+// CHECK: [[S_ARR_DST_BCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[S_ARR_DST_EL]] to i8*
+// CHECK: [[S_ARR_SRC_BCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[S_ARR_SRC_EL]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[S_ARR_DST_BCAST]], i8* [[S_ARR_SRC_BCAST]]{{.+}})
+// CHECK: [[S_ARR_DST_NEXT:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[S_ARR_DST_EL]], i{{[0-9]+}} 1
+// CHECK: [[S_ARR_SRC_NEXT:%.+]] = getelementptr{{.+}}
+// CHECK: [[CPY_IS_FINISHED:%.+]] = icmp eq [[S_FLOAT_TY]]* [[S_ARR_DST_NEXT]], [[S_ARR_BEGIN_GEP]]
+// CHECK: br i1 [[CPY_IS_FINISHED]], label %[[S_ARR_COPY_DONE]], label %[[S_ARR_COPY_BLOCK]]
+// CHECK: [[S_ARR_COPY_DONE]]:
+// CHECK: [[TMP_VAL1:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[TMP_PRIV]],
+// CHECK: [[VAR_ADDR_REF_BCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[VAR_ADDR_REF]] to i8*
+// CHECK: [[TMP_VAL1_BCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[TMP_VAL1]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[VAR_ADDR_REF_BCAST]], i8* [[TMP_VAL1_BCAST]],{{.+}})
+// CHECK: [[SVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[S_VAR_PRIV]],
+// CHECK: store i{{[0-9]+}} [[SVAR_VAL]], i{{[0-9]+}}* [[SVAR_ADDR_REF]],
+// CHECK: ret void
+
+// template tmain
+// CHECK: define{{.*}} i{{[0-9]+}} [[TMAIN_INT:@.+]]()
+// CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]],
+// CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR:@.+]]([[S_INT_TY]]* [[TEST]])
+// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
+// CHECK: call void [[OFFLOAD_FUN_1:@.+]](i{{[0-9]+}} {{.+}}, [2 x i{{[0-9]+}}]* {{.+}}, [2 x [[S_INT_TY]]]* {{.+}}, [[S_INT_TY]]* {{.+}})
+// CHECK: ret
+
+
+// CHECK: define internal void [[OFFLOAD_FUN_1]](
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_teams(%{{.+}}* @{{.+}}, i{{[0-9]+}} 4,
+// CHECK: ret
+
+// CHECK: define internal void [[OMP_OUTLINED_1:@.+]](i{{[0-9]+}}* noalias [[GTID_ADDR1:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [2 x i{{[0-9]+}}]*{{.+}} [[VEC_IN1:%.+]], i{{[0-9]+}}*{{.+}} [[T_VAR_IN1:%.+]], [2 x [[S_INT_TY]]]*{{.+}} [[S_ARR_IN1:%.+]], [[S_INT_TY]]*{{.+}} [[VAR_IN1:%.+]])
+// skip alloca of global_tid and bound_tid
+// CHECK: {{.+}} = alloca i{{[0-9]+}}*,
+// CHECK: {{.+}} = alloca i{{[0-9]+}}*,
+// CHECK: [[VEC_ADDR1:%.+]] = alloca [2 x i{{[0-9]+}}]*,
+// CHECK: [[T_VAR_ADDR1:%.+]] = alloca i{{[0-9]+}}*,
+// CHECK: [[S_ARR_ADDR1:%.+]] = alloca [2 x [[S_INT_TY]]]*,
+// CHECK: [[VAR_ADDR1:%.+]] = alloca [[S_INT_TY]]*,
+// skip loop variables
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: {{.+}} = alloca i{{[0-9]+}},
+// CHECK: [[OMP_IS_LAST1:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[T_VAR_PRIV1:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[VEC_PRIV1:%.+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK: [[S_ARR_PRIV1:%.+]] = alloca [2 x [[S_INT_TY]]],
+// CHECK: [[VAR_PRIV1:%.+]] = alloca [[S_INT_TY]],
+// CHECK: [[TMP_PRIV1:%.+]] = alloca [[S_INT_TY]]*,
+
+// skip init of bound and global tid
+// CHECK: store i{{[0-9]+}}* {{.*}},
+// CHECK: store i{{[0-9]+}}* {{.*}},
+// copy from parameters to local address variables
+// CHECK: store [2 x i{{[0-9]+}}]* [[VEC_IN1]], [2 x i{{[0-9]+}}]** [[VEC_ADDR1]],
+// CHECK: store i{{[0-9]+}}* [[T_VAR_IN1]], i{{[0-9]+}}** [[T_VAR_ADDR1]],
+// CHECK: store [2 x [[S_INT_TY]]]* [[S_ARR_IN1]], [2 x [[S_INT_TY]]]** [[S_ARR_ADDR1]],
+// CHECK: store [[S_INT_TY]]* [[VAR_IN1]], [[S_INT_TY]]** [[VAR_ADDR1]],
+
+// load content of local address variables
+// CHECK: [[VEC_ADDR_REF1:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** [[VEC_ADDR1]],
+// CHECK: [[T_VAR_ADDR_REF1:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[T_VAR_ADDR1]],
+// CHECK: [[S_ARR_ADDR_REF1:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** [[S_ARR_ADDR1]],
+// CHECK-DAG: store i{{[0-9]+}} 0, i{{[0-9]+}}* [[OMP_IS_LAST1]],
+// CHECK: [[VAR_ADDR1_REF:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[VAR_ADDR1]],
+// CHECK-DAG: store [[S_INT_TY]]* [[VAR_PRIV1]], [[S_INT_TY]]** [[TMP_PRIV1]],
+// CHECK: call void @__kmpc_for_static_init_4(
+// assignment: vec[i] = t_var;
+// CHECK: [[IV_VAL1:%.+]] =
+// CHECK: [[T_VAR_PRIV_VAL1:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_PRIV1]],
+// CHECK: [[VEC_PTR1:%.+]] = getelementptr inbounds [2 x i{{[0-9]+}}], [2 x i{{[0-9]+}}]* [[VEC_PRIV1]], i{{[0-9]+}} 0, i{{[0-9]+}} {{.+}}
+// CHECK: store i{{[0-9]+}} [[T_VAR_PRIV_VAL1]], i{{[0-9]+}}* [[VEC_PTR1]],
+
+// assignment: s_arr[i] = var;
+// CHECK-DAG: [[S_ARR_PTR1:%.+]] = getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[S_ARR_PRIV1]],
+// CHECK-DAG: [[TMP_VAL1:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[TMP_PRIV1]],
+// CHECK-DAG: [[S_ARR_PTR_BCAST1:%.+]] = bitcast [[S_INT_TY]]* [[S_ARR_PTR1]] to i8*
+// CHECK-DAG: [[TMP_VAL_BCAST1:%.+]] = bitcast [[S_INT_TY]]* [[TMP_VAL1]] to i8*
+// CHECK-DAG: call void @llvm.memcpy.{{.+}}(i8* [[S_ARR_PTR_BCAST1]], i8* [[TMP_VAL_BCAST1]],
+// CHECK: call void @__kmpc_for_static_fini(
+
+// lastprivates
+// CHECK: [[OMP_IS_LAST_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[OMP_IS_LAST1]],
+// CHECK: [[IS_LAST_IT:%.+]] = icmp ne i{{[0-9]+}} [[OMP_IS_LAST_VAL]], 0
+// CHECK: br i1 [[IS_LAST_IT]], label %[[OMP_LASTPRIV_BLOCK:.+]], label %[[OMP_LASTPRIV_DONE:.+]]
+
+// CHECK: [[OMP_LASTPRIV_BLOCK]]:
+// CHECK: [[T_VAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_PRIV1]],
+// CHECK: store i{{[0-9]+}} [[T_VAR_VAL]], i{{[0-9]+}}* [[T_VAR_ADDR_REF1]],
+// CHECK: [[BCAST_VEC_ADDR_REF:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_ADDR_REF1]] to i8*
+// CHECK: [[BCAST_VEC_PRIV:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV1]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[BCAST_VEC_ADDR_REF]], i8* [[BCAST_VEC_PRIV]],
+// CHECK: [[S_ARR_BEGIN:%.+]] = getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[S_ARR_ADDR_REF]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+// CHECK: [[S_ARR_PRIV_BCAST:%.+]] = bitcast [2 x [[S_INT_TY]]]* [[S_ARR_PRIV1]] to [[S_INT_TY]]*
+// CHECK: [[S_ARR_BEGIN_GEP:%.+]] = getelementptr [[S_INT_TY]], [[S_INT_TY]]* [[S_ARR_BEGIN]], i{{[0-9]+}} 2
+// CHECK: [[S_ARR_IS_EMPTY:%.+]] = icmp eq [[S_INT_TY]]* [[S_ARR_BEGIN]], [[S_ARR_BEGIN_GEP]]
+// CHECK: br i1 [[S_ARR_IS_EMPTY]], label %[[S_ARR_COPY_DONE:.+]], label %[[S_ARR_COPY_BLOCK:.+]]
+// CHECK: [[S_ARR_COPY_BLOCK]]:
+// CHECK: [[S_ARR_SRC_EL:%.+]] = phi [[S_INT_TY]]*{{.+}}
+// CHECK: [[S_ARR_DST_EL:%.+]] = phi [[S_INT_TY]]*{{.+}}
+// CHECK: [[S_ARR_DST_BCAST:%.+]] = bitcast [[S_INT_TY]]* [[S_ARR_DST_EL]] to i8*
+// CHECK: [[S_ARR_SRC_BCAST:%.+]] = bitcast [[S_INT_TY]]* [[S_ARR_SRC_EL]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[S_ARR_DST_BCAST]], i8* [[S_ARR_SRC_BCAST]]{{.+}})
+// CHECK: [[S_ARR_DST_NEXT:%.+]] = getelementptr [[S_INT_TY]], [[S_INT_TY]]* [[S_ARR_DST_EL]], i{{[0-9]+}} 1
+// CHECK: [[S_ARR_SRC_NEXT:%.+]] = getelementptr{{.+}}
+// CHECK: [[CPY_IS_FINISHED:%.+]] = icmp eq [[S_INT_TY]]* [[S_ARR_DST_NEXT]], [[S_ARR_BEGIN_GEP]]
+// CHECK: br i1 [[CPY_IS_FINISHED]], label %[[S_ARR_COPY_DONE]], label %[[S_ARR_COPY_BLOCK]]
+// CHECK: [[S_ARR_COPY_DONE]]:
+// CHECK: [[TMP_VAL1:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[TMP_PRIV1]],
+// CHECK: [[VAR_ADDR_REF_BCAST:%.+]] = bitcast [[S_INT_TY]]* [[VAR_ADDR1_REF]] to i8*
+// CHECK: [[TMP_VAL1_BCAST:%.+]] = bitcast [[S_INT_TY]]* [[TMP_VAL1]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[VAR_ADDR_REF_BCAST]], i8* [[TMP_VAL1_BCAST]],{{.+}})
+// CHECK: ret void
+// CHECK: !{!"llvm.loop.vectorize.enable", i1 true}
+#endif
diff --git a/test/OpenMP/teams_distribute_simd_lastprivate_messages.cpp b/test/OpenMP/teams_distribute_simd_lastprivate_messages.cpp
index 4c715bf2ce30..51dbfef22933 100644
--- a/test/OpenMP/teams_distribute_simd_lastprivate_messages.cpp
+++ b/test/OpenMP/teams_distribute_simd_lastprivate_messages.cpp
@@ -18,14 +18,14 @@ public:
const S2 &operator =(const S2&) const;
S2 &operator =(const S2&);
static float S2s; // expected-note {{static data member is predetermined as shared}}
- static const float S2sc;
+ static const float S2sc; // expected-note {{static data member is predetermined as shared}}
};
-const float S2::S2sc = 0; // expected-note {{static data member is predetermined as shared}}
+const float S2::S2sc = 0;
const S2 b;
const S2 ba[5];
class S3 {
int a;
- S3 &operator=(const S3 &s3); // expected-note 2 {{implicitly declared private here}}
+ S3 &operator=(const S3 &s3); // expected-note {{implicitly declared private here}}
public:
S3() : a(0) {}
@@ -52,7 +52,7 @@ public:
};
class S6 {
int a;
- S6() : a(0) {}
+ S6() : a(0) {} // expected-note {{implicitly declared private here}}
public:
S6(const S6 &s6) : a(s6.a) {}
@@ -255,12 +255,14 @@ int main(int argc, char **argv) {
#pragma omp teams distribute simd lastprivate(j)
for (i = 0; i < argc; ++i) foo();
+// expected-error@+2 {{firstprivate variable cannot be lastprivate}} expected-note@+2 {{defined as firstprivate}}
#pragma omp target
-#pragma omp teams distribute simd firstprivate(m) lastprivate(m) // expected-error {{'operator=' is a private member of 'S3'}}
+#pragma omp teams distribute simd firstprivate(m) lastprivate(m)
for (i = 0; i < argc; ++i) foo();
+// expected-error@+2 {{lastprivate variable cannot be firstprivate}} expected-note@+2 {{defined as lastprivate}}
#pragma omp target
-#pragma omp teams distribute simd lastprivate(n) firstprivate(n) // OK
+#pragma omp teams distribute simd lastprivate(n) firstprivate(n) // expected-error {{calling a private constructor of class 'S6'}}
for (i = 0; i < argc; ++i) foo();
static int si;
diff --git a/test/OpenMP/teams_distribute_simd_linear_messages.cpp b/test/OpenMP/teams_distribute_simd_linear_messages.cpp
index 6bfdb16274a5..a53f0e62dda2 100644
--- a/test/OpenMP/teams_distribute_simd_linear_messages.cpp
+++ b/test/OpenMP/teams_distribute_simd_linear_messages.cpp
@@ -18,34 +18,42 @@ void test_linear_colons()
{
int B = 0;
+// expected-error@+2 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
#pragma omp teams distribute simd linear(B:bfoo())
for (int i = 0; i < 10; ++i) ;
+// expected-error@+2 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
#pragma omp teams distribute simd linear(B::ib:B:bfoo()) // expected-error {{unexpected ':' in nested name specifier; did you mean '::'}}
for (int i = 0; i < 10; ++i) ;
+// expected-error@+2 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
#pragma omp teams distribute simd linear(B:ib) // expected-error {{use of undeclared identifier 'ib'; did you mean 'B::ib'}}
for (int i = 0; i < 10; ++i) ;
+// expected-error@+2 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
#pragma omp teams distribute simd linear(z:B:ib) // expected-error {{unexpected ':' in nested name specifier; did you mean '::'?}}
for (int i = 0; i < 10; ++i) ;
+// expected-error@+2 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
#pragma omp teams distribute simd linear(B:B::bfoo())
for (int i = 0; i < 10; ++i) ;
+// expected-error@+2 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
#pragma omp teams distribute simd linear(X::x : ::z)
for (int i = 0; i < 10; ++i) ;
+// expected-error@+2 3 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
#pragma omp teams distribute simd linear(B,::z, X::x)
for (int i = 0; i < 10; ++i) ;
+// expected-error@+2 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
#pragma omp teams distribute simd linear(::z)
for (int i = 0; i < 10; ++i) ;
@@ -54,6 +62,7 @@ void test_linear_colons()
#pragma omp teams distribute simd linear(B::bfoo()) // expected-error {{expected variable name}}
for (int i = 0; i < 10; ++i) ;
+// expected-error@+2 2 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
#pragma omp teams distribute simd linear(B::ib,B:C1+C2)
for (int i = 0; i < 10; ++i) ;
@@ -76,6 +85,7 @@ template<int L, class T, class N> T test_template(T* arr, N num) {
template<int LEN> int test_warn() {
int ind2 = 0;
+// expected-error@+2 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
#pragma omp teams distribute simd linear(ind2:LEN) // expected-warning {{zero linear step (ind2 should probably be const)}}
for (int i = 0; i < 100; i++) {
@@ -133,10 +143,12 @@ template<class I, class C> int foomain(I argc, C **argv) {
#pragma omp teams distribute simd linear () // expected-error {{expected expression}}
for (int k = 0; k < argc; ++k) ++k;
+// expected-error@+2 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
#pragma omp teams distribute simd linear (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
for (int k = 0; k < argc; ++k) ++k;
+// expected-error@+2 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
#pragma omp teams distribute simd linear (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
for (int k = 0; k < argc; ++k) ++k;
@@ -145,6 +157,7 @@ template<class I, class C> int foomain(I argc, C **argv) {
#pragma omp teams distribute simd linear (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
for (int k = 0; k < argc; ++k) ++k;
+// expected-error@+2 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
#pragma omp teams distribute simd linear (argc : 5)
for (int k = 0; k < argc; ++k) ++k;
@@ -161,6 +174,7 @@ template<class I, class C> int foomain(I argc, C **argv) {
#pragma omp teams distribute simd linear (argv[1]) // expected-error {{expected variable name}}
for (int k = 0; k < argc; ++k) ++k;
+// expected-error@+2 2 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
#pragma omp teams distribute simd linear(e, g)
for (int k = 0; k < argc; ++k) ++k;
@@ -169,32 +183,11 @@ template<class I, class C> int foomain(I argc, C **argv) {
#pragma omp teams distribute simd linear(h) // expected-error {{threadprivate or thread local variable cannot be linear}}
for (int k = 0; k < argc; ++k) ++k;
+// expected-error@+2 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
#pragma omp teams distribute simd linear(i)
for (int k = 0; k < argc; ++k) ++k;
- #pragma omp parallel
- {
- int v = 0;
- int i;
- #pragma omp target
- #pragma omp teams distribute simd linear(v:i)
- for (int k = 0; k < argc; ++k) { i = k; v += i; }
- }
-
-#pragma omp target
-#pragma omp teams distribute simd linear(j)
- for (int k = 0; k < argc; ++k) ++k;
-
- int v = 0;
-
-#pragma omp target
-#pragma omp teams distribute simd linear(v:j)
- for (int k = 0; k < argc; ++k) { ++k; v += j; }
-
-#pragma omp target
-#pragma omp teams distribute simd linear(i)
- for (int k = 0; k < argc; ++k) ++k;
return 0;
}
@@ -230,10 +223,12 @@ int main(int argc, char **argv) {
#pragma omp teams distribute simd linear () // expected-error {{expected expression}}
for (int k = 0; k < argc; ++k) ++k;
+// expected-error@+2 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
#pragma omp teams distribute simd linear (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
for (int k = 0; k < argc; ++k) ++k;
+// expected-error@+2 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
#pragma omp teams distribute simd linear (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
for (int k = 0; k < argc; ++k) ++k;
@@ -242,6 +237,7 @@ int main(int argc, char **argv) {
#pragma omp teams distribute simd linear (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
for (int k = 0; k < argc; ++k) ++k;
+// expected-error@+2 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
#pragma omp teams distribute simd linear (argc)
for (int k = 0; k < argc; ++k) ++k;
@@ -267,26 +263,6 @@ int main(int argc, char **argv) {
#pragma omp teams distribute simd linear(h, C::x) // expected-error 2 {{threadprivate or thread local variable cannot be linear}}
for (int k = 0; k < argc; ++k) ++k;
- #pragma omp parallel
- {
- int i;
- #pragma omp target
- #pragma omp teams distribute simd linear(i)
- for (int k = 0; k < argc; ++k) ++k;
-
- #pragma omp target
- #pragma omp teams distribute simd linear(i : 4)
- for (int k = 0; k < argc; ++k) { ++k; i += 4; }
- }
-
-#pragma omp target
-#pragma omp teams distribute simd linear(j)
- for (int k = 0; k < argc; ++k) ++k;
-
-#pragma omp target
-#pragma omp teams distribute simd linear(i)
- for (int k = 0; k < argc; ++k) ++k;
-
foomain<int,char>(argc,argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}}
return 0;
}
diff --git a/test/OpenMP/teams_distribute_simd_loop_messages.cpp b/test/OpenMP/teams_distribute_simd_loop_messages.cpp
index 81fbfe860a70..60e07a3db596 100644
--- a/test/OpenMP/teams_distribute_simd_loop_messages.cpp
+++ b/test/OpenMP/teams_distribute_simd_loop_messages.cpp
@@ -2,7 +2,7 @@
class S {
int a;
- S() : a(0) {}
+ S() : a(0) {} // expected-note {{implicitly declared private here}}
public:
S(int v) : a(v) {}
@@ -693,8 +693,9 @@ void test_loop_eh() {
void test_loop_firstprivate_lastprivate() {
S s(4);
+// expected-error@+2 {{lastprivate variable cannot be firstprivate}} expected-note@+2 {{defined as lastprivate}}
#pragma omp target
-#pragma omp teams distribute simd lastprivate(s) firstprivate(s)
+#pragma omp teams distribute simd lastprivate(s) firstprivate(s) // expected-error {{calling a private constructor of class 'S'}}
for (int i = 0; i < 16; ++i)
;
}
diff --git a/test/OpenMP/teams_distribute_simd_messages.cpp b/test/OpenMP/teams_distribute_simd_messages.cpp
index 9095caf38787..b00de796b0ed 100644
--- a/test/OpenMP/teams_distribute_simd_messages.cpp
+++ b/test/OpenMP/teams_distribute_simd_messages.cpp
@@ -9,6 +9,9 @@ static int pvt;
#pragma omp teams distribute simd // expected-error {{unexpected OpenMP directive '#pragma omp teams distribute simd'}}
int main(int argc, char **argv) {
+ #pragma omp target
+ #pragma omp teams distribute simd
+ f; // expected-error {{use of undeclared identifier 'f'}}
#pragma omp target
#pragma omp teams distribute simd { // expected-warning {{extra tokens at the end of '#pragma omp teams distribute simd' are ignored}}
for (int i = 0; i < argc; ++i)
diff --git a/test/OpenMP/teams_distribute_simd_private_codegen.cpp b/test/OpenMP/teams_distribute_simd_private_codegen.cpp
new file mode 100644
index 000000000000..ca9a673e2441
--- /dev/null
+++ b/test/OpenMP/teams_distribute_simd_private_codegen.cpp
@@ -0,0 +1,238 @@
+// RUN: %clang_cc1 -DCHECK -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -DCHECK -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+
+// RUN: %clang_cc1 -DLAMBDA -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+struct St {
+ int a, b;
+ St() : a(0), b(0) {}
+ St(const St &st) : a(st.a + st.b), b(0) {}
+ ~St() {}
+};
+
+volatile int g = 1212;
+volatile int &g1 = g;
+
+template <class T>
+struct S {
+ T f;
+ S(T a) : f(a + g) {}
+ S() : f(g) {}
+ S(const S &s, St t = St()) : f(s.f + t.a) {}
+ operator T() { return T(); }
+ ~S() {}
+};
+
+// CHECK-DAG: [[S_FLOAT_TY:%.+]] = type { float }
+// CHECK-DAG: [[S_INT_TY:%.+]] = type { i{{[0-9]+}} }
+
+template <typename T>
+T tmain() {
+ S<T> test;
+ T t_var = T();
+ T vec[] = {1, 2};
+ S<T> s_arr[] = {1, 2};
+ S<T> &var = test;
+#pragma omp target
+#pragma omp teams distribute simd private(t_var, vec, s_arr, var)
+ for (int i = 0; i < 2; ++i) {
+ vec[i] = t_var;
+ s_arr[i] = var;
+ }
+ return T();
+}
+
+// CHECK-DAG: [[TEST:@.+]] = global [[S_FLOAT_TY]] zeroinitializer,
+S<float> test;
+// CHECK-DAG: [[T_VAR:@.+]] = global i{{[0-9]+}} 333,
+int t_var = 333;
+// CHECK-DAG: [[VEC:@.+]] = global [2 x i{{[0-9]+}}] [i{{[0-9]+}} 1, i{{[0-9]+}} 2],
+int vec[] = {1, 2};
+// CHECK-DAG: [[S_ARR:@.+]] = global [2 x [[S_FLOAT_TY]]] zeroinitializer,
+S<float> s_arr[] = {1, 2};
+// CHECK-DAG: [[VAR:@.+]] = global [[S_FLOAT_TY]] zeroinitializer,
+S<float> var(3);
+// CHECK-DAG: [[SIVAR:@.+]] = internal global i{{[0-9]+}} 0,
+
+int main() {
+ static int sivar;
+#ifdef LAMBDA
+ // LAMBDA: [[G:@.+]] = global i{{[0-9]+}} 1212,
+ // LAMBDA-LABEL: @main
+ // LAMBDA: call void [[OUTER_LAMBDA:@.+]](
+ [&]() {
+ // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
+ // LAMBDA: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 1, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 0)
+ // LAMBDA: call void @[[LOFFL1:.+]](
+ // LAMBDA: ret
+#pragma omp target
+#pragma omp teams distribute simd private(g, g1, sivar)
+ for (int i = 0; i < 2; ++i) {
+ // LAMBDA: define{{.*}} internal{{.*}} void @[[LOFFL1]](i{{64|32}} {{%.+}})
+ // LAMBDA: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 0, {{.+}} @[[LOUTL1:.+]] to {{.+}})
+ // LAMBDA: ret void
+
+ // LAMBDA: define internal void @[[LOUTL1]]({{.+}})
+ // Skip global, bound tid and loop vars
+ // LAMBDA: {{.+}} = alloca i32*,
+ // LAMBDA: {{.+}} = alloca i32*,
+ // LAMBDA: alloca i32,
+ // LAMBDA: alloca i32,
+ // LAMBDA: alloca i32,
+ // LAMBDA: alloca i32,
+ // LAMBDA: alloca i32,
+ // LAMBDA: alloca i32,
+ // LAMBDA: [[G_PRIV:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[G1_PRIV:%.+]] = alloca i{{[0-9]+}}
+ // LAMBDA: [[TMP:%.+]] = alloca i{{[0-9]+}}*,
+ // LAMBDA: [[SIVAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: store{{.+}} [[G1_PRIV]], {{.+}} [[TMP]],
+
+ g = 1;
+ g1 = 1;
+ sivar = 2;
+ // LAMBDA: call void @__kmpc_for_static_init_4(
+ // LAMBDA-DAG: store{{.+}} 1, {{.+}} [[G_PRIV]],
+ // LAMBDA-DAG: store{{.+}} 2, {{.+}} [[SIVAR_PRIV]],
+ // LAMBDA-DAG: [[G1_REF:%.+]] = load{{.+}}, {{.+}} [[TMP]],
+ // LAMBDA-DAG: store{{.+}} 1, {{.+}} [[G1_REF]],
+ // LAMBDA: call void [[INNER_LAMBDA:@.+]](
+ // LAMBDA: call void @__kmpc_for_static_fini(
+ [&]() {
+ // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]])
+ // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]],
+ g = 2;
+ g1 = 2;
+ sivar = 4;
+ // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]]
+
+ // LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // LAMBDA: [[G_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G_PTR_REF]]
+ // LAMBDA: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[G_REF]]
+ // LAMBDA: [[G1_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // LAMBDA: [[G1_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G1_PTR_REF]]
+ // LAMBDA: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[G1_REF]]
+ // LAMBDA: [[SIVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+ // LAMBDA: [[SIVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SIVAR_PTR_REF]]
+ // LAMBDA: store i{{[0-9]+}} 4, i{{[0-9]+}}* [[SIVAR_REF]]
+ }();
+ }
+ }();
+ return 0;
+#else
+#pragma omp target
+#pragma omp teams distribute simd private(t_var, vec, s_arr, var, sivar)
+ for (int i = 0; i < 2; ++i) {
+ vec[i] = t_var;
+ s_arr[i] = var;
+ sivar += i;
+ }
+ return tmain<int>();
+#endif
+}
+
+// CHECK: define {{.*}}i{{[0-9]+}} @main()
+// CHECK: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 0, i8** null, i8** null, i{{64|32}}* null, i64* null, i32 0, i32 0)
+// CHECK: call void @[[OFFL1:.+]]()
+// CHECK: {{%.+}} = call{{.*}} i32 @[[TMAIN_INT:.+]]()
+// CHECK: ret
+
+// CHECK: define{{.*}} void @[[OFFL1]]()
+// CHECK: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 0, {{.+}} @[[OUTL1:.+]] to {{.+}})
+// CHECK: ret void
+
+// CHECK: define internal void @[[OUTL1]]({{.+}})
+// Skip global, bound tid and loop vars
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: {{.+}} = alloca i32,
+// CHECK: {{.+}} = alloca i32,
+// CHECK: {{.+}} = alloca i32,
+// CHECK: {{.+}} = alloca i32,
+// CHECK: {{.+}} = alloca i32,
+// CHECK: {{.+}} = alloca i32,
+// CHECK-DAG: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK-DAG: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK-DAG: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]],
+// CHECK-DAG: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]],
+// CHECK-DAG: [[SIVAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+
+// private(s_arr)
+// CHECK-DAG: [[S_ARR_PRIV_BGN:%.+]] = getelementptr{{.*}} [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[S_ARR_PRIV]],
+// CHECK-DAG: [[S_ARR_PTR_ALLOC:%.+]] = phi{{.+}} [ [[S_ARR_PRIV_BGN]], {{.+}} ], [ [[S_ARR_NEXT:%.+]], {{.+}} ]
+// CHECK-DAG: call void @{{.+}}({{.+}} [[S_ARR_PTR_ALLOC]])
+// CHECK-DAG: [[S_ARR_NEXT]] = getelementptr {{.+}} [[S_ARR_PTR_ALLOC]],
+
+// private(var)
+// CHECK-DAG: call void @{{.+}}({{.+}} [[VAR_PRIV]])
+
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK-DAG: {{.+}} = {{.+}} [[T_VAR_PRIV]]
+// CHECK-DAG: {{.+}} = {{.+}} [[VEC_PRIV]]
+// CHECK-DAG: {{.+}} = {{.+}} [[S_ARR_PRIV]]
+// CHECK-DAG: {{.+}} = {{.+}} [[VAR_PRIV]]
+// CHECK-DAG: {{.+}} = {{.+}} [[SIVAR_PRIV]]
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: ret void
+
+
+// CHECK: define{{.*}} i{{[0-9]+}} @[[TMAIN_INT]]()
+// CHECK: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 0,
+// CHECK: call void @[[TOFFL1:.+]]()
+// CHECK: ret
+
+// CHECK: define {{.*}}void @[[TOFFL1]]()
+// CHECK: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 0, {{.+}} @[[TOUTL1:.+]] to {{.+}})
+// CHECK: ret void
+
+// CHECK: define internal void @[[TOUTL1]]({{.+}})
+// Skip global, bound tid and loop vars
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_INT_TY]]],
+// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_INT_TY]],
+// CHECK: [[TMP:%.+]] = alloca [[S_INT_TY]]*,
+
+// private(s_arr)
+// CHECK-DAG: [[S_ARR_PRIV_BGN:%.+]] = getelementptr{{.*}} [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[S_ARR_PRIV]],
+// CHECK-DAG: [[S_ARR_PTR_ALLOC:%.+]] = phi{{.+}} [ [[S_ARR_PRIV_BGN]], {{.+}} ], [ [[S_ARR_NEXT:%.+]], {{.+}} ]
+// CHECK-DAG: call void @{{.+}}({{.+}} [[S_ARR_PTR_ALLOC]])
+// CHECK-DAG: [[S_ARR_NEXT]] = getelementptr {{.+}} [[S_ARR_PTR_ALLOC]],
+
+// CHECK-DAG: [[S_ARR_PRIV_BGN:%.+]] = getelementptr{{.*}} [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[S_ARR_PRIV]],
+// CHECK-DAG: [[S_ARR_PTR_ALLOC:%.+]] = phi{{.+}} [ [[S_ARR_PRIV_BGN]], {{.+}} ], [ [[S_ARR_NEXT:%.+]], {{.+}} ]
+// CHECK-DAG: call void @{{.+}}({{.+}} [[S_ARR_PTR_ALLOC]])
+// CHECK-DAG: [[S_ARR_NEXT]] = getelementptr {{.+}} [[S_ARR_PTR_ALLOC]],
+
+// private(var)
+// CHECK-DAG: call void @{{.+}}({{.+}} [[VAR_PRIV]])
+// CHECK-DAG: store{{.+}} [[VAR_PRIV]], {{.+}} [[TMP]]
+
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK-DAG: {{.+}} = {{.+}} [[T_VAR_PRIV]]
+// CHECK-DAG: {{.+}} = {{.+}} [[VEC_PRIV]]
+// CHECK-DAG: {{.+}} = {{.+}} [[S_ARR_PRIV]]
+// CHECK-DAG: {{.+}} = {{.+}} [[TMP]]
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: ret void
+
+// CHECK: !{!"llvm.loop.vectorize.enable", i1 true}
+#endif
diff --git a/test/OpenMP/teams_distribute_simd_reduction_codegen.cpp b/test/OpenMP/teams_distribute_simd_reduction_codegen.cpp
new file mode 100644
index 000000000000..3153cce3a923
--- /dev/null
+++ b/test/OpenMP/teams_distribute_simd_reduction_codegen.cpp
@@ -0,0 +1,218 @@
+// RUN: %clang_cc1 -DCHECK -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -DCHECK -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCHECK -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+
+// RUN: %clang_cc1 -DLAMBDA -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+template <typename T>
+T tmain() {
+ T t_var = T();
+ T vec[] = {1, 2};
+#pragma omp target
+#pragma omp teams distribute simd reduction(+: t_var)
+ for (int i = 0; i < 2; ++i) {
+ t_var += (T) i;
+ }
+ return T();
+}
+
+int main() {
+ static int sivar;
+#ifdef LAMBDA
+ // LAMBDA: [[RED_VAR:@.+]] = common global [8 x {{.+}}] zeroinitializer
+
+ // LAMBDA-LABEL: @main
+ // LAMBDA: call void [[OUTER_LAMBDA:@.+]](
+ [&]() {
+ // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
+ // LAMBDA: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 1, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 0)
+ // LAMBDA: call void @[[LOFFL1:.+]](
+ // LAMBDA: ret
+#pragma omp target
+#pragma omp teams distribute simd reduction(+: sivar)
+ for (int i = 0; i < 2; ++i) {
+ // LAMBDA: define{{.*}} internal{{.*}} void @[[LOFFL1]](i{{64|32}} [[SIVAR_ARG:%.+]])
+ // LAMBDA: [[SIVAR_ADDR:%.+]] = alloca i{{.+}},
+ // LAMBDA: store{{.+}} [[SIVAR_ARG]], {{.+}} [[SIVAR_ADDR]],
+ // LAMBDA: [[SIVAR_CONV:%.+]] = bitcast{{.+}} [[SIVAR_ADDR]] to
+ // LAMBDA: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[LOUTL1:.+]] to {{.+}}, {{.+}} [[SIVAR_CONV]])
+ // LAMBDA: ret void
+
+ // LAMBDA: define internal void @[[LOUTL1]]({{.+}}, {{.+}}, {{.+}} [[SIVAR_ARG:%.+]])
+ // Skip global and bound tid vars
+ // LAMBDA: {{.+}} = alloca i32*,
+ // LAMBDA: {{.+}} = alloca i32*,
+ // LAMBDA: [[SIVAR_ADDR:%.+]] = alloca i{{.+}}*,
+ // LAMBDA: [[SIVAR_PRIV:%.+]] = alloca i{{.+}},
+ // LAMBDA: [[RED_LIST:%.+]] = alloca [1 x {{.+}}],
+ // LAMBDA: store{{.+}} [[SIVAR_ARG]], {{.+}} [[SIVAR_ADDR]],
+ // LAMBDA: [[SIVAR_REF:%.+]] = load{{.+}}, {{.+}} [[SIVAR_ADDR]]
+ // LAMBDA: store{{.+}} 0, {{.+}} [[SIVAR_PRIV]],
+
+ // LAMBDA: call void @__kmpc_for_static_init_4(
+ // LAMBDA: store{{.+}}, {{.+}} [[SIVAR_PRIV]],
+ // LAMBDA: call void [[INNER_LAMBDA:@.+]](
+ // LAMBDA: call void @__kmpc_for_static_fini(
+ // LAMBDA: [[RED_LIST_GEP:%.+]] = getelementptr{{.+}} [[RED_LIST]],
+ // LAMBDA: [[SIVAR_PRIV_CAST:%.+]] = bitcast{{.+}} [[SIVAR_PRIV]] to
+ // LAMBDA: store{{.+}} [[SIVAR_PRIV_CAST]], {{.+}} [[RED_LIST_GEP]],
+ // LAMBDA: [[RED_LIST_BCAST:%.+]] = bitcast{{.+}} [[RED_LIST]] to
+ // LAMBDA: [[K_RED_RET:%.+]] = call{{.+}} @__kmpc_reduce({{.+}}, {{.+}}, {{.+}}, {{.+}}, {{.+}} [[RED_LIST_BCAST]], {{.+}} [[RED_FUN:@.+]], {{.+}} [[RED_VAR]])
+ // LAMBDA: switch{{.+}} [[K_RED_RET]], label{{.+}} [
+ // LAMBDA: {{.+}}, label %[[CASE1:.+]]
+ // LAMBDA: {{.+}}, label %[[CASE2:.+]]
+ // LAMBDA: ]
+ // LAMBDA: [[CASE1]]:
+ // LAMBDA-DAG: [[SIVAR_VAL:%.+]] = load{{.+}}, {{.+}} [[SIVAR_REF]],
+ // LAMBDA-DAG: [[SIVAR_PRIV_VAL:%.+]] = load{{.+}}, {{.+}} [[SIVAR_PRIV]],
+ // LAMBDA-DAG: [[SIVAR_INC:%.+]] = add{{.+}} [[SIVAR_VAL]], [[SIVAR_PRIV_VAL]]
+ // LAMBDA: store{{.+}} [[SIVAR_INC]], {{.+}} [[SIVAR_REF]],
+ // LAMBDA: call void @__kmpc_end_reduce({{.+}}, {{.+}}, {{.+}} [[RED_VAR]])
+ // LAMBDA: br
+ // LAMBDA: [[CASE2]]:
+ // LAMBDA-DAG: [[SIVAR_PRIV_VAL:%.+]] = load{{.+}}, {{.+}} [[SIVAR_PRIV]],
+ // LAMBDA-DAG: [[ATOMIC_RES:%.+]] = atomicrmw add{{.+}} [[SIVAR_REF]], {{.+}} [[SIVAR_PRIV_VAL]]
+ // LAMBDA: call void @__kmpc_end_reduce({{.+}}, {{.+}}, {{.+}} [[RED_VAR]])
+ // LAMBDA: br
+
+ sivar += i;
+
+ [&]() {
+ // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]])
+ // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]],
+
+ sivar += 4;
+ // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]]
+
+ // LAMBDA: [[SIVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // LAMBDA: [[SIVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SIVAR_PTR_REF]]
+ // LAMBDA: [[SIVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR_REF]]
+ // LAMBDA: [[SIVAR_INC:%.+]] = add{{.+}} [[SIVAR_VAL]], 4
+ // LAMBDA: store i{{[0-9]+}} [[SIVAR_INC]], i{{[0-9]+}}* [[SIVAR_REF]]
+ }();
+ }
+ }();
+ return 0;
+#else
+#pragma omp target
+#pragma omp teams distribute simd reduction(+: sivar)
+ for (int i = 0; i < 2; ++i) {
+ sivar += i;
+ }
+ return tmain<int>();
+#endif
+}
+
+// CHECK: [[RED_VAR:@.+]] = common global [8 x {{.+}}] zeroinitializer
+
+// CHECK: define {{.*}}i{{[0-9]+}} @main()
+// CHECK: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 1, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 0)
+// CHECK: call void @[[OFFL1:.+]](i{{64|32}} %{{.+}})
+// CHECK: {{%.+}} = call{{.*}} i32 @[[TMAIN_INT:.+]]()
+// CHECK: ret
+
+// CHECK: define{{.*}} void @[[OFFL1]](i{{64|32}} [[SIVAR_ARG:%.+]])
+// CHECK: [[SIVAR_ADDR:%.+]] = alloca i{{.+}},
+// CHECK: store{{.+}} [[SIVAR_ARG]], {{.+}} [[SIVAR_ADDR]],
+// CHECK-64: [[SIVAR_CONV:%.+]] = bitcast{{.+}} [[SIVAR_ADDR]] to
+// CHECK-64: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTL1:.+]] to {{.+}}, {{.+}} [[SIVAR_CONV]])
+// CHECK-32: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[OUTL1:.+]] to {{.+}}, {{.+}} [[SIVAR_ADDR]])
+// CHECK: ret void
+
+// CHECK: define internal void @[[OUTL1]]({{.+}}, {{.+}}, {{.+}} [[SIVAR_ARG:%.+]])
+// Skip global and bound tid vars
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: [[SIVAR_ADDR:%.+]] = alloca i{{.+}}*,
+// CHECK: [[SIVAR_PRIV:%.+]] = alloca i{{.+}},
+// CHECK: [[RED_LIST:%.+]] = alloca [1 x {{.+}}],
+// CHECK: store{{.+}} [[SIVAR_ARG]], {{.+}} [[SIVAR_ADDR]],
+// CHECK: [[SIVAR_REF:%.+]] = load{{.+}}, {{.+}} [[SIVAR_ADDR]]
+// CHECK: store{{.+}} 0, {{.+}} [[SIVAR_PRIV]],
+
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: store{{.+}}, {{.+}} [[SIVAR_PRIV]],
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: [[RED_LIST_GEP:%.+]] = getelementptr{{.+}} [[RED_LIST]],
+// CHECK: [[SIVAR_PRIV_CAST:%.+]] = bitcast{{.+}} [[SIVAR_PRIV]] to
+// CHECK: store{{.+}} [[SIVAR_PRIV_CAST]], {{.+}} [[RED_LIST_GEP]],
+// CHECK: [[RED_LIST_BCAST:%.+]] = bitcast{{.+}} [[RED_LIST]] to
+// CHECK: [[K_RED_RET:%.+]] = call{{.+}} @__kmpc_reduce({{.+}}, {{.+}}, {{.+}}, {{.+}}, {{.+}} [[RED_LIST_BCAST]], {{.+}} [[RED_FUN:@.+]], {{.+}} [[RED_VAR]])
+// CHECK: switch{{.+}} [[K_RED_RET]], label{{.+}} [
+// CHECK: {{.+}}, label %[[CASE1:.+]]
+// CHECK: {{.+}}, label %[[CASE2:.+]]
+// CHECK: ]
+// CHECK: [[CASE1]]:
+// CHECK-DAG: [[SIVAR_VAL:%.+]] = load{{.+}}, {{.+}} [[SIVAR_REF]],
+// CHECK-DAG: [[SIVAR_PRIV_VAL:%.+]] = load{{.+}}, {{.+}} [[SIVAR_PRIV]],
+// CHECK-DAG: [[SIVAR_INC:%.+]] = add{{.+}} [[SIVAR_VAL]], [[SIVAR_PRIV_VAL]]
+// CHECK: store{{.+}} [[SIVAR_INC]], {{.+}} [[SIVAR_REF]],
+// CHECK: call void @__kmpc_end_reduce({{.+}}, {{.+}}, {{.+}} [[RED_VAR]])
+// CHECK: br
+// CHECK: [[CASE2]]:
+// CHECK-DAG: [[SIVAR_PRIV_VAL:%.+]] = load{{.+}}, {{.+}} [[SIVAR_PRIV]],
+// CHECK-DAG: [[ATOMIC_RES:%.+]] = atomicrmw add{{.+}} [[SIVAR_REF]], {{.+}} [[SIVAR_PRIV_VAL]]
+// CHECK: call void @__kmpc_end_reduce({{.+}}, {{.+}}, {{.+}} [[RED_VAR]])
+// CHECK: br
+
+
+// CHECK: define{{.*}} i{{[0-9]+}} @[[TMAIN_INT]]()
+// CHECK: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 1,
+// CHECK: call void @[[TOFFL1:.+]]({{.+}})
+// CHECK: ret
+
+// CHECK: define{{.*}} void @[[TOFFL1]](i{{64|32}} [[TVAR_ARG:%.+]])
+// CHECK: [[TVAR_ADDR:%.+]] = alloca i{{.+}},
+// CHECK: store{{.+}} [[TVAR_ARG]], {{.+}} [[TVAR_ADDR]],
+// CHECK-64: [[TVAR_CONV:%.+]] = bitcast{{.+}} [[TVAR_ADDR]] to
+// CHECK-64: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[TOUTL1:.+]] to {{.+}}, {{.+}} [[TVAR_CONV]])
+// CHECK-32: call void {{.+}} @__kmpc_fork_teams({{.+}}, i32 1, {{.+}} @[[TOUTL1:.+]] to {{.+}}, {{.+}} [[TVAR_ADDR]])
+// CHECK: ret void
+
+// CHECK: define internal void @[[TOUTL1]]({{.+}}, {{.+}}, {{.+}} [[TVAR_ARG:%.+]])
+// Skip global and bound tid vars
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: {{.+}} = alloca i32*,
+// CHECK: [[TVAR_ADDR:%.+]] = alloca i{{.+}}*,
+// CHECK: [[TVAR_PRIV:%.+]] = alloca i{{.+}},
+// CHECK: [[RED_LIST:%.+]] = alloca [1 x {{.+}}],
+// CHECK: store{{.+}} [[TVAR_ARG]], {{.+}} [[TVAR_ADDR]],
+// CHECK: [[TVAR_REF:%.+]] = load{{.+}}, {{.+}} [[TVAR_ADDR]]
+// CHECK: store{{.+}} 0, {{.+}} [[TVAR_PRIV]],
+
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: store{{.+}}, {{.+}} [[TVAR_PRIV]],
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: [[RED_LIST_GEP:%.+]] = getelementptr{{.+}} [[RED_LIST]],
+// CHECK: [[TVAR_PRIV_CAST:%.+]] = bitcast{{.+}} [[TVAR_PRIV]] to
+// CHECK: store{{.+}} [[TVAR_PRIV_CAST]], {{.+}} [[RED_LIST_GEP]],
+// CHECK: [[RED_LIST_BCAST:%.+]] = bitcast{{.+}} [[RED_LIST]] to
+// CHECK: [[K_RED_RET:%.+]] = call{{.+}} @__kmpc_reduce({{.+}}, {{.+}}, {{.+}}, {{.+}}, {{.+}} [[RED_LIST_BCAST]], {{.+}} [[RED_FUN:@.+]], {{.+}} [[RED_VAR]])
+// CHECK: switch{{.+}} [[K_RED_RET]], label{{.+}} [
+// CHECK: {{.+}}, label %[[CASE1:.+]]
+// CHECK: {{.+}}, label %[[CASE2:.+]]
+// CHECK: ]
+// CHECK: [[CASE1]]:
+// CHECK-DAG: [[TVAR_VAL:%.+]] = load{{.+}}, {{.+}} [[TVAR_REF]],
+// CHECK-DAG: [[TVAR_PRIV_VAL:%.+]] = load{{.+}}, {{.+}} [[TVAR_PRIV]],
+// CHECK-DAG: [[TVAR_INC:%.+]] = add{{.+}} [[TVAR_VAL]], [[TVAR_PRIV_VAL]]
+// CHECK: store{{.+}} [[TVAR_INC]], {{.+}} [[TVAR_REF]],
+// CHECK: call void @__kmpc_end_reduce({{.+}}, {{.+}}, {{.+}} [[RED_VAR]])
+// CHECK: br
+// CHECK: [[CASE2]]:
+// CHECK-DAG: [[TVAR_PRIV_VAL:%.+]] = load{{.+}}, {{.+}} [[TVAR_PRIV]],
+// CHECK-DAG: [[ATOMIC_RES:%.+]] = atomicrmw add{{.+}} [[TVAR_REF]], {{.+}} [[TVAR_PRIV_VAL]]
+// CHECK: call void @__kmpc_end_reduce({{.+}}, {{.+}}, {{.+}} [[RED_VAR]])
+// CHECK: br
+
+// CHECK: !{!"llvm.loop.vectorize.enable", i1 true}
+#endif
diff --git a/test/OpenMP/teams_distribute_simd_reduction_messages.cpp b/test/OpenMP/teams_distribute_simd_reduction_messages.cpp
index 879ec688dcb5..09d22bd4bd81 100644
--- a/test/OpenMP/teams_distribute_simd_reduction_messages.cpp
+++ b/test/OpenMP/teams_distribute_simd_reduction_messages.cpp
@@ -19,9 +19,9 @@ public:
S2() : a(0) {}
S2(S2 &s2) : a(s2.a) {}
static float S2s; // expected-note 2 {{static data member is predetermined as shared}}
- static const float S2sc;
+ static const float S2sc; // expected-note 2 {{'S2sc' declared here}}
};
-const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}}
+const float S2::S2sc = 0;
S2 b; // expected-note 3 {{'b' defined here}}
const S2 ba[5]; // expected-note 2 {{'ba' defined here}}
class S3 {
diff --git a/test/OpenMP/teams_distribute_simd_shared_messages.cpp b/test/OpenMP/teams_distribute_simd_shared_messages.cpp
index cd963e8469a8..6b06f5b6f203 100644
--- a/test/OpenMP/teams_distribute_simd_shared_messages.cpp
+++ b/test/OpenMP/teams_distribute_simd_shared_messages.cpp
@@ -84,7 +84,7 @@ int main(int argc, char **argv) {
#pragma omp teams distribute simd shared (S1) // expected-error {{'S1' does not refer to a value}}
for (int j=0; j<100; j++) foo();
#pragma omp target
- #pragma omp teams distribute simd shared (a, b, c, d, f)
+ #pragma omp teams distribute simd shared (a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}}
for (int j=0; j<100; j++) foo();
#pragma omp target
#pragma omp teams distribute simd shared (argv[1]) // expected-error {{expected variable name}}
diff --git a/test/OpenMP/teams_messages.cpp b/test/OpenMP/teams_messages.cpp
index 3a42a0e8dd6a..642fe73cac75 100644
--- a/test/OpenMP/teams_messages.cpp
+++ b/test/OpenMP/teams_messages.cpp
@@ -7,6 +7,9 @@ void foo() {
int main(int argc, char **argv) {
#pragma omp target
+ #pragma omp teams
+ f; // expected-error {{use of undeclared identifier 'f'}}
+ #pragma omp target
#pragma omp teams { // expected-warning {{extra tokens at the end of '#pragma omp teams' are ignored}}
foo();
#pragma omp target
diff --git a/test/OpenMP/teams_private_codegen.cpp b/test/OpenMP/teams_private_codegen.cpp
index 1ba010fa5c3c..7ddf39c9b0ea 100644
--- a/test/OpenMP/teams_private_codegen.cpp
+++ b/test/OpenMP/teams_private_codegen.cpp
@@ -98,7 +98,7 @@ int main() {
// lambda and target region in main
// LAMBDA: define {{.+}} [[OUTER_LAMBDA]]([[CAP_TY]]* {{.+}})
- // LAMBDA: call void @[[OMP_OFFLOADING:.+]](i{{[0-9]+}}* {{.+}}, i{{[0-9]+}} {{.+}}
+ // LAMBDA: call void @[[OMP_OFFLOADING:.+]]()
// target region in struct constructor
// LAMBDA: define{{.*}} void [[ST_CONSTR:@.+]]([[SS_TY]]* %this,
@@ -154,7 +154,7 @@ int main() {
#pragma omp target
#pragma omp teams private(g, sivar)
{
- // LAMBDA: define{{.+}} @[[OMP_OFFLOADING]](i{{[0-9]+}}* {{.+}} [[G_IN:%.+]], i{{[0-9]+}} [[SIVAR_IN:%.+]]
+ // LAMBDA: define{{.+}} @[[OMP_OFFLOADING]]()
// LAMBDA: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_teams(%{{.+}}* @{{.+}}, i{{[0-9]+}} 0, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*)* [[OMP_OUTLINED_1:@.+]] to void
// LAMBDA: define {{.+}} [[OMP_OUTLINED_1]](i{{[0-9]+}}* {{.+}}, i{{[0-9]+}}* {{.+}}
@@ -196,14 +196,13 @@ int main() {
// CHECK: define{{.*}} i{{[0-9]+}} @main()
// CHECK: [[TEST:%.+]] = alloca [[S_FLOAT_TY]],
// CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR:@.+]]([[S_FLOAT_TY]]* [[TEST]])
-// CHECK: [[OFF_IN:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* {{%.+}},
-// CHECK: call void @[[OMP_OFFLOADING:.+]](i{{[0-9]+}} [[OFF_IN]]
+// CHECK: call void @[[OMP_OFFLOADING:.+]]()
// CHECK: = call{{.*}} i{{.+}} [[TMAIN_INT:@.+]]()
// CHECK: call void [[S_FLOAT_TY_DESTR:@.+]]([[S_FLOAT_TY]]*
// CHECK: ret
// target region in main function
-// CHECK: define{{.+}} @[[OMP_OFFLOADING]](i{{[0-9]+}}
+// CHECK: define{{.+}} @[[OMP_OFFLOADING]]()
// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_teams(%{{.+}}* @{{.+}}, i{{[0-9]+}} 0, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*)* [[OMP_OUTLINED:@.+]] to void
// CHECK: define internal void [[OMP_OUTLINED]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}})
diff --git a/test/OpenMP/teams_reduction_messages.cpp b/test/OpenMP/teams_reduction_messages.cpp
index 9974c147b72c..7aef97730d9e 100644
--- a/test/OpenMP/teams_reduction_messages.cpp
+++ b/test/OpenMP/teams_reduction_messages.cpp
@@ -25,9 +25,9 @@ public:
S2() : a(0) {}
S2(S2 &s2) : a(s2.a) {}
static float S2s; // expected-note 2 {{static data member is predetermined as shared}}
- static const float S2sc;
+ static const float S2sc; // expected-note 2 {{'S2sc' declared here}}
};
-const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}}
+const float S2::S2sc = 0;
S2 b; // expected-note 3 {{'b' defined here}}
const S2 ba[5]; // expected-note 2 {{'ba' defined here}}
class S3 {
diff --git a/test/OpenMP/teams_shared_messages.cpp b/test/OpenMP/teams_shared_messages.cpp
index e14ba1e32f47..6b013d099dce 100644
--- a/test/OpenMP/teams_shared_messages.cpp
+++ b/test/OpenMP/teams_shared_messages.cpp
@@ -84,7 +84,7 @@ int main(int argc, char **argv) {
#pragma omp teams shared (S1) // expected-error {{'S1' does not refer to a value}}
foo();
#pragma omp target
- #pragma omp teams shared (a, b, c, d, f)
+ #pragma omp teams shared (a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}}
foo();
#pragma omp target
#pragma omp teams shared (argv[1]) // expected-error {{expected variable name}}
diff --git a/test/OpenMP/vla_crash.c b/test/OpenMP/vla_crash.c
index 50dcf068707b..0dcba5503e4c 100644
--- a/test/OpenMP/vla_crash.c
+++ b/test/OpenMP/vla_crash.c
@@ -1,5 +1,4 @@
// RUN: %clang_cc1 -verify -triple powerpc64le-unknown-linux-gnu -fopenmp -x c -emit-llvm %s -o - | FileCheck %s
-// expected-no-diagnostics
int a;
@@ -20,3 +19,24 @@ void foo() {
// CHECK: define internal void [[OUTLINED]](i32* {{[^,]+}}, i32* {{[^,]+}}, i64 {{[^,]+}}, i32** {{[^,]+}}, i64 {{[^,]+}}, i32**** {{[^,]+}})
+// CHECK-LABEL: bar
+void bar(int n, int *a) {
+ // CHECK: [[N:%.+]] = alloca i32,
+ // CHECK: [[A:%.+]] = alloca i32*,
+ // CHECK: [[P:%.+]] = alloca i32*,
+ // CHECK: @__kmpc_global_thread_num
+ // CHECK: [[BC:%.+]] = bitcast i32** [[A]] to i32*
+ // CHECK: store i32* [[BC]], i32** [[P]],
+ // CHECK: call void @__kmpc_serialized_parallel
+ // CHECK: call void [[OUTLINED:@[^(]+]](i32* %{{[^,]+}}, i32* %{{[^,]+}}, i64 %{{[^,]+}}, i32** [[P]], i32** [[A]])
+ // CHECK: call void @__kmpc_end_serialized_parallel
+ // CHECK: ret void
+ // expected-warning@+1 {{incompatible pointer types initializing 'int (*)[n]' with an expression of type 'int **'}}
+ int(*p)[n] = &a;
+#pragma omp parallel if(0)
+ // expected-warning@+1 {{comparison of distinct pointer types ('int (*)[n]' and 'int **')}}
+ if (p == &a) {
+ }
+}
+
+// CHECK: define internal void [[OUTLINED]](i32* {{[^,]+}}, i32* {{[^,]+}}, i64 {{[^,]+}}, i32** {{[^,]+}}, i32** {{[^,]+}})
diff --git a/test/PCH/case-insensitive-include.c b/test/PCH/case-insensitive-include.c
index 1dcda273c2f2..c721225397ce 100644
--- a/test/PCH/case-insensitive-include.c
+++ b/test/PCH/case-insensitive-include.c
@@ -1,18 +1,19 @@
// REQUIRES: case-insensitive-filesystem
// Test this without pch.
-// RUN: cp %S/Inputs/case-insensitive-include.h %T
-// RUN: %clang_cc1 -Wno-nonportable-include-path -fsyntax-only %s -include %s -I %T -verify
+// RUN: mkdir -p %t-dir
+// RUN: cp %S/Inputs/case-insensitive-include.h %t-dir
+// RUN: %clang_cc1 -Wno-nonportable-include-path -fsyntax-only %s -include %s -I %t-dir -verify
// Test with pch.
-// RUN: %clang_cc1 -emit-pch -o %t.pch %s -I %T
+// RUN: %clang_cc1 -emit-pch -o %t.pch %s -I %t-dir
// Modify inode of the header.
-// RUN: cp %T/case-insensitive-include.h %t.copy
-// RUN: touch -r %T/case-insensitive-include.h %t.copy
-// RUN: mv %t.copy %T/case-insensitive-include.h
+// RUN: cp %t-dir/case-insensitive-include.h %t.copy
+// RUN: touch -r %t-dir/case-insensitive-include.h %t.copy
+// RUN: mv %t.copy %t-dir/case-insensitive-include.h
-// RUN: %clang_cc1 -fsyntax-only %s -include-pch %t.pch -I %T -verify
+// RUN: %clang_cc1 -fsyntax-only %s -include-pch %t.pch -I %t-dir -verify
// expected-no-diagnostics
diff --git a/test/PCH/cxx11-lambdas.mm b/test/PCH/cxx11-lambdas.mm
index 1f568f05e11a..9628d12aa15f 100644
--- a/test/PCH/cxx11-lambdas.mm
+++ b/test/PCH/cxx11-lambdas.mm
@@ -39,7 +39,7 @@ int init_capture(T t) {
}
struct X {
- template <typename T> X(T);
+ template <typename T> X(T) {}
};
struct Y { Y(const X &x = [] {}); };
diff --git a/test/PCH/cxx2a-bitfield-init.cpp b/test/PCH/cxx2a-bitfield-init.cpp
new file mode 100644
index 000000000000..344f3cb9129d
--- /dev/null
+++ b/test/PCH/cxx2a-bitfield-init.cpp
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -std=c++2a -include %s -verify %s
+// RUN: %clang_cc1 -std=c++2a -emit-pch %s -o %t
+// RUN: %clang_cc1 -std=c++2a -include-pch %t -verify %s -DPCH
+
+#ifndef HEADER
+#define HEADER
+
+struct S {
+ unsigned int n : 5 = 49; // expected-warning {{changes value}}
+};
+
+int a;
+template<bool B> struct T {
+ int m : B ? 8 : a = 42;
+};
+
+#else
+
+// expected-error@-5 {{constant expression}} expected-note@-5 {{cannot modify}}
+
+static_assert(S().n == 17);
+static_assert(T<true>().m == 0);
+int q = T<false>().m; // expected-note {{instantiation of}}
+
+#endif
diff --git a/test/PCH/include-timestamp.cpp b/test/PCH/include-timestamp.cpp
index d7d0fab13ac5..36b887aee85f 100644
--- a/test/PCH/include-timestamp.cpp
+++ b/test/PCH/include-timestamp.cpp
@@ -1,23 +1,25 @@
// Test that the timestamp is not included in the produced pch file with
// -fno-pch-timestamp.
+// RUN: mkdir -p %t-dir
+
// Copying files allow for read-only checkouts to run this test.
-// RUN: cp %S/Inputs/pragma-once2-pch.h %T
-// RUN: cp %S/Inputs/pragma-once2.h %T
-// RUN: cp %s %t1.cpp
+// RUN: cp %S/Inputs/pragma-once2-pch.h %t-dir
+// RUN: cp %S/Inputs/pragma-once2.h %t-dir
+// RUN: cp %s %t-dir/1.cpp
// Check timestamp is included by default.
-// RUN: %clang_cc1 -x c++-header -emit-pch -o %t %T/pragma-once2-pch.h
-// RUN: touch -m -a -t 201008011501 %T/pragma-once2.h
-// RUN: not %clang_cc1 -include-pch %t %t1.cpp 2>&1 | FileCheck -check-prefix=CHECK-TIMESTAMP %s
+// RUN: %clang_cc1 -x c++-header -emit-pch -o %t %t-dir/pragma-once2-pch.h
+// RUN: touch -m -a -t 201008011501 %t-dir/pragma-once2.h
+// RUN: not %clang_cc1 -include-pch %t %t-dir/1.cpp 2>&1 | FileCheck -check-prefix=CHECK-TIMESTAMP %s
// Check bitcode output as well.
// RUN: llvm-bcanalyzer -dump %t | FileCheck -check-prefix=CHECK-BITCODE-TIMESTAMP-ON %s
// Check timestamp inclusion is disabled by -fno-pch-timestamp.
-// RUN: %clang_cc1 -x c++-header -emit-pch -o %t %T/pragma-once2-pch.h -fno-pch-timestamp
-// RUN: touch -m -a -t 201008011502 %T/pragma-once2.h
-// RUN: %clang_cc1 -include-pch %t %t1.cpp 2>&1
+// RUN: %clang_cc1 -x c++-header -emit-pch -o %t %t-dir/pragma-once2-pch.h -fno-pch-timestamp
+// RUN: touch -m -a -t 201008011502 %t-dir/pragma-once2.h
+// RUN: %clang_cc1 -include-pch %t %t-dir/1.cpp 2>&1
// Check bitcode output as well.
// RUN: llvm-bcanalyzer -dump %t | FileCheck -check-prefix=CHECK-BITCODE-TIMESTAMP-OFF %s
diff --git a/test/PCH/line-directive-nofilename.c b/test/PCH/line-directive-nofilename.c
new file mode 100644
index 000000000000..0d2bcb78c2a4
--- /dev/null
+++ b/test/PCH/line-directive-nofilename.c
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -emit-pch -o %t %S/line-directive-nofilename.h
+// RUN: not %clang_cc1 -include-pch %t -fsyntax-only %s 2>&1 | FileCheck %s
+
+// This causes an "error: redefinition" diagnostic. The notes will have the
+// locations of the declarations from the PCH file.
+double foo, bar;
+
+// CHECK: line-directive-nofilename.h:42:5: note: previous definition is here
+// CHECK: foobar.h:100:5: note: previous definition is here
diff --git a/test/PCH/line-directive-nofilename.h b/test/PCH/line-directive-nofilename.h
new file mode 100644
index 000000000000..2e2d189de3f0
--- /dev/null
+++ b/test/PCH/line-directive-nofilename.h
@@ -0,0 +1,5 @@
+#line 42
+int foo; // This should appear as at line-directive-nofilename.h:42
+
+#line 100 "foobar.h"
+int bar; // This should appear as at foobar.h:100
diff --git a/test/PCH/pragma-pack.c b/test/PCH/pragma-pack.c
index 47a557002351..7b45e045b39e 100644
--- a/test/PCH/pragma-pack.c
+++ b/test/PCH/pragma-pack.c
@@ -1,21 +1,21 @@
// Test this without pch.
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -include %s -verify -fsyntax-only -DSET
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -include %s -verify -fsyntax-only -DRESET
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -include %s -verify -fsyntax-only -DPUSH
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -include %s -verify -fsyntax-only -DPUSH_POP
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -include %s -verify -fsyntax-only -DPUSH_POP_LABEL
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -include %s -verify -fsyntax-only -Wno-pragma-pack -DSET
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -include %s -verify -fsyntax-only -Wno-pragma-pack -DRESET
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -include %s -verify -fsyntax-only -Wno-pragma-pack -DPUSH
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -include %s -verify -fsyntax-only -Wno-pragma-pack -DPUSH_POP
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -include %s -verify -fsyntax-only -Wno-pragma-pack -DPUSH_POP_LABEL
// Test with pch.
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -DSET -emit-pch -o %t
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -DSET -verify -include-pch %t
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -DRESET -emit-pch -o %t
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -DRESET -verify -include-pch %t
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -DPUSH -emit-pch -o %t
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -DPUSH -verify -include-pch %t
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -DPUSH_POP -emit-pch -o %t
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -DPUSH_POP -verify -include-pch %t
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -DPUSH_POP_LABEL -emit-pch -o %t
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -DPUSH_POP_LABEL -verify -include-pch %t
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -Wno-pragma-pack -DSET -emit-pch -o %t
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -Wno-pragma-pack -DSET -verify -include-pch %t
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -Wno-pragma-pack -DRESET -emit-pch -o %t
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -Wno-pragma-pack -DRESET -verify -include-pch %t
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -Wno-pragma-pack -DPUSH -emit-pch -o %t
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -Wno-pragma-pack -DPUSH -verify -include-pch %t
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -Wno-pragma-pack -DPUSH_POP -emit-pch -o %t
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -Wno-pragma-pack -DPUSH_POP -verify -include-pch %t
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -Wno-pragma-pack -DPUSH_POP_LABEL -emit-pch -o %t
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -Wno-pragma-pack -DPUSH_POP_LABEL -verify -include-pch %t
#ifndef HEADER
#define HEADER
diff --git a/test/PCH/suspicious-pragma-pack.c b/test/PCH/suspicious-pragma-pack.c
new file mode 100644
index 000000000000..ac48ad3a8931
--- /dev/null
+++ b/test/PCH/suspicious-pragma-pack.c
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -verify -emit-pch -o %t
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -verify -include-pch %t
+
+#ifndef HEADER
+#define HEADER
+#pragma pack (push, 1)
+#else
+#pragma pack (2)
+#endif
+// expected-warning@-4 {{unterminated '#pragma pack (push, ...)' at end of file}}
diff --git a/test/Parser/MicrosoftExtensions.cpp b/test/Parser/MicrosoftExtensions.cpp
index c796eded1f0d..21635f0ee12f 100644
--- a/test/Parser/MicrosoftExtensions.cpp
+++ b/test/Parser/MicrosoftExtensions.cpp
@@ -51,7 +51,7 @@ struct __declspec(uuid("0000000-0000-0000-Z234-000000000047")) uuid_attr_bad4 {
struct __declspec(uuid("000000000000-0000-1234-000000000047")) uuid_attr_bad5 { };// expected-error {{uuid attribute contains a malformed GUID}}
[uuid("000000000000-0000-1234-000000000047")] struct uuid_attr_bad6 { };// expected-error {{uuid attribute contains a malformed GUID}}
-__declspec(uuid("000000A0-0000-0000-C000-000000000046")) int i; // expected-warning {{'uuid' attribute only applies to classes}}
+__declspec(uuid("000000A0-0000-0000-C000-000000000046")) int i; // expected-warning {{'uuid' attribute only applies to structs, unions, classes, and enums}}
struct __declspec(uuid("000000A0-0000-0000-C000-000000000046"))
struct_with_uuid { };
@@ -69,7 +69,7 @@ enum __declspec(uuid("000000A0-0000-0000-C000-000000000046"))
enum_with_uuid { };
enum enum_without_uuid { };
-int __declspec(uuid("000000A0-0000-0000-C000-000000000046")) inappropriate_uuid; // expected-warning {{'uuid' attribute only applies to classes and enumerations}}
+int __declspec(uuid("000000A0-0000-0000-C000-000000000046")) inappropriate_uuid; // expected-warning {{'uuid' attribute only applies to}}
int uuid_sema_test()
{
diff --git a/test/Parser/arm-windows-calling-convention-handling.c b/test/Parser/arm-windows-calling-convention-handling.c
index ee25e601931f..13669b196394 100644
--- a/test/Parser/arm-windows-calling-convention-handling.c
+++ b/test/Parser/arm-windows-calling-convention-handling.c
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -triple thumbv7-windows -fms-compatibility -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple aarch64-windows -fms-compatibility -fsyntax-only -verify %s
int __cdecl cdecl(int a, int b, int c, int d) { // expected-no-diagnostics
return a + b + c + d;
diff --git a/test/Parser/builtin_types_compatible.c b/test/Parser/builtin_types_compatible.c
index ac81e7b08dc9..d967a7023a49 100644
--- a/test/Parser/builtin_types_compatible.c
+++ b/test/Parser/builtin_types_compatible.c
@@ -41,3 +41,20 @@ static void test()
}
+enum E1 { E1Foo };
+enum E2 { E2Foo };
+
+static void testGccCompatibility() {
+ _Static_assert(__builtin_types_compatible_p(const volatile int, int), "");
+ _Static_assert(__builtin_types_compatible_p(int[5], int[]), "");
+ _Static_assert(!__builtin_types_compatible_p(int[5], int[4]), "");
+ _Static_assert(!__builtin_types_compatible_p(int *, int **), "");
+ _Static_assert(!__builtin_types_compatible_p(const int *, int *), "");
+ _Static_assert(!__builtin_types_compatible_p(enum E1, enum E2), "");
+
+ // GCC's __builtin_types_compatible_p ignores qualifiers on arrays.
+ _Static_assert(__builtin_types_compatible_p(const int[4], int[4]), "");
+ _Static_assert(__builtin_types_compatible_p(int[4], const int[4]), "");
+ _Static_assert(__builtin_types_compatible_p(const int[5][4], int[][4]), "");
+ _Static_assert(!__builtin_types_compatible_p(const int(*)[], int(*)[]), "");
+}
diff --git a/test/Parser/c2x-attributes.c b/test/Parser/c2x-attributes.c
new file mode 100644
index 000000000000..1be69f1ca28c
--- /dev/null
+++ b/test/Parser/c2x-attributes.c
@@ -0,0 +1,122 @@
+// RUN: %clang_cc1 -fsyntax-only -fdouble-square-bracket-attributes -verify %s
+
+enum [[]] E {
+ One [[]],
+ Two,
+ Three [[]]
+};
+
+enum [[]] { Four };
+[[]] enum E2 { Five }; // expected-error {{an attribute list cannot appear here}}
+
+// FIXME: this diagnostic can be improved.
+enum { [[]] Six }; // expected-error {{expected identifier}}
+
+// FIXME: this diagnostic can be improved.
+enum E3 [[]] { Seven }; // expected-error {{expected identifier or '('}}
+
+struct [[]] S1 {
+ int i [[]];
+ int [[]] j;
+ int k[10] [[]];
+ int l[[]][10];
+ [[]] int m, n;
+ int o [[]] : 12;
+};
+
+[[]] struct S2 { int a; }; // expected-error {{an attribute list cannot appear here}}
+struct S3 [[]] { int a; }; // expected-error {{an attribute list cannot appear here}}
+
+union [[]] U {
+ double d [[]];
+ [[]] int i;
+};
+
+[[]] union U2 { double d; }; // expected-error {{an attribute list cannot appear here}}
+union U3 [[]] { double d; }; // expected-error {{an attribute list cannot appear here}}
+
+struct [[]] IncompleteStruct;
+union [[]] IncompleteUnion;
+enum [[]] IncompleteEnum;
+enum __attribute__((deprecated)) IncompleteEnum2;
+
+[[]] void f1(void);
+void [[]] f2(void);
+void f3 [[]] (void);
+void f4(void) [[]];
+
+void f5(int i [[]], [[]] int j, int [[]] k);
+
+void f6(a, b) [[]] int a; int b; { // expected-error {{an attribute list cannot appear here}}
+}
+
+// FIXME: technically, an attribute list cannot appear here, but we currently
+// parse it as part of the return type of the function, which is reasonable
+// behavior given that we *don't* want to parse it as part of the K&R parameter
+// declarations. It is disallowed to avoid a parsing ambiguity we already
+// handle well.
+int (*f7(a, b))(int, int) [[]] int a; int b; {
+ return 0;
+}
+
+[[]] int a, b;
+int c [[]], d [[]];
+
+void f8(void) [[]] {
+ [[]] int i, j;
+ int k, l [[]];
+}
+
+[[]] void f9(void) {
+ int i[10] [[]];
+ int (*fp1)(void)[[]];
+ int (*fp2 [[]])(void);
+
+ int * [[]] *ipp;
+}
+
+void f10(int j[static 10] [[]], int k[*] [[]]);
+
+void f11(void) {
+ [[]] {}
+ [[]] if (1) {}
+
+ [[]] switch (1) {
+ [[]] case 1: [[]] break;
+ [[]] default: break;
+ }
+
+ goto foo;
+ [[]] foo: (void)1;
+
+ [[]] for (;;);
+ [[]] while (1);
+ [[]] do [[]] { } while(1);
+
+ [[]] (void)1;
+
+ [[]];
+
+ (void)sizeof(int [4][[]]);
+ (void)sizeof(struct [[]] S3 { int a [[]]; });
+
+ [[]] return;
+}
+
+[[attr]] void f12(void); // expected-warning {{unknown attribute 'attr' ignored}}
+[[vendor::attr]] void f13(void); // expected-warning {{unknown attribute 'attr' ignored}}
+
+// Ensure that asm statements properly handle double colons.
+void test_asm(void) {
+ asm("ret" :::);
+ asm("foo" :: "r" (xx)); // expected-error {{use of undeclared identifier 'xx'}}
+}
+
+// Do not allow 'using' to introduce vendor attribute namespaces.
+[[using vendor: attr1, attr2]] void f14(void); // expected-error {{expected ']'}} \
+ // expected-warning {{unknown attribute 'vendor' ignored}} \
+ // expected-warning {{unknown attribute 'using' ignored}}
+
+struct [[]] S4 *s; // expected-error {{an attribute list cannot appear here}}
+struct S5 {};
+int c = sizeof(struct [[]] S5); // expected-error {{an attribute list cannot appear here}}
diff --git a/test/Parser/c2x-attributes.m b/test/Parser/c2x-attributes.m
new file mode 100644
index 000000000000..f4610416cddc
--- /dev/null
+++ b/test/Parser/c2x-attributes.m
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -fsyntax-only -fdouble-square-bracket-attributes -verify %s
+// expected-no-diagnostics
+
+enum __attribute__((deprecated)) E1 : int; // ok
+enum [[deprecated]] E2 : int;
+
+@interface Base
+@end
+
+@interface S : Base
+- (void) bar;
+@end
+
+@interface T : Base
+- (S *) foo;
+@end
+
+
+void f(T *t) {
+ [[]][[t foo] bar];
+}
diff --git a/test/Parser/cxx-bool.cpp b/test/Parser/cxx-bool.cpp
index a8a161edb105..21591d10e906 100644
--- a/test/Parser/cxx-bool.cpp
+++ b/test/Parser/cxx-bool.cpp
@@ -1,4 +1,11 @@
-// RUN: %clang_cc1 -fsyntax-only %s
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// expected-no-diagnostics
bool a = true;
bool b = false;
+
+namespace pr34273 {
+ char c = "clang"[true];
+ char d = true["clang"];
+}
+
diff --git a/test/Parser/cxx-concept-declaration.cpp b/test/Parser/cxx-concept-declaration.cpp
index fad5975e4a96..2e9d1ac2fc38 100644
--- a/test/Parser/cxx-concept-declaration.cpp
+++ b/test/Parser/cxx-concept-declaration.cpp
@@ -1,28 +1,7 @@
-// Support parsing of function concepts and variable concepts
+// Support parsing of concepts
+// Disabled for now.
+// expected-no-diagnostics
// RUN: %clang_cc1 -std=c++14 -fconcepts-ts -x c++ -verify %s
-
-template<typename T> concept bool C1 = true;
-
-template<typename T> concept bool C2() { return true; }
-
-template<typename T>
-struct A { typedef bool Boolean; };
-
-template<int N>
-A<void>::Boolean concept C3(!0);
-
-template<typename T, int = 0>
-concept auto C4(void) -> bool { return true; }
-
-constexpr int One = 1;
-
-template <typename>
-static concept decltype(!0) C5 { bool(One) };
-
-template<typename T> concept concept bool C6 = true; // expected-warning {{duplicate 'concept' declaration specifier}}
-
-template<typename T> concept concept bool C7() { return true; } // expected-warning {{duplicate 'concept' declaration specifier}}
-
-template<concept T> concept bool D1 = true; // expected-error {{unknown type name 'T'}}
+// template<typename T> concept C1 = true;
diff --git a/test/Parser/cxx0x-attributes.cpp b/test/Parser/cxx0x-attributes.cpp
index 5db06bd3f2a3..4e3a2e4685e6 100644
--- a/test/Parser/cxx0x-attributes.cpp
+++ b/test/Parser/cxx0x-attributes.cpp
@@ -127,7 +127,7 @@ extern "C++" [[]] { } // expected-error {{an attribute list cannot appear here}}
[[]] using ns::i; // expected-error {{an attribute list cannot appear here}}
[[unknown]] using namespace ns; // expected-warning {{unknown attribute 'unknown' ignored}}
[[noreturn]] using namespace ns; // expected-error {{'noreturn' attribute only applies to functions}}
-namespace [[]] ns2 {} // expected-warning {{attributes on a namespace declaration are incompatible with C++ standards before C++17}}
+namespace [[]] ns2 {} // expected-warning {{attributes on a namespace declaration are a C++17 extension}}
using [[]] alignas(4) [[]] ns::i; // expected-error {{an attribute list cannot appear here}}
using [[]] alignas(4) [[]] foobar = int; // expected-error {{an attribute list cannot appear here}} expected-error {{'alignas' attribute only applies to}}
@@ -179,7 +179,7 @@ enum [[]] E2; // expected-error {{forbids forward references}}
enum [[]] E1;
enum [[]] E3 : int;
enum [[]] {
- k_123 [[]] = 123 // expected-warning {{attributes on an enumerator declaration are incompatible with C++ standards before C++17}}
+ k_123 [[]] = 123 // expected-warning {{attributes on an enumerator declaration are a C++17 extension}}
};
enum [[]] E1 e; // expected-error {{an attribute list cannot appear here}}
enum [[]] class E4 { }; // expected-error {{an attribute list cannot appear here}}
@@ -307,7 +307,7 @@ int v5()[[gnu::unused]]; // expected-warning {{attribute 'unused' ignored}}
[[attribute_declaration]]; // expected-warning {{unknown attribute 'attribute_declaration' ignored}}
[[noreturn]]; // expected-error {{'noreturn' attribute only applies to functions}}
-[[carries_dependency]]; // expected-error {{'carries_dependency' attribute only applies to functions, methods, and parameters}}
+[[carries_dependency]]; // expected-error {{'carries_dependency' attribute only applies to parameters, Objective-C methods, and functions}}
class A {
A([[gnu::unused]] int a);
diff --git a/test/Parser/cxx0x-condition.cpp b/test/Parser/cxx0x-condition.cpp
index 071e09e4158f..19d5a7395d41 100644
--- a/test/Parser/cxx0x-condition.cpp
+++ b/test/Parser/cxx0x-condition.cpp
@@ -14,11 +14,11 @@ void f() {
for (; int x = ++a; ) ;
if (S(a)) {} // ok
- if (S(a) = 0) {} // ok
+ if (S(a) = 0) {} // expected-warning {{redundant parentheses}} expected-note 2{{}}
if (S(a) == 0) {} // ok
if (S(n)) {} // expected-error {{unexpected type name 'n': expected expression}}
- if (S(n) = 0) {} // ok
+ if (S(n) = 0) {} // expected-warning {{redundant parentheses}} expected-note 2{{}}
if (S(n) == 0) {} // expected-error {{unexpected type name 'n': expected expression}}
if (S b(a)) {} // expected-error {{variable declaration in condition cannot have a parenthesized initializer}}
diff --git a/test/Parser/cxx1z-class-template-argument-deduction.cpp b/test/Parser/cxx1z-class-template-argument-deduction.cpp
index dac17dfbf480..b8f5a82d461b 100644
--- a/test/Parser/cxx1z-class-template-argument-deduction.cpp
+++ b/test/Parser/cxx1z-class-template-argument-deduction.cpp
@@ -180,6 +180,7 @@ namespace typename_specifier {
{(void)(typename T::A)(0);} // expected-error{{refers to class template member}}
{(void)(typename T::A){0};} // expected-error{{refers to class template member}}
{typename T::A (parens) = 0;} // expected-error {{refers to class template member in 'typename_specifier::X'; argument deduction not allowed here}}
+ // expected-warning@-1 {{disambiguated as redundant parentheses around declaration of variable named 'parens'}} expected-note@-1 {{add a variable name}} expected-note@-1{{remove parentheses}} expected-note@-1 {{add enclosing parentheses}}
{typename T::A *p = 0;} // expected-error {{refers to class template member}}
{typename T::A &r = *p;} // expected-error {{refers to class template member}}
{typename T::A arr[3] = 0;} // expected-error {{refers to class template member}}
diff --git a/test/Parser/cxx1z-decomposition.cpp b/test/Parser/cxx1z-decomposition.cpp
index 9cbe70e3c69b..cf4ba77723ad 100644
--- a/test/Parser/cxx1z-decomposition.cpp
+++ b/test/Parser/cxx1z-decomposition.cpp
@@ -32,13 +32,14 @@ namespace OtherDecl {
void f(auto [a, b, c]); // expected-error {{'auto' not allowed in function prototype}} expected-error {{'a'}}
void g() {
- // A condition is not a simple-declaration.
- for (; auto [a, b, c] = S(); ) {} // expected-error {{not permitted in this context}}
- if (auto [a, b, c] = S()) {} // expected-error {{not permitted in this context}}
- if (int n; auto [a, b, c] = S()) {} // expected-error {{not permitted in this context}}
- switch (auto [a, b, c] = S()) {} // expected-error {{not permitted in this context}}
- switch (int n; auto [a, b, c] = S()) {} // expected-error {{not permitted in this context}}
- while (auto [a, b, c] = S()) {} // expected-error {{not permitted in this context}}
+ // A condition is allowed as a Clang extension.
+ // See commentary in test/Parser/decomposed-condition.cpp
+ for (; auto [a, b, c] = S(); ) {} // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}} expected-error {{value of type 'S' is not contextually convertible to 'bool'}}
+ if (auto [a, b, c] = S()) {} // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}} expected-error {{value of type 'S' is not contextually convertible to 'bool'}}
+ if (int n; auto [a, b, c] = S()) {} // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}} expected-error {{value of type 'S' is not contextually convertible to 'bool'}}
+ switch (auto [a, b, c] = S()) {} // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}} expected-error {{statement requires expression of integer type ('S' invalid)}}
+ switch (int n; auto [a, b, c] = S()) {} // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}} expected-error {{statement requires expression of integer type ('S' invalid)}}
+ while (auto [a, b, c] = S()) {} // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}} expected-error {{value of type 'S' is not contextually convertible to 'bool'}}
// An exception-declaration is not a simple-declaration.
try {}
diff --git a/test/Parser/cxx1z-fold-expressions.cpp b/test/Parser/cxx1z-fold-expressions.cpp
index b1f7318e410d..342f11555fa7 100644
--- a/test/Parser/cxx1z-fold-expressions.cpp
+++ b/test/Parser/cxx1z-fold-expressions.cpp
@@ -43,3 +43,20 @@ template<typename ...T> void as_operand_of_cast(int a, T ...t) {
(int)(undeclared_junk + ...) + // expected-error {{undeclared}}
(int)(a + ...); // expected-error {{does not contain any unexpanded}}
}
+
+// fold-operator can be '>' or '>>'.
+template <int... N> constexpr bool greaterThan() { return (N > ...); }
+template <int... N> constexpr int rightShift() { return (N >> ...); }
+
+static_assert(greaterThan<2, 1>());
+static_assert(rightShift<10, 1>() == 5);
+
+template <auto V> constexpr auto Identity = V;
+
+// Support fold operators within templates.
+template <int... N> constexpr int nestedFoldOperator() {
+ return Identity<(Identity<0> >> ... >> N)> +
+ Identity<(N >> ... >> Identity<0>)>;
+}
+
+static_assert(nestedFoldOperator<3, 1>() == 1);
diff --git a/test/Parser/cxx1z-nested-namespace-definition.cpp b/test/Parser/cxx1z-nested-namespace-definition.cpp
index e5e809aa0366..e0c5244a3734 100644
--- a/test/Parser/cxx1z-nested-namespace-definition.cpp
+++ b/test/Parser/cxx1z-nested-namespace-definition.cpp
@@ -1,5 +1,5 @@
// RUN: cp %s %t
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++98
// RUN: not %clang_cc1 -x c++ -fixit %t -Werror -DFIXIT
// RUN: %clang_cc1 -x c++ %t -DFIXIT
// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++17 -Wc++14-compat
diff --git a/test/Parser/cxx2a-bitfield-init.cpp b/test/Parser/cxx2a-bitfield-init.cpp
new file mode 100644
index 000000000000..83f1575c96b9
--- /dev/null
+++ b/test/Parser/cxx2a-bitfield-init.cpp
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -std=c++2a -verify %s
+
+namespace std_example {
+ int a;
+ const int b = 0; // expected-note {{here}}
+ struct S {
+ int x1 : 8 = 42;
+ int x2 : 8 { 42 };
+ int y1 : true ? 8 : a = 42;
+ int y3 : (true ? 8 : b) = 42;
+ int z : 1 || new int { 1 };
+ };
+ static_assert(S{}.x1 == 42);
+ static_assert(S{}.x2 == 42);
+ static_assert(S{}.y1 == 0);
+ static_assert(S{}.y3 == 42);
+ static_assert(S{}.z == 0);
+
+ struct T {
+ int y2 : true ? 8 : b = 42; // expected-error {{cannot assign to variable 'b'}}
+ };
+}
diff --git a/test/Parser/cxx2a-spaceship.cpp b/test/Parser/cxx2a-spaceship.cpp
new file mode 100644
index 000000000000..24cece3eaa9d
--- /dev/null
+++ b/test/Parser/cxx2a-spaceship.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -std=c++2a -verify %s
+
+template<int> struct X {};
+
+X<1> operator<<(X<0>, X<0>);
+X<2> operator<=>(X<0>, X<1>);
+X<2> operator<=>(X<1>, X<0>);
+X<3> operator<(X<0>, X<2>);
+X<3> operator<(X<2>, X<0>);
+
+void f(X<0> x0, X<1> x1) {
+ X<2> a = x0 <=> x0 << x0;
+ X<2> b = x0 << x0 <=> x0; // expected-warning {{overloaded operator << has higher precedence than comparison operator}} expected-note 2{{}}
+ X<3> c = x0 < x0 <=> x1;
+ X<3> d = x1 <=> x0 < x0;
+ X<3> e = x0 < x0 <=> x0 << x0;
+ X<3> f = x0 << x0 <=> x0 < x0; // expected-warning {{overloaded operator << has higher precedence than comparison operator}} expected-note 2{{}}
+}
diff --git a/test/Parser/decomposed-condition.cpp b/test/Parser/decomposed-condition.cpp
new file mode 100644
index 000000000000..c41c82292e8d
--- /dev/null
+++ b/test/Parser/decomposed-condition.cpp
@@ -0,0 +1,61 @@
+// RUN: %clang_cc1 -std=c++1z %s -verify
+
+struct Na {
+ bool flag;
+ float data;
+};
+
+struct Rst {
+ bool flag;
+ float data;
+ explicit operator bool() const {
+ return flag;
+ }
+};
+
+Rst f();
+Na g();
+
+namespace CondInIf {
+void h() {
+ if (auto [ok, d] = f()) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}}
+ ;
+ if (auto [ok, d] = g()) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}} expected-error {{value of type 'Na' is not contextually convertible to 'bool'}}
+ ;
+}
+} // namespace CondInIf
+
+namespace CondInWhile {
+void h() {
+ while (auto [ok, d] = f()) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}}
+ ;
+ while (auto [ok, d] = g()) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}} expected-error {{value of type 'Na' is not contextually convertible to 'bool'}}
+ ;
+}
+} // namespace CondInWhile
+
+namespace CondInFor {
+void h() {
+ for (; auto [ok, d] = f();) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}}
+ ;
+ for (; auto [ok, d] = g();) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}} expected-error {{value of type 'Na' is not contextually convertible to 'bool'}}
+ ;
+}
+} // namespace CondInFor
+
+struct IntegerLike {
+ bool flag;
+ float data;
+ operator int() const {
+ return int(data);
+ }
+};
+
+namespace CondInSwitch {
+void h(IntegerLike x) {
+ switch (auto [ok, d] = x) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}}
+ ;
+ switch (auto [ok, d] = g()) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}} expected-error {{statement requires expression of integer type ('Na' invalid)}}
+ ;
+}
+} // namespace CondInSwitch
diff --git a/test/Parser/editor-placeholder-recovery.cpp b/test/Parser/editor-placeholder-recovery.cpp
index 48c290ee9a14..d68e087d6fba 100644
--- a/test/Parser/editor-placeholder-recovery.cpp
+++ b/test/Parser/editor-placeholder-recovery.cpp
@@ -69,3 +69,7 @@ void Struct::method(<#Struct &x#>, noSupressionHere) { // expected-error {{unkno
// expected-error@-2 {{editor placeholder in source file}}
#endif
}
+
+void handleTrigraph() {
+ <??=placeholder#> // expected-error {{expected expression}} expected-error {{expected expression}} expected-warning {{trigraph converted to '#' character}}
+}
diff --git a/test/Parser/ms-square-bracket-attributes.mm b/test/Parser/ms-square-bracket-attributes.mm
index a158cf7b2b90..c1fc14cec563 100644
--- a/test/Parser/ms-square-bracket-attributes.mm
+++ b/test/Parser/ms-square-bracket-attributes.mm
@@ -133,7 +133,7 @@ void use_it() {
(void)__uuidof(OuterClass::sic);
}
-// expected-warning@+1 {{'uuid' attribute only applies to classes}}
+// expected-warning@+1 {{'uuid' attribute only applies to structs, unions, classes, and enums}}
[uuid("000000A0-0000-0000-C000-000000000049")] void f();
}
diff --git a/test/Parser/objcxx11-invalid-lambda.cpp b/test/Parser/objcxx11-invalid-lambda.cpp
new file mode 100644
index 000000000000..74c5636b6a07
--- /dev/null
+++ b/test/Parser/objcxx11-invalid-lambda.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -x objective-c++ -std=c++11 %s
+
+void foo() { // expected-note {{to match this '{'}}
+ int bar;
+ auto baz = [
+ bar( // expected-note {{to match this '('}} expected-note {{to match this '('}}
+ foo_undeclared() // expected-error{{use of undeclared identifier 'foo_undeclared'}} expected-error{{use of undeclared identifier 'foo_undeclared'}}
+ /* ) */
+ ] () { }; // expected-error{{expected ')'}}
+} // expected-error{{expected ')'}} expected-error{{expected ';' at end of declaration}} expected-error{{expected '}'}}
diff --git a/test/Parser/pragma-options.c b/test/Parser/pragma-options.c
index d168a2751a27..a35f0b087eb6 100644
--- a/test/Parser/pragma-options.c
+++ b/test/Parser/pragma-options.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple i386-apple-darwin9 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -Wno-pragma-pack -fsyntax-only -verify %s
/* expected-warning {{expected 'align' following '#pragma options'}} */ #pragma options
/* expected-warning {{expected '=' following '#pragma options align'}} */ #pragma options align
diff --git a/test/Parser/pragma-options.cpp b/test/Parser/pragma-options.cpp
index 84cd38dfb3cd..8f5a2152c7b1 100644
--- a/test/Parser/pragma-options.cpp
+++ b/test/Parser/pragma-options.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple i386-apple-darwin9 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -Wno-pragma-pack -fsyntax-only -verify %s
// expected-no-diagnostics
class C {
diff --git a/test/Parser/pragma-pack.c b/test/Parser/pragma-pack.c
index 0859f4157ce3..d2aefaa888f4 100644
--- a/test/Parser/pragma-pack.c
+++ b/test/Parser/pragma-pack.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -Wno-pragma-pack -verify %s
// Note that this puts the expected lines before the directives to work around
// limitations in the -verify mode.
diff --git a/test/Preprocessor/arm-target-features.c b/test/Preprocessor/arm-target-features.c
index b206e1cf36fd..0067e108d338 100644
--- a/test/Preprocessor/arm-target-features.c
+++ b/test/Preprocessor/arm-target-features.c
@@ -214,6 +214,7 @@
// A5:#define __ARM_ARCH_7A__ 1
// A5-NOT:#define __ARM_ARCH_EXT_IDIV__
// A5:#define __ARM_ARCH_PROFILE 'A'
+// A5-NOT:#define __ARM_DWARF_EH__ 1
// A5-NOT: #define __ARM_FEATURE_DIRECTED_ROUNDING
// A5:#define __ARM_FEATURE_DSP 1
// A5-NOT: #define __ARM_FEATURE_NUMERIC_MAXMIN
@@ -225,6 +226,7 @@
// A7:#define __ARM_ARCH 7
// A7:#define __ARM_ARCH_EXT_IDIV__ 1
// A7:#define __ARM_ARCH_PROFILE 'A'
+// A7-NOT:#define __ARM_DWARF_EH__ 1
// A7:#define __ARM_FEATURE_DSP 1
// A7:#define __ARM_FP 0xE
diff --git a/test/Preprocessor/c17.c b/test/Preprocessor/c17.c
new file mode 100644
index 000000000000..c610e84f9830
--- /dev/null
+++ b/test/Preprocessor/c17.c
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c17 %s
+// expected-no-diagnostics
+
+_Static_assert(__STDC_VERSION__ == 201710L, "Incorrect __STDC_VERSION__");
diff --git a/test/Preprocessor/cuda-types.cu b/test/Preprocessor/cuda-types.cu
index 5f7b91655cdf..9e96f6a15e6e 100644
--- a/test/Preprocessor/cuda-types.cu
+++ b/test/Preprocessor/cuda-types.cu
@@ -5,42 +5,44 @@
// FIXME: We really should make __GCC_HAVE_SYNC_COMPARE_AND_SWAP identical on
// host and device, but architecturally this is difficult at the moment.
+// RUN: mkdir -p %t
+
// RUN: %clang --cuda-host-only -nocudainc -target i386-unknown-linux-gnu -x cuda -E -dM -o - /dev/null \
// RUN: | grep 'define __[^ ]*\(TYPE\|MAX\|SIZEOF|WIDTH\)\|define __GCC_ATOMIC' \
-// RUN: | grep -v '__LDBL\|_LONG_DOUBLE' > %T/i386-host-defines-filtered
+// RUN: | grep -v '__FLT128\|__LDBL\|_LONG_DOUBLE' > %t/i386-host-defines-filtered
// RUN: %clang --cuda-device-only -nocudainc -nocudalib -target i386-unknown-linux-gnu -x cuda -E -dM -o - /dev/null \
// RUN: | grep 'define __[^ ]*\(TYPE\|MAX\|SIZEOF|WIDTH\)\|define __GCC_ATOMIC' \
-// RUN: | grep -v '__LDBL\|_LONG_DOUBLE' > %T/i386-device-defines-filtered
-// RUN: diff %T/i386-host-defines-filtered %T/i386-device-defines-filtered
+// RUN: | grep -v '__FLT128\|__LDBL\|_LONG_DOUBLE' > %t/i386-device-defines-filtered
+// RUN: diff %t/i386-host-defines-filtered %t/i386-device-defines-filtered
// RUN: %clang --cuda-host-only -nocudainc -target x86_64-unknown-linux-gnu -x cuda -E -dM -o - /dev/null \
// RUN: | grep 'define __[^ ]*\(TYPE\|MAX\|SIZEOF|WIDTH\)\|define __GCC_ATOMIC' \
-// RUN: | grep -v '__LDBL\|_LONG_DOUBLE' > %T/x86_64-host-defines-filtered
+// RUN: | grep -v '__FLT128\|__LDBL\|_LONG_DOUBLE' > %t/x86_64-host-defines-filtered
// RUN: %clang --cuda-device-only -nocudainc -nocudalib -target x86_64-unknown-linux-gnu -x cuda -E -dM -o - /dev/null \
// RUN: | grep 'define __[^ ]*\(TYPE\|MAX\|SIZEOF|WIDTH\)\|define __GCC_ATOMIC' \
-// RUN: | grep -v '__LDBL\|_LONG_DOUBLE' > %T/x86_64-device-defines-filtered
-// RUN: diff %T/x86_64-host-defines-filtered %T/x86_64-device-defines-filtered
+// RUN: | grep -v '__FLT128\|__LDBL\|_LONG_DOUBLE' > %t/x86_64-device-defines-filtered
+// RUN: diff %t/x86_64-host-defines-filtered %t/x86_64-device-defines-filtered
// RUN: %clang --cuda-host-only -nocudainc -target powerpc64-unknown-linux-gnu -x cuda -E -dM -o - /dev/null \
// RUN: | grep 'define __[^ ]*\(TYPE\|MAX\|SIZEOF|WIDTH\)\|define __GCC_ATOMIC' \
-// RUN: | grep -v '__LDBL\|_LONG_DOUBLE' > %T/powerpc64-host-defines-filtered
+// RUN: | grep -v '__FLT128\|__LDBL\|_LONG_DOUBLE' > %t/powerpc64-host-defines-filtered
// RUN: %clang --cuda-device-only -nocudainc -nocudalib -target powerpc64-unknown-linux-gnu -x cuda -E -dM -o - /dev/null \
// RUN: | grep 'define __[^ ]*\(TYPE\|MAX\|SIZEOF|WIDTH\)\|define __GCC_ATOMIC' \
-// RUN: | grep -v '__LDBL\|_LONG_DOUBLE' > %T/powerpc64-device-defines-filtered
-// RUN: diff %T/powerpc64-host-defines-filtered %T/powerpc64-device-defines-filtered
+// RUN: | grep -v '__FLT128\|__LDBL\|_LONG_DOUBLE' > %t/powerpc64-device-defines-filtered
+// RUN: diff %t/powerpc64-host-defines-filtered %t/powerpc64-device-defines-filtered
// RUN: %clang --cuda-host-only -nocudainc -target i386-windows-msvc -x cuda -E -dM -o - /dev/null \
// RUN: | grep 'define __[^ ]*\(TYPE\|MAX\|SIZEOF|WIDTH\)\|define __GCC_ATOMIC' \
-// RUN: | grep -v '__LDBL\|_LONG_DOUBLE' > %T/i386-msvc-host-defines-filtered
+// RUN: | grep -v '__FLT128\|__LDBL\|_LONG_DOUBLE' > %t/i386-msvc-host-defines-filtered
// RUN: %clang --cuda-device-only -nocudainc -nocudalib -target i386-windows-msvc -x cuda -E -dM -o - /dev/null \
// RUN: | grep 'define __[^ ]*\(TYPE\|MAX\|SIZEOF|WIDTH\)\|define __GCC_ATOMIC' \
-// RUN: | grep -v '__LDBL\|_LONG_DOUBLE' > %T/i386-msvc-device-defines-filtered
-// RUN: diff %T/i386-msvc-host-defines-filtered %T/i386-msvc-device-defines-filtered
+// RUN: | grep -v '__FLT128\|__LDBL\|_LONG_DOUBLE' > %t/i386-msvc-device-defines-filtered
+// RUN: diff %t/i386-msvc-host-defines-filtered %t/i386-msvc-device-defines-filtered
// RUN: %clang --cuda-host-only -nocudainc -target x86_64-windows-msvc -x cuda -E -dM -o - /dev/null \
// RUN: | grep 'define __[^ ]*\(TYPE\|MAX\|SIZEOF|WIDTH\)\|define __GCC_ATOMIC' \
-// RUN: | grep -v '__LDBL\|_LONG_DOUBLE' > %T/x86_64-msvc-host-defines-filtered
+// RUN: | grep -v '__FLT128\|__LDBL\|_LONG_DOUBLE' > %t/x86_64-msvc-host-defines-filtered
// RUN: %clang --cuda-device-only -nocudainc -nocudalib -target x86_64-windows-msvc -x cuda -E -dM -o - /dev/null \
// RUN: | grep 'define __[^ ]*\(TYPE\|MAX\|SIZEOF|WIDTH\)\|define __GCC_ATOMIC' \
-// RUN: | grep -v '__LDBL\|_LONG_DOUBLE' > %T/x86_64-msvc-device-defines-filtered
-// RUN: diff %T/x86_64-msvc-host-defines-filtered %T/x86_64-msvc-device-defines-filtered
+// RUN: | grep -v '__FLT128\|__LDBL\|_LONG_DOUBLE' > %t/x86_64-msvc-device-defines-filtered
+// RUN: diff %t/x86_64-msvc-host-defines-filtered %t/x86_64-msvc-device-defines-filtered
diff --git a/test/Preprocessor/has_c_attribute.c b/test/Preprocessor/has_c_attribute.c
new file mode 100644
index 000000000000..dc22da7e4cd6
--- /dev/null
+++ b/test/Preprocessor/has_c_attribute.c
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -fdouble-square-bracket-attributes -std=c11 -E %s -o - | FileCheck %s
+
+// CHECK: has_fallthrough
+#if __has_c_attribute(fallthrough)
+ int has_fallthrough();
+#endif
+
+// CHECK: does_not_have_selectany
+#if !__has_c_attribute(selectany)
+ int does_not_have_selectany();
+#endif
+
diff --git a/test/Preprocessor/hexagon-predefines.c b/test/Preprocessor/hexagon-predefines.c
index 065ecc069422..fe87262ae635 100644
--- a/test/Preprocessor/hexagon-predefines.c
+++ b/test/Preprocessor/hexagon-predefines.c
@@ -1,32 +1,57 @@
// RUN: %clang_cc1 -E -dM -triple hexagon-unknown-elf -target-cpu hexagonv5 %s | FileCheck %s -check-prefix CHECK-V5
-
// CHECK-V5: #define __HEXAGON_ARCH__ 5
// CHECK-V5: #define __HEXAGON_V5__ 1
+// CHECK-V5-NOT: #define __HVX_LENGTH__
+// CHECK-V5-NOT: #define __HVX__ 1
// CHECK-V5: #define __hexagon__ 1
// RUN: %clang_cc1 -E -dM -triple hexagon-unknown-elf -target-cpu hexagonv55 %s | FileCheck %s -check-prefix CHECK-V55
-
// CHECK-V55: #define __HEXAGON_ARCH__ 55
// CHECK-V55: #define __HEXAGON_V55__ 1
+// CHECK-V55-NOT: #define __HVX_LENGTH__
+// CHECK-V55-NOT: #define __HVX__ 1
// CHECK-V55: #define __hexagon__ 1
// RUN: %clang_cc1 -E -dM -triple hexagon-unknown-elf -target-cpu hexagonv60 %s | FileCheck %s -check-prefix CHECK-V60
-
// CHECK-V60: #define __HEXAGON_ARCH__ 60
// CHECK-V60: #define __HEXAGON_V60__ 1
+// CHECK-V60-NOT: #define __HVX_LENGTH__
+// CHECK-V60-NOT: #define __HVX__ 1
// CHECK-V60: #define __hexagon__ 1
-// RUN: %clang_cc1 -E -dM -triple hexagon-unknown-elf -target-cpu hexagonv60 -target-feature +hvx %s | FileCheck %s -check-prefix CHECK-V60HVX
-
-// CHECK-V60HVX: #define __HEXAGON_ARCH__ 60
-// CHECK-V60HVX: #define __HEXAGON_V60__ 1
-// CHECK-V60HVX: #define __HVX__ 1
-
-// RUN: %clang_cc1 -E -dM -triple hexagon-unknown-elf -target-cpu hexagonv60 -target-feature +hvx-double %s | FileCheck %s -check-prefix CHECK-V60HVXD
-
-// CHECK-V60HVXD: #define __HEXAGON_ARCH__ 60
-// CHECK-V60HVXD: #define __HEXAGON_V60__ 1
-// CHECK-V60HVXD: #define __HVXDBL__ 1
-// CHECK-V60HVXD: #define __HVX__ 1
-// CHECK-V60HVXD: #define __hexagon__ 1
-
+// RUN: %clang_cc1 -E -dM -triple hexagon-unknown-elf -target-cpu hexagonv62 %s | FileCheck %s -check-prefix CHECK-V62
+// CHECK-V62: #define __HEXAGON_ARCH__ 62
+// CHECK-V62: #define __HEXAGON_V62__ 1
+// CHECK-V62-NOT: #define __HVX_LENGTH__
+// CHECK-V62-NOT: #define __HVX__ 1
+// CHECK-V62: #define __hexagon__ 1
+
+// RUN: %clang_cc1 -E -dM -triple hexagon-unknown-elf -target-cpu hexagonv65 %s | FileCheck %s -check-prefix CHECK-V65
+// CHECK-V65: #define __HEXAGON_ARCH__ 65
+// CHECK-V65: #define __HEXAGON_V65__ 1
+// CHECK-V65-NOT: #define __HVX_LENGTH__
+// CHECK-V65-NOT: #define __HVX__ 1
+// CHECK-V65: #define __hexagon__ 1
+
+// The HVX flags are explicitly defined by the driver.
+// RUN: %clang_cc1 -E -dM -triple hexagon-unknown-elf -target-cpu hexagonv60 \
+// RUN: -target-feature +hvxv60 -target-feature +hvx-length64b %s | FileCheck \
+// RUN: %s -check-prefix CHECK-V60HVX-64B
+// CHECK-V60HVX-64B: #define __HEXAGON_ARCH__ 60
+// CHECK-V60HVX-64B: #define __HEXAGON_V60__ 1
+// CHECK-V60HVX-64B-NOT: #define __HVXDBL__ 1
+// CHECK-V60HVX-64B: #define __HVX_ARCH__ 60
+// CHECK-V60HVX-64B: #define __HVX_LENGTH__ 64
+// CHECK-V60HVX-64B: #define __HVX__ 1
+// CHECK-V60HVX-64B: #define __hexagon__ 1
+
+// RUN: %clang_cc1 -E -dM -triple hexagon-unknown-elf -target-cpu hexagonv60 \
+// RUN: -target-feature +hvxv60 -target-feature +hvx-length128b %s | FileCheck \
+// RUN: %s -check-prefix CHECK-V60HVX-128B
+// CHECK-V60HVX-128B: #define __HEXAGON_ARCH__ 60
+// CHECK-V60HVX-128B: #define __HEXAGON_V60__ 1
+// CHECK-V60HVX-128B: #define __HVXDBL__ 1
+// CHECK-V60HVX-128B: #define __HVX_ARCH__ 60
+// CHECK-V60HVX-128B: #define __HVX_LENGTH__ 128
+// CHECK-V60HVX-128B: #define __HVX__ 1
+// CHECK-V60HVX-128B: #define __hexagon__ 1
diff --git a/test/Preprocessor/init.c b/test/Preprocessor/init.c
index 5a77d06d2403..51e1233456b8 100644
--- a/test/Preprocessor/init.c
+++ b/test/Preprocessor/init.c
@@ -253,18 +253,18 @@
// SCHAR-NOT:#define __UNSIGNED_CHAR__
// SCHAR:#define __clang__ 1
//
-// RUN: %clang_cc1 -E -dM -fshort-wchar < /dev/null | FileCheck -match-full-lines -check-prefix SHORTWCHAR %s
+// RUN: %clang_cc1 -E -dM -fwchar-type=short -fno-signed-wchar < /dev/null | FileCheck -match-full-lines -check-prefix SHORTWCHAR %s
// wchar_t is u16 for targeting Win32.
-// FIXME: Implement and check x86_64-cygwin.
-// RUN: %clang_cc1 -E -dM -fno-short-wchar -triple=x86_64-w64-mingw32 < /dev/null | FileCheck -match-full-lines -check-prefix SHORTWCHAR %s
+// RUN: %clang_cc1 -E -dM -fwchar-type=short -fno-signed-wchar -triple=x86_64-w64-mingw32 < /dev/null | FileCheck -match-full-lines -check-prefix SHORTWCHAR %s
+// RUN: %clang_cc1 -dM -fwchar-type=short -fno-signed-wchar -triple=x86_64-unknown-windows-cygnus -E /dev/null | FileCheck -match-full-lines -check-prefix SHORTWCHAR %s
//
// SHORTWCHAR: #define __SIZEOF_WCHAR_T__ 2
// SHORTWCHAR: #define __WCHAR_MAX__ 65535
// SHORTWCHAR: #define __WCHAR_TYPE__ unsigned short
// SHORTWCHAR: #define __WCHAR_WIDTH__ 16
//
-// RUN: %clang_cc1 -E -dM -fno-short-wchar -triple=i686-unknown-unknown < /dev/null | FileCheck -match-full-lines -check-prefix SHORTWCHAR2 %s
-// RUN: %clang_cc1 -E -dM -fno-short-wchar -triple=x86_64-unknown-unknown < /dev/null | FileCheck -match-full-lines -check-prefix SHORTWCHAR2 %s
+// RUN: %clang_cc1 -E -dM -fwchar-type=int -triple=i686-unknown-unknown < /dev/null | FileCheck -match-full-lines -check-prefix SHORTWCHAR2 %s
+// RUN: %clang_cc1 -E -dM -fwchar-type=int -triple=x86_64-unknown-unknown < /dev/null | FileCheck -match-full-lines -check-prefix SHORTWCHAR2 %s
//
// SHORTWCHAR2: #define __SIZEOF_WCHAR_T__ 4
// SHORTWCHAR2: #define __WCHAR_WIDTH__ 32
@@ -301,6 +301,20 @@
// AARCH64:#define __DBL_MIN_EXP__ (-1021)
// AARCH64:#define __DBL_MIN__ 2.2250738585072014e-308
// AARCH64:#define __DECIMAL_DIG__ __LDBL_DECIMAL_DIG__
+// AARCH64:#define __FLT16_DECIMAL_DIG__ 5
+// AARCH64:#define __FLT16_DENORM_MIN__ 5.9604644775390625e-8F16
+// AARCH64:#define __FLT16_DIG__ 3
+// AARCH64:#define __FLT16_EPSILON__ 9.765625e-4F16
+// AARCH64:#define __FLT16_HAS_DENORM__ 1
+// AARCH64:#define __FLT16_HAS_INFINITY__ 1
+// AARCH64:#define __FLT16_HAS_QUIET_NAN__ 1
+// AARCH64:#define __FLT16_MANT_DIG__ 11
+// AARCH64:#define __FLT16_MAX_10_EXP__ 4
+// AARCH64:#define __FLT16_MAX_EXP__ 15
+// AARCH64:#define __FLT16_MAX__ 6.5504e+4F16
+// AARCH64:#define __FLT16_MIN_10_EXP__ (-13)
+// AARCH64:#define __FLT16_MIN_EXP__ (-14)
+// AARCH64:#define __FLT16_MIN__ 6.103515625e-5F16
// AARCH64:#define __FLT_DENORM_MIN__ 1.40129846e-45F
// AARCH64:#define __FLT_DIG__ 6
// AARCH64:#define __FLT_EPSILON__ 1.19209290e-7F
@@ -946,7 +960,7 @@
// AARCH64-OPENBSD:#define __INT_LEAST32_FMTd__ "d"
// AARCH64-OPENBSD:#define __INT_LEAST32_FMTi__ "i"
// AARCH64-OPENBSD:#define __INT_LEAST32_MAX__ 2147483647
-// AARCH64-OPENSD:#define __INT_LEAST32_TYPE__ int
+// AARCH64-OPENBSD:#define __INT_LEAST32_TYPE__ int
// AARCH64-OPENBSD:#define __INT_LEAST64_FMTd__ "ld"
// AARCH64-OPENBSD:#define __INT_LEAST64_FMTi__ "li"
// AARCH64-OPENBSD:#define __INT_LEAST64_MAX__ 9223372036854775807L
@@ -1229,6 +1243,7 @@
// AARCH64-FREEBSD:#define __WCHAR_TYPE__ unsigned int
// AARCH64-FREEBSD:#define __WCHAR_UNSIGNED__ 1
// AARCH64-FREEBSD:#define __WCHAR_WIDTH__ 32
+// AARCH64-FREEBSD:#define __WINT_MAX__ 2147483647
// AARCH64-FREEBSD:#define __WINT_TYPE__ int
// AARCH64-FREEBSD:#define __WINT_WIDTH__ 32
// AARCH64-FREEBSD:#define __aarch64__ 1
@@ -1236,13 +1251,13 @@
// RUN: %clang_cc1 -E -dM -ffreestanding -triple=aarch64-apple-ios7.0 < /dev/null | FileCheck -match-full-lines -check-prefix AARCH64-DARWIN %s
//
// AARCH64-DARWIN: #define _LP64 1
-// AARCH64-NOT: #define __AARCH64EB__ 1
+// AARCH64-DARWIN-NOT: #define __AARCH64EB__ 1
// AARCH64-DARWIN: #define __AARCH64EL__ 1
-// AARCH64-NOT: #define __AARCH_BIG_ENDIAN 1
+// AARCH64-DARWIN-NOT: #define __AARCH_BIG_ENDIAN 1
// AARCH64-DARWIN: #define __ARM_64BIT_STATE 1
// AARCH64-DARWIN: #define __ARM_ARCH 8
// AARCH64-DARWIN: #define __ARM_ARCH_ISA_A64 1
-// AARCH64-NOT: #define __ARM_BIG_ENDIAN 1
+// AARCH64-DARWIN-NOT: #define __ARM_BIG_ENDIAN 1
// AARCH64-DARWIN: #define __BIGGEST_ALIGNMENT__ 8
// AARCH64-DARWIN: #define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
// AARCH64-DARWIN: #define __CHAR16_TYPE__ unsigned short
@@ -1424,6 +1439,173 @@
// AARCH64-DARWIN: #define __WINT_WIDTH__ 32
// AARCH64-DARWIN: #define __aarch64__ 1
+// RUN: %clang_cc1 -E -dM -ffreestanding -triple=thumbv7-windows-msvc < /dev/null | FileCheck -match-full-lines -check-prefix ARM-MSVC %s
+//
+// ARM-MSVC: #define _M_ARM_NT 1
+// ARM-MSVC: #define _WIN32 1
+// ARM-MSVC-NOT:#define __ARM_DWARF_EH__ 1
+
+// RUN: %clang_cc1 -E -dM -ffreestanding -triple=aarch64-windows-msvc < /dev/null | FileCheck -match-full-lines -check-prefix AARCH64-MSVC %s
+//
+// AARCH64-MSVC: #define _INTEGRAL_MAX_BITS 64
+// AARCH64-MSVC-NOT: #define _LP64 1
+// AARCH64-MSVC: #define _M_ARM64 1
+// AARCH64-MSVC: #define _WIN32 1
+// AARCH64-MSVC: #define _WIN64 1
+// AARCH64-MSVC: #define __AARCH64EL__ 1
+// AARCH64-MSVC: #define __ARM_64BIT_STATE 1
+// AARCH64-MSVC: #define __ARM_ACLE 200
+// AARCH64-MSVC: #define __ARM_ALIGN_MAX_STACK_PWR 4
+// AARCH64-MSVC: #define __ARM_ARCH 8
+// AARCH64-MSVC: #define __ARM_ARCH_ISA_A64 1
+// AARCH64-MSVC: #define __ARM_ARCH_PROFILE 'A'
+// AARCH64-MSVC: #define __ARM_FEATURE_CLZ 1
+// AARCH64-MSVC: #define __ARM_FEATURE_DIRECTED_ROUNDING 1
+// AARCH64-MSVC: #define __ARM_FEATURE_DIV 1
+// AARCH64-MSVC: #define __ARM_FEATURE_FMA 1
+// AARCH64-MSVC: #define __ARM_FEATURE_IDIV 1
+// AARCH64-MSVC: #define __ARM_FEATURE_LDREX 0xF
+// AARCH64-MSVC: #define __ARM_FEATURE_NUMERIC_MAXMIN 1
+// AARCH64-MSVC: #define __ARM_FEATURE_UNALIGNED 1
+// AARCH64-MSVC: #define __ARM_FP 0xE
+// AARCH64-MSVC: #define __ARM_FP16_ARGS 1
+// AARCH64-MSVC: #define __ARM_FP16_FORMAT_IEEE 1
+// AARCH64-MSVC: #define __ARM_PCS_AAPCS64 1
+// AARCH64-MSVC: #define __ARM_SIZEOF_MINIMAL_ENUM 4
+// AARCH64-MSVC: #define __ARM_SIZEOF_WCHAR_T 4
+// AARCH64-MSVC: #define __BIGGEST_ALIGNMENT__ 16
+// AARCH64-MSVC: #define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
+// AARCH64-MSVC: #define __CHAR16_TYPE__ unsigned short
+// AARCH64-MSVC: #define __CHAR32_TYPE__ unsigned int
+// AARCH64-MSVC: #define __CHAR_BIT__ 8
+// AARCH64-MSVC: #define __CONSTANT_CFSTRINGS__ 1
+// AARCH64-MSVC: #define __DBL_DECIMAL_DIG__ 17
+// AARCH64-MSVC: #define __DBL_DENORM_MIN__ 4.9406564584124654e-324
+// AARCH64-MSVC: #define __DBL_DIG__ 15
+// AARCH64-MSVC: #define __DBL_EPSILON__ 2.2204460492503131e-16
+// AARCH64-MSVC: #define __DBL_HAS_DENORM__ 1
+// AARCH64-MSVC: #define __DBL_HAS_INFINITY__ 1
+// AARCH64-MSVC: #define __DBL_HAS_QUIET_NAN__ 1
+// AARCH64-MSVC: #define __DBL_MANT_DIG__ 53
+// AARCH64-MSVC: #define __DBL_MAX_10_EXP__ 308
+// AARCH64-MSVC: #define __DBL_MAX_EXP__ 1024
+// AARCH64-MSVC: #define __DBL_MAX__ 1.7976931348623157e+308
+// AARCH64-MSVC: #define __DBL_MIN_10_EXP__ (-307)
+// AARCH64-MSVC: #define __DBL_MIN_EXP__ (-1021)
+// AARCH64-MSVC: #define __DBL_MIN__ 2.2250738585072014e-308
+// AARCH64-MSVC: #define __DECIMAL_DIG__ __LDBL_DECIMAL_DIG__
+// AARCH64-MSVC: #define __FINITE_MATH_ONLY__ 0
+// AARCH64-MSVC: #define __FLT_DECIMAL_DIG__ 9
+// AARCH64-MSVC: #define __FLT_DENORM_MIN__ 1.40129846e-45F
+// AARCH64-MSVC: #define __FLT_DIG__ 6
+// AARCH64-MSVC: #define __FLT_EPSILON__ 1.19209290e-7F
+// AARCH64-MSVC: #define __FLT_EVAL_METHOD__ 0
+// AARCH64-MSVC: #define __FLT_HAS_DENORM__ 1
+// AARCH64-MSVC: #define __FLT_HAS_INFINITY__ 1
+// AARCH64-MSVC: #define __FLT_HAS_QUIET_NAN__ 1
+// AARCH64-MSVC: #define __FLT_MANT_DIG__ 24
+// AARCH64-MSVC: #define __FLT_MAX_10_EXP__ 38
+// AARCH64-MSVC: #define __FLT_MAX_EXP__ 128
+// AARCH64-MSVC: #define __FLT_MAX__ 3.40282347e+38F
+// AARCH64-MSVC: #define __FLT_MIN_10_EXP__ (-37)
+// AARCH64-MSVC: #define __FLT_MIN_EXP__ (-125)
+// AARCH64-MSVC: #define __FLT_MIN__ 1.17549435e-38F
+// AARCH64-MSVC: #define __FLT_RADIX__ 2
+// AARCH64-MSVC: #define __INT_MAX__ 2147483647
+// AARCH64-MSVC: #define __LDBL_DECIMAL_DIG__ 17
+// AARCH64-MSVC: #define __LDBL_DENORM_MIN__ 4.9406564584124654e-324L
+// AARCH64-MSVC: #define __LDBL_DIG__ 15
+// AARCH64-MSVC: #define __LDBL_EPSILON__ 2.2204460492503131e-16L
+// AARCH64-MSVC: #define __LDBL_HAS_DENORM__ 1
+// AARCH64-MSVC: #define __LDBL_HAS_INFINITY__ 1
+// AARCH64-MSVC: #define __LDBL_HAS_QUIET_NAN__ 1
+// AARCH64-MSVC: #define __LDBL_MANT_DIG__ 53
+// AARCH64-MSVC: #define __LDBL_MAX_10_EXP__ 308
+// AARCH64-MSVC: #define __LDBL_MAX_EXP__ 1024
+// AARCH64-MSVC: #define __LDBL_MAX__ 1.7976931348623157e+308L
+// AARCH64-MSVC: #define __LDBL_MIN_10_EXP__ (-307)
+// AARCH64-MSVC: #define __LDBL_MIN_EXP__ (-1021)
+// AARCH64-MSVC: #define __LDBL_MIN__ 2.2250738585072014e-308L
+// AARCH64-MSVC: #define __LITTLE_ENDIAN__ 1
+// AARCH64-MSVC: #define __LONG_LONG_MAX__ 9223372036854775807LL
+// AARCH64-MSVC: #define __LONG_MAX__ 2147483647L
+// AARCH64-MSVC-NOT: #define __LP64__ 1
+// AARCH64-MSVC: #define __NO_INLINE__ 1
+// AARCH64-MSVC: #define __OBJC_BOOL_IS_BOOL 0
+// AARCH64-MSVC: #define __ORDER_BIG_ENDIAN__ 4321
+// AARCH64-MSVC: #define __ORDER_LITTLE_ENDIAN__ 1234
+// AARCH64-MSVC: #define __ORDER_PDP_ENDIAN__ 3412
+// AARCH64-MSVC: #define __POINTER_WIDTH__ 64
+// AARCH64-MSVC: #define __PRAGMA_REDEFINE_EXTNAME 1
+// AARCH64-MSVC: #define __SCHAR_MAX__ 127
+// AARCH64-MSVC: #define __SHRT_MAX__ 32767
+// AARCH64-MSVC: #define __SIG_ATOMIC_MAX__ 2147483647
+// AARCH64-MSVC: #define __SIG_ATOMIC_WIDTH__ 32
+// AARCH64-MSVC: #define __SIZEOF_DOUBLE__ 8
+// AARCH64-MSVC: #define __SIZEOF_FLOAT__ 4
+// AARCH64-MSVC: #define __SIZEOF_INT128__ 16
+// AARCH64-MSVC: #define __SIZEOF_INT__ 4
+// AARCH64-MSVC: #define __SIZEOF_LONG_DOUBLE__ 8
+// AARCH64-MSVC: #define __SIZEOF_LONG_LONG__ 8
+// AARCH64-MSVC: #define __SIZEOF_LONG__ 4
+// AARCH64-MSVC: #define __SIZEOF_POINTER__ 8
+// AARCH64-MSVC: #define __SIZEOF_PTRDIFF_T__ 8
+// AARCH64-MSVC: #define __SIZEOF_SHORT__ 2
+// AARCH64-MSVC: #define __SIZEOF_SIZE_T__ 8
+// AARCH64-MSVC: #define __SIZEOF_WCHAR_T__ 2
+// AARCH64-MSVC: #define __SIZEOF_WINT_T__ 4
+// AARCH64-MSVC: #define __SIZE_MAX__ 18446744073709551615ULL
+// AARCH64-MSVC: #define __SIZE_TYPE__ long long unsigned int
+// AARCH64-MSVC: #define __SIZE_WIDTH__ 64
+// AARCH64-MSVC: #define __STDC_HOSTED__ 0
+// AARCH64-MSVC: #define __STDC_UTF_16__ 1
+// AARCH64-MSVC: #define __STDC_UTF_32__ 1
+// AARCH64-MSVC: #define __STDC_VERSION__ 201112L
+// AARCH64-MSVC: #define __STDC__ 1
+// AARCH64-MSVC: #define __UINT16_C_SUFFIX__
+// AARCH64-MSVC: #define __UINT16_MAX__ 65535
+// AARCH64-MSVC: #define __UINT16_TYPE__ unsigned short
+// AARCH64-MSVC: #define __UINT32_C_SUFFIX__ U
+// AARCH64-MSVC: #define __UINT32_MAX__ 4294967295U
+// AARCH64-MSVC: #define __UINT32_TYPE__ unsigned int
+// AARCH64-MSVC: #define __UINT64_C_SUFFIX__ ULL
+// AARCH64-MSVC: #define __UINT64_MAX__ 18446744073709551615ULL
+// AARCH64-MSVC: #define __UINT64_TYPE__ long long unsigned int
+// AARCH64-MSVC: #define __UINT8_C_SUFFIX__
+// AARCH64-MSVC: #define __UINT8_MAX__ 255
+// AARCH64-MSVC: #define __UINT8_TYPE__ unsigned char
+// AARCH64-MSVC: #define __UINTMAX_C_SUFFIX__ ULL
+// AARCH64-MSVC: #define __UINTMAX_MAX__ 18446744073709551615ULL
+// AARCH64-MSVC: #define __UINTMAX_TYPE__ long long unsigned int
+// AARCH64-MSVC: #define __UINTMAX_WIDTH__ 64
+// AARCH64-MSVC: #define __UINTPTR_MAX__ 18446744073709551615ULL
+// AARCH64-MSVC: #define __UINTPTR_TYPE__ long long unsigned int
+// AARCH64-MSVC: #define __UINTPTR_WIDTH__ 64
+// AARCH64-MSVC: #define __UINT_FAST16_MAX__ 65535
+// AARCH64-MSVC: #define __UINT_FAST16_TYPE__ unsigned short
+// AARCH64-MSVC: #define __UINT_FAST32_MAX__ 4294967295U
+// AARCH64-MSVC: #define __UINT_FAST32_TYPE__ unsigned int
+// AARCH64-MSVC: #define __UINT_FAST64_MAX__ 18446744073709551615ULL
+// AARCH64-MSVC: #define __UINT_FAST64_TYPE__ long long unsigned int
+// AARCH64-MSVC: #define __UINT_FAST8_MAX__ 255
+// AARCH64-MSVC: #define __UINT_FAST8_TYPE__ unsigned char
+// AARCH64-MSVC: #define __UINT_LEAST16_MAX__ 65535
+// AARCH64-MSVC: #define __UINT_LEAST16_TYPE__ unsigned short
+// AARCH64-MSVC: #define __UINT_LEAST32_MAX__ 4294967295U
+// AARCH64-MSVC: #define __UINT_LEAST32_TYPE__ unsigned int
+// AARCH64-MSVC: #define __UINT_LEAST64_MAX__ 18446744073709551615ULL
+// AARCH64-MSVC: #define __UINT_LEAST64_TYPE__ long long unsigned int
+// AARCH64-MSVC: #define __UINT_LEAST8_MAX__ 255
+// AARCH64-MSVC: #define __UINT_LEAST8_TYPE__ unsigned char
+// AARCH64-MSVC: #define __USER_LABEL_PREFIX__
+// AARCH64-MSVC: #define __WCHAR_MAX__ 65535
+// AARCH64-MSVC: #define __WCHAR_TYPE__ unsigned short
+// AARCH64-MSVC: #define __WCHAR_UNSIGNED__ 1
+// AARCH64-MSVC: #define __WCHAR_WIDTH__ 16
+// AARCH64-MSVC: #define __WINT_TYPE__ int
+// AARCH64-MSVC: #define __WINT_WIDTH__ 32
+// AARCH64-MSVC: #define __aarch64__ 1
+
// RUN: %clang_cc1 -E -dM -ffreestanding -triple=arm-none-none < /dev/null | FileCheck -match-full-lines -check-prefix ARM %s
// RUN: %clang_cc1 -x c++ -E -dM -ffreestanding -triple=arm-none-none < /dev/null | FileCheck -match-full-lines -check-prefix ARM -check-prefix ARM-CXX %s
//
@@ -1493,10 +1675,10 @@
// ARM:#define __INTMAX_MAX__ 9223372036854775807LL
// ARM:#define __INTMAX_TYPE__ long long int
// ARM:#define __INTMAX_WIDTH__ 64
-// ARM:#define __INTPTR_FMTd__ "ld"
-// ARM:#define __INTPTR_FMTi__ "li"
-// ARM:#define __INTPTR_MAX__ 2147483647L
-// ARM:#define __INTPTR_TYPE__ long int
+// ARM:#define __INTPTR_FMTd__ "d"
+// ARM:#define __INTPTR_FMTi__ "i"
+// ARM:#define __INTPTR_MAX__ 2147483647
+// ARM:#define __INTPTR_TYPE__ int
// ARM:#define __INTPTR_WIDTH__ 32
// ARM:#define __INT_FAST16_FMTd__ "hd"
// ARM:#define __INT_FAST16_FMTi__ "hi"
@@ -1588,8 +1770,8 @@
// ARM:#define __UINTMAX_MAX__ 18446744073709551615ULL
// ARM:#define __UINTMAX_TYPE__ long long unsigned int
// ARM:#define __UINTMAX_WIDTH__ 64
-// ARM:#define __UINTPTR_MAX__ 4294967295UL
-// ARM:#define __UINTPTR_TYPE__ long unsigned int
+// ARM:#define __UINTPTR_MAX__ 4294967295U
+// ARM:#define __UINTPTR_TYPE__ unsigned int
// ARM:#define __UINTPTR_WIDTH__ 32
// ARM:#define __UINT_FAST16_MAX__ 65535
// ARM:#define __UINT_FAST16_TYPE__ unsigned short
@@ -1616,6 +1798,11 @@
// ARM:#define __arm 1
// ARM:#define __arm__ 1
+// RUN: %clang_cc1 -dM -ffreestanding -triple arm-none-none -target-abi apcs-gnu -E /dev/null -o - | FileCheck -match-full-lines -check-prefix ARM-APCS-GNU %s
+// ARM-APCS-GNU: #define __INTPTR_TYPE__ int
+// ARM-APCS-GNU: #define __PTRDIFF_TYPE__ int
+// ARM-APCS-GNU: #define __SIZE_TYPE__ unsigned int
+
// RUN: %clang_cc1 -E -dM -ffreestanding -triple=armeb-none-none < /dev/null | FileCheck -match-full-lines -check-prefix ARM-BE %s
//
// ARM-BE-NOT:#define _LP64
@@ -1685,10 +1872,10 @@
// ARM-BE:#define __INTMAX_MAX__ 9223372036854775807LL
// ARM-BE:#define __INTMAX_TYPE__ long long int
// ARM-BE:#define __INTMAX_WIDTH__ 64
-// ARM-BE:#define __INTPTR_FMTd__ "ld"
-// ARM-BE:#define __INTPTR_FMTi__ "li"
-// ARM-BE:#define __INTPTR_MAX__ 2147483647L
-// ARM-BE:#define __INTPTR_TYPE__ long int
+// ARM-BE:#define __INTPTR_FMTd__ "d"
+// ARM-BE:#define __INTPTR_FMTi__ "i"
+// ARM-BE:#define __INTPTR_MAX__ 2147483647
+// ARM-BE:#define __INTPTR_TYPE__ int
// ARM-BE:#define __INTPTR_WIDTH__ 32
// ARM-BE:#define __INT_FAST16_FMTd__ "hd"
// ARM-BE:#define __INT_FAST16_FMTi__ "hi"
@@ -1778,8 +1965,8 @@
// ARM-BE:#define __UINTMAX_MAX__ 18446744073709551615ULL
// ARM-BE:#define __UINTMAX_TYPE__ long long unsigned int
// ARM-BE:#define __UINTMAX_WIDTH__ 64
-// ARM-BE:#define __UINTPTR_MAX__ 4294967295UL
-// ARM-BE:#define __UINTPTR_TYPE__ long unsigned int
+// ARM-BE:#define __UINTPTR_MAX__ 4294967295U
+// ARM-BE:#define __UINTPTR_TYPE__ unsigned int
// ARM-BE:#define __UINTPTR_WIDTH__ 32
// ARM-BE:#define __UINT_FAST16_MAX__ 65535
// ARM-BE:#define __UINT_FAST16_TYPE__ unsigned short
@@ -1878,10 +2065,10 @@
// ARMEABISOFTFP:#define __INTMAX_MAX__ 9223372036854775807LL
// ARMEABISOFTFP:#define __INTMAX_TYPE__ long long int
// ARMEABISOFTFP:#define __INTMAX_WIDTH__ 64
-// ARMEABISOFTFP:#define __INTPTR_FMTd__ "ld"
-// ARMEABISOFTFP:#define __INTPTR_FMTi__ "li"
-// ARMEABISOFTFP:#define __INTPTR_MAX__ 2147483647L
-// ARMEABISOFTFP:#define __INTPTR_TYPE__ long int
+// ARMEABISOFTFP:#define __INTPTR_FMTd__ "d"
+// ARMEABISOFTFP:#define __INTPTR_FMTi__ "i"
+// ARMEABISOFTFP:#define __INTPTR_MAX__ 2147483647
+// ARMEABISOFTFP:#define __INTPTR_TYPE__ int
// ARMEABISOFTFP:#define __INTPTR_WIDTH__ 32
// ARMEABISOFTFP:#define __INT_FAST16_FMTd__ "hd"
// ARMEABISOFTFP:#define __INT_FAST16_FMTi__ "hi"
@@ -1973,8 +2160,8 @@
// ARMEABISOFTFP:#define __UINTMAX_MAX__ 18446744073709551615ULL
// ARMEABISOFTFP:#define __UINTMAX_TYPE__ long long unsigned int
// ARMEABISOFTFP:#define __UINTMAX_WIDTH__ 64
-// ARMEABISOFTFP:#define __UINTPTR_MAX__ 4294967295UL
-// ARMEABISOFTFP:#define __UINTPTR_TYPE__ long unsigned int
+// ARMEABISOFTFP:#define __UINTPTR_MAX__ 4294967295U
+// ARMEABISOFTFP:#define __UINTPTR_TYPE__ unsigned int
// ARMEABISOFTFP:#define __UINTPTR_WIDTH__ 32
// ARMEABISOFTFP:#define __UINT_FAST16_MAX__ 65535
// ARMEABISOFTFP:#define __UINT_FAST16_TYPE__ unsigned short
@@ -2073,10 +2260,10 @@
// ARMEABIHARDFP:#define __INTMAX_MAX__ 9223372036854775807LL
// ARMEABIHARDFP:#define __INTMAX_TYPE__ long long int
// ARMEABIHARDFP:#define __INTMAX_WIDTH__ 64
-// ARMEABIHARDFP:#define __INTPTR_FMTd__ "ld"
-// ARMEABIHARDFP:#define __INTPTR_FMTi__ "li"
-// ARMEABIHARDFP:#define __INTPTR_MAX__ 2147483647L
-// ARMEABIHARDFP:#define __INTPTR_TYPE__ long int
+// ARMEABIHARDFP:#define __INTPTR_FMTd__ "d"
+// ARMEABIHARDFP:#define __INTPTR_FMTi__ "i"
+// ARMEABIHARDFP:#define __INTPTR_MAX__ 2147483647
+// ARMEABIHARDFP:#define __INTPTR_TYPE__ int
// ARMEABIHARDFP:#define __INTPTR_WIDTH__ 32
// ARMEABIHARDFP:#define __INT_FAST16_FMTd__ "hd"
// ARMEABIHARDFP:#define __INT_FAST16_FMTi__ "hi"
@@ -2168,8 +2355,8 @@
// ARMEABIHARDFP:#define __UINTMAX_MAX__ 18446744073709551615ULL
// ARMEABIHARDFP:#define __UINTMAX_TYPE__ long long unsigned int
// ARMEABIHARDFP:#define __UINTMAX_WIDTH__ 64
-// ARMEABIHARDFP:#define __UINTPTR_MAX__ 4294967295UL
-// ARMEABIHARDFP:#define __UINTPTR_TYPE__ long unsigned int
+// ARMEABIHARDFP:#define __UINTPTR_MAX__ 4294967295U
+// ARMEABIHARDFP:#define __UINTPTR_TYPE__ unsigned int
// ARMEABIHARDFP:#define __UINTPTR_WIDTH__ 32
// ARMEABIHARDFP:#define __UINT_FAST16_MAX__ 65535
// ARMEABIHARDFP:#define __UINT_FAST16_TYPE__ unsigned short
@@ -2413,13 +2600,6 @@
// RUN: %clang -target x86_64-apple-darwin -arch armv7 -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=ARM-MACHO-NO-EABI %s
// ARM-MACHO-NO-EABI-NOT: #define __ARM_EABI__ 1
-// RUN: %clang_cc1 -E -dM -ffreestanding -triple=armv7-bitrig-gnueabihf < /dev/null | FileCheck -match-full-lines -check-prefix ARM-BITRIG %s
-// ARM-BITRIG:#define __ARM_DWARF_EH__ 1
-// ARM-BITRIG:#define __SIZEOF_SIZE_T__ 4
-// ARM-BITRIG:#define __SIZE_MAX__ 4294967295UL
-// ARM-BITRIG:#define __SIZE_TYPE__ long unsigned int
-// ARM-BITRIG:#define __SIZE_WIDTH__ 32
-
// Check that -mhwdiv works properly for targets which don't have the hwdiv feature enabled by default.
// RUN: %clang -target arm -mhwdiv=arm -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=ARMHWDIV-ARM %s
@@ -2472,6 +2652,10 @@
// Thumbebv7: #define __THUMB_INTERWORK__ 1
// Thumbebv7: #define __thumb2__ 1
+// RUN: %clang -E -dM -ffreestanding -target thumbv7-pc-mingw32 %s -o - | FileCheck -match-full-lines -check-prefix THUMB-MINGW %s
+
+// THUMB-MINGW:#define __ARM_DWARF_EH__ 1
+
//
// RUN: %clang_cc1 -E -dM -ffreestanding -triple=i386-none-none < /dev/null | FileCheck -match-full-lines -check-prefix I386 %s
//
@@ -4706,6 +4890,16 @@
// RUN: | FileCheck -match-full-lines -check-prefix NOMIPS-NAN2008 %s
// NOMIPS-NAN2008-NOT:#define __mips_nan2008 1
//
+// RUN: %clang_cc1 -target-cpu mips32r3 -target-feature +abs2008 \
+// RUN: -E -dM -triple=mips-none-none < /dev/null \
+// RUN: | FileCheck -match-full-lines -check-prefix MIPS-ABS2008 %s
+// MIPS-ABS2008:#define __mips_abs2008 1
+//
+// RUN: %clang_cc1 -target-cpu mips32r3 -target-feature -abs2008 \
+// RUN: -E -dM -triple=mips-none-none < /dev/null \
+// RUN: | FileCheck -match-full-lines -check-prefix NOMIPS-ABS2008 %s
+// NOMIPS-ABS2008-NOT:#define __mips_abs2008 1
+//
// RUN: %clang_cc1 -target-feature -fp64 \
// RUN: -E -dM -triple=mips-none-none < /dev/null \
// RUN: | FileCheck -match-full-lines -check-prefix MIPS32-MFP32 %s
@@ -8247,6 +8441,7 @@
// X86_64-CLOUDABI:#define __WCHAR_MAX__ 2147483647
// X86_64-CLOUDABI:#define __WCHAR_TYPE__ int
// X86_64-CLOUDABI:#define __WCHAR_WIDTH__ 32
+// X86_64-CLOUDABI:#define __WINT_MAX__ 2147483647
// X86_64-CLOUDABI:#define __WINT_TYPE__ int
// X86_64-CLOUDABI:#define __WINT_WIDTH__ 32
// X86_64-CLOUDABI:#define __amd64 1
@@ -8801,6 +8996,7 @@
// KFREEBSDI686-DEFINE:#define __GLIBC__ 1
//
// RUN: %clang_cc1 -x c++ -triple i686-pc-linux-gnu -fobjc-runtime=gcc -E -dM < /dev/null | FileCheck -match-full-lines -check-prefix GNUSOURCE %s
+// RUN: %clang_cc1 -x c++ -triple sparc-rtems-elf -E -dM < /dev/null | FileCheck -match-full-lines -check-prefix GNUSOURCE %s
// GNUSOURCE:#define _GNU_SOURCE 1
//
// RUN: %clang_cc1 -x c++ -std=c++98 -fno-rtti -E -dM < /dev/null | FileCheck -match-full-lines -check-prefix NORTTI %s
@@ -8906,7 +9102,7 @@
// WEBASSEMBLY32-NEXT:#define __DECIMAL_DIG__ __LDBL_DECIMAL_DIG__
// WEBASSEMBLY32-NOT:#define __ELF__
// WEBASSEMBLY32-NEXT:#define __FINITE_MATH_ONLY__ 0
-// WEBASSEMBLY32-NEXT:#define __FLT_DECIMAL_DIG__ 9
+// WEBASSEMBLY32:#define __FLT_DECIMAL_DIG__ 9
// WEBASSEMBLY32-NEXT:#define __FLT_DENORM_MIN__ 1.40129846e-45F
// WEBASSEMBLY32-NEXT:#define __FLT_DIG__ 6
// WEBASSEMBLY32-NEXT:#define __FLT_EPSILON__ 1.19209290e-7F
@@ -9023,6 +9219,11 @@
// WEBASSEMBLY32-NOT:#define __LP64__
// WEBASSEMBLY32-NEXT:#define __NO_INLINE__ 1
// WEBASSEMBLY32-NEXT:#define __OBJC_BOOL_IS_BOOL 0
+// WEBASSEMBLY32-NEXT:#define __OPENCL_MEMORY_SCOPE_ALL_SVM_DEVICES 3
+// WEBASSEMBLY32-NEXT:#define __OPENCL_MEMORY_SCOPE_DEVICE 2
+// WEBASSEMBLY32-NEXT:#define __OPENCL_MEMORY_SCOPE_SUB_GROUP 4
+// WEBASSEMBLY32-NEXT:#define __OPENCL_MEMORY_SCOPE_WORK_GROUP 1
+// WEBASSEMBLY32-NEXT:#define __OPENCL_MEMORY_SCOPE_WORK_ITEM 0
// WEBASSEMBLY32-NEXT:#define __ORDER_BIG_ENDIAN__ 4321
// WEBASSEMBLY32-NEXT:#define __ORDER_LITTLE_ENDIAN__ 1234
// WEBASSEMBLY32-NEXT:#define __ORDER_PDP_ENDIAN__ 3412
@@ -9165,6 +9366,7 @@
// WEBASSEMBLY32-NEXT:#define __WCHAR_TYPE__ int
// WEBASSEMBLY32-NOT:#define __WCHAR_UNSIGNED__
// WEBASSEMBLY32-NEXT:#define __WCHAR_WIDTH__ 32
+// WEBASSEMBLY32-NEXT:#define __WINT_MAX__ 2147483647
// WEBASSEMBLY32-NEXT:#define __WINT_TYPE__ int
// WEBASSEMBLY32-NOT:#define __WINT_UNSIGNED__
// WEBASSEMBLY32-NEXT:#define __WINT_WIDTH__ 32
@@ -9232,7 +9434,7 @@
// WEBASSEMBLY64-NEXT:#define __DECIMAL_DIG__ __LDBL_DECIMAL_DIG__
// WEBASSEMBLY64-NOT:#define __ELF__
// WEBASSEMBLY64-NEXT:#define __FINITE_MATH_ONLY__ 0
-// WEBASSEMBLY64-NEXT:#define __FLT_DECIMAL_DIG__ 9
+// WEBASSEMBLY64:#define __FLT_DECIMAL_DIG__ 9
// WEBASSEMBLY64-NEXT:#define __FLT_DENORM_MIN__ 1.40129846e-45F
// WEBASSEMBLY64-NEXT:#define __FLT_DIG__ 6
// WEBASSEMBLY64-NEXT:#define __FLT_EPSILON__ 1.19209290e-7F
@@ -9349,6 +9551,11 @@
// WEBASSEMBLY64-NEXT:#define __LP64__ 1
// WEBASSEMBLY64-NEXT:#define __NO_INLINE__ 1
// WEBASSEMBLY64-NEXT:#define __OBJC_BOOL_IS_BOOL 0
+// WEBASSEMBLY64-NEXT:#define __OPENCL_MEMORY_SCOPE_ALL_SVM_DEVICES 3
+// WEBASSEMBLY64-NEXT:#define __OPENCL_MEMORY_SCOPE_DEVICE 2
+// WEBASSEMBLY64-NEXT:#define __OPENCL_MEMORY_SCOPE_SUB_GROUP 4
+// WEBASSEMBLY64-NEXT:#define __OPENCL_MEMORY_SCOPE_WORK_GROUP 1
+// WEBASSEMBLY64-NEXT:#define __OPENCL_MEMORY_SCOPE_WORK_ITEM 0
// WEBASSEMBLY64-NEXT:#define __ORDER_BIG_ENDIAN__ 4321
// WEBASSEMBLY64-NEXT:#define __ORDER_LITTLE_ENDIAN__ 1234
// WEBASSEMBLY64-NEXT:#define __ORDER_PDP_ENDIAN__ 3412
@@ -9491,6 +9698,7 @@
// WEBASSEMBLY64-NEXT:#define __WCHAR_TYPE__ int
// WEBASSEMBLY64-NOT:#define __WCHAR_UNSIGNED__
// WEBASSEMBLY64-NEXT:#define __WCHAR_WIDTH__ 32
+// WEBASSEMBLY64-NEXT:#define __WINT_MAX__ 2147483647
// WEBASSEMBLY64-NEXT:#define __WINT_TYPE__ int
// WEBASSEMBLY64-NOT:#define __WINT_UNSIGNED__
// WEBASSEMBLY64-NEXT:#define __WINT_WIDTH__ 32
@@ -9692,11 +9900,11 @@
// RUN: %clang_cc1 -E -dM -ffreestanding \
-// RUN: -triple i686-windows-msvc -fms-compatibility < /dev/null \
+// RUN: -triple i686-windows-msvc -fms-compatibility -x c++ < /dev/null \
// RUN: | FileCheck -match-full-lines -check-prefix MSVC-X32 %s
// RUN: %clang_cc1 -E -dM -ffreestanding \
-// RUN: -triple x86_64-windows-msvc -fms-compatibility < /dev/null \
+// RUN: -triple x86_64-windows-msvc -fms-compatibility -x c++ < /dev/null \
// RUN: | FileCheck -match-full-lines -check-prefix MSVC-X64 %s
// MSVC-X32:#define __CLANG_ATOMIC_BOOL_LOCK_FREE 2
@@ -9710,6 +9918,7 @@
// MSVC-X32-NEXT:#define __CLANG_ATOMIC_SHORT_LOCK_FREE 2
// MSVC-X32-NEXT:#define __CLANG_ATOMIC_WCHAR_T_LOCK_FREE 2
// MSVC-X32-NOT:#define __GCC_ATOMIC{{.*}}
+// MSVC-X32:#define __STDCPP_DEFAULT_NEW_ALIGNMENT__ 8U
// MSVC-X64:#define __CLANG_ATOMIC_BOOL_LOCK_FREE 2
// MSVC-X64-NEXT:#define __CLANG_ATOMIC_CHAR16_T_LOCK_FREE 2
@@ -9721,7 +9930,8 @@
// MSVC-X64-NEXT:#define __CLANG_ATOMIC_POINTER_LOCK_FREE 2
// MSVC-X64-NEXT:#define __CLANG_ATOMIC_SHORT_LOCK_FREE 2
// MSVC-X64-NEXT:#define __CLANG_ATOMIC_WCHAR_T_LOCK_FREE 2
-// MSVC-X86-NOT:#define __GCC_ATOMIC{{.*}}
+// MSVC-X64-NOT:#define __GCC_ATOMIC{{.*}}
+// MSVC-X64:#define __STDCPP_DEFAULT_NEW_ALIGNMENT__ 16ULL
// RUN: %clang_cc1 -E -dM -ffreestanding \
// RUN: -triple=aarch64-apple-ios9 < /dev/null \
@@ -9731,3 +9941,65 @@
// RUN: | FileCheck -check-prefix=DARWIN %s
// DARWIN:#define __STDC_NO_THREADS__ 1
+
+// RUN: %clang_cc1 -triple i386-apple-macosx -ffreestanding -dM -E /dev/null -o - | FileCheck -match-full-lines -check-prefix MACOS-32 %s
+// RUN: %clang_cc1 -triple x86_64-apple-macosx -ffreestanding -dM -E /dev/null -o - | FileCheck -match-full-lines -check-prefix MACOS-64 %s
+
+// MACOS-32: #define __INTPTR_TYPE__ long int
+// MACOS-32: #define __PTRDIFF_TYPE__ int
+// MACOS-32: #define __SIZE_TYPE__ long unsigned int
+
+// MACOS-64: #define __INTPTR_TYPE__ long int
+// MACOS-64: #define __PTRDIFF_TYPE__ long int
+// MACOS-64: #define __SIZE_TYPE__ long unsigned int
+
+// RUN: %clang_cc1 -triple i386-apple-ios-simulator -ffreestanding -dM -E /dev/null -o - | FileCheck -match-full-lines -check-prefix IOS-32 %s
+// RUN: %clang_cc1 -triple armv7-apple-ios -ffreestanding -dM -E /dev/null -o - | FileCheck -match-full-lines -check-prefix IOS-32 %s
+// RUN: %clang_cc1 -triple x86_64-apple-ios-simulator -ffreestanding -dM -E /dev/null -o - | FileCheck -match-full-lines -check-prefix IOS-64 %s
+// RUN: %clang_cc1 -triple arm64-apple-ios -ffreestanding -dM -E /dev/null -o - | FileCheck -match-full-lines -check-prefix IOS-64 %s
+
+// IOS-32: #define __INTPTR_TYPE__ long int
+// IOS-32: #define __PTRDIFF_TYPE__ int
+// IOS-32: #define __SIZE_TYPE__ long unsigned int
+
+// IOS-64: #define __INTPTR_TYPE__ long int
+// IOS-64: #define __PTRDIFF_TYPE__ long int
+// IOS-64: #define __SIZE_TYPE__ long unsigned int
+
+// RUN: %clang_cc1 -triple i386-apple-tvos-simulator -ffreestanding -dM -E /dev/null -o - | FileCheck -match-full-lines -check-prefix TVOS-32 %s
+// RUN: %clang_cc1 -triple armv7-apple-tvos -ffreestanding -dM -E /dev/null -o - | FileCheck -match-full-lines -check-prefix TVOS-32 %s
+// RUN: %clang_cc1 -triple x86_64-apple-tvos-simulator -ffreestanding -dM -E /dev/null -o - | FileCheck -match-full-lines -check-prefix TVOS-64 %s
+// RUN: %clang_cc1 -triple arm64-apple-tvos -ffreestanding -dM -E /dev/null -o - | FileCheck -match-full-lines -check-prefix TVOS-64 %s
+
+// TVOS-32: #define __INTPTR_TYPE__ long int
+// TVOS-32: #define __PTRDIFF_TYPE__ int
+// TVOS-32: #define __SIZE_TYPE__ long unsigned int
+
+// TVOS-64: #define __INTPTR_TYPE__ long int
+// TVOS-64: #define __PTRDIFF_TYPE__ long int
+// TVOS-64: #define __SIZE_TYPE__ long unsigned int
+
+// RUN: %clang_cc1 -triple i386-apple-watchos-simulator -ffreestanding -dM -E /dev/null -o - | FileCheck -match-full-lines -check-prefix WATCHOS-32 %s
+// RUN: %clang_cc1 -triple armv7k-apple-watchos -ffreestanding -dM -E /dev/null -o - | FileCheck -match-full-lines -check-prefix WATCHOS-64 %s
+// RUN: %clang_cc1 -triple x86_64-apple-watchos-simulator -ffreestanding -dM -E /dev/null -o - | FileCheck -match-full-lines -check-prefix WATCHOS-64 %s
+// RUN: %clang_cc1 -triple arm64-apple-watchos -ffreestanding -dM -E /dev/null -o - | FileCheck -match-full-lines -check-prefix WATCHOS-64 %s
+
+// WATCHOS-32: #define __INTPTR_TYPE__ long int
+// WATCHOS-32: #define __PTRDIFF_TYPE__ int
+// WATCHOS-32: #define __SIZE_TYPE__ long unsigned int
+
+// WATCHOS-64: #define __INTPTR_TYPE__ long int
+// WATCHOS-64: #define __PTRDIFF_TYPE__ long int
+// WATCHOS-64: #define __SIZE_TYPE__ long unsigned int
+
+// RUN: %clang_cc1 -triple armv7-apple-none-macho -ffreestanding -dM -E /dev/null -o - | FileCheck -match-full-lines -check-prefix ARM-DARWIN-BAREMETAL-32 %s
+// RUN: %clang_cc1 -triple arm64-apple-none-macho -ffreestanding -dM -E /dev/null -o - | FileCheck -match-full-lines -check-prefix ARM-DARWIN-BAREMETAL-64 %s
+
+// ARM-DARWIN-BAREMETAL-32: #define __INTPTR_TYPE__ long int
+// ARM-DARWIN-BAREMETAL-32: #define __PTRDIFF_TYPE__ int
+// ARM-DARWIN-BAREMETAL-32: #define __SIZE_TYPE__ long unsigned int
+
+// ARM-DARWIN-BAREMETAL-64: #define __INTPTR_TYPE__ long int
+// ARM-DARWIN-BAREMETAL-64: #define __PTRDIFF_TYPE__ long int
+// ARM-DARWIN-BAREMETAL-64: #define __SIZE_TYPE__ long unsigned int
+
diff --git a/test/Preprocessor/is_target.c b/test/Preprocessor/is_target.c
new file mode 100644
index 000000000000..44bdb11c35af
--- /dev/null
+++ b/test/Preprocessor/is_target.c
@@ -0,0 +1,67 @@
+// RUN: %clang_cc1 -fsyntax-only -triple x86_64-apple-darwin-simulator -verify %s
+
+#if !__is_target_arch(x86_64) || !__is_target_arch(X86_64)
+ #error "mismatching arch"
+#endif
+
+#if __is_target_arch(arm64)
+ #error "mismatching arch"
+#endif
+
+// Silently ignore invalid archs. This will ensure that older compilers will
+// accept headers that support new arches/vendors/os variants.
+#if __is_target_arch(foo)
+ #error "invalid arch"
+#endif
+
+#if !__is_target_vendor(apple) || !__is_target_vendor(APPLE)
+ #error "mismatching vendor"
+#endif
+
+#if __is_target_vendor(unknown)
+ #error "mismatching vendor"
+#endif
+
+#if __is_target_vendor(foo)
+ #error "invalid vendor"
+#endif
+
+#if !__is_target_os(darwin) || !__is_target_os(DARWIN)
+ #error "mismatching os"
+#endif
+
+#if __is_target_os(ios)
+ #error "mismatching os"
+#endif
+
+#if __is_target_os(foo)
+ #error "invalid os"
+#endif
+
+#if !__is_target_environment(simulator) || !__is_target_environment(SIMULATOR)
+ #error "mismatching environment"
+#endif
+
+#if __is_target_environment(unknown)
+ #error "mismatching environment"
+#endif
+
+#if __is_target_environment(foo)
+ #error "invalid environment"
+#endif
+
+#if !__has_builtin(__is_target_arch) || !__has_builtin(__is_target_os) || !__has_builtin(__is_target_vendor) || !__has_builtin(__is_target_environment)
+ #error "has builtin doesn't work"
+#endif
+
+#if __is_target_arch(11) // expected-error {{builtin feature check macro requires a parenthesized identifier}}
+ #error "invalid arch"
+#endif
+
+#if __is_target_arch x86 // expected-error{{missing '(' after '__is_target_arch'}}
+ #error "invalid arch"
+#endif
+
+#if __is_target_arch ( x86 // expected-error {{unterminated function-like macro invocation}}
+ #error "invalid arch"
+#endif // expected-error@-2 {{expected value in expression}}
diff --git a/test/Preprocessor/is_target_arm.c b/test/Preprocessor/is_target_arm.c
new file mode 100644
index 000000000000..9e1afe6ec6c1
--- /dev/null
+++ b/test/Preprocessor/is_target_arm.c
@@ -0,0 +1,51 @@
+// RUN: %clang_cc1 -fsyntax-only -triple thumbv7--windows-msvc19.11.0 -verify %s
+// RUN: %clang_cc1 -fsyntax-only -triple armv7--windows-msvc19.11.0 -DARM -verify %s
+// expected-no-diagnostics
+
+// ARM does match arm and thumb.
+#if !__is_target_arch(arm)
+ #error "mismatching arch"
+#endif
+
+#if __is_target_arch(armeb) || __is_target_arch(armebv7) || __is_target_arch(thumbeb) || __is_target_arch(thumbebv7)
+ #error "mismatching arch"
+#endif
+
+// ARMV7 does match armv7 and thumbv7.
+#if !__is_target_arch(armv7)
+ #error "mismatching arch"
+#endif
+
+// ARMV6 does not match armv7 or thumbv7.
+#if __is_target_arch(armv6)
+ #error "mismatching arch"
+#endif
+
+#if __is_target_arch(arm64)
+ #error "mismatching arch"
+#endif
+
+#ifndef ARM
+
+// Allow checking for precise arch + subarch.
+#if !__is_target_arch(thumbv7)
+ #error "mismatching arch"
+#endif
+
+// But also allow checking for the arch without subarch.
+#if !__is_target_arch(thumb)
+ #error "mismatching arch"
+#endif
+
+// Same arch with a different subarch doesn't match.
+#if __is_target_arch(thumbv6)
+ #error "mismatching arch"
+#endif
+
+#else
+
+#if __is_target_arch(thumbv7) || __is_target_arch(thumb)
+ #error "mismatching arch"
+#endif
+
+#endif
diff --git a/test/Preprocessor/is_target_arm64.c b/test/Preprocessor/is_target_arm64.c
new file mode 100644
index 000000000000..87ebe94d18e3
--- /dev/null
+++ b/test/Preprocessor/is_target_arm64.c
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fsyntax-only -triple arm64-apple-ios11 -verify %s
+// expected-no-diagnostics
+
+#if !__is_target_arch(arm64) || !__is_target_arch(aarch64)
+ #error "mismatching arch"
+#endif
+
+#if __is_target_arch(aarch64_be)
+ #error "mismatching arch"
+#endif
diff --git a/test/Preprocessor/is_target_environment_version.c b/test/Preprocessor/is_target_environment_version.c
new file mode 100644
index 000000000000..e93386013c3b
--- /dev/null
+++ b/test/Preprocessor/is_target_environment_version.c
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -fsyntax-only -triple x86_64-pc-windows-msvc18.0.0 -verify %s
+// expected-no-diagnostics
+
+#if !__is_target_environment(msvc)
+ #error "mismatching environment"
+#endif
diff --git a/test/Preprocessor/is_target_os_darwin.c b/test/Preprocessor/is_target_os_darwin.c
new file mode 100644
index 000000000000..4c807ce19499
--- /dev/null
+++ b/test/Preprocessor/is_target_os_darwin.c
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -fsyntax-only -triple x86_64-apple-macos -DMAC -verify %s
+// RUN: %clang_cc1 -fsyntax-only -triple x86_64-apple-ios -verify %s
+// RUN: %clang_cc1 -fsyntax-only -triple x86_64-apple-tvos -verify %s
+// RUN: %clang_cc1 -fsyntax-only -triple x86_64-apple-watchos -verify %s
+// expected-no-diagnostics
+
+#if !__is_target_os(darwin)
+ #error "mismatching os"
+#endif
+
+// macOS matches both macOS and macOSX.
+#ifdef MAC
+
+#if !__is_target_os(macos)
+ #error "mismatching os"
+#endif
+
+#if !__is_target_os(macosx)
+ #error "mismatching os"
+#endif
+
+#if __is_target_os(ios)
+ #error "mismatching os"
+#endif
+
+#endif
diff --git a/test/Preprocessor/is_target_unknown.c b/test/Preprocessor/is_target_unknown.c
new file mode 100644
index 000000000000..d81afcbd2241
--- /dev/null
+++ b/test/Preprocessor/is_target_unknown.c
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -fsyntax-only -triple i686-unknown-unknown -verify %s
+// RUN: %clang_cc1 -fsyntax-only -triple i686-- -verify %s
+// expected-no-diagnostics
+
+#if __is_target_arch(unknown)
+ #error "mismatching arch"
+#endif
+
+// Unknown vendor is allowed.
+#if !__is_target_vendor(unknown)
+ #error "mismatching vendor"
+#endif
+
+// Unknown OS is allowed.
+#if !__is_target_os(unknown)
+ #error "mismatching OS"
+#endif
+
+// Unknown environment is allowed.
+#if !__is_target_environment(unknown)
+ #error "mismatching environment"
+#endif
diff --git a/test/Preprocessor/macro_raw_string.cpp b/test/Preprocessor/macro_raw_string.cpp
new file mode 100644
index 000000000000..d56894888d1f
--- /dev/null
+++ b/test/Preprocessor/macro_raw_string.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -E -std=c++11 %s -o %t
+// RUN: %clang_cc1 %t
+
+#define FOO(str) foo(#str)
+
+extern void foo(const char *str);
+
+void bar() {
+ FOO(R"(foo
+ bar)");
+}
diff --git a/test/Preprocessor/macro_vaopt_check.cpp b/test/Preprocessor/macro_vaopt_check.cpp
new file mode 100644
index 000000000000..25a4564fba7e
--- /dev/null
+++ b/test/Preprocessor/macro_vaopt_check.cpp
@@ -0,0 +1,64 @@
+// RUN: %clang_cc1 %s -Eonly -verify -Wno-all -pedantic -std=c++2a
+
+//expected-error@+1{{missing '('}}
+#define V1(...) __VA_OPT__
+#undef V1
+// OK
+#define V1(...) __VA_OPT__ ()
+#undef V1
+
+//expected-warning@+1{{can only appear in the expansion of a variadic macro}}
+#define V2() __VA_OPT__(x)
+#undef V2
+
+//expected-error@+2{{missing ')' after}}
+//expected-note@+1{{to match this '('}}
+#define V3(...) __VA_OPT__(
+#undef V3
+
+#define V4(...) __VA_OPT__(__VA_ARGS__)
+#undef V4
+
+//expected-error@+1{{nested}}
+#define V5(...) __VA_OPT__(__VA_OPT__())
+#undef V5
+
+//expected-error@+1{{not followed by}}
+#define V1(...) __VA_OPT__ (#)
+#undef V1
+
+//expected-error@+1{{cannot appear at start}}
+#define V1(...) __VA_OPT__ (##)
+#undef V1
+
+//expected-error@+1{{cannot appear at start}}
+#define V1(...) __VA_OPT__ (## X) x
+#undef V1
+
+//expected-error@+1{{cannot appear at end}}
+#define V1(...) y __VA_OPT__ (X ##)
+#undef V1
+
+
+#define FOO(x,...) # __VA_OPT__(x) #x #__VA_OPT__(__VA_ARGS__) //OK
+
+//expected-error@+1{{not followed by a macro parameter}}
+#define V1(...) __VA_OPT__(#)
+#undef V1
+
+//expected-error@+1{{cannot appear at start}}
+#define V1(...) a __VA_OPT__(##) b
+#undef V1
+
+//expected-error@+1{{cannot appear at start}}
+#define V1(...) a __VA_OPT__(a ## b) b __VA_OPT__(##)
+#undef V1
+
+#define V1(x,...) # __VA_OPT__(b x) // OK
+#undef V1
+
+//expected-error@+2{{missing ')' after}}
+//expected-note@+1{{to match this '('}}
+#define V1(...) __VA_OPT__ ((())
+#undef V1
+
diff --git a/test/Preprocessor/macro_vaopt_expand.cpp b/test/Preprocessor/macro_vaopt_expand.cpp
new file mode 100644
index 000000000000..5e007512015b
--- /dev/null
+++ b/test/Preprocessor/macro_vaopt_expand.cpp
@@ -0,0 +1,148 @@
+// RUN: %clang_cc1 -E %s -pedantic -std=c++2a | FileCheck -strict-whitespace %s
+
+#define LPAREN (
+#define RPAREN )
+
+#define A0 expandedA0
+#define A1 expandedA1 A0
+#define A2 expandedA2 A1
+#define A3 expandedA3 A2
+
+#define A() B LPAREN )
+#define B() C LPAREN )
+#define C() D LPAREN )
+
+
+#define F(x, y) x + y
+#define ELLIP_FUNC(...) __VA_OPT__(__VA_ARGS__)
+
+1: ELLIP_FUNC(F, LPAREN, 'a', 'b', RPAREN);
+2: ELLIP_FUNC(F LPAREN 'a', 'b' RPAREN);
+#undef F
+#undef ELLIP_FUNC
+
+// CHECK: 1: F, (, 'a', 'b', );
+// CHECK: 2: 'a' + 'b';
+
+#define F(...) f(0 __VA_OPT__(,) __VA_ARGS__)
+3: F(a, b, c) // replaced by f(0, a, b, c)
+4: F() // replaced by f(0)
+
+// CHECK: 3: f(0 , a, b, c)
+// CHECK: 4: f(0 )
+#undef F
+
+#define G(X, ...) f(0, X __VA_OPT__(,) __VA_ARGS__)
+
+5: G(a, b, c) // replaced by f(0, a , b, c)
+6: G(a) // replaced by f(0, a)
+7: G(a,) // replaced by f(0, a)
+7.1: G(a,,)
+
+
+// CHECK: 5: f(0, a , b, c)
+// CHECK: 6: f(0, a )
+// CHECK: 7: f(0, a )
+// CHECK: 7.1: f(0, a , ,)
+#undef G
+
+#define HT_B() TONG
+
+#define F(x, ...) HT_ ## __VA_OPT__(x x A() #x)
+
+8: F(1)
+9: F(A(),1)
+
+// CHECK: 8: HT_
+// CHECK: 9: TONG C ( ) B ( ) "A()"
+#undef HT_B
+#undef F
+
+#define F(a,...) #__VA_OPT__(A1 a)
+
+10: F(A())
+11: F(A1 A(), 1)
+// CHECK: 10: ""
+// CHECK: 11: "A1 expandedA1 expandedA0 B ( )"
+#undef F
+
+
+#define F(a,...) a ## __VA_OPT__(A1 a) ## __VA_ARGS__ ## a
+12.0: F()
+12: F(,)
+13: F(B,)
+// CHECK: 12.0:
+// CHECK: 12:
+// CHECK: 13: BB
+#undef F
+
+#define F(...) #__VA_OPT__() X ## __VA_OPT__() #__VA_OPT__( )
+
+14: F()
+15: F(1)
+
+// CHECK: 14: "" X ""
+// CHECK: 15: "" X ""
+
+#undef F
+
+#define SDEF(sname, ...) S sname __VA_OPT__(= { __VA_ARGS__ })
+
+16: SDEF(foo); // replaced by S foo;
+17: SDEF(bar, 1, 2); // replaced by S bar = { 1, 2 };
+
+// CHECK: 16: S foo ;
+// CHECK: 17: S bar = { 1, 2 };
+#undef SDEF
+
+#define F(a,...) A() #__VA_OPT__(A3 __VA_ARGS__ a ## __VA_ARGS__ ## a ## C A3) A()
+
+18: F()
+19: F(,)
+20: F(,A3)
+21: F(A3, A(),A0)
+
+
+// CHECK: 18: B ( ) "" B ( )
+// CHECK: 19: B ( ) "" B ( )
+// CHECK: 20: B ( ) "A3 expandedA3 expandedA2 expandedA1 expandedA0 A3C A3" B ( )
+// CHECK: 21: B ( ) "A3 B ( ),expandedA0 A3A(),A0A3C A3" B ( )
+
+#undef F
+
+#define F(a,...) A() #__VA_OPT__(A3 __VA_ARGS__ a ## __VA_ARGS__ ## a ## C A3) a __VA_OPT__(A0 __VA_ARGS__ a ## __VA_ARGS__ ## a ## C A0) A()
+
+22: F()
+23: F(,)
+24: F(,A0)
+25: F(A0, A(),A0)
+
+
+// CHECK: 22: B ( ) "" B ( )
+// CHECK: 23: B ( ) "" B ( )
+// CHECK: 24: B ( ) "A3 expandedA0 A0C A3" expandedA0 expandedA0 A0C expandedA0 B ( )
+// CHECK: 25: B ( ) "A3 B ( ),expandedA0 A0A(),A0A0C A3" expandedA0 expandedA0 C ( ),expandedA0 A0A(),A0A0C expandedA0 B ( )
+
+#undef F
+
+#define F(a,...) __VA_OPT__(B a ## a) ## 1
+#define G(a,...) __VA_OPT__(B a) ## 1
+26: F(,1)
+26_1: G(,1)
+// CHECK: 26: B1
+// CHECK: 26_1: B1
+#undef F
+#undef G
+
+#define F(a,...) B ## __VA_OPT__(a 1) ## 1
+#define G(a,...) B ## __VA_OPT__(a ## a 1) ## 1
+
+27: F(,1)
+27_1: F(A0,1)
+28: G(,1)
+// CHECK: 27: B11
+// CHECK: 27_1: BexpandedA0 11
+// CHECK: 28: B11
+
+#undef F
+#undef G
diff --git a/test/Preprocessor/pr19649-unsigned-wchar_t.c b/test/Preprocessor/pr19649-unsigned-wchar_t.c
index 4bbe1b57ce46..0f0886b2e909 100644
--- a/test/Preprocessor/pr19649-unsigned-wchar_t.c
+++ b/test/Preprocessor/pr19649-unsigned-wchar_t.c
@@ -1,5 +1,5 @@
// RUN: %clang_cc1 -triple i386-pc-cygwin -E -x c %s
-// RUN: %clang_cc1 -triple powerpc64-unknown-linux-gnu -E -fshort-wchar -x c %s
+// RUN: %clang_cc1 -triple powerpc64-unknown-linux-gnu -E -fwchar-type=short -fno-signed-wchar -x c %s
#if (L'\0' - 1 < 0)
# error "Unexpected expression evaluation result"
diff --git a/test/Preprocessor/pragma_assume_nonnull.c b/test/Preprocessor/pragma_assume_nonnull.c
new file mode 100644
index 000000000000..4aa124113e2d
--- /dev/null
+++ b/test/Preprocessor/pragma_assume_nonnull.c
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -E %s | FileCheck %s
+
+// CHECK: #pragma clang assume_nonnull begin
+#pragma clang assume_nonnull begin
+
+int bar(int * ip) { return *ip; }
+
+// CHECK: #pragma clang assume_nonnull end
+#pragma clang assume_nonnull end
+
+int foo(int * _Nonnull ip) { return *ip; }
+
+int main() {
+ return bar(0) + foo(0); // expected-warning 2 {{null passed to a callee that requires a non-null argument}}
+}
diff --git a/test/Preprocessor/predefined-arch-macros.c b/test/Preprocessor/predefined-arch-macros.c
index 85e78b661d47..892e2783942e 100644
--- a/test/Preprocessor/predefined-arch-macros.c
+++ b/test/Preprocessor/predefined-arch-macros.c
@@ -156,6 +156,8 @@
// CHECK_I686_M32: #define __i686__ 1
// CHECK_I686_M32: #define __pentiumpro 1
// CHECK_I686_M32: #define __pentiumpro__ 1
+// CHECK_I686_M32: #define __tune_i686__ 1
+// CHECK_I686_M32: #define __tune_pentiumpro__ 1
// CHECK_I686_M32: #define i386 1
// RUN: not %clang -march=i686 -m64 -E -dM %s -o - 2>&1 \
// RUN: -target i386-unknown-linux \
@@ -783,6 +785,77 @@
// CHECK_KNL_M64: #define __tune_knl__ 1
// CHECK_KNL_M64: #define __x86_64 1
// CHECK_KNL_M64: #define __x86_64__ 1
+
+// RUN: %clang -march=knm -m32 -E -dM %s -o - 2>&1 \
+// RUN: -target i386-unknown-linux \
+// RUN: | FileCheck -match-full-lines %s -check-prefix=CHECK_KNM_M32
+// CHECK_KNM_M32: #define __AES__ 1
+// CHECK_KNM_M32: #define __AVX2__ 1
+// CHECK_KNM_M32: #define __AVX512CD__ 1
+// CHECK_KNM_M32: #define __AVX512ER__ 1
+// CHECK_KNM_M32: #define __AVX512F__ 1
+// CHECK_KNM_M32: #define __AVX512PF__ 1
+// CHECK_KNM_M32: #define __AVX512VPOPCNTDQ__ 1
+// CHECK_KNM_M32: #define __AVX__ 1
+// CHECK_KNM_M32: #define __BMI2__ 1
+// CHECK_KNM_M32: #define __BMI__ 1
+// CHECK_KNM_M32: #define __F16C__ 1
+// CHECK_KNM_M32: #define __FMA__ 1
+// CHECK_KNM_M32: #define __LZCNT__ 1
+// CHECK_KNM_M32: #define __MMX__ 1
+// CHECK_KNM_M32: #define __PCLMUL__ 1
+// CHECK_KNM_M32: #define __POPCNT__ 1
+// CHECK_KNM_M32: #define __PREFETCHWT1__ 1
+// CHECK_KNM_M32: #define __RDRND__ 1
+// CHECK_KNM_M32: #define __RTM__ 1
+// CHECK_KNM_M32: #define __SSE2__ 1
+// CHECK_KNM_M32: #define __SSE3__ 1
+// CHECK_KNM_M32: #define __SSE4_1__ 1
+// CHECK_KNM_M32: #define __SSE4_2__ 1
+// CHECK_KNM_M32: #define __SSE__ 1
+// CHECK_KNM_M32: #define __SSSE3__ 1
+// CHECK_KNM_M32: #define __XSAVEOPT__ 1
+// CHECK_KNM_M32: #define __XSAVE__ 1
+// CHECK_KNM_M32: #define __i386 1
+// CHECK_KNM_M32: #define __i386__ 1
+// CHECK_KNM_M32: #define i386 1
+
+// RUN: %clang -march=knm -m64 -E -dM %s -o - 2>&1 \
+// RUN: -target i386-unknown-linux \
+// RUN: | FileCheck -match-full-lines %s -check-prefix=CHECK_KNM_M64
+// CHECK_KNM_M64: #define __AES__ 1
+// CHECK_KNM_M64: #define __AVX2__ 1
+// CHECK_KNM_M64: #define __AVX512CD__ 1
+// CHECK_KNM_M64: #define __AVX512ER__ 1
+// CHECK_KNM_M64: #define __AVX512F__ 1
+// CHECK_KNM_M64: #define __AVX512PF__ 1
+// CHECK_KNM_M64: #define __AVX512VPOPCNTDQ__ 1
+// CHECK_KNM_M64: #define __AVX__ 1
+// CHECK_KNM_M64: #define __BMI2__ 1
+// CHECK_KNM_M64: #define __BMI__ 1
+// CHECK_KNM_M64: #define __F16C__ 1
+// CHECK_KNM_M64: #define __FMA__ 1
+// CHECK_KNM_M64: #define __LZCNT__ 1
+// CHECK_KNM_M64: #define __MMX__ 1
+// CHECK_KNM_M64: #define __PCLMUL__ 1
+// CHECK_KNM_M64: #define __POPCNT__ 1
+// CHECK_KNM_M64: #define __PREFETCHWT1__ 1
+// CHECK_KNM_M64: #define __RDRND__ 1
+// CHECK_KNM_M64: #define __RTM__ 1
+// CHECK_KNM_M64: #define __SSE2_MATH__ 1
+// CHECK_KNM_M64: #define __SSE2__ 1
+// CHECK_KNM_M64: #define __SSE3__ 1
+// CHECK_KNM_M64: #define __SSE4_1__ 1
+// CHECK_KNM_M64: #define __SSE4_2__ 1
+// CHECK_KNM_M64: #define __SSE_MATH__ 1
+// CHECK_KNM_M64: #define __SSE__ 1
+// CHECK_KNM_M64: #define __SSSE3__ 1
+// CHECK_KNM_M64: #define __XSAVEOPT__ 1
+// CHECK_KNM_M64: #define __XSAVE__ 1
+// CHECK_KNM_M64: #define __amd64 1
+// CHECK_KNM_M64: #define __amd64__ 1
+// CHECK_KNM_M64: #define __x86_64 1
+// CHECK_KNM_M64: #define __x86_64__ 1
//
// RUN: %clang -march=skylake-avx512 -m32 -E -dM %s -o - 2>&1 \
// RUN: -target i386-unknown-linux \
@@ -819,11 +892,11 @@
// CHECK_SKX_M32: #define __XSAVEOPT__ 1
// CHECK_SKX_M32: #define __XSAVES__ 1
// CHECK_SKX_M32: #define __XSAVE__ 1
+// CHECK_SKX_M32: #define __corei7 1
+// CHECK_SKX_M32: #define __corei7__ 1
// CHECK_SKX_M32: #define __i386 1
// CHECK_SKX_M32: #define __i386__ 1
-// CHECK_SKX_M32: #define __skx 1
-// CHECK_SKX_M32: #define __skx__ 1
-// CHECK_SKX_M32: #define __tune_skx__ 1
+// CHECK_SKX_M32: #define __tune_corei7__ 1
// CHECK_SKX_M32: #define i386 1
// RUN: %clang -march=skylake-avx512 -m64 -E -dM %s -o - 2>&1 \
@@ -865,9 +938,9 @@
// CHECK_SKX_M64: #define __XSAVE__ 1
// CHECK_SKX_M64: #define __amd64 1
// CHECK_SKX_M64: #define __amd64__ 1
-// CHECK_SKX_M64: #define __skx 1
-// CHECK_SKX_M64: #define __skx__ 1
-// CHECK_SKX_M64: #define __tune_skx__ 1
+// CHECK_SKX_M64: #define __corei7 1
+// CHECK_SKX_M64: #define __corei7__ 1
+// CHECK_SKX_M64: #define __tune_corei7__ 1
// CHECK_SKX_M64: #define __x86_64 1
// CHECK_SKX_M64: #define __x86_64__ 1
//
@@ -908,8 +981,11 @@
// CHECK_CNL_M32: #define __XSAVEOPT__ 1
// CHECK_CNL_M32: #define __XSAVES__ 1
// CHECK_CNL_M32: #define __XSAVE__ 1
+// CHECK_CNL_M32: #define __corei7 1
+// CHECK_CNL_M32: #define __corei7__ 1
// CHECK_CNL_M32: #define __i386 1
// CHECK_CNL_M32: #define __i386__ 1
+// CHECK_CNL_M32: #define __tune_corei7__ 1
// CHECK_CNL_M32: #define i386 1
//
// RUN: %clang -march=cannonlake -m64 -E -dM %s -o - 2>&1 \
@@ -951,9 +1027,101 @@
// CHECK_CNL_M64: #define __XSAVE__ 1
// CHECK_CNL_M64: #define __amd64 1
// CHECK_CNL_M64: #define __amd64__ 1
+// CHECK_CNL_M64: #define __corei7 1
+// CHECK_CNL_M64: #define __corei7__ 1
+// CHECK_CNL_M64: #define __tune_corei7__ 1
// CHECK_CNL_M64: #define __x86_64 1
// CHECK_CNL_M64: #define __x86_64__ 1
+// RUN: %clang -march=icelake -m32 -E -dM %s -o - 2>&1 \
+// RUN: -target i386-unknown-linux \
+// RUN: | FileCheck -match-full-lines %s -check-prefix=CHECK_ICL_M32
+// CHECK_ICL_M32: #define __AES__ 1
+// CHECK_ICL_M32: #define __AVX2__ 1
+// CHECK_ICL_M32: #define __AVX512BW__ 1
+// CHECK_ICL_M32: #define __AVX512CD__ 1
+// CHECK_ICL_M32: #define __AVX512DQ__ 1
+// CHECK_ICL_M32: #define __AVX512F__ 1
+// CHECK_ICL_M32: #define __AVX512IFMA__ 1
+// CHECK_ICL_M32: #define __AVX512VBMI__ 1
+// CHECK_ICL_M32: #define __AVX512VL__ 1
+// CHECK_ICL_M32: #define __AVX__ 1
+// CHECK_ICL_M32: #define __BMI2__ 1
+// CHECK_ICL_M32: #define __BMI__ 1
+// CHECK_ICL_M32: #define __CLFLUSHOPT__ 1
+// CHECK_ICL_M32: #define __F16C__ 1
+// CHECK_ICL_M32: #define __FMA__ 1
+// CHECK_ICL_M32: #define __LZCNT__ 1
+// CHECK_ICL_M32: #define __MMX__ 1
+// CHECK_ICL_M32: #define __MPX__ 1
+// CHECK_ICL_M32: #define __PCLMUL__ 1
+// CHECK_ICL_M32: #define __POPCNT__ 1
+// CHECK_ICL_M32: #define __RDRND__ 1
+// CHECK_ICL_M32: #define __RTM__ 1
+// CHECK_ICL_M32: #define __SGX__ 1
+// CHECK_ICL_M32: #define __SHA__ 1
+// CHECK_ICL_M32: #define __SSE2__ 1
+// CHECK_ICL_M32: #define __SSE3__ 1
+// CHECK_ICL_M32: #define __SSE4_1__ 1
+// CHECK_ICL_M32: #define __SSE4_2__ 1
+// CHECK_ICL_M32: #define __SSE__ 1
+// CHECK_ICL_M32: #define __SSSE3__ 1
+// CHECK_ICL_M32: #define __XSAVEC__ 1
+// CHECK_ICL_M32: #define __XSAVEOPT__ 1
+// CHECK_ICL_M32: #define __XSAVES__ 1
+// CHECK_ICL_M32: #define __XSAVE__ 1
+// CHECK_ICL_M32: #define __corei7 1
+// CHECK_ICL_M32: #define __corei7__ 1
+// CHECK_ICL_M32: #define __i386 1
+// CHECK_ICL_M32: #define __i386__ 1
+// CHECK_ICL_M32: #define __tune_corei7__ 1
+// CHECK_ICL_M32: #define i386 1
+//
+// RUN: %clang -march=icelake -m64 -E -dM %s -o - 2>&1 \
+// RUN: -target i386-unknown-linux \
+// RUN: | FileCheck -match-full-lines %s -check-prefix=CHECK_ICL_M64
+// CHECK_ICL_M64: #define __AES__ 1
+// CHECK_ICL_M64: #define __AVX2__ 1
+// CHECK_ICL_M64: #define __AVX512BW__ 1
+// CHECK_ICL_M64: #define __AVX512CD__ 1
+// CHECK_ICL_M64: #define __AVX512DQ__ 1
+// CHECK_ICL_M64: #define __AVX512F__ 1
+// CHECK_ICL_M64: #define __AVX512IFMA__ 1
+// CHECK_ICL_M64: #define __AVX512VBMI__ 1
+// CHECK_ICL_M64: #define __AVX512VL__ 1
+// CHECK_ICL_M64: #define __AVX__ 1
+// CHECK_ICL_M64: #define __BMI2__ 1
+// CHECK_ICL_M64: #define __BMI__ 1
+// CHECK_ICL_M64: #define __CLFLUSHOPT__ 1
+// CHECK_ICL_M64: #define __F16C__ 1
+// CHECK_ICL_M64: #define __FMA__ 1
+// CHECK_ICL_M64: #define __LZCNT__ 1
+// CHECK_ICL_M64: #define __MMX__ 1
+// CHECK_ICL_M64: #define __MPX__ 1
+// CHECK_ICL_M64: #define __PCLMUL__ 1
+// CHECK_ICL_M64: #define __POPCNT__ 1
+// CHECK_ICL_M64: #define __RDRND__ 1
+// CHECK_ICL_M64: #define __RTM__ 1
+// CHECK_ICL_M64: #define __SGX__ 1
+// CHECK_ICL_M64: #define __SHA__ 1
+// CHECK_ICL_M64: #define __SSE2__ 1
+// CHECK_ICL_M64: #define __SSE3__ 1
+// CHECK_ICL_M64: #define __SSE4_1__ 1
+// CHECK_ICL_M64: #define __SSE4_2__ 1
+// CHECK_ICL_M64: #define __SSE__ 1
+// CHECK_ICL_M64: #define __SSSE3__ 1
+// CHECK_ICL_M64: #define __XSAVEC__ 1
+// CHECK_ICL_M64: #define __XSAVEOPT__ 1
+// CHECK_ICL_M64: #define __XSAVES__ 1
+// CHECK_ICL_M64: #define __XSAVE__ 1
+// CHECK_ICL_M64: #define __amd64 1
+// CHECK_ICL_M64: #define __amd64__ 1
+// CHECK_ICL_M64: #define __corei7 1
+// CHECK_ICL_M64: #define __corei7__ 1
+// CHECK_ICL_M64: #define __tune_corei7__ 1
+// CHECK_ICL_M64: #define __x86_64 1
+// CHECK_ICL_M64: #define __x86_64__ 1
+
// RUN: %clang -march=atom -m32 -E -dM %s -o - 2>&1 \
// RUN: -target i386-unknown-linux \
// RUN: | FileCheck -match-full-lines %s -check-prefix=CHECK_ATOM_M32
@@ -991,6 +1159,7 @@
// RUN: | FileCheck %s -check-prefix=CHECK_GLM_M32
// CHECK_GLM_M32: #define __AES__ 1
// CHECK_GLM_M32: #define __CLFLUSHOPT__ 1
+// CHECK_GLM_M32: #define __FSGSBASE__ 1
// CHECK_GLM_M32: #define __FXSR__ 1
// CHECK_GLM_M32: #define __MMX__ 1
// CHECK_GLM_M32: #define __MPX__ 1
@@ -1010,26 +1179,19 @@
// CHECK_GLM_M32: #define __XSAVEOPT__ 1
// CHECK_GLM_M32: #define __XSAVES__ 1
// CHECK_GLM_M32: #define __XSAVE__ 1
-// CHECK_GLM_M32: #define __clang__ 1
// CHECK_GLM_M32: #define __goldmont 1
// CHECK_GLM_M32: #define __goldmont__ 1
// CHECK_GLM_M32: #define __i386 1
// CHECK_GLM_M32: #define __i386__ 1
-// CHECK_GLM_M32: #define __linux 1
-// CHECK_GLM_M32: #define __linux__ 1
-// CHECK_GLM_M32: #define __llvm__ 1
// CHECK_GLM_M32: #define __tune_goldmont__ 1
-// CHECK_GLM_M32: #define __unix 1
-// CHECK_GLM_M32: #define __unix__ 1
// CHECK_GLM_M32: #define i386 1
-// CHECK_GLM_M32: #define linux 1
-// CHECK_GLM_M32: #define unix 1
//
// RUN: %clang -march=goldmont -m64 -E -dM %s -o - 2>&1 \
// RUN: -target i386-unknown-linux \
// RUN: | FileCheck %s -check-prefix=CHECK_GLM_M64
// CHECK_GLM_M64: #define __AES__ 1
// CHECK_GLM_M64: #define __CLFLUSHOPT__ 1
+// CHECK_GLM_M64: #define __FSGSBASE__ 1
// CHECK_GLM_M64: #define __FXSR__ 1
// CHECK_GLM_M64: #define __MMX__ 1
// CHECK_GLM_M64: #define __MPX__ 1
@@ -1047,19 +1209,11 @@
// CHECK_GLM_M64: #define __XSAVEOPT__ 1
// CHECK_GLM_M64: #define __XSAVES__ 1
// CHECK_GLM_M64: #define __XSAVE__ 1
-// CHECK_GLM_M64: #define __gnu_linux__ 1
// CHECK_GLM_M64: #define __goldmont 1
// CHECK_GLM_M64: #define __goldmont__ 1
-// CHECK_GLM_M64: #define __linux 1
-// CHECK_GLM_M64: #define __linux__ 1
-// CHECK_GLM_M64: #define __llvm__ 1
// CHECK_GLM_M64: #define __tune_goldmont__ 1
-// CHECK_GLM_M64: #define __unix 1
-// CHECK_GLM_M64: #define __unix__ 1
// CHECK_GLM_M64: #define __x86_64 1
// CHECK_GLM_M64: #define __x86_64__ 1
-// CHECK_GLM_M64: #define linux 1
-// CHECK_GLM_M64: #define unix 1
//
// RUN: %clang -march=slm -m32 -E -dM %s -o - 2>&1 \
// RUN: -target i386-unknown-linux \
@@ -1099,15 +1253,19 @@
//
// RUN: %clang -march=lakemont -m32 -E -dM %s -o - 2>&1 \
// RUN: -target i386-unknown-linux \
-// RUN: | FileCheck %s -check-prefix=CHECK_LMT_M32
-// CHECK_LMT_M32: #define __i386 1
-// CHECK_LMT_M32: #define __i386__ 1
-// CHECK_LMT_M32: #define __tune_lakemont__ 1
-// CHECK_LMT_M32: #define i386 1
+// RUN: | FileCheck %s -check-prefix=CHECK_LAKEMONT_M32
+// CHECK_LAKEMONT_M32: #define __i386 1
+// CHECK_LAKEMONT_M32: #define __i386__ 1
+// CHECK_LAKEMONT_M32: #define __i586 1
+// CHECK_LAKEMONT_M32: #define __i586__ 1
+// CHECK_LAKEMONT_M32: #define __pentium 1
+// CHECK_LAKEMONT_M32: #define __pentium__ 1
+// CHECK_LAKEMONT_M32: #define __tune_lakemont__ 1
+// CHECK_LAKEMONT_M32: #define i386 1
// RUN: not %clang -march=lakemont -m64 -E -dM %s -o - 2>&1 \
// RUN: -target i386-unknown-linux \
-// RUN: | FileCheck %s -check-prefix=CHECK_LMT_M64
-// CHECK_LMT_M64: error:
+// RUN: | FileCheck %s -check-prefix=CHECK_LAKEMONT_M64
+// CHECK_LAKEMONT_M64: error:
//
// RUN: %clang -march=geode -m32 -E -dM %s -o - 2>&1 \
// RUN: -target i386-unknown-linux \
@@ -2135,21 +2293,61 @@
// RUN: -target sparcel-unknown-linux \
// RUN: | FileCheck -match-full-lines %s -check-prefix=CHECK_SPARCEL
// RUN: %clang -E -dM %s -o - -target sparcel-myriad -mcpu=myriad2 2>&1 \
-// RUN: | FileCheck -match-full-lines %s -check-prefix=CHECK_MYRIAD2-1 -check-prefix=CHECK_SPARCEL
+// RUN: | FileCheck -match-full-lines %s -check-prefix=CHECK_MYRIAD2-2 \
+// RUN: -check-prefix=CHECK_SPARCEL -check-prefix=CHECK_MYRIAD2
// RUN: %clang -E -dM %s -o - -target sparcel-myriad -mcpu=myriad2.1 2>&1 \
-// RUN: | FileCheck -match-full-lines %s -check-prefix=CHECK_MYRIAD2-1 -check-prefix=CHECK_SPARCEL
+// RUN: | FileCheck -match-full-lines %s -check-prefix=CHECK_MYRIAD2-1 \
+// RUN: -check-prefix=CHECK_SPARCEL -check-prefix=CHECK_MYRIAD2
// RUN: %clang -E -dM %s -o - -target sparcel-myriad -mcpu=myriad2.2 2>&1 \
-// RUN: | FileCheck -match-full-lines %s -check-prefix=CHECK_MYRIAD2-2 -check-prefix=CHECK_SPARCEL
+// RUN: | FileCheck -match-full-lines %s -check-prefix=CHECK_MYRIAD2-2 \
+// RUN: -check-prefix=CHECK_SPARCEL -check-prefix=CHECK_MYRIAD2
+// RUN: %clang -E -dM %s -o - -target sparcel-myriad -mcpu=myriad2.3 2>&1 \
+// RUN: | FileCheck -match-full-lines %s -check-prefix=CHECK_MYRIAD2-3 \
+// RUN: -check-prefix=CHECK_SPARCEL -check-prefix=CHECK_MYRIAD2
+// RUN: %clang -E -dM %s -o - -target sparcel-myriad -mcpu=ma2100 2>&1 \
+// RUN: | FileCheck -match-full-lines %s -check-prefix=CHECK_MYRIAD2-1 \
+// RUN: -check-prefix=CHECK_SPARCEL -check-prefix=CHECK_MYRIAD2
+// RUN: %clang -E -dM %s -o - -target sparcel-myriad -mcpu=ma2150 2>&1 \
+// RUN: | FileCheck -match-full-lines %s -check-prefix=CHECK_MYRIAD2-2 \
+// RUN: -check-prefix=CHECK_SPARCEL -check-prefix=CHECK_MYRIAD2
+// RUN: %clang -E -dM %s -o - -target sparcel-myriad -mcpu=ma2155 2>&1 \
+// RUN: | FileCheck -match-full-lines %s -check-prefix=CHECK_MYRIAD2-2 \
+// RUN: -check-prefix=CHECK_SPARCEL -check-prefix=CHECK_MYRIAD2
// RUN: %clang -E -dM %s -o - -target sparcel-myriad -mcpu=ma2450 2>&1 \
-// RUN: | FileCheck -match-full-lines %s -check-prefix=CHECK_MYRIAD2-2 -check-prefix=CHECK_SPARCEL
+// RUN: | FileCheck -match-full-lines %s -check-prefix=CHECK_MYRIAD2-2 \
+// RUN: -check-prefix=CHECK_SPARCEL -check-prefix=CHECK_MYRIAD2
+// RUN: %clang -E -dM %s -o - -target sparcel-myriad -mcpu=ma2455 2>&1 \
+// RUN: | FileCheck -match-full-lines %s -check-prefix=CHECK_MYRIAD2-2 \
+// RUN: -check-prefix=CHECK_SPARCEL -check-prefix=CHECK_MYRIAD2
+// RUN: %clang -E -dM %s -o - -target sparcel-myriad -mcpu=ma2x5x 2>&1 \
+// RUN: | FileCheck -match-full-lines %s -check-prefix=CHECK_MYRIAD2-2 \
+// RUN: -check-prefix=CHECK_SPARCEL -check-prefix=CHECK_MYRIAD2
+// RUN: %clang -E -dM %s -o - -target sparcel-myriad -mcpu=ma2080 2>&1 \
+// RUN: | FileCheck -match-full-lines %s -check-prefix=CHECK_MYRIAD2-3 \
+// RUN: -check-prefix=CHECK_SPARCEL -check-prefix=CHECK_MYRIAD2
+// RUN: %clang -E -dM %s -o - -target sparcel-myriad -mcpu=ma2085 2>&1 \
+// RUN: | FileCheck -match-full-lines %s -check-prefix=CHECK_MYRIAD2-3 \
+// RUN: -check-prefix=CHECK_SPARCEL -check-prefix=CHECK_MYRIAD2
+// RUN: %clang -E -dM %s -o - -target sparcel-myriad -mcpu=ma2480 2>&1 \
+// RUN: | FileCheck -match-full-lines %s -check-prefix=CHECK_MYRIAD2-3 \
+// RUN: -check-prefix=CHECK_SPARCEL -check-prefix=CHECK_MYRIAD2
+// RUN: %clang -E -dM %s -o - -target sparcel-myriad -mcpu=ma2485 2>&1 \
+// RUN: | FileCheck -match-full-lines %s -check-prefix=CHECK_MYRIAD2-3 \
+// RUN: -check-prefix=CHECK_SPARCEL -check-prefix=CHECK_MYRIAD2
+// RUN: %clang -E -dM %s -o - -target sparcel-myriad -mcpu=ma2x8x 2>&1 \
+// RUN: | FileCheck -match-full-lines %s -check-prefix=CHECK_MYRIAD2-3 \
+// RUN: -check-prefix=CHECK_SPARCEL -check-prefix=CHECK_MYRIAD2
// CHECK_SPARCEL: #define __LITTLE_ENDIAN__ 1
+// CHECK_MYRIAD2: #define __leon__ 1
// CHECK_MYRIAD2-1: #define __myriad2 1
// CHECK_MYRIAD2-1: #define __myriad2__ 1
// CHECK_MYRIAD2-2: #define __myriad2 2
// CHECK_MYRIAD2-2: #define __myriad2__ 2
+// CHECK_MYRIAD2-3: #define __myriad2 3
+// CHECK_MYRIAD2-3: #define __myriad2__ 3
// CHECK_SPARCEL: #define __sparc 1
// CHECK_SPARCEL: #define __sparc__ 1
-// CHECK_MYRIAD2-1: #define __sparc_v8__ 1
+// CHECK_MYRIAD2: #define __sparc_v8__ 1
// CHECK_SPARCEL: #define __sparcv8 1
//
// RUN: %clang -E -dM %s -o - 2>&1 \
diff --git a/test/Preprocessor/predefined-macros.c b/test/Preprocessor/predefined-macros.c
index 662a712d6477..def1ef90f55d 100644
--- a/test/Preprocessor/predefined-macros.c
+++ b/test/Preprocessor/predefined-macros.c
@@ -185,9 +185,89 @@
// CHECK-CL20-NOT: #define __FAST_RELAXED_MATH__ 1
// CHECK-FRM: #define __FAST_RELAXED_MATH__ 1
-// RUN: %clang_cc1 -triple aarch64-windows %s -E -dM -o - -x cl \
+// RUN: %clang_cc1 %s -E -dM -o - -x cl \
+// RUN: | FileCheck %s --check-prefix=MSCOPE
+// MSCOPE:#define __OPENCL_MEMORY_SCOPE_ALL_SVM_DEVICES 3
+// MSCOPE:#define __OPENCL_MEMORY_SCOPE_DEVICE 2
+// MSCOPE:#define __OPENCL_MEMORY_SCOPE_SUB_GROUP 4
+// MSCOPE:#define __OPENCL_MEMORY_SCOPE_WORK_GROUP 1
+// MSCOPE:#define __OPENCL_MEMORY_SCOPE_WORK_ITEM 0
+
+// RUN: %clang_cc1 -triple i386-windows %s -E -dM -o - \
+// RUN: | FileCheck -match-full-lines %s --check-prefix=CHECK-X86-WIN
+
+// CHECK-X86-WIN-NOT: #define WIN32 1
+// CHECK-X86-WIN-NOT: #define WIN64 1
+// CHECK-X86-WIN-NOT: #define WINNT 1
+// CHECK-X86-WIN: #define _WIN32 1
+// CHECK-X86-WIN-NOT: #define _WIN64 1
+
+// RUN: %clang_cc1 -triple thumbv7-windows %s -E -dM -o - \
+// RUN: | FileCheck -match-full-lines %s --check-prefix=CHECK-ARM-WIN
+
+// CHECK-ARM-WIN-NOT: #define WIN32 1
+// CHECK-ARM-WIN-NOT: #define WIN64 1
+// CHECK-ARM-WIN-NOT: #define WINNT 1
+// CHECK-ARM-WIN: #define _WIN32 1
+// CHECK-ARM-WIN-NOT: #define _WIN64 1
+
+// RUN: %clang_cc1 -triple x86_64-windows %s -E -dM -o - \
+// RUN: | FileCheck -match-full-lines %s --check-prefix=CHECK-AMD64-WIN
+
+// CHECK-AMD64-WIN-NOT: #define WIN32 1
+// CHECK-AMD64-WIN-NOT: #define WIN64 1
+// CHECK-AMD64-WIN-NOT: #define WINNT 1
+// CHECK-AMD64-WIN: #define _WIN32 1
+// CHECK-AMD64-WIN: #define _WIN64 1
+
+// RUN: %clang_cc1 -triple aarch64-windows %s -E -dM -o - \
// RUN: | FileCheck -match-full-lines %s --check-prefix=CHECK-ARM64-WIN
+// CHECK-ARM64-WIN-NOT: #define WIN32 1
+// CHECK-ARM64-WIN-NOT: #define WIN64 1
+// CHECK-ARM64-WIN-NOT: #define WINNT 1
// CHECK-ARM64-WIN: #define _M_ARM64 1
// CHECK-ARM64-WIN: #define _WIN32 1
// CHECK-ARM64-WIN: #define _WIN64 1
+
+// RUN: %clang_cc1 -triple i686-windows-gnu %s -E -dM -o - \
+// RUN: | FileCheck -match-full-lines %s --check-prefix=CHECK-X86-MINGW
+
+// CHECK-X86-MINGW: #define WIN32 1
+// CHECK-X86-MINGW-NOT: #define WIN64 1
+// CHECK-X86-MINGW: #define WINNT 1
+// CHECK-X86-MINGW: #define _WIN32 1
+// CHECK-X86-MINGW-NOT: #define _WIN64 1
+
+// RUN: %clang_cc1 -triple thumbv7-windows-gnu %s -E -dM -o - \
+// RUN: | FileCheck -match-full-lines %s --check-prefix=CHECK-ARM-MINGW
+
+// CHECK-ARM-MINGW: #define WIN32 1
+// CHECK-ARM-MINGW-NOT: #define WIN64 1
+// CHECK-ARM-MINGW: #define WINNT 1
+// CHECK-ARM-MINGW: #define _WIN32 1
+// CHECK-ARM-MINGW-NOT: #define _WIN64 1
+
+// RUN: %clang_cc1 -triple x86_64-windows-gnu %s -E -dM -o - \
+// RUN: | FileCheck -match-full-lines %s --check-prefix=CHECK-AMD64-MINGW
+
+// CHECK-AMD64-MINGW: #define WIN32 1
+// CHECK-AMD64-MINGW: #define WIN64 1
+// CHECK-AMD64-MINGW: #define WINNT 1
+// CHECK-AMD64-MINGW: #define _WIN32 1
+// CHECK-AMD64-MINGW: #define _WIN64 1
+
+// RUN: %clang_cc1 -triple aarch64-windows-gnu %s -E -dM -o - \
+// RUN: | FileCheck -match-full-lines %s --check-prefix=CHECK-ARM64-MINGW
+
+// CHECK-ARM64-MINGW-NOT: #define _M_ARM64 1
+// CHECK-ARM64-MINGW: #define WIN32 1
+// CHECK-ARM64-MINGW: #define WIN64 1
+// CHECK-ARM64-MINGW: #define WINNT 1
+// CHECK-ARM64-MINGW: #define _WIN32 1
+// CHECK-ARM64-MINGW: #define _WIN64 1
+// CHECK-ARM64-MINGW: #define __aarch64__ 1
+
+// RUN: %clang_cc1 %s -E -dM -o - -x cl -triple spir-unknown-unknown \
+// RUN: | FileCheck -match-full-lines %s --check-prefix=CHECK-SPIR
+// CHECK-SPIR: #define __IMAGE_SUPPORT__ 1
diff --git a/test/Preprocessor/print-assembler.s b/test/Preprocessor/print-assembler.s
new file mode 100644
index 000000000000..c4e2e031f2d5
--- /dev/null
+++ b/test/Preprocessor/print-assembler.s
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -E -x assembler-with-cpp %s -o - | FileCheck %s --strict-whitespace
+
+.intel_syntax noprefix
+.text
+ .global _main
+_main:
+# asdf
+# asdf
+ mov bogus_name, 20
+ mov rax, 5
+ ret
+
+// CHECK-LABEL: _main:
+// CHECK-NEXT: {{^}} # asdf
+// CHECK-NEXT: {{^}} # asdf
+// CHECK-NEXT: mov bogus_name, 20
diff --git a/test/Preprocessor/stdint.c b/test/Preprocessor/stdint.c
index 01b0da718627..3b32346d5edc 100644
--- a/test/Preprocessor/stdint.c
+++ b/test/Preprocessor/stdint.c
@@ -28,8 +28,8 @@
// ARM:typedef int8_t int_fast8_t;
// ARM:typedef uint8_t uint_fast8_t;
//
-// ARM:typedef long int intptr_t;
-// ARM:typedef long unsigned int uintptr_t;
+// ARM:typedef int intptr_t;
+// ARM:typedef unsigned int uintptr_t;
//
// ARM:typedef long long int intmax_t;
// ARM:typedef long long unsigned int uintmax_t;
@@ -74,9 +74,9 @@
// ARM:INT_FAST64_MAX_ 9223372036854775807LL
// ARM:UINT_FAST64_MAX_ 18446744073709551615ULL
//
-// ARM:INTPTR_MIN_ (-2147483647L -1)
-// ARM:INTPTR_MAX_ 2147483647L
-// ARM:UINTPTR_MAX_ 4294967295UL
+// ARM:INTPTR_MIN_ (-2147483647 -1)
+// ARM:INTPTR_MAX_ 2147483647
+// ARM:UINTPTR_MAX_ 4294967295U
// ARM:PTRDIFF_MIN_ (-2147483647 -1)
// ARM:PTRDIFF_MAX_ 2147483647
// ARM:SIZE_MAX_ 4294967295U
diff --git a/test/Preprocessor/wchar_t.c b/test/Preprocessor/wchar_t.c
new file mode 100644
index 000000000000..6c47a2bb6a37
--- /dev/null
+++ b/test/Preprocessor/wchar_t.c
@@ -0,0 +1,113 @@
+// RUN: %clang_cc1 -triple i386-pc-solaris -dM -E %s -o - | FileCheck %s -check-prefix CHECK-SOLARIS
+// CHECK-SOLARIS-DAG: #define __WCHAR_MAX__ 2147483647
+// CHECK-SOLARIS-DAG: #define __WCHAR_TYPE__ int
+// CHECK-SOLARIS-NOT: #define __WCHAR_UNSIGNED__ 0
+
+// RUN: %clang_cc1 -triple avr-unknown-unknown -fwchar-type=int -fsigned-wchar -dM -E %s -o - | FileCheck %s -check-prefix CHECK-AVR
+// CHECK-AVR-DAG: #define __WCHAR_MAX__ 32767
+// CHECK-AVR-DAG: #define __WCHAR_TYPE__ int
+// CHECK-AVR-NOT: #define __WCHAR_UNSIGNED__ 0
+
+// RUN: %clang_cc1 -triple arm-unknown-none-gnu -fsigned-wchar -dM -E %s -o - | FileCheck %s -check-prefix CHECK-ARM-APCS
+// CHECK-ARM-APCS-DAG: #define __WCHAR_MAX__ 2147483647
+// CHECK-ARM-APCS-DAG: #define __WCHAR_TYPE__ int
+// CHECK-ARM-APCS-NOT: #define __WCHAR_UNSIGNED__ 0
+
+// RUN: %clang_cc1 -triple arm-unknown-netbsd-gnu -fsigned-wchar -dM -E %s -o - | FileCheck %s -check-prefix CHECK-ARM-NETBSD-AAPCS
+// CHECK-ARM-NETBSD-AAPCS-DAG: #define __WCHAR_MAX__ 2147483647
+// CHECK-ARM-NETBSD-AAPCS-DAG: #define __WCHAR_TYPE__ int
+// CHECK-ARM-NETBSD-AAPCS-NOT: #define __WCHAR_UNSIGNED__ 0
+
+// RUN: %clang_cc1 -triple arm-unknown-openbsd -fsigned-wchar -dM -E %s -o - | FileCheck %s -check-prefix CHECK-ARM-OPENBSD
+// CHECK-ARM-OPENBSD-DAG: #define __WCHAR_MAX__ 2147483647
+// CHECK-ARM-OPENBSD-DAG: #define __WCHAR_TYPE__ int
+// CHECK-ARM-OPENBSD-NOT: #define __WCHAR_UNSIGNED__ 0
+
+// RUN: %clang_cc1 -triple arm64-apple-ios -fsigned-wchar -dM -E %s -o - | FileCheck %s -check-prefix CHECK-ARM64-DARWIN
+// CHECK-ARM64-DARWIN-DAG: #define __WCHAR_MAX__ 2147483647
+// CHECK-ARM64-DARWIN-DAG: #define __WCHAR_TYPE__ int
+// CHECK-ARM64-DARWIN-NOT: #define __WCHAR_UNSIGNED__ 0
+
+// RUN: %clang_cc1 -triple aarch64-unknown-netbsd -fsigned-wchar -dM -E %s -o - | FileCheck %s -check-prefix CHECK-ARM64-NETBSD
+// CHECK-ARM64-NETBSD-DAG: #define __WCHAR_MAX__ 2147483647
+// CHECK-ARM64-NETBSD-DAG: #define __WCHAR_TYPE__ int
+// CHECK-ARM64-NETBSD-NOT: #define __WCHAR_UNSIGNED__ 0
+
+// RUN: %clang_cc1 -triple aarch64-unknown-openbsd -fsigned-wchar -dM -E %s -o - | FileCheck %s -check-prefix CHECK-ARM64-OPENBSD
+// CHECK-ARM64-OPENBSD-DAG: #define __WCHAR_MAX__ 2147483647
+// CHECK-ARM64-OPENBSD-DAG: #define __WCHAR_TYPE__ int
+// CHECK-ARM64-OPENBSD-NOT: #define __WCHAR_UNSIGNED__ 0
+
+// RUN: %clang_cc1 -triple aarch64-unknown-none -fwchar-type=int -fno-signed-wchar -dM -E %s -o - | FileCheck %s -check-prefix CHECK-ARM64-AAPCS64
+// CHECK-ARM64-AAPCS64-DAG: #define __WCHAR_MAX__ 4294967295U
+// CHECK-ARM64-AAPCS64-DAG: #define __WCHAR_TYPE__ unsigned int
+// CHECK-ARM64-AAPCS64-DAG: #define __WCHAR_UNSIGNED__ 1
+
+// RUN: %clang_cc1 -triple xcore-unknown-unknown -fwchar-type=char -fno-signed-wchar -dM -E %s -o - | FileCheck %s -check-prefix CHECK-XCORE
+// CHECK-XCORE-DAG: #define __WCHAR_MAX__ 255
+// CHECK-XCORE-DAG: #define __WCHAR_TYPE__ unsigned char
+// CHECK-XCORE-DAG: #define __WCHAR_UNSIGNED__ 1
+
+// RUN: %clang_cc1 -triple x86_64-unknown-windows-cygnus -fwchar-type=short -fno-signed-wchar -dM -E %s -o - | FileCheck %s -check-prefix CHECK-CYGWIN-X64
+// CHECK-CYGWIN-X64-DAG: #define __WCHAR_MAX__ 65535
+// CHECK-CYGWIN-X64-DAG: #define __WCHAR_TYPE__ unsigned short
+// CHECK-CYGWIN-X64-DAG: #define __WCHAR_UNSIGNED__ 1
+
+// RUN: %clang_cc1 -triple x86_64-unknown-windows-msvc -fwchar-type=short -fno-signed-wchar -dM -E %s -o - | FileCheck %s -check-prefix CHECK-MSVC-X64
+// CHECK-MSVC-X64-DAG: #define __WCHAR_MAX__ 65535
+// CHECK-MSVC-X64-DAG: #define __WCHAR_TYPE__ unsigned short
+// CHECK-MSVC-X64-DAG: #define __WCHAR_UNSIGNED__ 1
+
+// RUN: %clang_cc1 -triple i686-unknown-windows-cygnus -fwchar-type=short -fno-signed-wchar -dM -E %s -o - | FileCheck %s -check-prefix CHECK-CYGWIN-X86
+// CHECK-CYGWIN-X86-DAG: #define __WCHAR_MAX__ 65535
+// CHECK-CYGWIN-X86-DAG: #define __WCHAR_TYPE__ unsigned short
+// CHECK-CYGWIN-X86-DAG: #define __WCHAR_UNSIGNED__ 1
+
+// RUN: %clang_cc1 -triple i686-unknown-windows-msvc -fwchar-type=short -fno-signed-wchar -dM -E %s -o - | FileCheck %s -check-prefix CHECK-MSVC-X86
+// CHECK-MSVC-X86-DAG: #define __WCHAR_MAX__ 65535
+// CHECK-MSVC-X86-DAG: #define __WCHAR_TYPE__ unsigned short
+// CHECK-MSVC-X86-DAG: #define __WCHAR_UNSIGNED__ 1
+
+// RUN: %clang_cc1 -triple x86_64-scei-ps4 -fwchar-type=short -fno-signed-wchar -dM -E %s -o - | FileCheck %s -check-prefix CHECK-PS4
+// CHECK-PS4-DAG: #define __WCHAR_MAX__ 65535
+// CHECK-PS4-DAG: #define __WCHAR_TYPE__ unsigned short
+// CHECK-PS4-DAG: #define __WCHAR_UNSIGNED__ 1
+
+// RUN: %clang_cc1 -triple thumbv7-unknown-windows-cygnus -fwchar-type=short -fno-signed-wchar -dM -E %s -o - | FileCheck %s -check-prefix CHECK-CYGWIN-ARM
+// CHECK-CYGWIN-ARM-DAG: #define __WCHAR_MAX__ 65535
+// CHECK-CYGWIN-ARM-DAG: #define __WCHAR_TYPE__ unsigned short
+// CHECK-CYGWIN-ARM-DAG: #define __WCHAR_UNSIGNED__ 1
+
+// RUN: %clang_cc1 -triple thumbv7-unknown-windows-msvc -fwchar-type=short -fno-signed-wchar -dM -E %s -o - | FileCheck %s -check-prefix CHECK-MSVC-ARM
+// CHECK-MSVC-ARM-DAG: #define __WCHAR_MAX__ 65535
+// CHECK-MSVC-ARM-DAG: #define __WCHAR_TYPE__ unsigned short
+// CHECK-MSVC-ARM-DAG: #define __WCHAR_UNSIGNED__ 1
+
+// RUN: %clang_cc1 -triple aarch64-unknown-windows-msvc -fwchar-type=short -fno-signed-wchar -dM -E %s -o - | FileCheck %s -check-prefix CHECK-MSVC-ARM64
+// CHECK-MSVC-ARM64-DAG: #define __WCHAR_MAX__ 65535
+// CHECK-MSVC-ARM64-DAG: #define __WCHAR_TYPE__ unsigned short
+// CHECK-MSVC-ARM64-DAG: #define __WCHAR_UNSIGNED__ 1
+
+// RUN: %clang_cc1 -triple i386-apple-macosx -dM -E %s -o - | FileCheck %s -check-prefix CHECK-DARWIN
+// RUN: %clang_cc1 -triple x86_64-apple-macosx -dM -E %s -o - | FileCheck %s -check-prefix CHECK-DARWIN
+// RUN: %clang_cc1 -triple ppc64-apple-macosx -dM -E %s -o - | FileCheck %s -check-prefix CHECK-DARWIN
+// RUN: %clang_cc1 -triple i386-apple-ios -dM -E %s -o - | FileCheck %s -check-prefix CHECK-DARWIN
+// RUN: %clang_cc1 -triple x86_64-apple-ios -dM -E %s -o - | FileCheck %s -check-prefix CHECK-DARWIN
+// RUN: %clang_cc1 -triple armv7-apple-ios -dM -E %s -o - | FileCheck %s -check-prefix CHECK-DARWIN
+// RUN: %clang_cc1 -triple aarch64-apple-ios -dM -E %s -o - | FileCheck %s -check-prefix CHECK-DARWIN
+// RUN: %clang_cc1 -triple i386-apple-tvos -dM -E %s -o - | FileCheck %s -check-prefix CHECK-DARWIN
+// RUN: %clang_cc1 -triple x86_64-apple-tvos -dM -E %s -o - | FileCheck %s -check-prefix CHECK-DARWIN
+// RUN: %clang_cc1 -triple armv7-apple-tvos -dM -E %s -o - | FileCheck %s -check-prefix CHECK-DARWIN
+// RUN: %clang_cc1 -triple aarch64-apple-tvos -dM -E %s -o - | FileCheck %s -check-prefix CHECK-DARWIN
+// RUN: %clang_cc1 -triple i386-apple-watchos -dM -E %s -o - | FileCheck %s -check-prefix CHECK-DARWIN
+// RUN: %clang_cc1 -triple x86_64-apple-watchos -dM -E %s -o - | FileCheck %s -check-prefix CHECK-DARWIN
+// RUN: %clang_cc1 -triple armv7-apple-watchos -dM -E %s -o - | FileCheck %s -check-prefix CHECK-DARWIN
+// RUN: %clang_cc1 -triple aarch64-apple-watchos -dM -E %s -o - | FileCheck %s -check-prefix CHECK-DARWIN
+// CHECK-DARWIN: #define __WCHAR_TYPE__ int
+
+// RUN: %clang_cc1 -triple i686-unknown-windows-msvc -fwchar-type=int -fsigned-wchar -dM -E %s -o - | FileCheck %s -check-prefix CHECK-WINDOWS-ISO10646
+// RUN: %clang_cc1 -triple x86_64-unknown-windows-msvc -fwchar-type=int -fsigned-wchar -dM -E %s -o - | FileCheck %s -check-prefix CHECK-WINDOWS-ISO10646
+// RUN: %clang_cc1 -triple thumbv7-unknown-windows-msvc -fwchar-type=int -fsigned-wchar -dM -E %s -o - | FileCheck %s -check-prefix CHECK-WINDOWS-ISO10646
+// RUN: %clang_cc1 -triple aarch64-unknown-windows-msvc -fwchar-type=int -fsigned-wchar -dM -E %s -o - | FileCheck %s -check-prefix CHECK-WINDOWS-ISO10646
+// CHECK-WINDOWS-ISO10646: #define __WCHAR_TYPE__ int
+
diff --git a/test/Preprocessor/woa-defaults.c b/test/Preprocessor/woa-defaults.c
index 6eab3b96f414..4eef863b23a1 100644
--- a/test/Preprocessor/woa-defaults.c
+++ b/test/Preprocessor/woa-defaults.c
@@ -10,9 +10,12 @@
// CHECK: #define _M_THUMB _M_ARM
// CHECK: #define _WIN32 1
+
// CHECK: #define __ARM_PCS 1
// CHECK: #define __ARM_PCS_VFP 1
// CHECK: #define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
+// CHECK: #define __INTPTR_TYPE__ int
+// CHECK: #define __PTRDIFF_TYPE__ int
// CHECK: #define __SIZEOF_DOUBLE__ 8
// CHECK: #define __SIZEOF_FLOAT__ 4
// CHECK: #define __SIZEOF_INT__ 4
@@ -25,6 +28,8 @@
// CHECK: #define __SIZEOF_SIZE_T__ 4
// CHECK: #define __SIZEOF_WCHAR_T__ 2
// CHECK: #define __SIZEOF_WINT_T__ 4
+// CHECK: #define __SIZE_TYPE__ unsigned int
+// CHECK: #define __UINTPTR_TYPE__ unsigned int
// CHECK-NOT: __THUMB_INTERWORK__
// CHECK-NOT: __ARM_EABI__
diff --git a/test/Preprocessor/x86_target_features.c b/test/Preprocessor/x86_target_features.c
index ce3835f91f42..e2d0e39a03f8 100644
--- a/test/Preprocessor/x86_target_features.c
+++ b/test/Preprocessor/x86_target_features.c
@@ -333,6 +333,10 @@
// ADX: #define __ADX__ 1
+// RUN: %clang -target i386-unknown-unknown -mshstk -x c -E -dM -o - %s | FileCheck -match-full-lines --check-prefix=CETSS %s
+
+// CETSS: #define __SHSTK__ 1
+
// RUN: %clang -target i386-unknown-unknown -march=atom -mrdseed -x c -E -dM -o - %s | FileCheck -match-full-lines --check-prefix=RDSEED %s
// RDSEED: #define __RDSEED__ 1
diff --git a/test/Profile/Inputs/c-captured.proftext b/test/Profile/Inputs/c-captured.proftext
index a35e67b7a402..e82d4f544fbc 100644
--- a/test/Profile/Inputs/c-captured.proftext
+++ b/test/Profile/Inputs/c-captured.proftext
@@ -1,23 +1,23 @@
c-captured.c:__captured_stmt
-10
+42129
2
1
1
c-captured.c:__captured_stmt.1
-266
+4752450705
3
1
10
1
main
-0
+24
1
1
debug_captured
-650
+11043906705
3
1
1
diff --git a/test/Profile/Inputs/c-counter-overflows.proftext b/test/Profile/Inputs/c-counter-overflows.proftext
index 5a3633ecfc78..b2e5dd1d77ae 100644
--- a/test/Profile/Inputs/c-counter-overflows.proftext
+++ b/test/Profile/Inputs/c-counter-overflows.proftext
@@ -1,5 +1,5 @@
main
-285734896137
+10111551811706059223
8
1
68719476720
diff --git a/test/Profile/Inputs/c-general.proftext b/test/Profile/Inputs/c-general.proftext
index 19e5bd3db442..c0d03b4b755e 100644
--- a/test/Profile/Inputs/c-general.proftext
+++ b/test/Profile/Inputs/c-general.proftext
@@ -1,5 +1,5 @@
simple_loops
-16515
+1245818015463121
4
1
100
@@ -7,7 +7,7 @@ simple_loops
75
conditionals
-74917022372782735
+4190663230902537370
11
1
100
@@ -22,7 +22,7 @@ conditionals
100
early_exits
-44128811889290
+8265526549255474475
9
1
0
@@ -35,7 +35,7 @@ early_exits
0
jumps
-2016037664281362839
+15872630527555456493
22
1
1
@@ -61,7 +61,7 @@ jumps
9
switches
-2745195701975551402
+11892326508727782373
19
1
1
@@ -84,7 +84,7 @@ switches
0
big_switch
-10218718452081869619
+16933280399284440835
17
1
32
@@ -105,7 +105,7 @@ big_switch
2
boolean_operators
-291222909838
+1245693242827665
8
1
100
@@ -117,7 +117,7 @@ boolean_operators
50
boolop_loops
-9760565944591
+11270260636676715317
9
1
50
@@ -130,14 +130,14 @@ boolop_loops
26
conditional_operator
-848
+54992
3
1
0
1
do_fallthrough
-16586
+6898770640283947069
4
1
10
@@ -145,12 +145,12 @@ do_fallthrough
8
main
-0
+24
1
1
c-general.c:static_func
-4
+18129
2
1
10
diff --git a/test/Profile/Inputs/c-unprofiled-blocks.proftext b/test/Profile/Inputs/c-unprofiled-blocks.proftext
index 87b48e13fbbe..ef7f653811fb 100644
--- a/test/Profile/Inputs/c-unprofiled-blocks.proftext
+++ b/test/Profile/Inputs/c-unprofiled-blocks.proftext
@@ -1,5 +1,5 @@
never_called
-44257542701577
+5644096560937528444
9
0
0
@@ -12,12 +12,12 @@ never_called
0
main
-1
+24
1
1
dead_code
-2859007309808137
+9636018207904213947
10
1
0
diff --git a/test/Profile/Inputs/cxx-class.proftext b/test/Profile/Inputs/cxx-class.proftext
index 77645fbc2066..112200681ab4 100644
--- a/test/Profile/Inputs/cxx-class.proftext
+++ b/test/Profile/Inputs/cxx-class.proftext
@@ -1,52 +1,52 @@
_Z14simple_wrapperv
-4
+18129
2
1
100
main
-0
+24
1
1
_ZN6SimpleD1Ev
-10
+42129
2
0
0
_ZN6SimpleD2Ev
-10
+42129
2
100
99
_ZN6Simple6methodEv
-10
+42129
2
100
99
_ZN6SimpleC1Ei
-10
+42129
2
0
0
_ZN6SimpleC2Ei
-10
+42129
2
100
99
_ZN7DerivedC1Ev
-10
+42129
2
100
99
_ZN7DerivedD2Ev
-10
+42129
2
100
99
diff --git a/test/Profile/Inputs/cxx-hash-v2.profdata.v5 b/test/Profile/Inputs/cxx-hash-v2.profdata.v5
new file mode 100644
index 000000000000..5d7fb1f3697a
--- /dev/null
+++ b/test/Profile/Inputs/cxx-hash-v2.profdata.v5
Binary files differ
diff --git a/test/Profile/Inputs/cxx-hash-v2.proftext b/test/Profile/Inputs/cxx-hash-v2.proftext
new file mode 100644
index 000000000000..65c564524acb
--- /dev/null
+++ b/test/Profile/Inputs/cxx-hash-v2.proftext
@@ -0,0 +1,239 @@
+_Z11loop_returnv
+# Func Hash:
+1160721
+# Num Counters:
+2
+# Counter Values:
+0
+0
+
+_Z10loop_breakv
+# Func Hash:
+1160593
+# Num Counters:
+2
+# Counter Values:
+0
+0
+
+_Z8no_gotosv
+# Func Hash:
+1
+# Num Counters:
+2
+# Counter Values:
+0
+0
+
+_Z13loop_continuev
+# Func Hash:
+1160657
+# Num Counters:
+2
+# Counter Values:
+0
+0
+
+_Z18loop_after_if_elsev
+# Func Hash:
+11044458641
+# Num Counters:
+3
+# Counter Values:
+0
+0
+0
+
+_Z21consecutive_try_catchv
+# Func Hash:
+49221687100497
+# Num Counters:
+5
+# Counter Values:
+0
+0
+0
+0
+0
+
+_Z16nested_try_catchv
+# Func Hash:
+49147600487505
+# Num Counters:
+5
+# Counter Values:
+0
+0
+0
+0
+0
+
+_Z13indirect_gotov
+# Func Hash:
+1345
+# Num Counters:
+2
+# Counter Values:
+0
+0
+
+_Z17nested_for_rangesv
+# Func Hash:
+1332305
+# Num Counters:
+3
+# Counter Values:
+0
+0
+0
+
+_Z18loop_in_then_blockv
+# Func Hash:
+11040003281
+# Num Counters:
+3
+# Counter Values:
+0
+0
+0
+
+_Z22consecutive_for_rangesv
+# Func Hash:
+1380689
+# Num Counters:
+3
+# Counter Values:
+0
+0
+0
+
+_Z15consecutive_dosv
+# Func Hash:
+856273
+# Num Counters:
+3
+# Counter Values:
+0
+0
+0
+
+_Z11direct_gotov
+# Func Hash:
+1281
+# Num Counters:
+2
+# Counter Values:
+0
+0
+
+main
+# Func Hash:
+24
+# Num Counters:
+1
+# Counter Values:
+1
+
+_Z11double_lnotv
+# Func Hash:
+174695569
+# Num Counters:
+2
+# Counter Values:
+0
+0
+
+_Z18if_inside_of_whilev
+# Func Hash:
+36250705
+# Num Counters:
+3
+# Counter Values:
+0
+0
+0
+
+_Z11single_lnotv
+# Func Hash:
+2729105
+# Num Counters:
+2
+# Counter Values:
+0
+0
+
+_Z19if_outside_of_whilev
+# Func Hash:
+38053009
+# Num Counters:
+3
+# Counter Values:
+0
+0
+0
+
+_Z8no_throwv
+# Func Hash:
+0
+# Num Counters:
+1
+# Counter Values:
+0
+
+_Z9has_throwv
+# Func Hash:
+25
+# Num Counters:
+1
+# Counter Values:
+0
+
+_Z10nested_dosv
+# Func Hash:
+799825
+# Num Counters:
+3
+# Counter Values:
+0
+0
+0
+
+_Z16if_inside_of_forv
+# Func Hash:
+4750648401
+# Num Counters:
+3
+# Counter Values:
+0
+0
+0
+
+_Z18loop_in_else_blockv
+# Func Hash:
+11044398161
+# Num Counters:
+3
+# Counter Values:
+0
+0
+0
+
+_Z17if_outside_of_forv
+# Func Hash:
+4752450705
+# Num Counters:
+3
+# Counter Values:
+0
+0
+0
+
+_Z10loop_emptyv
+# Func Hash:
+18129
+# Num Counters:
+2
+# Counter Values:
+0
+0
+
diff --git a/test/Profile/Inputs/cxx-lambda.proftext b/test/Profile/Inputs/cxx-lambda.proftext
index 36646b5ab37c..e49cd8d6ec12 100644
--- a/test/Profile/Inputs/cxx-lambda.proftext
+++ b/test/Profile/Inputs/cxx-lambda.proftext
@@ -1,17 +1,17 @@
cxx-lambda.cpp:_ZZ7lambdasvENK3$_0clEi
-654
+11211970062
3
10
9
9
main
-0
+24
1
1
_Z7lambdasv
-41226
+2895087587861649
4
1
1
diff --git a/test/Profile/Inputs/cxx-rangefor.proftext b/test/Profile/Inputs/cxx-rangefor.proftext
index 7d2d1ef58d29..b59729207859 100644
--- a/test/Profile/Inputs/cxx-rangefor.proftext
+++ b/test/Profile/Inputs/cxx-rangefor.proftext
@@ -1,5 +1,5 @@
_Z9range_forv
-0x000000000014a28a
+6169071350249721981
5
1
4
@@ -8,6 +8,6 @@ _Z9range_forv
1
main
-0
+24
1
1
diff --git a/test/Profile/Inputs/cxx-templates.proftext b/test/Profile/Inputs/cxx-templates.proftext
index 5ea840038d59..5b9d8e4569d3 100644
--- a/test/Profile/Inputs/cxx-templates.proftext
+++ b/test/Profile/Inputs/cxx-templates.proftext
@@ -1,16 +1,16 @@
main
-0
+24
1
1
_Z4loopILj0EEvv
-4
+18129
2
1
0
_Z4loopILj100EEvv
-4
+18129
2
1
100
diff --git a/test/Profile/Inputs/cxx-throws.proftext b/test/Profile/Inputs/cxx-throws.proftext
index 1d197b9eae38..32fcf5d50cd4 100644
--- a/test/Profile/Inputs/cxx-throws.proftext
+++ b/test/Profile/Inputs/cxx-throws.proftext
@@ -1,5 +1,5 @@
_Z6throwsv
-18359008150154
+340120998528097520
9
1
100
@@ -12,14 +12,14 @@ _Z6throwsv
100
_Z11unreachablei
-0x28a
+706946049169
3
1
1
0
main
-0x2cc
+187765848
3
1
1
diff --git a/test/Profile/Inputs/func-entry.proftext b/test/Profile/Inputs/func-entry.proftext
index f7c2052035d4..1548c2d7f343 100644
--- a/test/Profile/Inputs/func-entry.proftext
+++ b/test/Profile/Inputs/func-entry.proftext
@@ -1,10 +1,10 @@
foo
-0
+24
1
1000
main
-4
+1160280
2
1
10000
diff --git a/test/Profile/Inputs/gcc-flag-compatibility.proftext b/test/Profile/Inputs/gcc-flag-compatibility.proftext
index 99d41bb03f39..38eb9e5dc55f 100644
--- a/test/Profile/Inputs/gcc-flag-compatibility.proftext
+++ b/test/Profile/Inputs/gcc-flag-compatibility.proftext
@@ -1,5 +1,5 @@
main
-4
+1160280
2
1
100
diff --git a/test/Profile/Inputs/objc-general.proftext b/test/Profile/Inputs/objc-general.proftext
index 8d6771f9b324..f0034ae8cd73 100644
--- a/test/Profile/Inputs/objc-general.proftext
+++ b/test/Profile/Inputs/objc-general.proftext
@@ -1,17 +1,30 @@
objc-general.m:__13+[A foreach:]_block_invoke
-10
+42129
2
2
1
objc-general.m:+[A foreach:]
-6
+401
2
1
2
main
-0
+24
1
1
+consecutive_objc_for_ranges
+1642897
+3
+0
+0
+0
+
+nested_objc_for_ranges
+1598545
+3
+0
+0
+0
diff --git a/test/Profile/c-outdated-data.c b/test/Profile/c-outdated-data.c
index b686f94d804e..2b9773478930 100644
--- a/test/Profile/c-outdated-data.c
+++ b/test/Profile/c-outdated-data.c
@@ -7,10 +7,10 @@
// RUN: %clang_cc1 -triple x86_64-apple-macosx10.9 -main-file-name c-outdated-data.c %s -o /dev/null -emit-llvm -fprofile-instrument-use-path=%t.profdata 2>&1 | FileCheck %s -check-prefix=NO_MISSING
// RUN: %clang_cc1 -triple x86_64-apple-macosx10.9 -main-file-name c-outdated-data.c %s -o /dev/null -emit-llvm -Wprofile-instr-missing -fprofile-instrument-use-path=%t.profdata 2>&1 | FileCheck %s -check-prefix=WITH_MISSING
-// NO_MISSING: warning: profile data may be out of date: of 3 functions, 1 has mismatched data that will be ignored
+// NO_MISSING: warning: profile data may be out of date: of 3 functions, 2 have mismatched data that will be ignored
// NO_MISSING-NOT: 1 has no data
-// WITH_MISSING: warning: profile data may be out of date: of 3 functions, 1 has mismatched data that will be ignored
+// WITH_MISSING: warning: profile data may be out of date: of 3 functions, 2 have mismatched data that will be ignored
// WITH_MISSING: warning: profile data may be incomplete: of 3 functions, 1 has no data
void no_usable_data() {
diff --git a/test/Profile/cxx-hash-v2.cpp b/test/Profile/cxx-hash-v2.cpp
new file mode 100644
index 000000000000..995fe008f523
--- /dev/null
+++ b/test/Profile/cxx-hash-v2.cpp
@@ -0,0 +1,177 @@
+// REQUIRES: shell
+
+// Check that all of the hashes in this file are unique (i.e, that none of the
+// profiles for these functions are mutually interchangeable).
+//
+// RUN: llvm-profdata show -all-functions %S/Inputs/cxx-hash-v2.profdata.v5 | grep "Hash: 0x" | sort > %t.hashes
+// RUN: uniq %t.hashes > %t.hashes.unique
+// RUN: diff %t.hashes %t.hashes.unique
+
+// RUN: llvm-profdata merge %S/Inputs/cxx-hash-v2.proftext -o %t.profdata
+// RUN: %clang_cc1 -std=c++11 -fexceptions -fcxx-exceptions -triple x86_64-apple-macosx10.9 -main-file-name cxx-hash-v2.mm %s -o /dev/null -emit-llvm -fprofile-instrument-use-path=%t.profdata 2>&1 | FileCheck %s -allow-empty
+// RUN: %clang_cc1 -std=c++11 -fexceptions -fcxx-exceptions -triple x86_64-apple-macosx10.9 -main-file-name cxx-hash-v2.mm %s -o /dev/null -emit-llvm -fprofile-instrument-use-path=%S/Inputs/cxx-hash-v2.profdata.v5 2>&1 | FileCheck %s -allow-empty
+
+// CHECK-NOT: warning: profile data may be out of date
+
+int x;
+int arr[1] = {0};
+
+void loop_after_if_else() {
+ if (1)
+ x = 1;
+ else
+ x = 2;
+ while (0)
+ ++x;
+}
+
+void loop_in_then_block() {
+ if (1) {
+ while (0)
+ ++x;
+ } else {
+ x = 2;
+ }
+}
+
+void loop_in_else_block() {
+ if (1) {
+ x = 1;
+ } else {
+ while (0)
+ ++x;
+ }
+}
+
+void if_inside_of_for() {
+ for (x = 0; x < 0; ++x) {
+ x = 1;
+ if (1)
+ x = 2;
+ }
+}
+
+void if_outside_of_for() {
+ for (x = 0; x < 0; ++x)
+ x = 1;
+ if (1)
+ x = 2;
+}
+
+void if_inside_of_while() {
+ while (0) {
+ x = 1;
+ if (1)
+ x = 2;
+ }
+}
+
+void if_outside_of_while() {
+ while (0)
+ x = 1;
+ if (1)
+ x = 2;
+}
+
+void nested_dos() {
+ do {
+ do {
+ ++x;
+ } while (0);
+ } while (0);
+}
+
+void consecutive_dos() {
+ do {
+ } while (0);
+ do {
+ ++x;
+ } while (0);
+}
+
+void loop_empty() {
+ for (x = 0; x < 5; ++x) {}
+}
+
+void loop_return() {
+ for (x = 0; x < 5; ++x)
+ return;
+}
+
+void loop_continue() {
+ for (x = 0; x < 5; ++x)
+ continue;
+}
+
+void loop_break() {
+ for (x = 0; x < 5; ++x)
+ break;
+}
+
+void no_gotos() {
+ static void *dispatch[] = {&&done};
+ x = 0;
+done:
+ ++x;
+}
+
+void direct_goto() {
+ static void *dispatch[] = {&&done};
+ x = 0;
+ goto done;
+done:
+ ++x;
+}
+
+void indirect_goto() {
+ static void *dispatch[] = {&&done};
+ x = 0;
+ goto *dispatch[x];
+done:
+ ++x;
+}
+
+void nested_for_ranges() {
+ for (int a : arr)
+ for (int b : arr)
+ ++x;
+}
+
+void consecutive_for_ranges() {
+ for (int a : arr) {}
+ for (int b : arr)
+ ++x;
+}
+
+void nested_try_catch() {
+ try {
+ try {
+ ++x;
+ } catch (...) {}
+ } catch (...) {}
+}
+
+void consecutive_try_catch() {
+ try {} catch (...) {}
+ try {
+ ++x;
+ } catch (...) {}
+}
+
+void no_throw() {}
+
+void has_throw() {
+ throw 0;
+}
+
+void single_lnot() {
+ if (!x) {}
+}
+
+void double_lnot() {
+ if (!!x) {}
+}
+
+int main() {
+ return 0;
+}
diff --git a/test/Profile/objc-general.m b/test/Profile/objc-general.m
index b679627a48e8..7a4cac941205 100644
--- a/test/Profile/objc-general.m
+++ b/test/Profile/objc-general.m
@@ -3,7 +3,9 @@
// RUN: %clang_cc1 -triple x86_64-apple-macosx10.9 -main-file-name objc-general.m %s -o - -emit-llvm -fblocks -fprofile-instrument=clang | FileCheck -check-prefix=PGOGEN %s
// RUN: llvm-profdata merge %S/Inputs/objc-general.proftext -o %t.profdata
-// RUN: %clang_cc1 -triple x86_64-apple-macosx10.9 -main-file-name objc-general.m %s -o - -emit-llvm -fblocks -fprofile-instrument-use-path=%t.profdata | FileCheck -check-prefix=PGOUSE %s
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.9 -main-file-name objc-general.m %s -o - -emit-llvm -fblocks -fprofile-instrument-use-path=%t.profdata 2>&1 | FileCheck -check-prefix=PGOUSE %s
+
+// PGOUSE-NOT: warning: profile data may be out of date
#ifdef HAVE_FOUNDATION
@@ -63,6 +65,20 @@ struct NSFastEnumerationState;
}
@end
+void nested_objc_for_ranges(NSArray *arr) {
+ int x = 0;
+ for (id a in arr)
+ for (id b in arr)
+ ++x;
+}
+
+void consecutive_objc_for_ranges(NSArray *arr) {
+ int x = 0;
+ for (id a in arr) {}
+ for (id b in arr)
+ ++x;
+}
+
// PGOUSE-DAG: ![[FR1]] = !{!"branch_weights", i32 2, i32 3}
// PGOUSE-DAG: ![[FR2]] = !{!"branch_weights", i32 3, i32 2}
// PGOUSE-DAG: ![[BL1]] = !{!"branch_weights", i32 2, i32 2}
diff --git a/test/Refactor/Extract/ExtractExprIntoFunction.cpp b/test/Refactor/Extract/ExtractExprIntoFunction.cpp
new file mode 100644
index 000000000000..0fccc9298597
--- /dev/null
+++ b/test/Refactor/Extract/ExtractExprIntoFunction.cpp
@@ -0,0 +1,70 @@
+// RUN: clang-refactor extract -selection=test:%s %s -- -std=c++14 2>&1 | grep -v CHECK | FileCheck %s
+
+
+void simpleExtractNoCaptures() {
+ int i = /*range=->+0:33*/1 + 2;
+}
+
+// CHECK: 1 '' results:
+// CHECK: static int extracted() {
+// CHECK-NEXT: return 1 + 2;{{$}}
+// CHECK-NEXT: }{{[[:space:]].*}}
+// CHECK-NEXT: void simpleExtractNoCaptures() {
+// CHECK-NEXT: int i = /*range=->+0:33*/extracted();{{$}}
+// CHECK-NEXT: }
+
+void simpleExtractStmtNoCaptures() {
+ /*range astatement=->+1:13*/int a = 1;
+ int b = 2;
+}
+// CHECK: 1 'astatement' results:
+// CHECK: static void extracted() {
+// CHECK-NEXT: int a = 1;
+// CHECK-NEXT: int b = 2;{{$}}
+// CHECK-NEXT: }{{[[:space:]].*}}
+// CHECK-NEXT: void simpleExtractStmtNoCaptures() {
+// CHECK-NEXT: /*range astatement=->+1:13*/extracted();{{$}}
+// CHECK-NEXT: }
+
+
+void blankRangeNoExtraction() {
+ int i = /*range blank=*/1 + 2;
+}
+
+// CHECK: 1 'blank' results:
+// CHECK-NEXT: the provided selection does not overlap with the AST nodes of interest
+
+int outOfBodyCodeNoExtraction = /*range out_of_body_expr=->+0:72*/1 + 2;
+
+struct OutOfBodyStuff {
+ int FieldInit = /*range out_of_body_expr=->+0:58*/1 + 2;
+
+ void foo(int x =/*range out_of_body_expr=->+0:58*/1 + 2);
+};
+
+auto inFunctionOutOfBody() -> decltype(/*range out_of_body_expr=->+0:79*/1 + 2) {
+ struct OutOfBodyStuff {
+ int FieldInit = /*range out_of_body_expr=->+0:60*/1 + 2;
+
+ void foo(int x =/*range out_of_body_expr=->+0:60*/1 + 2);
+ };
+ enum E {
+ X = /*range out_of_body_expr=->+0:48*/1 + 2
+ };
+ int x = 0;
+ using T = decltype(/*range out_of_body_expr=->+0:61*/x + 3);
+ return x;
+}
+
+// CHECK: 8 'out_of_body_expr' results:
+// CHECK: the selected code is not a part of a function's / method's body
+
+void simpleExpressionNoExtraction() {
+ int i = /*range simple_expr=->+0:41*/1 + /*range simple_expr=->+0:76*/(2);
+ (void) /*range simple_expr=->+0:40*/i;
+ (void)/*range simple_expr=->+0:47*/"literal";
+ (void)/*range simple_expr=->+0:41*/'c';
+}
+
+// CHECK: 5 'simple_expr' results:
+// CHECK-NEXT: the selected expression is too simple to extract
diff --git a/test/Refactor/Extract/ExtractionSemicolonPolicy.cpp b/test/Refactor/Extract/ExtractionSemicolonPolicy.cpp
new file mode 100644
index 000000000000..5caf9d452684
--- /dev/null
+++ b/test/Refactor/Extract/ExtractionSemicolonPolicy.cpp
@@ -0,0 +1,192 @@
+// RUN: clang-refactor extract -selection=test:%s %s -- -std=c++11 -fcxx-exceptions | grep -v CHECK | FileCheck %s
+
+struct Rectangle { int width, height; };
+
+void extractStatement(const Rectangle &r) {
+ /*range adeclstmt=->+0:59*/int area = r.width * r.height;
+}
+// CHECK: 1 'adeclstmt' results:
+// CHECK: static void extracted() {
+// CHECK-NEXT: int area = r.width * r.height;{{$}}
+// CHECK-NEXT: }{{[[:space:]].*}}
+// CHECK-NEXT: void extractStatement(const Rectangle &r) {
+// CHECK-NEXT: /*range adeclstmt=->+0:59*/extracted();{{$}}
+// CHECK-NEXT: }
+
+void extractStatementNoSemiIf(const Rectangle &r) {
+ /*range bextractif=->+2:4*/if (r.width) {
+ int x = r.height;
+ }
+}
+// CHECK: 1 'bextractif' results:
+// CHECK: static void extracted() {
+// CHECK-NEXT: if (r.width) {
+// CHECK-NEXT: int x = r.height;
+// CHECK-NEXT: }{{$}}
+// CHECK-NEXT: }{{[[:space:]].*}}
+// CHECK-NEXT: void extractStatementNoSemiIf(const Rectangle &r) {
+// CHECK-NEXT: /*range bextractif=->+2:4*/extracted();{{$}}
+// CHECK-NEXT: }
+
+void extractStatementDontExtraneousSemi(const Rectangle &r) {
+ /*range cextractif=->+2:4*/if (r.width) {
+ int x = r.height;
+ } ;
+} //^ This semicolon shouldn't be extracted.
+// CHECK: 1 'cextractif' results:
+// CHECK: static void extracted() {
+// CHECK-NEXT: if (r.width) {
+// CHECK-NEXT: int x = r.height;
+// CHECK-NEXT: }{{$}}
+// CHECK-NEXT: }{{[[:space:]].*}}
+// CHECK-NEXT: void extractStatementDontExtraneousSemi(const Rectangle &r) {
+// CHECK-NEXT: extracted(); ;{{$}}
+// CHECK-NEXT: }
+
+void extractStatementNotSemiSwitch() {
+ /*range dextract=->+5:4*/switch (2) {
+ case 1:
+ break;
+ case 2:
+ break;
+ }
+}
+// CHECK: 1 'dextract' results:
+// CHECK: static void extracted() {
+// CHECK-NEXT: switch (2) {
+// CHECK-NEXT: case 1:
+// CHECK-NEXT: break;
+// CHECK-NEXT: case 2:
+// CHECK-NEXT: break;
+// CHECK-NEXT: }{{$}}
+// CHECK-NEXT: }{{[[:space:]].*}}
+// CHECK-NEXT: void extractStatementNotSemiSwitch() {
+// CHECK-NEXT: extracted();{{$}}
+// CHECK-NEXT: }
+
+void extractStatementNotSemiWhile() {
+ /*range eextract=->+2:4*/while (true) {
+ int x = 0;
+ }
+}
+// CHECK: 1 'eextract' results:
+// CHECK: static void extracted() {
+// CHECK-NEXT: while (true) {
+// CHECK-NEXT: int x = 0;
+// CHECK-NEXT: }{{$}}
+// CHECK-NEXT: }{{[[:space:]].*}}
+// CHECK-NEXT: void extractStatementNotSemiWhile() {
+// CHECK-NEXT: extracted();{{$}}
+// CHECK-NEXT: }
+
+void extractStatementNotSemiFor() {
+ /*range fextract=->+1:4*/for (int i = 0; i < 10; ++i) {
+ }
+}
+// CHECK: 1 'fextract' results:
+// CHECK: static void extracted() {
+// CHECK-NEXT: for (int i = 0; i < 10; ++i) {
+// CHECK-NEXT: }{{$}}
+// CHECK-NEXT: }{{[[:space:]].*}}
+// CHECK-NEXT: void extractStatementNotSemiFor() {
+// CHECK-NEXT: extracted();{{$}}
+// CHECK-NEXT: }
+
+struct XS {
+ int *begin() { return 0; }
+ int *end() { return 0; }
+};
+
+void extractStatementNotSemiRangedFor(XS xs) {
+ /*range gextract=->+1:4*/for (int i : xs) {
+ }
+}
+// CHECK: 1 'gextract' results:
+// CHECK: static void extracted() {
+// CHECK-NEXT: for (int i : xs) {
+// CHECK-NEXT: }{{$}}
+// CHECK-NEXT: }{{[[:space:]].*}}
+// CHECK-NEXT: void extractStatementNotSemiRangedFor(XS xs) {
+// CHECK-NEXT: extracted();{{$}}
+// CHECK-NEXT: }
+
+void extractStatementNotSemiRangedTryCatch() {
+ /*range hextract=->+3:4*/try { int x = 0; }
+ catch (const int &i) {
+ int y = i;
+ }
+}
+// CHECK: 1 'hextract' results:
+// CHECK: static void extracted() {
+// CHECK-NEXT: try { int x = 0; }
+// CHECK-NEXT: catch (const int &i) {
+// CHECK-NEXT: int y = i;
+// CHECK-NEXT: }{{$}}
+// CHECK-NEXT: }{{[[:space:]].*}}
+// CHECK-NEXT: void extractStatementNotSemiRangedTryCatch() {
+// CHECK-NEXT: extracted();{{$}}
+// CHECK-NEXT: }
+
+void extractCantFindSemicolon() {
+ /*range iextract=->+1:17*/do {
+ } while (true)
+ // Add a semicolon in both the extracted and original function as we don't
+ // want to extract the semicolon below.
+ ;
+}
+// CHECK: 1 'iextract' results:
+// CHECK: static void extracted() {
+// CHECK-NEXT: do {
+// CHECK-NEXT: } while (true);{{$}}
+// CHECK-NEXT: }{{[[:space:]].*}}
+// CHECK-NEXT: void extractCantFindSemicolon() {
+// CHECK-NEXT: extracted();{{$}}
+// CHECK-NEXT: //
+// CHECK-NEXT: //
+// CHECK-NEXT: ;
+// CHECK-NEXT: }
+
+void extractFindSemicolon() {
+ /*range jextract=->+1:17*/do {
+ } while (true) /*grab*/ ;
+}
+// CHECK: 1 'jextract' results:
+// CHECK: static void extracted() {
+// CHECK-NEXT: do {
+// CHECK-NEXT: } while (true) /*grab*/ ;{{$}}
+// CHECK-NEXT: }{{[[:space:]].*}}
+// CHECK-NEXT: void extractFindSemicolon() {
+// CHECK-NEXT: extracted();{{$}}
+// CHECK-NEXT: }
+
+void call();
+
+void careForNonCompoundSemicolons1() {
+ /*range kextract=->+1:11*/if (true)
+ call();
+}
+// CHECK: 1 'kextract' results:
+// CHECK: static void extracted() {
+// CHECK-NEXT: if (true)
+// CHECK-NEXT: call();{{$}}
+// CHECK-NEXT: }{{[[:space:]].*}}
+// CHECK-NEXT: void careForNonCompoundSemicolons1() {
+// CHECK-NEXT: extracted();{{$}}
+// CHECK-NEXT: }
+
+void careForNonCompoundSemicolons2() {
+ /*range lextract=->+3:1*/for (int i = 0; i < 10; ++i)
+ while (i != 0)
+ ;
+ // end right here111!
+}
+// CHECK: 1 'lextract' results:
+// CHECK: static void extracted() {
+// CHECK-NEXT: for (int i = 0; i < 10; ++i)
+// CHECK-NEXT: while (i != 0)
+// CHECK-NEXT: ;{{$}}
+// CHECK-NEXT: }{{[[:space:]].*}}
+// CHECK-NEXT: void careForNonCompoundSemicolons2() {
+// CHECK-NEXT: extracted();{{$}}
+// CHECK-NEXT: //
+// CHECK-NEXT: }
diff --git a/test/Refactor/Extract/ExtractionSemicolonPolicy.m b/test/Refactor/Extract/ExtractionSemicolonPolicy.m
new file mode 100644
index 000000000000..10e6a164f248
--- /dev/null
+++ b/test/Refactor/Extract/ExtractionSemicolonPolicy.m
@@ -0,0 +1,56 @@
+// RUN: clang-refactor extract -selection=test:%s %s -- 2>&1 | grep -v CHECK | FileCheck %s
+
+@interface NSArray
++ (id)arrayWithObjects:(const id [])objects count:(unsigned long)cnt;
+@end
+
+void extractStatementNoSemiObjCFor(NSArray *array) {
+ /*range astmt=->+2:4*/for (id i in array) {
+ int x = 0;
+ }
+}
+// CHECK: 1 'astmt' results:
+// CHECK: static void extracted() {
+// CHECK-NEXT: for (id i in array) {
+// CHECK-NEXT: int x = 0;
+// CHECK-NEXT: }{{$}}
+// CHECK-NEXT: }{{[[:space:]].*}}
+
+void extractStatementNoSemiSync() {
+ id lock;
+ /*range bstmt=->+2:4*/@synchronized(lock) {
+ int x = 0;
+ }
+}
+// CHECK: 1 'bstmt' results:
+// CHECK: static void extracted() {
+// CHECK-NEXT: @synchronized(lock) {
+// CHECK-NEXT: int x = 0;
+// CHECK-NEXT: }{{$}}
+// CHECK-NEXT: }{{[[:space:]].*}}
+
+void extractStatementNoSemiAutorel() {
+ /*range cstmt=->+2:4*/@autoreleasepool {
+ int x = 0;
+ }
+}
+// CHECK: 1 'cstmt' results:
+// CHECK: static void extracted() {
+// CHECK-NEXT: @autoreleasepool {
+// CHECK-NEXT: int x = 0;
+// CHECK-NEXT: }{{$}}
+// CHECK-NEXT: }{{[[:space:]].*}}
+
+void extractStatementNoSemiTryFinalllllly() {
+ /*range dstmt=->+3:4*/@try {
+ int x = 0;
+ } @finally {
+ }
+}
+// CHECK: 1 'dstmt' results:
+// CHECK: static void extracted() {
+// CHECK-NEXT: @try {
+// CHECK-NEXT: int x = 0;
+// CHECK-NEXT: } @finally {
+// CHECK-NEXT: }{{$}}
+// CHECK-NEXT: }{{[[:space:]].*}}
diff --git a/test/Refactor/Extract/FromMethodToFunction.cpp b/test/Refactor/Extract/FromMethodToFunction.cpp
new file mode 100644
index 000000000000..86bec16edfd1
--- /dev/null
+++ b/test/Refactor/Extract/FromMethodToFunction.cpp
@@ -0,0 +1,42 @@
+// RUN: clang-refactor extract -selection=test:%s %s -- -std=c++11 2>&1 | grep -v CHECK | FileCheck --check-prefixes=CHECK,CHECK-INNER %s
+// RUN: clang-refactor extract -selection=test:%s %s -- -std=c++11 -DMULTIPLE 2>&1 | grep -v CHECK | FileCheck --check-prefixes=CHECK,CHECK-OUTER %s
+
+#ifdef MULTIPLE
+class OuterClass {
+#define PREFIX OuterClass ::
+#else
+#define PREFIX
+#endif
+
+class AClass {
+
+ int method(int x) {
+ return /*range inner=->+0:38*/1 + 2 * 2;
+ }
+// CHECK-INNER: 1 'inner' results:
+// CHECK-INNER: static int extracted() {
+// CHECK-INNER-NEXT: return 1 + 2 * 2;{{$}}
+// CHECK-INNER-NEXT: }{{[[:space:]].*}}
+// CHECK-INNER-NEXT: class AClass {
+
+// CHECK-OUTER: 1 'inner' results:
+// CHECK-OUTER: static int extracted() {
+// CHECK-OUTER-NEXT: return 1 + 2 * 2;{{$}}
+// CHECK-OUTER-NEXT: }{{[[:space:]].*}}
+// CHECK-OUTER-NEXT: class OuterClass {
+
+ int otherMethod(int x);
+};
+
+#ifdef MULTIPLE
+};
+#endif
+
+int PREFIX AClass::otherMethod(int x) {
+ return /*range outofline=->+0:46*/2 * 2 - 1;
+}
+// CHECK: 1 'outofline' results:
+// CHECK: static int extracted() {
+// CHECK-NEXT: return 2 * 2 - 1;{{$}}
+// CHECK-NEXT: }{{[[:space:]].*}}
+// CHECK-NEXT: int PREFIX AClass::otherMethod
diff --git a/test/Refactor/Extract/ObjCProperty.m b/test/Refactor/Extract/ObjCProperty.m
new file mode 100644
index 000000000000..152ccb348421
--- /dev/null
+++ b/test/Refactor/Extract/ObjCProperty.m
@@ -0,0 +1,41 @@
+// RUN: clang-refactor extract -selection=test:%s %s -- 2>&1 | grep -v CHECK | FileCheck %s
+
+@interface HasProperty
+
+@property (strong) HasProperty *item;
+
+- (HasProperty *)implicitProp;
+
+- (void)setImplicitSetter:(HasProperty *)value;
+
+@end
+
+@implementation HasProperty
+
+- (void)allowGetterExtraction {
+ /*range allow_getter=->+0:42*/self.item;
+ /*range allow_imp_getter=->+0:54*/self.implicitProp;
+}
+// CHECK: 1 'allow_getter' results:
+// CHECK: extracted() {
+// CHECK-NEXT: return self.item;{{$}}
+// CHECK-NEXT: }{{[[:space:]].*}}
+// CHECK-NEXT: - (void)allowGetterExtraction {
+// CHECK-NEXT: extracted();
+
+// CHECK: 1 'allow_imp_getter' results:
+// CHECK: extracted() {
+// CHECK-NEXT: return self.implicitProp;{{$}}
+// CHECK-NEXT: }{{[[:space:]].*}}
+// CHECK-NEXT: - (void)allowGetterExtraction {
+// CHECK-NEXT: self.item;
+// CHECK-NEXT: extracted();
+
+- (void)prohibitSetterExtraction {
+ /*range prohibit_setter=->+0:45*/self.item = 0;
+ /*range prohibit_setter=->+0:55*/self.implicitSetter = 0;
+}
+// CHECK: 2 'prohibit_setter' results:
+// CHECK: the selected expression can't be extracted
+
+@end
diff --git a/test/Refactor/LocalRename/BuiltinOffsetof.cpp b/test/Refactor/LocalRename/BuiltinOffsetof.cpp
new file mode 100644
index 000000000000..3119eeb7e524
--- /dev/null
+++ b/test/Refactor/LocalRename/BuiltinOffsetof.cpp
@@ -0,0 +1,32 @@
+// RUN: clang-refactor local-rename -selection=test:%s -new-name=bar %s -- | grep -v CHECK | FileCheck %s
+
+struct Struct {
+ int /*range f=*/field;
+};
+
+struct Struct2 {
+ Struct /*range array=*/array[4][2];
+};
+
+void foo() {
+ (void)__builtin_offsetof(Struct, /*range f=*/field);
+ (void)__builtin_offsetof(Struct2, /*range array=*/array[1][0]./*range f=*/field);
+}
+
+#define OFFSET_OF_(X, Y) __builtin_offsetof(X, Y)
+
+class SubclassOffsetof : public Struct {
+ void foo() {
+ (void)OFFSET_OF_(SubclassOffsetof, field);
+ }
+};
+
+// CHECK: 2 'array' results:
+// CHECK: Struct /*range array=*/bar[4][2];
+// CHECK: __builtin_offsetof(Struct2, /*range array=*/bar[1][0]./*range f=*/field);
+
+// CHECK: 3 'f' results:
+// CHECK: int /*range f=*/bar;
+// CHECK: __builtin_offsetof(Struct, /*range f=*/bar);
+// CHECK-NEXT: __builtin_offsetof(Struct2, /*range array=*/array[1][0]./*range f=*/bar);
+// CHECK: OFFSET_OF_(SubclassOffsetof, bar);
diff --git a/test/Refactor/LocalRename/Field.cpp b/test/Refactor/LocalRename/Field.cpp
new file mode 100644
index 000000000000..e674401b9653
--- /dev/null
+++ b/test/Refactor/LocalRename/Field.cpp
@@ -0,0 +1,11 @@
+// RUN: clang-refactor local-rename -selection=test:%s -new-name=Bar %s -- | grep -v CHECK | FileCheck %s
+
+class Baz {
+ int /*range=*/Foo;
+ // CHECK: int /*range=*/Bar;
+public:
+ Baz();
+};
+
+Baz::Baz() : /*range=*/Foo(0) {}
+// CHECK: Baz::Baz() : /*range=*/Bar(0) {}
diff --git a/test/Refactor/LocalRename/NoSymbolSelectedError.cpp b/test/Refactor/LocalRename/NoSymbolSelectedError.cpp
new file mode 100644
index 000000000000..98de61a45f46
--- /dev/null
+++ b/test/Refactor/LocalRename/NoSymbolSelectedError.cpp
@@ -0,0 +1,8 @@
+// RUN: not clang-refactor local-rename -selection=%s:4:1 -new-name=Bar %s -- 2>&1 | grep -v CHECK | FileCheck %s
+// RUN: clang-refactor local-rename -selection=test:%s -new-name=Bar %s -- 2>&1 | grep -v CHECK | FileCheck --check-prefix=TESTCHECK %s
+
+class Baz { // CHECK: [[@LINE]]:1: error: there is no symbol at the given location
+};
+/*range=*/;
+// TESTCHECK: 1 '' results:
+// TESTCHECK-NEXT: there is no symbol at the given location
diff --git a/test/Refactor/LocalRename/QualifiedRename.cpp b/test/Refactor/LocalRename/QualifiedRename.cpp
new file mode 100644
index 000000000000..d9eb138e5c76
--- /dev/null
+++ b/test/Refactor/LocalRename/QualifiedRename.cpp
@@ -0,0 +1,24 @@
+// RUN: clang-refactor local-rename -old-qualified-name="foo::A" -new-qualified-name="bar::B" %s -- -std=c++11 2>&1 | grep -v CHECK | FileCheck %s
+
+namespace foo {
+class A {};
+}
+// CHECK: namespace foo {
+// CHECK-NEXT: class B {};
+// CHECK-NEXT: }
+
+namespace bar {
+void f(foo::A* a) {
+ foo::A b;
+}
+// CHECK: void f(B* a) {
+// CHECK-NEXT: B b;
+// CHECK-NEXT: }
+}
+
+void f(foo::A* a) {
+ foo::A b;
+}
+// CHECK: void f(bar::B* a) {
+// CHECK-NEXT: bar::B b;
+// CHECK-NEXT: }
diff --git a/test/Refactor/tool-apply-replacements.cpp b/test/Refactor/tool-apply-replacements.cpp
new file mode 100644
index 000000000000..59b0991dd273
--- /dev/null
+++ b/test/Refactor/tool-apply-replacements.cpp
@@ -0,0 +1,9 @@
+// RUN: sed -e 's#//.*$##' %s > %t.cpp
+// RUN: clang-refactor local-rename -selection=%t.cpp:7:7 -new-name=test %t.cpp -- | FileCheck %s
+// RUN: clang-refactor local-rename -selection=%t.cpp:7:7-7:15 -new-name=test %t.cpp -- | FileCheck %s
+// RUN: clang-refactor local-rename -i -selection=%t.cpp:7:7 -new-name=test %t.cpp --
+// RUN: FileCheck -input-file=%t.cpp %s
+
+class RenameMe {
+// CHECK: class test {
+};
diff --git a/test/Refactor/tool-common-options.c b/test/Refactor/tool-common-options.c
new file mode 100644
index 000000000000..b41c8c701e8c
--- /dev/null
+++ b/test/Refactor/tool-common-options.c
@@ -0,0 +1,3 @@
+// RUN: not clang-refactor 2>&1 | FileCheck --check-prefix=MISSING_ACTION %s
+// MISSING_ACTION: error: no refactoring action given
+// MISSING_ACTION-NEXT: note: the following actions are supported:
diff --git a/test/Refactor/tool-selection-option.c b/test/Refactor/tool-selection-option.c
new file mode 100644
index 000000000000..f80457a0678d
--- /dev/null
+++ b/test/Refactor/tool-selection-option.c
@@ -0,0 +1,15 @@
+// RUN: rm -f %t.cp.c
+// RUN: cp %s %t.cp.c
+// RUN: clang-refactor local-rename -selection=%t.cp.c:6:5 -new-name=test -v %t.cp.c -- | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor local-rename -selection=%t.cp.c:6:5-6:9 -new-name=test -v %t.cp.c -- | FileCheck --check-prefix=CHECK2 %s
+
+int test;
+
+// CHECK1: invoking action 'local-rename':
+// CHECK1-NEXT: -selection={{.*}}.cp.c:6:5 -> {{.*}}.cp.c:6:5
+
+// CHECK2: invoking action 'local-rename':
+// CHECK2-NEXT: -selection={{.*}}.cp.c:6:5 -> {{.*}}.cp.c:6:9
+
+// RUN: not clang-refactor local-rename -selection=%s:6:5 -new-name=test -v %t.cp.c -- 2>&1 | FileCheck --check-prefix=CHECK-FILE-ERR %s
+// CHECK-FILE-ERR: given file is not in the target TU
diff --git a/test/Refactor/tool-test-support.c b/test/Refactor/tool-test-support.c
new file mode 100644
index 000000000000..0e073f6e1c1e
--- /dev/null
+++ b/test/Refactor/tool-test-support.c
@@ -0,0 +1,46 @@
+// RUN: clang-refactor local-rename -selection=test:%s -new-name=test -v %s -- | FileCheck %s
+
+/*range=*/int test;
+
+/*range named=*/int test2;
+
+/*range= +1*/int test3;
+
+/* range = +100 */int test4;
+
+/*range named =+0*/int test5;
+
+/*range =->+0:22*/int test6;
+
+// CHECK: Test selection group '':
+// CHECK-NEXT: 105-105
+// CHECK-NEXT: 158-158
+// CHECK-NEXT: 197-197
+// CHECK-NEXT: 248-251
+// CHECK-NEXT: Test selection group 'named':
+// CHECK-NEXT: 132-132
+// CHECK-NEXT: 218-218
+
+// The following invocations are in the default group:
+
+// CHECK: invoking action 'local-rename':
+// CHECK-NEXT: -selection={{.*}}tool-test-support.c:3:11
+
+// CHECK: invoking action 'local-rename':
+// CHECK-NEXT: -selection={{.*}}tool-test-support.c:7:15
+
+// CHECK: invoking action 'local-rename':
+// CHECK-NEXT: -selection={{.*}}tool-test-support.c:9:29
+
+// CHECK: invoking action 'local-rename':
+// CHECK-NEXT: -selection={{.*}}tool-test-support.c:13:19 -> {{.*}}tool-test-support.c:13:22
+
+// The following invocations are in the 'named' group, and they follow
+// the default invocation even if some of their ranges occur prior to the
+// ranges from the default group because the groups are tested one-by-one:
+
+// CHECK: invoking action 'local-rename':
+// CHECK-NEXT: -selection={{.*}}tool-test-support.c:5:17
+
+// CHECK: invoking action 'local-rename':
+// CHECK-NEXT: -selection={{.*}}tool-test-support.c:11:20
diff --git a/test/Rewriter/objc-modern-metadata-visibility2.mm b/test/Rewriter/objc-modern-metadata-visibility2.mm
deleted file mode 100644
index 4e64ac4beb46..000000000000
--- a/test/Rewriter/objc-modern-metadata-visibility2.mm
+++ /dev/null
@@ -1,45 +0,0 @@
-// REQUIRES: abi-breaking-checks
-// NOTE: This test has been split from objc-modern-metadata-visibility.mm in
-// order to test with -reverse-iterate as this flag is only present with
-// ABI_BREAKING_CHECKS.
-
-// RUN: %clang_cc1 -E %s -o %t.mm -mllvm -reverse-iterate
-// RUN: %clang_cc1 -x objective-c++ -fblocks -fms-extensions -rewrite-objc %t.mm -mllvm -reverse-iterate -o - | FileCheck %s
-// rdar://11144048
-
-@class NSString;
-
-@interface NSObject {
- Class isa;
-}
-@end
-
-@interface Sub : NSObject {
- int subIvar;
- NSString *nsstring;
-@private
- id PrivateIvar;
-}
-@end
-
-@implementation Sub
-- (id) MyNSString { return subIvar ? PrivateIvar : nsstring; }
-@end
-
-@interface NSString @end
-@implementation NSString @end
-
-// CHECK: __declspec(allocate(".objc_ivar$B")) extern "C" __declspec(dllimport) unsigned long OBJC_IVAR_$_Sub$subIvar;
-// CHECK: __declspec(allocate(".objc_ivar$B")) extern "C" unsigned long OBJC_IVAR_$_Sub$PrivateIvar;
-// CHECK: __declspec(allocate(".objc_ivar$B")) extern "C" __declspec(dllimport) unsigned long OBJC_IVAR_$_Sub$nsstring;
-// CHECK: #pragma warning(disable:4273)
-// CHECK: __declspec(allocate(".objc_ivar$B")) extern "C" __declspec(dllexport) unsigned long int OBJC_IVAR_$_Sub$subIvar
-// CHECK: __declspec(allocate(".objc_ivar$B")) extern "C" __declspec(dllexport) unsigned long int OBJC_IVAR_$_Sub$nsstring
-// CHECK: __declspec(allocate(".objc_ivar$B")) extern "C" unsigned long int OBJC_IVAR_$_Sub$PrivateIvar
-// CHECK: extern "C" __declspec(dllimport) struct _class_t OBJC_METACLASS_$_NSObject;
-// CHECK: extern "C" __declspec(dllexport) struct _class_t OBJC_METACLASS_$_Sub
-// CHECK: extern "C" __declspec(dllimport) struct _class_t OBJC_CLASS_$_NSObject;
-// CHECK: extern "C" __declspec(dllexport) struct _class_t OBJC_CLASS_$_Sub
-// CHECK: extern "C" __declspec(dllexport) struct _class_t OBJC_CLASS_$_NSString;
-// CHECK: extern "C" __declspec(dllexport) struct _class_t OBJC_METACLASS_$_NSString
-// CHECK: extern "C" __declspec(dllexport) struct _class_t OBJC_CLASS_$_NSString
diff --git a/test/Sema/Inputs/pragma-pack1.h b/test/Sema/Inputs/pragma-pack1.h
new file mode 100644
index 000000000000..abbf8a8609f1
--- /dev/null
+++ b/test/Sema/Inputs/pragma-pack1.h
@@ -0,0 +1,27 @@
+
+#ifndef NO_RECORD_1
+struct ReceivesPragma { };
+#endif
+
+#ifdef SET_FIRST_HEADER
+#pragma pack (16)
+#ifndef SET_SECOND_HEADER
+// expected-note@-2 2 {{previous '#pragma pack' directive that modifies alignment is here}}
+#else
+// expected-note@-4 1 {{previous '#pragma pack' directive that modifies alignment is here}}
+#endif
+// expected-warning@+3 {{non-default #pragma pack value changes the alignment of struct or union members in the included file}}
+#endif
+
+#include "pragma-pack2.h"
+
+#ifdef SET_SECOND_HEADER
+// expected-warning@-3 {{the current #pragma pack aligment value is modified in the included file}}
+#endif
+
+#ifdef PUSH_POP_FIRST_HEADER
+// This is fine, we don't change the current value.
+#pragma pack (push, 4)
+
+#pragma pack (pop)
+#endif
diff --git a/test/Sema/Inputs/pragma-pack2.h b/test/Sema/Inputs/pragma-pack2.h
new file mode 100644
index 000000000000..a41621544d75
--- /dev/null
+++ b/test/Sema/Inputs/pragma-pack2.h
@@ -0,0 +1,8 @@
+
+#ifndef NO_RECORD_2
+struct S { int x; };
+#endif
+
+#ifdef SET_SECOND_HEADER
+#pragma pack (8) // expected-note 2 {{previous '#pragma pack' directive that modifies alignment is here}}
+#endif
diff --git a/test/Sema/_Float128.c b/test/Sema/_Float128.c
new file mode 100644
index 000000000000..f0c3c6d555ef
--- /dev/null
+++ b/test/Sema/_Float128.c
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -verify %s
+// RUN: %clang_cc1 -triple powerpc64-linux -verify %s
+// RUN: %clang_cc1 -triple i686-windows-gnu -verify %s
+// RUN: %clang_cc1 -triple x86_64-windows-gnu -verify %s
+// RUN: %clang_cc1 -triple x86_64-windows-msvc -verify %s
+
+#if defined(__FLOAT128__) || defined(__SIZEOF_FLOAT128__)
+_Float128 f;
+_Float128 tiny = __FLT128_EPSILON__;
+int g(int x, _Float128 *y) {
+ return x + *y;
+}
+
+// expected-no-diagnostics
+#else
+_Float128 f; // expected-error {{__float128 is not supported on this target}}
+float tiny = __FLT128_EPSILON__; // expected-error{{use of undeclared identifier}}
+int g(int x, _Float128 *y) { // expected-error {{__float128 is not supported on this target}}
+ return x + *y;
+}
+
+#endif // defined(__FLOAT128__) || defined(__SIZEOF_FLOAT128__)
diff --git a/test/Sema/assign.c b/test/Sema/assign.c
index 1fff77864420..5bdfa9a3a5df 100644
--- a/test/Sema/assign.c
+++ b/test/Sema/assign.c
@@ -16,3 +16,46 @@ void test3() {
b[4] = 1; // expected-error {{read-only variable is not assignable}}
b2[4] = 1; // expected-error {{read-only variable is not assignable}}
}
+
+typedef struct I {
+ const int a; // expected-note 4{{nested data member 'a' declared const here}} \
+ expected-note 6{{data member 'a' declared const here}}
+} I;
+typedef struct J {
+ struct I i;
+} J;
+typedef struct K {
+ struct J *j;
+} K;
+
+void testI(struct I i1, struct I i2) {
+ i1 = i2; // expected-error {{cannot assign to variable 'i1' with const-qualified data member 'a'}}
+}
+void testJ1(struct J j1, struct J j2) {
+ j1 = j2; // expected-error {{cannot assign to variable 'j1' with nested const-qualified data member 'a'}}
+}
+void testJ2(struct J j, struct I i) {
+ j.i = i; // expected-error {{cannot assign to non-static data member 'i' with const-qualified data member 'a'}}
+}
+void testK1(struct K k, struct J j) {
+ *(k.j) = j; // expected-error {{cannot assign to lvalue with nested const-qualified data member 'a'}}
+}
+void testK2(struct K k, struct I i) {
+ k.j->i = i; // expected-error {{cannot assign to non-static data member 'i' with const-qualified data member 'a'}}
+}
+
+void testI_(I i1, I i2) {
+ i1 = i2; // expected-error {{cannot assign to variable 'i1' with const-qualified data member 'a'}}
+}
+void testJ1_(J j1, J j2) {
+ j1 = j2; // expected-error {{cannot assign to variable 'j1' with nested const-qualified data member 'a'}}
+}
+void testJ2_(J j, I i) {
+ j.i = i; // expected-error {{cannot assign to non-static data member 'i' with const-qualified data member 'a'}}
+}
+void testK1_(K k, J j) {
+ *(k.j) = j; // expected-error {{cannot assign to lvalue with nested const-qualified data member 'a'}}
+}
+void testK2_(K k, I i) {
+ k.j->i = i; // expected-error {{cannot assign to non-static data member 'i' with const-qualified data member 'a'}}
+}
diff --git a/test/Sema/attr-alias.c b/test/Sema/attr-alias.c
index 151052f89e51..93136706a7e5 100644
--- a/test/Sema/attr-alias.c
+++ b/test/Sema/attr-alias.c
@@ -2,7 +2,4 @@
void g() {}
-// It is important that the following string be in the error message. The gcc
-// testsuite looks for it to decide if a target supports aliases.
-
-void f() __attribute__((alias("g"))); //expected-error {{only weak aliases are supported}}
+void f() __attribute__((alias("g"))); //expected-error {{aliases are not supported on darwin}}
diff --git a/test/Sema/attr-availability-app-extensions.c b/test/Sema/attr-availability-app-extensions.c
index 8f9dcbc763d1..c66c14ed1a15 100644
--- a/test/Sema/attr-availability-app-extensions.c
+++ b/test/Sema/attr-availability-app-extensions.c
@@ -21,8 +21,19 @@ __attribute__((availability(ios,unavailable)))
#endif
void f1(int); // expected-note {{'f1' has been explicitly marked unavailable here}}
+#if __has_feature(attribute_availability_app_extension)
+ __attribute__((availability(macOSApplicationExtension,unavailable)))
+#ifndef TVOS
+ __attribute__((availability(iOSApplicationExtension,unavailable)))
+#else
+ __attribute__((availability(tvOSApplicationExtension,unavailable)))
+#endif
+#endif
+void f2(int); // expected-note {{'f2' has been explicitly marked unavailable here}}
+
void test() {
f0(1); // expected-error {{'f0' is unavailable: not available on}}
f1(1); // expected-error {{'f1' is unavailable}}
+ f2(2); // expected-error {{'f2' is unavailable: not available on}}
}
diff --git a/test/Sema/attr-availability-ios.c b/test/Sema/attr-availability-ios.c
index 6462d58beec0..3f901bb33cb5 100644
--- a/test/Sema/attr-availability-ios.c
+++ b/test/Sema/attr-availability-ios.c
@@ -2,13 +2,13 @@
void f0(int) __attribute__((availability(ios,introduced=2.0,deprecated=2.1))); // expected-note {{'f0' has been explicitly marked deprecated here}}
void f1(int) __attribute__((availability(ios,introduced=2.1)));
-void f2(int) __attribute__((availability(ios,introduced=2.0,deprecated=3.0))); // expected-note {{'f2' has been explicitly marked deprecated here}}
+void f2(int) __attribute__((availability(iOS,introduced=2.0,deprecated=3.0))); // expected-note {{'f2' has been explicitly marked deprecated here}}
void f3(int) __attribute__((availability(ios,introduced=3.0)));
void f4(int) __attribute__((availability(macosx,introduced=10.1,deprecated=10.3,obsoleted=10.5), availability(ios,introduced=2.0,deprecated=2.1,obsoleted=3.0))); // expected-note{{explicitly marked unavailable}}
void f5(int) __attribute__((availability(ios,introduced=2.0))) __attribute__((availability(ios,deprecated=3.0))); // expected-note {{'f5' has been explicitly marked deprecated here}}
void f6(int) __attribute__((availability(ios,deprecated=3.0)));
-void f6(int) __attribute__((availability(ios,introduced=2.0))); // expected-note {{'f6' has been explicitly marked deprecated here}}
+void f6(int) __attribute__((availability(iOS,introduced=2.0))); // expected-note {{'f6' has been explicitly marked deprecated here}}
void test() {
f0(0); // expected-warning{{'f0' is deprecated: first deprecated in iOS 2.1}}
diff --git a/test/Sema/attr-availability-macosx.c b/test/Sema/attr-availability-macosx.c
index f422811708fa..d39086985088 100644
--- a/test/Sema/attr-availability-macosx.c
+++ b/test/Sema/attr-availability-macosx.c
@@ -10,7 +10,7 @@ void f2(int) __attribute__((availability(macosx,introduced=10.4,deprecated=10.5)
void f3(int) __attribute__((availability(macosx,introduced=10.6)));
void f4(int) __attribute__((availability(macosx,introduced=10.1,deprecated=10.3,obsoleted=10.5), availability(ios,introduced=2.0,deprecated=3.0))); // expected-note{{explicitly marked unavailable}}
void f5(int) __attribute__((availability(ios,introduced=3.2), availability(macosx,unavailable))); // expected-note{{'f5' has been explicitly marked unavailable here}}
-void f6(int) __attribute__((availability(macosx,strict,introduced=10.6))); //expected-note{{'f6' has been explicitly marked unavailable here}}
+void f6(int) __attribute__((availability(macOS,strict,introduced=10.6))); //expected-note{{'f6' has been explicitly marked unavailable here}}
void test() {
f0(0);
@@ -47,7 +47,7 @@ enum __attribute__((availability(macosx,introduced=8.0,deprecated=9.0))) {
};
// Make sure the note is on the declaration with the actual availability attributes.
-struct __attribute__((availability(macosx,strict,introduced=10.9))) type_info // \
+struct __attribute__((availability(macOS,strict,introduced=10.9))) type_info // \
expected-note{{'type_info' has been explicitly marked unavailable here}}
{
};
diff --git a/test/Sema/attr-availability-tvos.c b/test/Sema/attr-availability-tvos.c
index 642246425b37..d53d6ac8edc4 100644
--- a/test/Sema/attr-availability-tvos.c
+++ b/test/Sema/attr-availability-tvos.c
@@ -36,7 +36,7 @@ void f10(int);
// Test tvOS specific attributes.
void f0_tvos(int) __attribute__((availability(tvos,introduced=2.0,deprecated=2.1))); // expected-note {{'f0_tvos' has been explicitly marked deprecated here}}
void f1_tvos(int) __attribute__((availability(tvos,introduced=2.1)));
-void f2_tvos(int) __attribute__((availability(tvos,introduced=2.0,deprecated=3.0))); // expected-note {{'f2_tvos' has been explicitly marked deprecated here}}
+void f2_tvos(int) __attribute__((availability(tvOS,introduced=2.0,deprecated=3.0))); // expected-note {{'f2_tvos' has been explicitly marked deprecated here}}
void f3_tvos(int) __attribute__((availability(tvos,introduced=3.0)));
void f4_tvos(int) __attribute__((availability(macosx,introduced=10.1,deprecated=10.3,obsoleted=10.5), availability(tvos,introduced=2.0,deprecated=2.1,obsoleted=3.0))); // expected-note{{explicitly marked unavailable}}
void f5_tvos(int) __attribute__((availability(tvos,introduced=2.0))) __attribute__((availability(ios,deprecated=3.0)));
@@ -44,7 +44,7 @@ void f5_attr_reversed_tvos(int) __attribute__((availability(ios, deprecated=3.0)
void f5b_tvos(int) __attribute__((availability(tvos,introduced=2.0))) __attribute__((availability(tvos,deprecated=3.0))); // expected-note {{'f5b_tvos' has been explicitly marked deprecated here}}
void f5c_tvos(int) __attribute__((availability(ios,introduced=2.0))) __attribute__((availability(ios,deprecated=3.0))); // expected-note {{'f5c_tvos' has been explicitly marked deprecated here}}
void f6_tvos(int) __attribute__((availability(tvos,deprecated=3.0)));
-void f6_tvos(int) __attribute__((availability(tvos,introduced=2.0))); // expected-note {{'f6_tvos' has been explicitly marked deprecated here}}
+void f6_tvos(int) __attribute__((availability(tvOS,introduced=2.0))); // expected-note {{'f6_tvos' has been explicitly marked deprecated here}}
void test_tvos() {
f0_tvos(0); // expected-warning{{'f0_tvos' is deprecated: first deprecated in tvOS 2.1}}
diff --git a/test/Sema/attr-availability-watchos.c b/test/Sema/attr-availability-watchos.c
index cb9f968bd6ab..ec7f3a7d3afd 100644
--- a/test/Sema/attr-availability-watchos.c
+++ b/test/Sema/attr-availability-watchos.c
@@ -25,7 +25,7 @@ void test() {
// Test watchOS specific attributes.
void f0_watchos(int) __attribute__((availability(watchos,introduced=2.0,deprecated=2.1))); // expected-note {{'f0_watchos' has been explicitly marked deprecated here}}
void f1_watchos(int) __attribute__((availability(watchos,introduced=2.1)));
-void f2_watchos(int) __attribute__((availability(watchos,introduced=2.0,deprecated=3.0))); // expected-note {{'f2_watchos' has been explicitly marked deprecated here}}
+void f2_watchos(int) __attribute__((availability(watchOS,introduced=2.0,deprecated=3.0))); // expected-note {{'f2_watchos' has been explicitly marked deprecated here}}
void f3_watchos(int) __attribute__((availability(watchos,introduced=3.0)));
void f4_watchos(int) __attribute__((availability(macosx,introduced=10.1,deprecated=10.3,obsoleted=10.5), availability(watchos,introduced=2.0,deprecated=2.1,obsoleted=3.0))); // expected-note{{explicitly marked unavailable}}
void f5_watchos(int) __attribute__((availability(watchos,introduced=2.0))) __attribute__((availability(ios,deprecated=3.0)));
@@ -33,7 +33,7 @@ void f5_attr_reversed_watchos(int) __attribute__((availability(ios, deprecated=3
void f5b_watchos(int) __attribute__((availability(watchos,introduced=2.0))) __attribute__((availability(watchos,deprecated=3.0))); // expected-note {{'f5b_watchos' has been explicitly marked deprecated here}}
void f5c_watchos(int) __attribute__((availability(ios,introduced=2.0))) __attribute__((availability(ios,deprecated=3.0))); // expected-note {{'f5c_watchos' has been explicitly marked deprecated here}}
void f6_watchos(int) __attribute__((availability(watchos,deprecated=3.0)));
-void f6_watchos(int) __attribute__((availability(watchos,introduced=2.0))); // expected-note {{'f6_watchos' has been explicitly marked deprecated here}}
+void f6_watchos(int) __attribute__((availability(watchOS,introduced=2.0))); // expected-note {{'f6_watchos' has been explicitly marked deprecated here}}
void test_watchos() {
f0_watchos(0); // expected-warning{{'f0_watchos' is deprecated: first deprecated in watchOS 2.1}}
diff --git a/test/Sema/attr-capabilities.c b/test/Sema/attr-capabilities.c
index 89967704865f..21cbae9e6090 100644
--- a/test/Sema/attr-capabilities.c
+++ b/test/Sema/attr-capabilities.c
@@ -11,8 +11,8 @@ typedef union { int a; char* b; } __attribute__((capability("mutex"))) MutexUnio
// Test an invalid capability name
struct __attribute__((capability("wrong"))) IncorrectName {}; // expected-warning {{invalid capability name 'wrong'; capability name must be 'mutex' or 'role'}}
-int Test1 __attribute__((capability("test1"))); // expected-error {{'capability' attribute only applies to structs, unions, and typedefs}}
-int Test2 __attribute__((shared_capability("test2"))); // expected-error {{'shared_capability' attribute only applies to structs, unions, and typedefs}}
+int Test1 __attribute__((capability("test1"))); // expected-error {{'capability' attribute only applies to structs, unions, classes, and typedefs}}
+int Test2 __attribute__((shared_capability("test2"))); // expected-error {{'shared_capability' attribute only applies to structs, unions, classes, and typedefs}}
int Test3 __attribute__((acquire_capability("test3"))); // expected-warning {{'acquire_capability' attribute only applies to functions}}
int Test4 __attribute__((try_acquire_capability("test4"))); // expected-error {{'try_acquire_capability' attribute only applies to functions}}
int Test5 __attribute__((release_capability("test5"))); // expected-warning {{'release_capability' attribute only applies to functions}}
@@ -37,9 +37,6 @@ void Func6(void) __attribute__((requires_shared_capability(BadCapability))) {}
void Func7(void) __attribute__((assert_capability(GUI))) {}
void Func8(void) __attribute__((assert_shared_capability(GUI))) {}
-void Func9(void) __attribute__((assert_capability())) {} // expected-error {{'assert_capability' attribute takes one argument}}
-void Func10(void) __attribute__((assert_shared_capability())) {} // expected-error {{'assert_shared_capability' attribute takes one argument}}
-
void Func11(void) __attribute__((acquire_capability(GUI))) {}
void Func12(void) __attribute__((acquire_shared_capability(GUI))) {}
diff --git a/test/Sema/attr-capabilities.cpp b/test/Sema/attr-capabilities.cpp
new file mode 100644
index 000000000000..5bae94edaa41
--- /dev/null
+++ b/test/Sema/attr-capabilities.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -fsyntax-only -Wthread-safety -verify %s
+
+class __attribute__((shared_capability("mutex"))) Mutex {
+ public:
+ void func1() __attribute__((assert_capability(this)));
+ void func2() __attribute__((assert_capability(!this)));
+
+ const Mutex& operator!() const { return *this; }
+};
+
+class NotACapability {
+ public:
+ void func1() __attribute__((assert_capability(this))); // expected-warning {{'assert_capability' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'NotACapability *'}}
+ void func2() __attribute__((assert_capability(!this))); // expected-warning {{'assert_capability' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'bool'}}
+
+ const NotACapability& operator!() const { return *this; }
+};
diff --git a/test/Sema/attr-cleanup.c b/test/Sema/attr-cleanup.c
index 26f283a1a4fa..36692898c191 100644
--- a/test/Sema/attr-cleanup.c
+++ b/test/Sema/attr-cleanup.c
@@ -2,16 +2,16 @@
void c1(int *a);
-extern int g1 __attribute((cleanup(c1))); // expected-warning {{'cleanup' attribute ignored}}
-int g2 __attribute((cleanup(c1))); // expected-warning {{'cleanup' attribute ignored}}
-static int g3 __attribute((cleanup(c1))); // expected-warning {{'cleanup' attribute ignored}}
+extern int g1 __attribute((cleanup(c1))); // expected-warning {{'cleanup' attribute only applies to local variables}}
+int g2 __attribute((cleanup(c1))); // expected-warning {{'cleanup' attribute only applies to local variables}}
+static int g3 __attribute((cleanup(c1))); // expected-warning {{'cleanup' attribute only applies to local variables}}
void t1()
{
int v1 __attribute((cleanup)); // expected-error {{'cleanup' attribute takes one argument}}
int v2 __attribute((cleanup(1, 2))); // expected-error {{'cleanup' attribute takes one argument}}
- static int v3 __attribute((cleanup(c1))); // expected-warning {{'cleanup' attribute ignored}}
+ static int v3 __attribute((cleanup(c1))); // expected-warning {{'cleanup' attribute only applies to local variables}}
int v4 __attribute((cleanup(h))); // expected-error {{use of undeclared identifier 'h'}}
@@ -46,3 +46,5 @@ void t5() {
void t6(void) {
int i __attribute__((cleanup((void *)0))); // expected-error {{'cleanup' argument is not a function}}
}
+
+void t7(__attribute__((cleanup(c4))) int a) {} // expected-warning {{'cleanup' attribute only applies to local variables}}
diff --git a/test/Sema/attr-deprecated-c2x.c b/test/Sema/attr-deprecated-c2x.c
new file mode 100644
index 000000000000..2505f1294c38
--- /dev/null
+++ b/test/Sema/attr-deprecated-c2x.c
@@ -0,0 +1,54 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only -fdouble-square-bracket-attributes
+
+int f() [[deprecated]]; // expected-note 2 {{'f' has been explicitly marked deprecated here}}
+void g() [[deprecated]];// expected-note {{'g' has been explicitly marked deprecated here}}
+void g();
+
+extern int var [[deprecated]]; // expected-note 2 {{'var' has been explicitly marked deprecated here}}
+
+int a() {
+ int (*ptr)() = f; // expected-warning {{'f' is deprecated}}
+ f(); // expected-warning {{'f' is deprecated}}
+
+ // test if attributes propagate to functions
+ g(); // expected-warning {{'g' is deprecated}}
+
+ return var; // expected-warning {{'var' is deprecated}}
+}
+
+// test if attributes propagate to variables
+extern int var;
+int w() {
+ return var; // expected-warning {{'var' is deprecated}}
+}
+
+int old_fn() [[deprecated]];// expected-note {{'old_fn' has been explicitly marked deprecated here}}
+int old_fn();
+int (*fn_ptr)() = old_fn; // expected-warning {{'old_fn' is deprecated}}
+
+int old_fn() {
+ return old_fn()+1; // no warning, deprecated functions can use deprecated symbols.
+}
+
+struct foo {
+ int x [[deprecated]]; // expected-note 3 {{'x' has been explicitly marked deprecated here}}
+};
+
+void test1(struct foo *F) {
+ ++F->x; // expected-warning {{'x' is deprecated}}
+ struct foo f1 = { .x = 17 }; // expected-warning {{'x' is deprecated}}
+ struct foo f2 = { 17 }; // expected-warning {{'x' is deprecated}}
+}
+
+typedef struct foo foo_dep [[deprecated]]; // expected-note {{'foo_dep' has been explicitly marked deprecated here}}
+foo_dep *test2; // expected-warning {{'foo_dep' is deprecated}}
+
+struct [[deprecated, // expected-note {{'bar_dep' has been explicitly marked deprecated here}}
+ invalid_attribute]] bar_dep ; // expected-warning {{unknown attribute 'invalid_attribute' ignored}}
+
+struct bar_dep *test3; // expected-warning {{'bar_dep' is deprecated}}
+
+[[deprecated("this is the message")]] int i; // expected-note {{'i' has been explicitly marked deprecated here}}
+void test4(void) {
+ i = 12; // expected-warning {{'i' is deprecated: this is the message}}
+}
diff --git a/test/Sema/attr-disable-tail-calls.c b/test/Sema/attr-disable-tail-calls.c
index 4574d5e0b66b..e8f5bcc73ee8 100644
--- a/test/Sema/attr-disable-tail-calls.c
+++ b/test/Sema/attr-disable-tail-calls.c
@@ -8,6 +8,6 @@ void __attribute__((naked,disable_tail_calls)) foo2(int a) { // expected-error {
__asm__("");
}
-int g0 __attribute__((disable_tail_calls)); // expected-warning {{'disable_tail_calls' attribute only applies to functions and methods}}
+int g0 __attribute__((disable_tail_calls)); // expected-warning {{'disable_tail_calls' attribute only applies to functions and Objective-C methods}}
int foo3(int a) __attribute__((disable_tail_calls("abc"))); // expected-error {{'disable_tail_calls' attribute takes no arguments}}
diff --git a/test/Sema/attr-long-call.c b/test/Sema/attr-long-call.c
new file mode 100644
index 000000000000..cd3de1bf9e41
--- /dev/null
+++ b/test/Sema/attr-long-call.c
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -triple mips-linux-gnu -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple mips64-linux-gnu -fsyntax-only -verify %s
+
+__attribute__((long_call(0))) void foo1(); // expected-error {{'long_call' attribute takes no arguments}}
+__attribute__((short_call(0))) void foo9(); // expected-error {{'short_call' attribute takes no arguments}}
+__attribute__((far(0))) void foo2(); // expected-error {{'far' attribute takes no arguments}}
+__attribute__((near(0))) void foo3(); // expected-error {{'near' attribute takes no arguments}}
+
+__attribute((long_call)) int a; // expected-warning {{attribute only applies to functions}}
+__attribute((short_call)) int d; // expected-warning {{attribute only applies to functions}}
+__attribute((far)) int a; // expected-warning {{attribute only applies to functions}}
+__attribute((near)) int a; // expected-warning {{attribute only applies to functions}}
+
+__attribute((long_call)) void foo4();
+__attribute((short_call)) void foo10();
+__attribute((far)) void foo5();
+__attribute((near)) void foo6();
+
+__attribute((long_call, far)) void foo7();
+__attribute((short_call, near)) void foo11();
+
+__attribute((far, near)) void foo8(); // expected-error {{'far' and 'near' attributes are not compatible}} \
+ // expected-note {{conflicting attribute is here}}
+
+__attribute((short_call, long_call)) void foo12(); // expected-error {{'short_call' and 'long_call' attributes are not compatible}} \
+ // expected-note {{conflicting attribute is here}}
diff --git a/test/Sema/attr-minsize.c b/test/Sema/attr-minsize.c
index 7b1c6ae66f1b..d2374b6113be 100644
--- a/test/Sema/attr-minsize.c
+++ b/test/Sema/attr-minsize.c
@@ -2,4 +2,4 @@
int foo() __attribute__((__minsize__));
-int var1 __attribute__((__minsize__)); // expected-error{{'__minsize__' attribute only applies to functions and methods}}
+int var1 __attribute__((__minsize__)); // expected-error{{'__minsize__' attribute only applies to functions and Objective-C methods}}
diff --git a/test/Sema/attr-mode.c b/test/Sema/attr-mode.c
index e160d8d4846d..c0e0426e0098 100644
--- a/test/Sema/attr-mode.c
+++ b/test/Sema/attr-mode.c
@@ -26,8 +26,8 @@ typedef unsigned unwind_word __attribute((mode(unwind_word)));
int **__attribute((mode(QI)))* i32; // expected-error{{mode attribute}}
-__attribute__((mode(QI))) int invalid_func() { return 1; } // expected-error{{'mode' attribute only applies to variables, enums, fields and typedefs}}
-enum invalid_enum { A1 __attribute__((mode(QI))) }; // expected-error{{'mode' attribute only applies to variables, enums, fields and typedefs}}
+__attribute__((mode(QI))) int invalid_func() { return 1; } // expected-error{{'mode' attribute only applies to variables, enums, typedefs, and non-static data members}}
+enum invalid_enum { A1 __attribute__((mode(QI))) }; // expected-error{{'mode' attribute only applies to}}
typedef _Complex double c32 __attribute((mode(SC)));
int c32_test[sizeof(c32) == 8 ? 1 : -1];
diff --git a/test/Sema/attr-nodebug.c b/test/Sema/attr-nodebug.c
index e7ca58d3ba15..355778411d3e 100644
--- a/test/Sema/attr-nodebug.c
+++ b/test/Sema/attr-nodebug.c
@@ -2,7 +2,7 @@
int a __attribute__((nodebug));
-void b(int p __attribute__((nodebug))) { // expected-warning {{'nodebug' attribute only applies to variables and functions}}
+void b(int p __attribute__((nodebug))) { // expected-warning {{'nodebug' attribute only applies to functions, function pointers, Objective-C methods, and variables}}
int b __attribute__((nodebug));
}
diff --git a/test/Sema/attr-section.c b/test/Sema/attr-section.c
index c64b10d80ff6..bc4247411130 100644
--- a/test/Sema/attr-section.c
+++ b/test/Sema/attr-section.c
@@ -10,7 +10,7 @@ int y __attribute__((section(
// PR6007
void test() {
- __attribute__((section("NEAR,x"))) int n1; // expected-error {{'section' attribute only applies to functions, methods, properties, and global variables}}
+ __attribute__((section("NEAR,x"))) int n1; // expected-error {{'section' attribute only applies to functions, global variables, Objective-C methods, and Objective-C properties}}
__attribute__((section("NEAR,x"))) static int n2; // ok.
}
@@ -18,4 +18,17 @@ void test() {
void __attribute__((section("foo,zed"))) test2(void); // expected-note {{previous attribute is here}}
void __attribute__((section("bar,zed"))) test2(void) {} // expected-warning {{section does not match previous declaration}}
-enum __attribute__((section("NEAR,x"))) e { one }; // expected-error {{'section' attribute only applies to functions, methods, properties, and global variables}}
+enum __attribute__((section("NEAR,x"))) e { one }; // expected-error {{'section' attribute only applies to}}
+
+extern int a; // expected-note {{previous declaration is here}}
+int *b = &a;
+extern int a __attribute__((section("foo,zed"))); // expected-warning {{section attribute is specified on redeclared variable}}
+
+// Not a warning.
+int c;
+int c __attribute__((section("foo,zed")));
+
+// Also OK.
+struct r_debug {};
+extern struct r_debug _r_debug;
+struct r_debug _r_debug __attribute__((nocommon, section(".r_debug,bar")));
diff --git a/test/Sema/attr-target.c b/test/Sema/attr-target.c
index 6c6b461904d1..058bfc421a19 100644
--- a/test/Sema/attr-target.c
+++ b/test/Sema/attr-target.c
@@ -2,7 +2,13 @@
int __attribute__((target("avx,sse4.2,arch=ivybridge"))) foo() { return 4; }
int __attribute__((target())) bar() { return 4; } //expected-error {{'target' attribute takes one argument}}
-int __attribute__((target("tune=sandybridge"))) baz() { return 4; } //expected-warning {{Ignoring unsupported 'tune=' in the target attribute string}}
-int __attribute__((target("fpmath=387"))) walrus() { return 4; } //expected-warning {{Ignoring unsupported 'fpmath=' in the target attribute string}}
+int __attribute__((target("tune=sandybridge"))) baz() { return 4; } //expected-warning {{ignoring unsupported 'tune=' in the target attribute string}}
+int __attribute__((target("fpmath=387"))) walrus() { return 4; } //expected-warning {{ignoring unsupported 'fpmath=' in the target attribute string}}
+int __attribute__((target("avx,sse4.2,arch=hiss"))) meow() { return 4; }//expected-warning {{ignoring unsupported architecture 'hiss' in the target attribute string}}
+int __attribute__((target("woof"))) bark() { return 4; }//expected-warning {{ignoring unsupported 'woof' in the target attribute string}}
+int __attribute__((target("arch="))) turtle() { return 4; } // no warning, same as saying 'nothing'.
+int __attribute__((target("arch=hiss,arch=woof"))) pine_tree() { return 4; } //expected-warning {{ignoring unsupported architecture 'hiss' in the target attribute string}}
+int __attribute__((target("arch=ivybridge,arch=haswell"))) oak_tree() { return 4; } //expected-warning {{ignoring duplicate 'arch=' in the target attribute string}}
+
diff --git a/test/Sema/attr-weak.c b/test/Sema/attr-weak.c
index df74554487e2..e3610caba584 100644
--- a/test/Sema/attr-weak.c
+++ b/test/Sema/attr-weak.c
@@ -5,10 +5,10 @@ extern int g1 __attribute__((weak_import));
int g2 __attribute__((weak));
int g3 __attribute__((weak_import)); // expected-warning {{'weak_import' attribute cannot be specified on a definition}}
int __attribute__((weak_import)) g4(void);
-void __attribute__((weak_import)) g5(void) {
+void __attribute__((weak_import)) g5(void) {
}
-struct __attribute__((weak)) s0 {}; // expected-warning {{'weak' attribute only applies to variables and functions}}
+struct __attribute__((weak)) s0 {}; // expected-warning {{'weak' attribute only applies to variables, functions, and classes}}
struct __attribute__((weak_import)) s1 {}; // expected-warning {{'weak_import' attribute only applies to variables and functions}}
static int x __attribute__((weak)); // expected-error {{weak declaration cannot have internal linkage}}
diff --git a/test/Sema/builtin-assume-aligned.c b/test/Sema/builtin-assume-aligned.c
index 33c1b74488e1..057a500b321a 100644
--- a/test/Sema/builtin-assume-aligned.c
+++ b/test/Sema/builtin-assume-aligned.c
@@ -47,7 +47,7 @@ void test_void_assume_aligned(void) __attribute__((assume_aligned(32))); // expe
int test_int_assume_aligned(void) __attribute__((assume_aligned(16))); // expected-warning {{'assume_aligned' attribute only applies to return values that are pointers}}
void *test_ptr_assume_aligned(void) __attribute__((assume_aligned(64))); // no-warning
-int j __attribute__((assume_aligned(8))); // expected-warning {{'assume_aligned' attribute only applies to functions and methods}}
+int j __attribute__((assume_aligned(8))); // expected-warning {{'assume_aligned' attribute only applies to Objective-C methods and functions}}
void *test_no_fn_proto() __attribute__((assume_aligned(32))); // no-warning
void *test_with_fn_proto(void) __attribute__((assume_aligned(128))); // no-warning
diff --git a/test/Sema/builtin-cpu-supports.c b/test/Sema/builtin-cpu-supports.c
index c537b4140b27..026b5b7e38e9 100644
--- a/test/Sema/builtin-cpu-supports.c
+++ b/test/Sema/builtin-cpu-supports.c
@@ -12,9 +12,15 @@ int main() {
if (__builtin_cpu_supports(str)) // expected-error {{expression is not a string literal}}
a(str);
+
+ if (__builtin_cpu_is("int")) // expected-error {{invalid cpu name for builtin}}
+ a("intel");
#else
if (__builtin_cpu_supports("vsx")) // expected-error {{use of unknown builtin}}
a("vsx");
+
+ if (__builtin_cpu_is("pwr9")) // expected-error {{use of unknown builtin}}
+ a("pwr9");
#endif
return 0;
diff --git a/test/Sema/builtins-arm.c b/test/Sema/builtins-arm.c
index 668b8284ffeb..373bbae31e7f 100644
--- a/test/Sema/builtins-arm.c
+++ b/test/Sema/builtins-arm.c
@@ -2,6 +2,8 @@
// RUN: %clang_cc1 -triple armv7 -target-abi apcs-gnu \
// RUN: -fsyntax-only -verify %s
+#include <arm_acle.h>
+
void f(void *a, void *b) {
__clear_cache(); // expected-error {{too few arguments to function call, expected 2, have 0}} // expected-note {{'__clear_cache' is a builtin with type 'void (void *, void *)}}
__clear_cache(a); // expected-error {{too few arguments to function call, expected 2, have 1}}
@@ -136,3 +138,185 @@ void test6(int a, int b, int c) {
__builtin_arm_mrrc2(15, a, 0); // expected-error {{argument to '__builtin_arm_mrrc2' must be a constant integer}}
__builtin_arm_mrrc2(15, 0, a); // expected-error {{argument to '__builtin_arm_mrrc2' must be a constant integer}}
}
+
+void test_9_3_multiplications(int a, int b) {
+ int r;
+ r = __builtin_arm_smulbb(a, b);
+ r = __builtin_arm_smulbb(1, -9);
+
+ r = __builtin_arm_smulbt(a, b);
+ r = __builtin_arm_smulbt(0, b);
+
+ r = __builtin_arm_smultb(a, b);
+ r = __builtin_arm_smultb(5, b);
+
+ r = __builtin_arm_smultt(a, b);
+ r = __builtin_arm_smultt(a, -1);
+
+ r = __builtin_arm_smulwb(a, b);
+ r = __builtin_arm_smulwb(1, 2);
+
+ r = __builtin_arm_smulwt(a, b);
+ r = __builtin_arm_smulwt(-1, -2);
+ r = __builtin_arm_smulwt(-1.0f, -2);
+}
+
+void test_9_4_1_width_specified_saturation(int a, int b) {
+ unsigned u;
+ int s;
+
+ s = __builtin_arm_ssat(8, 2);
+ s = __builtin_arm_ssat(a, 1);
+ s = __builtin_arm_ssat(a, 32);
+ s = __builtin_arm_ssat(a, 0); // expected-error {{argument should be a value from 1 to 32}}
+ s = __builtin_arm_ssat(a, 33); // expected-error {{argument should be a value from 1 to 32}}
+ s = __builtin_arm_ssat(a, b); // expected-error {{argument to '__builtin_arm_ssat' must be a constant integer}}
+
+ u = __builtin_arm_usat(8, 2);
+ u = __builtin_arm_usat(a, 0);
+ u = __builtin_arm_usat(a, 31);
+ u = __builtin_arm_usat(a, 32); // expected-error {{argument should be a value from 0 to 31}}
+ u = __builtin_arm_usat(a, b); // expected-error {{argument to '__builtin_arm_usat' must be a constant integer}}
+}
+
+void test_9_4_2_saturating_addition_subtraction(int a, int b) {
+ int s;
+ s = __builtin_arm_qadd(a, b);
+ s = __builtin_arm_qadd(-1, 0);
+
+ s = __builtin_arm_qsub(a, b);
+ s = __builtin_arm_qsub(0, -1);
+
+ s = __builtin_arm_qdbl(a);
+}
+
+void test_9_4_3_accumulating_multiplications(int a, int b, int c) {
+ int s;
+
+ s = __builtin_arm_smlabb(a, b, c);
+ s = __builtin_arm_smlabb(1, b, c);
+ s = __builtin_arm_smlabb(a, 2, c);
+ s = __builtin_arm_smlabb(a, b, -3);
+
+ s = __builtin_arm_smlabt(a, b, c);
+ s = __builtin_arm_smlabt(1, b, c);
+ s = __builtin_arm_smlabt(a, 2, c);
+ s = __builtin_arm_smlabt(a, b, -3);
+
+ s = __builtin_arm_smlatb(a, b, c);
+ s = __builtin_arm_smlatt(1, b, c);
+ s = __builtin_arm_smlawb(a, 2, c);
+ s = __builtin_arm_smlawt(a, b, -3);
+}
+
+void test_9_5_4_parallel_16bit_saturation(int16x2_t a) {
+ unsigned u;
+ int s;
+
+ s = __builtin_arm_ssat16(a, 1);
+ s = __builtin_arm_ssat16(a, 16);
+ s = __builtin_arm_ssat16(a, 0); // expected-error {{argument should be a value from 1 to 16}}
+ s = __builtin_arm_ssat16(a, 17); // expected-error {{argument should be a value from 1 to 16}}
+
+ u = __builtin_arm_usat16(a, 0);
+ u = __builtin_arm_usat16(a, 15);
+ u = __builtin_arm_usat16(a, 16); // expected-error {{argument should be a value from 0 to 15}}
+}
+
+void test_9_5_5_packing_and_unpacking(int16x2_t a, int8x4_t b, uint16x2_t c, uint8x4_t d) {
+ int16x2_t x;
+ uint16x2_t y;
+
+ x = __builtin_arm_sxtab16(a, b);
+ x = __builtin_arm_sxtab16(1, -1);
+ x = __builtin_arm_sxtb16(b);
+ x = __builtin_arm_sxtb16(-b);
+
+ y = __builtin_arm_uxtab16(c, d);
+ y = __builtin_arm_uxtab16(-1, -2);
+ y = __builtin_arm_uxtb16(d);
+ y = __builtin_arm_uxtb16(-1);
+}
+
+uint8x4_t
+test_9_5_6_parallel_selection(uint8x4_t a, uint8x4_t b) {
+ return __builtin_arm_sel(a, b);
+}
+
+void test_9_5_7_parallel_8bit_addition_substraction(int8x4_t a, int8x4_t b,
+ uint8x4_t c, uint8x4_t d) {
+ int8x4_t s;
+ uint8x4_t u;
+
+ s = __builtin_arm_qadd8(a, b);
+ s = __builtin_arm_qsub8(a, b);
+ s = __builtin_arm_sadd8(a, b);
+ s = __builtin_arm_shadd8(a, b);
+ s = __builtin_arm_shsub8(a, b);
+ s = __builtin_arm_ssub8(a, b);
+
+ u = __builtin_arm_uadd8(c, d);
+ u = __builtin_arm_uhadd8(c, d);
+ u = __builtin_arm_uhsub8(c, d);
+ u = __builtin_arm_uqadd8(c, d);
+ u = __builtin_arm_uqsub8(c, d);
+ u = __builtin_arm_usub8(c, d);
+}
+
+void test_9_5_8_absolute_differences(uint8x4_t a, uint8x4_t b, uint32_t c) {
+ uint32_t r;
+
+ r = __builtin_arm_usad8(a, b);
+ r = __builtin_arm_usada8(a, b, c);
+}
+
+void test_9_5_9_parallel_addition_and_subtraction(int16x2_t a, int16x2_t b,
+ uint16x2_t c, uint16x2_t d) {
+ int16x2_t x;
+ uint16x2_t y;
+
+ x = __builtin_arm_qadd16(a, b);
+ x = __builtin_arm_qasx(a, b);
+ x = __builtin_arm_qsax(a, b);
+ x = __builtin_arm_qsub16(a, b);
+ x = __builtin_arm_sadd16(a, b);
+ x = __builtin_arm_sasx(a, b);
+ x = __builtin_arm_shadd16(a, b);
+ x = __builtin_arm_shasx(a, b);
+ x = __builtin_arm_shsax(a, b);
+ x = __builtin_arm_shsub16(a, b);
+ x = __builtin_arm_ssax(a, b);
+ x = __builtin_arm_ssub16(a, b);
+
+ y = __builtin_arm_uadd16(c, d);
+ y = __builtin_arm_uasx(c, d);
+ y = __builtin_arm_uhadd16(c, d);
+ y = __builtin_arm_uhasx(c, d);
+ y = __builtin_arm_uhsax(c, d);
+ y = __builtin_arm_uhsub16(c, d);
+ y = __builtin_arm_uqadd16(c, d);
+ y = __builtin_arm_uqasx(c, d);
+ y = __builtin_arm_uqsax(c, d);
+ y = __builtin_arm_uqsub16(c, d);
+ y = __builtin_arm_usax(c, d);
+ y = __builtin_arm_usub16(c, d);
+}
+
+void test_9_5_10_parallel_16bit_multiplication(int16x2_t a, int16x2_t b,
+ int32_t c, int64_t d) {
+ int32_t x;
+ int64_t y;
+
+ x = __builtin_arm_smlad(a, b, c);
+ x = __builtin_arm_smladx(a, b, c);
+ y = __builtin_arm_smlald(a, b, d);
+ y = __builtin_arm_smlaldx(a, b, d);
+ x = __builtin_arm_smlsd(a, b, c);
+ x = __builtin_arm_smlsdx(a, b, c);
+ y = __builtin_arm_smlsld(a, b, d);
+ y = __builtin_arm_smlsldx(a, b, d);
+ x = __builtin_arm_smuad(a, b);
+ x = __builtin_arm_smuadx(a, b);
+ x = __builtin_arm_smusd(a, b);
+ x = __builtin_arm_smusdx(a, b);
+}
diff --git a/test/Sema/c2x-fallthrough.c b/test/Sema/c2x-fallthrough.c
new file mode 100644
index 000000000000..2fd69c4da0f2
--- /dev/null
+++ b/test/Sema/c2x-fallthrough.c
@@ -0,0 +1,75 @@
+// RUN: %clang_cc1 -fsyntax-only -fdouble-square-bracket-attributes -verify %s
+
+void f(int n) {
+ switch (n) {
+ case 0:
+ n += 1;
+ [[fallthrough]]; // ok
+ case 1:
+ if (n) {
+ [[fallthrough]]; // ok
+ } else {
+ return;
+ }
+ case 2:
+ for (int n = 0; n != 10; ++n)
+ [[fallthrough]]; // expected-error {{does not directly precede switch label}}
+ case 3:
+ while (1)
+ [[fallthrough]]; // expected-error {{does not directly precede switch label}}
+ case 4:
+ while (0)
+ [[fallthrough]]; // expected-error {{does not directly precede switch label}}
+ case 5:
+ do [[fallthrough]]; while (1); // expected-error {{does not directly precede switch label}}
+ case 6:
+ do [[fallthrough]]; while (0); // expected-error {{does not directly precede switch label}}
+ case 7:
+ switch (n) {
+ case 0:
+ // FIXME: This should be an error, even though the next thing we do is to
+ // fall through in an outer switch statement.
+ [[fallthrough]];
+ }
+ case 8:
+ [[fallthrough]]; // expected-error {{does not directly precede switch label}}
+ goto label;
+ label:
+ case 9:
+ n += 1;
+ case 10: // no warning, -Wimplicit-fallthrough is not enabled in this test, and does not need to
+ // be enabled for these diagnostics to be produced.
+ break;
+ }
+}
+
+[[fallthrough]] typedef int n1; // expected-error {{'fallthrough' attribute cannot be applied to a declaration}}
+typedef int [[fallthrough]] n2; // expected-error {{'fallthrough' attribute cannot be applied to types}}
+typedef int n3 [[fallthrough]]; // expected-error {{'fallthrough' attribute cannot be applied to a declaration}}
+
+enum [[fallthrough]] E { // expected-error {{'fallthrough' attribute cannot be applied to a declaration}}
+ One
+};
+struct [[fallthrough]] S { // expected-error {{'fallthrough' attribute cannot be applied to a declaration}}
+ int i;
+};
+
+[[fallthrough]] // expected-error {{'fallthrough' attribute cannot be applied to a declaration}}
+void g(void) {
+ [[fallthrough]] int n; // expected-error {{'fallthrough' attribute cannot be applied to a declaration}}
+ [[fallthrough]] ++n; // expected-error-re {{{{^}}fallthrough attribute is only allowed on empty statements}}
+
+ switch (n) {
+ // FIXME: This should be an error.
+ [[fallthrough]];
+ return;
+
+ case 0:
+ [[fallthrough, fallthrough]]; // expected-error {{multiple times}}
+ case 1:
+ [[fallthrough(0)]]; // expected-error {{argument list}}
+ case 2:
+ break;
+ }
+}
+
diff --git a/test/Sema/c2x-maybe_unused-errors.c b/test/Sema/c2x-maybe_unused-errors.c
new file mode 100644
index 000000000000..68150dded9d5
--- /dev/null
+++ b/test/Sema/c2x-maybe_unused-errors.c
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -fsyntax-only -Wunused -fdouble-square-bracket-attributes -verify %s
+
+struct [[maybe_unused]] S1 { // ok
+ int a [[maybe_unused]];
+};
+struct [[maybe_unused maybe_unused]] S2 { // expected-error {{attribute 'maybe_unused' cannot appear multiple times in an attribute specifier}}
+ int a;
+};
+struct [[maybe_unused("Wrong")]] S3 { // expected-error {{'maybe_unused' cannot have an argument list}}
+ int a;
+};
+
diff --git a/test/Sema/c2x-maybe_unused.c b/test/Sema/c2x-maybe_unused.c
new file mode 100644
index 000000000000..816cf7835fa9
--- /dev/null
+++ b/test/Sema/c2x-maybe_unused.c
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -fsyntax-only -Wunused -fdouble-square-bracket-attributes -verify %s
+
+struct [[maybe_unused]] S1 { // ok
+ int a [[maybe_unused]];
+};
+
+enum [[maybe_unused]] E1 {
+ EnumVal [[maybe_unused]]
+};
+
+[[maybe_unused]] void unused_func([[maybe_unused]] int parm) {
+ typedef int maybe_unused_int [[maybe_unused]];
+ [[maybe_unused]] int I;
+}
+
+void f1(void) {
+ int x; // expected-warning {{unused variable}}
+ typedef int I; // expected-warning {{unused typedef 'I'}}
+
+ // Should not warn about these due to not being used.
+ [[maybe_unused]] int y;
+ typedef int maybe_unused_int [[maybe_unused]];
+
+ // Should not warn about these uses.
+ struct S1 s;
+ maybe_unused_int test;
+ y = 12;
+}
+
+void f2(void);
+[[maybe_unused]] void f2(void);
+
+void f2(void) {
+}
+
diff --git a/test/Sema/c2x-nodiscard.c b/test/Sema/c2x-nodiscard.c
new file mode 100644
index 000000000000..fc5b12347e62
--- /dev/null
+++ b/test/Sema/c2x-nodiscard.c
@@ -0,0 +1,49 @@
+// RUN: %clang_cc1 -fsyntax-only -fdouble-square-bracket-attributes -verify %s
+
+struct [[nodiscard]] S1 { // ok
+ int i;
+};
+struct [[nodiscard nodiscard]] S2 { // expected-error {{attribute 'nodiscard' cannot appear multiple times in an attribute specifier}}
+ int i;
+};
+struct [[nodiscard("Wrong")]] S3 { // expected-error {{'nodiscard' cannot have an argument list}}
+ int i;
+};
+
+[[nodiscard]] int f1(void);
+enum [[nodiscard]] E1 { One };
+
+[[nodiscard]] int i; // expected-warning {{'nodiscard' attribute only applies to Objective-C methods, enums, structs, unions, classes, functions, and function pointers}}
+
+struct [[nodiscard]] S4 {
+ int i;
+};
+struct S4 get_s(void);
+
+enum [[nodiscard]] E2 { Two };
+enum E2 get_e(void);
+
+[[nodiscard]] int get_i();
+
+void f2(void) {
+ get_s(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ get_i(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ get_e(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ // Okay, warnings are not encouraged
+ (void)get_s();
+ (void)get_i();
+ (void)get_e();
+}
+
+struct [[nodiscard]] error_info{
+ int i;
+};
+
+struct error_info enable_missile_safety_mode(void);
+void launch_missiles(void);
+void test_missiles(void) {
+ enable_missile_safety_mode(); // expected-warning {{ignoring return value of function declared with 'nodiscard'}}
+ launch_missiles();
+}
+
diff --git a/test/Sema/compare.c b/test/Sema/compare.c
index 887bce06306c..97586a7cc05e 100644
--- a/test/Sema/compare.c
+++ b/test/Sema/compare.c
@@ -77,7 +77,7 @@ int ints(long a, unsigned long b) {
((int) a == (unsigned int) B) +
((short) a == (unsigned short) B) +
((signed char) a == (unsigned char) B) +
- (a < (unsigned long) B) + // expected-warning {{comparison of integers of different signs}}
+ (a < (unsigned long) B) + // expected-warning {{comparison of unsigned expression < 0 is always false}}
(a < (unsigned int) B) +
(a < (unsigned short) B) +
(a < (unsigned char) B) +
@@ -85,8 +85,8 @@ int ints(long a, unsigned long b) {
((int) a < B) +
((short) a < B) +
((signed char) a < B) +
- ((long) a < (unsigned long) B) + // expected-warning {{comparison of integers of different signs}}
- ((int) a < (unsigned int) B) + // expected-warning {{comparison of integers of different signs}}
+ ((long) a < (unsigned long) B) + // expected-warning {{comparison of unsigned expression < 0 is always false}}
+ ((int) a < (unsigned int) B) + // expected-warning {{comparison of unsigned expression < 0 is always false}}
((short) a < (unsigned short) B) +
((signed char) a < (unsigned char) B) +
@@ -308,8 +308,59 @@ int rdar8414119_bar(unsigned x) {
int rdar8511238() {
enum A { A_foo, A_bar };
enum A a;
+
+ if (a == 0)
+ return 0;
+ if (a != 0)
+ return 0;
if (a < 0) // expected-warning {{comparison of unsigned enum expression < 0 is always false}}
- return 0;
+ return 0;
+ if (a <= 0)
+ return 0;
+ if (a > 0)
+ return 0;
+ if (a >= 0) // expected-warning {{comparison of unsigned enum expression >= 0 is always true}}
+ return 0;
+
+ if (0 == a)
+ return 0;
+ if (0 != a)
+ return 0;
+ if (0 < a)
+ return 0;
+ if (0 <= a) // expected-warning {{comparison of 0 <= unsigned enum expression is always true}}
+ return 0;
+ if (0 > a) // expected-warning {{comparison of 0 > unsigned enum expression is always false}}
+ return 0;
+ if (0 >= a)
+ return 0;
+
+ if (a == 0U)
+ return 0;
+ if (a != 0U)
+ return 0;
+ if (a < 0U) // expected-warning {{comparison of unsigned enum expression < 0 is always false}}
+ return 0;
+ if (a <= 0U)
+ return 0;
+ if (a > 0U)
+ return 0;
+ if (a >= 0U) // expected-warning {{comparison of unsigned enum expression >= 0 is always true}}
+ return 0;
+
+ if (0U == a)
+ return 0;
+ if (0U != a)
+ return 0;
+ if (0U < a)
+ return 0;
+ if (0U <= a) // expected-warning {{comparison of 0 <= unsigned enum expression is always true}}
+ return 0;
+ if (0U > a) // expected-warning {{comparison of 0 > unsigned enum expression is always false}}
+ return 0;
+ if (0U >= a)
+ return 0;
+
return 20;
}
diff --git a/test/Sema/const-eval.c b/test/Sema/const-eval.c
index 1b0a325dd188..d60296f27992 100644
--- a/test/Sema/const-eval.c
+++ b/test/Sema/const-eval.c
@@ -144,3 +144,11 @@ void *PR28739a = (__int128)(unsigned long)-1 + &PR28739a;
void *PR28739b = &PR28739b + (__int128)(unsigned long)-1;
__int128 PR28739c = (&PR28739c + (__int128)(unsigned long)-1) - &PR28739c;
void *PR28739d = &(&PR28739d)[(__int128)(unsigned long)-1];
+
+struct PR35214_X {
+ int k;
+ int arr[];
+};
+int PR35214_x;
+int PR35214_y = ((struct PR35214_X *)&PR35214_x)->arr[1]; // expected-error {{not a compile-time constant}}
+int *PR35214_z = &((struct PR35214_X *)&PR35214_x)->arr[1]; // ok, &PR35214_x + 2
diff --git a/test/Sema/dllexport.c b/test/Sema/dllexport.c
index 7991a455b4de..2e0fe0ce114a 100644
--- a/test/Sema/dllexport.c
+++ b/test/Sema/dllexport.c
@@ -5,17 +5,17 @@
// Invalid usage.
__declspec(dllexport) typedef int typedef1;
-// expected-warning@-1{{'dllexport' attribute only applies to variables and functions}}
+// expected-warning@-1{{'dllexport' attribute only applies to functions, variables, classes, and Objective-C interfaces}}
typedef __declspec(dllexport) int typedef2;
-// expected-warning@-1{{'dllexport' attribute only applies to variables and functions}}
+// expected-warning@-1{{'dllexport' attribute only applies to}}
typedef int __declspec(dllexport) typedef3;
-// expected-warning@-1{{'dllexport' attribute only applies to variables and functions}}
+// expected-warning@-1{{'dllexport' attribute only applies to}}
typedef __declspec(dllexport) void (*FunTy)();
-// expected-warning@-1{{'dllexport' attribute only applies to variables and functions}}
+// expected-warning@-1{{'dllexport' attribute only applies to}}
enum __declspec(dllexport) Enum { EnumVal };
-// expected-warning@-1{{'dllexport' attribute only applies to variables and functions}}
+// expected-warning@-1{{'dllexport' attribute only applies to}}
struct __declspec(dllexport) Record {};
-// expected-warning@-1{{'dllexport' attribute only applies to variables and functions}}
+// expected-warning@-1{{'dllexport' attribute only applies to}}
diff --git a/test/Sema/dllimport.c b/test/Sema/dllimport.c
index a7fb00e3f773..988a8e33a7ef 100644
--- a/test/Sema/dllimport.c
+++ b/test/Sema/dllimport.c
@@ -2,20 +2,21 @@
// RUN: %clang_cc1 -triple x86_64-win32 -fsyntax-only -fms-extensions -verify -std=c11 -DMS %s
// RUN: %clang_cc1 -triple i686-mingw32 -fsyntax-only -fms-extensions -verify -std=c11 -DGNU %s
// RUN: %clang_cc1 -triple x86_64-mingw32 -fsyntax-only -fms-extensions -verify -std=c99 -DGNU %s
+// RUN: %clang_cc1 -triple aarch64-win32 -fsyntax-only -fms-extensions -verify -std=c99 -DMS %s
// Invalid usage.
__declspec(dllimport) typedef int typedef1;
-// expected-warning@-1{{'dllimport' attribute only applies to variables and functions}}
+// expected-warning@-1{{'dllimport' attribute only applies to functions, variables, classes, and Objective-C interfaces}}
typedef __declspec(dllimport) int typedef2;
-// expected-warning@-1{{'dllimport' attribute only applies to variables and functions}}
+// expected-warning@-1{{'dllimport' attribute only applies to}}
typedef int __declspec(dllimport) typedef3;
-// expected-warning@-1{{'dllimport' attribute only applies to variables and functions}}
+// expected-warning@-1{{'dllimport' attribute only applies to}}
typedef __declspec(dllimport) void (*FunTy)();
-// expected-warning@-1{{'dllimport' attribute only applies to variables and functions}}
+// expected-warning@-1{{'dllimport' attribute only applies to}}
enum __declspec(dllimport) Enum { EnumVal };
-// expected-warning@-1{{'dllimport' attribute only applies to variables and functions}}
+// expected-warning@-1{{'dllimport' attribute only applies to}}
struct __declspec(dllimport) Record {};
-// expected-warning@-1{{'dllimport' attribute only applies to variables and functions}}
+// expected-warning@-1{{'dllimport' attribute only applies to}}
@@ -210,9 +211,14 @@ __declspec(dllimport) void redecl6();
void redecl7();
__declspec(dllimport) inline void redecl7() {}
-// PR31069: Don't crash trying to merge attributes for redeclaration of invalid decl.
+// PR31069: Don't crash trying to merge attributes for redeclaration of invalid
+// decl.
void __declspec(dllimport) redecl8(unknowntype X); // expected-error{{unknown type name 'unknowntype'}}
void redecl8(unknowntype X) { } // expected-error{{unknown type name 'unknowntype'}}
+// PR32021: Similarly, don't crash trying to merge attributes from a valid
+// decl to an invalid redeclaration.
+void __declspec(dllimport) redecl9(void); // expected-note{{previous declaration is here}}
+int redecl9(void) {} // expected-error{{conflicting types for 'redecl9'}}
// External linkage is required.
__declspec(dllimport) static int staticFunc(); // expected-error{{'staticFunc' must have external linkage when declared 'dllimport'}}
diff --git a/test/Sema/enum-sign-conversion.c b/test/Sema/enum-sign-conversion.c
new file mode 100644
index 000000000000..518fc670d314
--- /dev/null
+++ b/test/Sema/enum-sign-conversion.c
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -triple=x86_64-pc-linux-gnu -fsyntax-only -verify -DUNSIGNED -Wsign-conversion %s
+// RUN: %clang_cc1 -triple=x86_64-pc-win32 -fsyntax-only -verify -Wsign-conversion %s
+
+// PR35200
+enum X { A,B,C};
+int f(enum X x) {
+#ifdef UNSIGNED
+ return x; // expected-warning {{implicit conversion changes signedness: 'enum X' to 'int'}}
+#else
+ // expected-no-diagnostics
+ return x;
+#endif
+}
diff --git a/test/Sema/enum.c b/test/Sema/enum.c
index 3546bfe48fc6..f9e40690c6a6 100644
--- a/test/Sema/enum.c
+++ b/test/Sema/enum.c
@@ -123,3 +123,15 @@ int NegativeShortTest[NegativeShort == -1 ? 1 : -1];
// PR24610
enum Color { Red, Green, Blue }; // expected-note{{previous use is here}}
typedef struct Color NewColor; // expected-error {{use of 'Color' with tag type that does not match previous declaration}}
+
+// PR28903
+// In C it is valid to define tags inside enums.
+struct PR28903 {
+ enum {
+ PR28903_A = (enum {
+ PR28903_B,
+ PR28903_C = PR28903_B
+ })0
+ };
+ int makeStructNonEmpty;
+};
diff --git a/test/Sema/error-type-safety.cpp b/test/Sema/error-type-safety.cpp
new file mode 100644
index 000000000000..223645de0f71
--- /dev/null
+++ b/test/Sema/error-type-safety.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+#define INT_TAG 42
+
+static const int test_in
+ __attribute__((type_tag_for_datatype(test, int))) = INT_TAG;
+
+// Argument index: 1, Type tag index: 2
+void test_bounds_index(...)
+ __attribute__((argument_with_type_tag(test, 1, 2)));
+
+// Argument index: 3, Type tag index: 1
+void test_bounds_arg_index(...)
+ __attribute__((argument_with_type_tag(test, 3, 1)));
+
+void test_bounds()
+{
+ // Test the boundary edges (ensure no off-by-one) with argument indexing.
+ test_bounds_index(1, INT_TAG);
+
+ test_bounds_index(1); // expected-error {{type tag index 2 is greater than the number of arguments specified}}
+ test_bounds_arg_index(INT_TAG, 1); // expected-error {{argument index 3 is greater than the number of arguments specified}}
+}
diff --git a/test/Sema/format-strings-fixit-ssize_t.c b/test/Sema/format-strings-fixit-ssize_t.c
index 5208a294a480..f8893a14a412 100644
--- a/test/Sema/format-strings-fixit-ssize_t.c
+++ b/test/Sema/format-strings-fixit-ssize_t.c
@@ -1,7 +1,7 @@
// RUN: cp %s %t
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -pedantic -Wall -fixit %t
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -pedantic -Wall -Werror %t
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -E -o - %t | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -std=c99 -pedantic -Wall -fixit %t
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -std=c99 -fsyntax-only -pedantic -Wall -Werror %t
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -std=c99 -E -o - %t | FileCheck %s
/* This is a test of the various code modification hints that are
provided as part of warning or extension diagnostics. All of the
@@ -9,10 +9,14 @@
compile cleanly with -Werror -pedantic. */
int printf(char const *, ...);
+int scanf(const char *, ...);
void test() {
typedef signed long int ssize_t;
printf("%f", (ssize_t) 42);
+ ssize_t s;
+ scanf("%f", &s);
}
// CHECK: printf("%zd", (ssize_t) 42);
+// CHECK: scanf("%zd", &s)
diff --git a/test/Sema/format-strings-scanf.c b/test/Sema/format-strings-scanf.c
index 7a92842b2454..b7cdd7dd4a9a 100644
--- a/test/Sema/format-strings-scanf.c
+++ b/test/Sema/format-strings-scanf.c
@@ -1,10 +1,28 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -Wformat-nonliteral %s
+// RUN: %clang_cc1 -std=c11 -fsyntax-only -verify -Wformat-nonliteral %s
// Test that -Wformat=0 works:
-// RUN: %clang_cc1 -fsyntax-only -Werror -Wformat=0 %s
+// RUN: %clang_cc1 -std=c11 -fsyntax-only -Werror -Wformat=0 %s
#include <stdarg.h>
-typedef __typeof(sizeof(int)) size_t;
+typedef __SIZE_TYPE__ size_t;
+#define __SSIZE_TYPE__ \
+ __typeof__(_Generic((__SIZE_TYPE__)0, \
+ unsigned long long int : (long long int)0, \
+ unsigned long int : (long int)0, \
+ unsigned int : (int)0, \
+ unsigned short : (short)0, \
+ unsigned char : (signed char)0))
+typedef __SSIZE_TYPE__ ssize_t;
+
+typedef __PTRDIFF_TYPE__ ptrdiff_t;
+#define __UNSIGNED_PTRDIFF_TYPE__ \
+ __typeof__(_Generic((__PTRDIFF_TYPE__)0, \
+ long long int : (unsigned long long int)0, \
+ long int : (unsigned long int)0, \
+ int : (unsigned int)0, \
+ short : (unsigned short)0, \
+ signed char : (unsigned char)0))
+
typedef struct _FILE FILE;
typedef __WCHAR_TYPE__ wchar_t;
@@ -172,6 +190,46 @@ void test_qualifiers(const int *cip, volatile int* vip,
scanf("%d", (cip_t)0); // expected-warning{{format specifies type 'int *' but the argument has type 'cip_t' (aka 'const int *')}}
}
+void test_size_types() {
+ size_t s = 0;
+ scanf("%zu", &s); // No warning.
+
+ double d1 = 0.;
+ scanf("%zu", &d1); // expected-warning-re{{format specifies type 'size_t *' (aka '{{.+}}') but the argument has type 'double *'}}
+
+ ssize_t ss = 0;
+ scanf("%zd", &s); // No warning.
+
+ double d2 = 0.;
+ scanf("%zd", &d2); // expected-warning-re{{format specifies type 'ssize_t *' (aka '{{.+}}') but the argument has type 'double *'}}
+
+ ssize_t sn = 0;
+ scanf("%zn", &sn); // No warning.
+
+ double d3 = 0.;
+ scanf("%zn", &d3); // expected-warning-re{{format specifies type 'ssize_t *' (aka '{{.+}}') but the argument has type 'double *'}}
+}
+
+void test_ptrdiff_t_types() {
+ __UNSIGNED_PTRDIFF_TYPE__ p1 = 0;
+ scanf("%tu", &p1); // No warning.
+
+ double d1 = 0.;
+ scanf("%tu", &d1); // expected-warning-re{{format specifies type 'unsigned ptrdiff_t *' (aka '{{.+}}') but the argument has type 'double *'}}
+
+ ptrdiff_t p2 = 0;
+ scanf("%td", &p2); // No warning.
+
+ double d2 = 0.;
+ scanf("%td", &d2); // expected-warning-re{{format specifies type 'ptrdiff_t *' (aka '{{.+}}') but the argument has type 'double *'}}
+
+ ptrdiff_t p3 = 0;
+ scanf("%tn", &p3); // No warning.
+
+ double d3 = 0.;
+ scanf("%tn", &d3); // expected-warning-re{{format specifies type 'ptrdiff_t *' (aka '{{.+}}') but the argument has type 'double *'}}
+}
+
void check_conditional_literal(char *s, int *i) {
scanf(0 ? "%s" : "%d", i); // no warning
scanf(1 ? "%s" : "%d", i); // expected-warning{{format specifies type 'char *'}}
diff --git a/test/Sema/fp16vec-sema.c b/test/Sema/fp16vec-sema.c
new file mode 100644
index 000000000000..aefb5f86a14b
--- /dev/null
+++ b/test/Sema/fp16vec-sema.c
@@ -0,0 +1,51 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+typedef __fp16 half4 __attribute__ ((vector_size (8)));
+typedef float float4 __attribute__ ((vector_size (16)));
+typedef short short4 __attribute__ ((vector_size (8)));
+typedef int int4 __attribute__ ((vector_size (16)));
+
+half4 hv0, hv1;
+float4 fv0, fv1;
+short4 sv0;
+int4 iv0;
+
+void testFP16Vec(int c) {
+ hv0 = hv0 + hv1;
+ hv0 = hv0 - hv1;
+ hv0 = hv0 * hv1;
+ hv0 = hv0 / hv1;
+ hv0 = c ? hv0 : hv1;
+ hv0 += hv1;
+ hv0 -= hv1;
+ hv0 *= hv1;
+ hv0 /= hv1;
+ sv0 = hv0 == hv1;
+ sv0 = hv0 != hv1;
+ sv0 = hv0 < hv1;
+ sv0 = hv0 > hv1;
+ sv0 = hv0 <= hv1;
+ sv0 = hv0 >= hv1;
+ sv0 = hv0 || hv1; // expected-error{{logical expression with vector types 'half4' (vector of 4 '__fp16' values) and 'half4' is only supported in C++}}
+ sv0 = hv0 && hv1; // expected-error{{logical expression with vector types 'half4' (vector of 4 '__fp16' values) and 'half4' is only supported in C++}}
+
+ // Implicit conversion between half vectors and float vectors are not allowed.
+ hv0 = fv0; // expected-error{{assigning to}}
+ fv0 = hv0; // expected-error{{assigning to}}
+ hv0 = (half4)fv0; // expected-error{{invalid conversion between}}
+ fv0 = (float4)hv0; // expected-error{{invalid conversion between}}
+ hv0 = fv0 + fv1; // expected-error{{assigning to}}
+ fv0 = hv0 + hv1; // expected-error{{assigning to}}
+ hv0 = hv0 + fv1; // expected-error{{cannot convert between vector}}
+ hv0 = c ? hv0 : fv1; // expected-error{{cannot convert between vector}}
+ sv0 = hv0 == fv1; // expected-error{{cannot convert between vector}}
+ sv0 = hv0 < fv1; // expected-error{{cannot convert between vector}}
+ sv0 = hv0 || fv1; // expected-error{{cannot convert between vector}} expected-error{{invalid operands to binary expression}}
+ iv0 = hv0 == hv1; // expected-error{{assigning to}}
+
+ // FIXME: clang currently disallows using these operators on vectors, which is
+ // allowed by gcc.
+ sv0 = !hv0; // expected-error{{invalid argument type}}
+ hv0++; // expected-error{{cannot increment value of type}}
+ ++hv0; // expected-error{{cannot increment value of type}}
+}
diff --git a/test/Sema/implicit-decl-c90.c b/test/Sema/implicit-decl-c90.c
new file mode 100644
index 000000000000..6b3491cff7cf
--- /dev/null
+++ b/test/Sema/implicit-decl-c90.c
@@ -0,0 +1,50 @@
+// RUN: %clang_cc1 %s -std=c90 -verify -fsyntax-only
+void t0(int x) {
+ int explicit_decl();
+ int (*p)();
+ if(x > 0)
+ x = g() + 1; // expected-note {{previous implicit declaration}}
+ p = g;
+ if(x < 0) {
+ extern void u(int (*)[h()]);
+ int (*q)() = h;
+ }
+ p = h; /* expected-error {{use of undeclared identifier 'h'}} */
+}
+
+void t1(int x) {
+ int (*p)();
+ switch (x) {
+ g();
+ case 0:
+ x = h() + 1;
+ break;
+ case 1:
+ p = g;
+ p = h;
+ break;
+ }
+ p = g; /* expected-error {{use of undeclared identifier 'g'}} */
+ p = h; /* expected-error {{use of undeclared identifier 'h'}} */
+ explicit_decl();
+ p = explicit_decl;
+}
+
+int t2(int x) {
+ int y = ({ if (x > 0) x = g() + 1; 2*x; });
+ int (*p)() = g; /* expected-error {{use of undeclared identifier 'g'}} */
+ return y;
+}
+
+int PR34822() {
+ {int i = sizeof(PR34822_foo());} /* expected-note {{previous definition is here}} */
+ {extern int PR34822_foo;} /* expected-error {{redefinition of 'PR34822_foo' as different kind of symbol}} */
+
+ {extern int PR34822_bar;} /* expected-note {{previous declaration is here}} */
+ {int i = sizeof(PR34822_bar());} /* expected-warning {{use of out-of-scope declaration of 'PR34822_bar' whose type is not compatible with that of an implicit declaration}} expected-error {{called object type 'int' is not a function or function pointer}} */
+}
+
+int (*p)() = g; /* expected-error {{use of undeclared identifier 'g'}} */
+int (*q)() = h; /* expected-error {{use of undeclared identifier 'h'}} */
+
+float g(); /* expected-error {{conflicting types for 'g'}} */
diff --git a/test/Sema/implicit-decl.c b/test/Sema/implicit-decl.c
index ffab9a6f913c..a04bb0e22ef1 100644
--- a/test/Sema/implicit-decl.c
+++ b/test/Sema/implicit-decl.c
@@ -9,8 +9,7 @@ void func() {
int32_t *vector[16];
const char compDesc[16 + 1];
int32_t compCount = 0;
- if (_CFCalendarDecomposeAbsoluteTimeV(compDesc, vector, compCount)) { // expected-note {{previous implicit declaration is here}} \
- expected-error {{implicit declaration of function '_CFCalendarDecomposeAbsoluteTimeV' is invalid in C99}}
+ if (_CFCalendarDecomposeAbsoluteTimeV(compDesc, vector, compCount)) { // expected-error {{implicit declaration of function '_CFCalendarDecomposeAbsoluteTimeV' is invalid in C99}} expected-note {{previous implicit declaration}}
}
printg("Hello, World!\n"); // expected-error{{implicit declaration of function 'printg' is invalid in C99}} \
@@ -18,7 +17,7 @@ void func() {
__builtin_is_les(1, 3); // expected-error{{use of unknown builtin '__builtin_is_les'}}
}
-Boolean _CFCalendarDecomposeAbsoluteTimeV(const char *componentDesc, int32_t **vector, int32_t count) { // expected-error{{conflicting types for '_CFCalendarDecomposeAbsoluteTimeV'}}
+Boolean _CFCalendarDecomposeAbsoluteTimeV(const char *componentDesc, int32_t **vector, int32_t count) { // expected-error {{conflicting types}}
return 0;
}
diff --git a/test/Sema/inline-asm-validate-amdgpu.cl b/test/Sema/inline-asm-validate-amdgpu.cl
index d60b09e0ce9d..bc2580c5738b 100644
--- a/test/Sema/inline-asm-validate-amdgpu.cl
+++ b/test/Sema/inline-asm-validate-amdgpu.cl
@@ -1,6 +1,7 @@
// REQUIRES: amdgpu-registered-target
-// RUN: %clang_cc1 -x cl -triple amdgcn -fsyntax-only %s
-// expected-no-diagnostics
+// RUN: %clang_cc1 -triple amdgcn -fsyntax-only -verify %s
+
+#pragma OPENCL EXTENSION cl_khr_fp64 : enable
kernel void test () {
@@ -9,6 +10,67 @@ kernel void test () {
// sgpr constraints
__asm__ ("s_mov_b32 %0, %1" : "=s" (sgpr) : "s" (imm) : );
+ __asm__ ("s_mov_b32 %0, %1" : "={s1}" (sgpr) : "{exec}" (imm) : );
+ __asm__ ("s_mov_b32 %0, %1" : "={s1}" (sgpr) : "{exe" (imm) : ); // expected-error {{invalid input constraint '{exe' in asm}}
+ __asm__ ("s_mov_b32 %0, %1" : "={s1}" (sgpr) : "{exec" (imm) : ); // expected-error {{invalid input constraint '{exec' in asm}}
+ __asm__ ("s_mov_b32 %0, %1" : "={s1}" (sgpr) : "{exec}a" (imm) : ); // expected-error {{invalid input constraint '{exec}a' in asm}}
+
// vgpr constraints
__asm__ ("v_mov_b32 %0, %1" : "=v" (vgpr) : "v" (imm) : );
}
+
+__kernel void
+test_float(const __global float *a, const __global float *b, __global float *c, unsigned i)
+{
+ float ai = a[i];
+ float bi = b[i];
+ float ci;
+
+ __asm("v_add_f32_e32 v1, v2, v3" : "={v1}"(ci) : "{v2}"(ai), "{v3}"(bi) : );
+ __asm("v_add_f32_e32 v1, v2, v3" : ""(ci) : "{v2}"(ai), "{v3}"(bi) : ); // expected-error {{invalid output constraint '' in asm}}
+ __asm("v_add_f32_e32 v1, v2, v3" : "="(ci) : "{v2}"(ai), "{v3}"(bi) : ); // expected-error {{invalid output constraint '=' in asm}}
+ __asm("v_add_f32_e32 v1, v2, v3" : "={a}"(ci) : "{v2}"(ai), "{v3}"(bi) : ); // expected-error {{invalid output constraint '={a}' in asm}}
+ __asm("v_add_f32_e32 v1, v2, v3" : "={"(ci) : "{v2}"(ai), "{v3}"(bi) : ); // expected-error {{invalid output constraint '={' in asm}}
+ __asm("v_add_f32_e32 v1, v2, v3" : "={}"(ci) : "{v2}"(ai), "{v3}"(bi) : ); // expected-error {{invalid output constraint '={}' in asm}}
+ __asm("v_add_f32_e32 v1, v2, v3" : "={v"(ci) : "{v2}"(ai), "{v3}"(bi) : ); // expected-error {{invalid output constraint '={v' in asm}}
+ __asm("v_add_f32_e32 v1, v2, v3" : "={v1a}"(ci) : "{v2}"(ai), "{v3}"(bi) : ); // expected-error {{invalid output constraint '={v1a}' in asm}}
+ __asm("v_add_f32_e32 v1, v2, v3" : "={va}"(ci) : "{v2}"(ai), "{v3}"(bi) : ); // expected-error {{invalid output constraint '={va}' in asm}}
+ __asm("v_add_f32_e32 v1, v2, v3" : "={v1}a"(ci) : "{v2}"(ai), "{v3}"(bi) : ); // expected-error {{invalid output constraint '={v1}a' in asm}}
+ __asm("v_add_f32_e32 v1, v2, v3" : "={v1"(ci) : "{v2}"(ai), "{v3}"(bi) : ); // expected-error {{invalid output constraint '={v1' in asm}}
+ __asm("v_add_f32_e32 v1, v2, v3" : "=v1}"(ci) : "{v2}"(ai), "{v3}"(bi) : ); // expected-error {{invalid output constraint '=v1}' in asm}}
+
+ __asm("v_add_f32_e32 v1, v2, v3" : "={v[1]}"(ci) : "{v[2]}"(ai), "{v[3]}"(bi) : );
+ __asm("v_add_f32_e32 v1, v2, v3" : "={v[1}"(ci) : "{v[2]}"(ai), "{v[3]}"(bi) : ); // expected-error {{invalid output constraint '={v[1}' in asm}}
+ __asm("v_add_f32_e32 v1, v2, v3" : "={v[1]"(ci) : "{v[2]}"(ai), "{v[3]}"(bi) : ); // expected-error {{invalid output constraint '={v[1]' in asm}}
+ __asm("v_add_f32_e32 v1, v2, v3" : "={v[a]}"(ci) : "{v[2]}"(ai), "{v[3]}"(bi) : ); // expected-error {{invalid output constraint '={v[a]}' in asm}}
+
+ __asm("v_add_f32_e32 v1, v2, v3" : "=v"(ci) : "v"(ai), "v"(bi) : );
+ __asm("v_add_f32_e32 v1, v2, v3" : "=v1"(ci) : "v2"(ai), "v3"(bi) : ); /// expected-error {{invalid output constraint '=v1' in asm}}
+
+ __asm("v_add_f32_e32 v1, v2, v3" : "={v1}"(ci) : "{a}"(ai), "{v3}"(bi) : ); // expected-error {{invalid input constraint '{a}' in asm}}
+ __asm("v_add_f32_e32 v1, v2, v3" : "={v1}"(ci) : "{v2}"(ai), "{a}"(bi) : ); // expected-error {{invalid input constraint '{a}' in asm}}
+ c[i] = ci;
+}
+
+__kernel void
+test_double(const __global double *a, const __global double *b, __global double *c, unsigned i)
+{
+ double ai = a[i];
+ double bi = b[i];
+ double ci;
+
+ __asm("v_add_f64_e64 v[1:2], v[3:4], v[5:6]" : "={v[1:2]}"(ci) : "{v[3:4]}"(ai), "{v[5:6]}"(bi) : );
+ __asm("v_add_f64_e64 v[1:2], v[3:4], v[5:6]" : "=v{[1:2]}"(ci) : "{v[3:4]}"(ai), "{v[5:6]}"(bi) : ); //expected-error {{invalid output constraint '=v{[1:2]}' in asm}}
+ __asm("v_add_f64_e64 v[1:2], v[3:4], v[5:6]" : "={v[1:2]a}"(ci) : "{v[3:4]}"(ai), "{v[5:6]}"(bi) : ); //expected-error {{invalid output constraint '={v[1:2]a}' in asm}}
+ __asm("v_add_f64_e64 v[1:2], v[3:4], v[5:6]" : "={v[1:2]}a"(ci) : "{v[3:4]}"(ai), "{v[5:6]}"(bi) : ); //expected-error {{invalid output constraint '={v[1:2]}a' in asm}}
+ __asm("v_add_f64_e64 v[1:2], v[3:4], v[5:6]" : "={v[1:"(ci) : "{v[3:4]}"(ai), "{v[5:6]}"(bi) : ); //expected-error {{invalid output constraint '={v[1:' in asm}}
+ __asm("v_add_f64_e64 v[1:2], v[3:4], v[5:6]" : "={v[1:]}"(ci) : "{v[3:4]}"(ai), "{v[5:6]}"(bi) : ); //expected-error {{invalid output constraint '={v[1:]}' in asm}}
+ __asm("v_add_f64_e64 v[1:2], v[3:4], v[5:6]" : "={v[:2]}"(ci) : "{v[3:4]}"(ai), "{v[5:6]}"(bi) : ); //expected-error {{invalid output constraint '={v[:2]}' in asm}}
+ __asm("v_add_f64_e64 v[1:2], v[3:4], v[5:6]" : "={v[1:2]"(ci) : "{v[3:4]}"(ai), "{v[5:6]}"(bi) : ); //expected-error {{invalid output constraint '={v[1:2]' in asm}}
+ __asm("v_add_f64_e64 v[1:2], v[3:4], v[5:6]" : "={v[1:2}"(ci) : "{v[3:4]}"(ai), "{v[5:6]}"(bi) : ); //expected-error {{invalid output constraint '={v[1:2}' in asm}}
+ __asm("v_add_f64_e64 v[1:2], v[3:4], v[5:6]" : "={v[2:1]}"(ci) : "{v[3:4]}"(ai), "{v[5:6]}"(bi) : ); //expected-error {{invalid output constraint '={v[2:1]}' in asm}}
+
+ __asm("v_add_f64_e64 v[1:2], v[3:4], v[5:6]" : "=v[1:2]"(ci) : "v[3:4]"(ai), "v[5:6]"(bi) : ); //expected-error {{invalid output constraint '=v[1:2]' in asm}}
+
+ c[i] = ci;
+}
diff --git a/test/Sema/internal_linkage.c b/test/Sema/internal_linkage.c
index f4deccca63d1..37090a333315 100644
--- a/test/Sema/internal_linkage.c
+++ b/test/Sema/internal_linkage.c
@@ -15,7 +15,7 @@ int var5 __attribute__((internal_linkage)); // expected-error{{'internal_linkage
int var5 __attribute__((common)); // expected-note{{conflicting attribute is here}}
__attribute__((internal_linkage)) int f() {}
-struct __attribute__((internal_linkage)) S { // expected-warning{{'internal_linkage' attribute only applies to variables and functions}}
+struct __attribute__((internal_linkage)) S { // expected-warning{{'internal_linkage' attribute only applies to variables, functions, and classes}}
};
__attribute__((internal_linkage("foo"))) int g() {} // expected-error{{'internal_linkage' attribute takes no arguments}}
diff --git a/test/Sema/ms-annotation.c b/test/Sema/ms-annotation.c
new file mode 100644
index 000000000000..9a2beebf065a
--- /dev/null
+++ b/test/Sema/ms-annotation.c
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -triple i686-windows %s -verify -fms-extensions
+// RUN: %clang_cc1 -x c++ -std=c++11 -triple i686-windows %s -verify -fms-extensions
+// RUN: %clang_cc1 -x c++ -std=c++14 -triple i686-windows %s -verify -fms-extensions
+
+void test1(void) {
+ __annotation(); // expected-error {{too few arguments to function call, expected at least 1, have 0}}
+ __annotation(1); // expected-error {{must be wide string constants}}
+ __annotation(L"a1");
+ __annotation(L"a1", L"a2");
+ __annotation(L"a1", L"a2", 42); // expected-error {{must be wide string constants}}
+ __annotation(L"a1", L"a2", L"a3");
+ __annotation(L"multi " L"part " L"string");
+}
diff --git a/test/Sema/ms-inline-asm.c b/test/Sema/ms-inline-asm.c
index 952112ea8cf8..3fc74fa99c35 100644
--- a/test/Sema/ms-inline-asm.c
+++ b/test/Sema/ms-inline-asm.c
@@ -59,18 +59,13 @@ int t2(int *arr, int i) {
mov eax, arr[1 + (2 * 5) - 3 + 1<<1];
}
- // expected-error@+1 {{cannot use base register with variable reference}}
- __asm { mov eax, arr[ebp + 1 + (2 * 5) - 3 + 1<<1] }
- // expected-error@+1 {{cannot use index register with variable reference}}
- __asm { mov eax, arr[esi * 4] }
// expected-error@+1 {{cannot use more than one symbol in memory operand}}
__asm { mov eax, arr[i] }
// expected-error@+1 {{cannot use more than one symbol in memory operand}}
__asm { mov eax, global[i] }
- // FIXME: Why don't we diagnose this?
- // expected-Xerror@+1 {{cannot reference multiple local variables in assembly operand}}
- //__asm mov eax, [arr + i];
+ // expected-error@+1 {{cannot use more than one symbol in memory operand}}
+ __asm mov eax, [arr + i];
return 0;
}
@@ -98,7 +93,7 @@ void t4() {
__asm { mov eax, fs:[0] A.a }
__asm { mov eax, fs:[0].A.a }
__asm { mov eax, fs:[0].a } // expected-error {{Unable to lookup field reference!}}
- __asm { mov eax, fs:[0]. A.a } // expected-error {{Unexpected token type!}}
+ __asm { mov eax, fs:[0]. A.a } // expected-error {{unexpected token in argument list}}
}
void test_operand_size() {
diff --git a/test/Sema/noescape.c b/test/Sema/noescape.c
new file mode 100644
index 000000000000..39f3f6f542ac
--- /dev/null
+++ b/test/Sema/noescape.c
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+void escapefunc(int *);
+void noescapefunc(__attribute__((noescape)) int *);
+void (*escapefuncptr)(int *);
+void (*noescapefuncptr)(__attribute__((noescape)) int *);
+
+void func_ne(__attribute__((noescape)) int *, int *);
+void func_en(int *, __attribute__((noescape)) int *);
+
+void (*funcptr_ee)(int *, int *);
+void (*funcptr_nn)(__attribute__((noescape)) int *, __attribute__((noescape)) int *);
+
+void test0(int c) {
+ escapefuncptr = &escapefunc;
+ escapefuncptr = &noescapefunc;
+ noescapefuncptr = &escapefunc; // expected-warning {{incompatible function pointer types assigning to 'void (*)(__attribute__((noescape)) int *)' from 'void (*)(int *)'}}
+ noescapefuncptr = &noescapefunc;
+
+ escapefuncptr = c ? &escapefunc : &noescapefunc;
+ noescapefuncptr = c ? &escapefunc : &noescapefunc; // expected-warning {{incompatible function pointer types assigning to 'void (*)(__attribute__((noescape)) int *)' from 'void (*)(int *)'}}
+
+ funcptr_ee = c ? &func_ne : &func_en;
+ funcptr_nn = c ? &func_ne : &func_en; // expected-warning {{incompatible function pointer types assigning to 'void (*)(__attribute__((noescape)) int *, __attribute__((noescape)) int *)' from 'void (*)(int *, int *)'}}
+}
diff --git a/test/Sema/nonnull.c b/test/Sema/nonnull.c
index 217bbb16df60..b589bb3d1ffd 100644
--- a/test/Sema/nonnull.c
+++ b/test/Sema/nonnull.c
@@ -37,7 +37,7 @@ int test_int_returns_nonnull(void) __attribute__((returns_nonnull)); // expected
void *test_ptr_returns_nonnull(void) __attribute__((returns_nonnull)); // no-warning
int i __attribute__((nonnull)); // expected-warning {{'nonnull' attribute only applies to functions, methods, and parameters}}
-int j __attribute__((returns_nonnull)); // expected-warning {{'returns_nonnull' attribute only applies to functions and methods}}
+int j __attribute__((returns_nonnull)); // expected-warning {{'returns_nonnull' attribute only applies to Objective-C methods and functions}}
void *test_no_fn_proto() __attribute__((returns_nonnull)); // no-warning
void *test_with_fn_proto(void) __attribute__((returns_nonnull)); // no-warning
diff --git a/test/Sema/outof-range-constant-compare.c b/test/Sema/outof-range-constant-compare.c
index 4b1637c46c5e..ccb55e4a1663 100644
--- a/test/Sema/outof-range-constant-compare.c
+++ b/test/Sema/outof-range-constant-compare.c
@@ -6,6 +6,7 @@ int value(void);
int main()
{
int a = value();
+
if (a == 0x1234567812345678L) // expected-warning {{comparison of constant 1311768465173141112 with expression of type 'int' is always false}}
return 0;
if (a != 0x1234567812345678L) // expected-warning {{comparison of constant 1311768465173141112 with expression of type 'int' is always true}}
@@ -74,6 +75,7 @@ int main()
return 0;
if (0x1234567812345678L >= s) // expected-warning {{comparison of constant 1311768465173141112 with expression of type 'short' is always true}}
return 0;
+
long l = value();
if (l == 0x1234567812345678L)
return 0;
@@ -101,40 +103,6 @@ int main()
if (0x1234567812345678L >= l)
return 0;
- unsigned un = 0;
- if (un == 0x0000000000000000L)
- return 0;
- if (un != 0x0000000000000000L)
- return 0;
- if (un < 0x0000000000000000L)
- return 0;
- if (un <= 0x0000000000000000L)
- return 0;
- if (un > 0x0000000000000000L)
- return 0;
- if (un >= 0x0000000000000000L)
- return 0;
-
- if (0x0000000000000000L == un)
- return 0;
- if (0x0000000000000000L != un)
- return 0;
- if (0x0000000000000000L < un)
- return 0;
- if (0x0000000000000000L <= un)
- return 0;
- if (0x0000000000000000L > un)
- return 0;
- if (0x0000000000000000L >= un)
- return 0;
- float fl = 0;
- if (fl == 0x0000000000000000L) // no warning
- return 0;
-
- float dl = 0;
- if (dl == 0x0000000000000000L) // no warning
- return 0;
-
enum E {
yes,
no,
diff --git a/test/Sema/outof-range-enum-constant-compare.c b/test/Sema/outof-range-enum-constant-compare.c
new file mode 100644
index 000000000000..b9ce08f68c0e
--- /dev/null
+++ b/test/Sema/outof-range-enum-constant-compare.c
@@ -0,0 +1,379 @@
+// RUN: %clang_cc1 -triple=x86_64-pc-linux-gnu -fsyntax-only -DUNSIGNED -verify %s
+// RUN: %clang_cc1 -triple=x86_64-pc-win32 -fsyntax-only -DSIGNED -verify %s
+// RUN: %clang_cc1 -triple=x86_64-pc-linux-gnu -fsyntax-only -DUNSIGNED -DSILENCE -Wno-tautological-constant-out-of-range-compare -verify %s
+// RUN: %clang_cc1 -triple=x86_64-pc-win32 -fsyntax-only -DSIGNED -DSILENCE -Wno-tautological-constant-out-of-range-compare -verify %s
+
+int main() {
+ enum A { A_a = 2 };
+ enum A a;
+
+#ifdef SILENCE
+ // expected-no-diagnostics
+#endif
+
+#ifdef UNSIGNED
+#ifndef SILENCE
+ if (a < 4294967296) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always true}}
+ return 0;
+ if (4294967296 >= a) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always true}}
+ return 0;
+ if (a > 4294967296) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always false}}
+ return 0;
+ if (4294967296 <= a) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always false}}
+ return 0;
+ if (a <= 4294967296) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always true}}
+ return 0;
+ if (4294967296 > a) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always true}}
+ return 0;
+ if (a >= 4294967296) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always false}}
+ return 0;
+ if (4294967296 < a) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always false}}
+ return 0;
+ if (a == 4294967296) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always false}}
+ return 0;
+ if (4294967296 != a) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always true}}
+ return 0;
+ if (a != 4294967296) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always true}}
+ return 0;
+ if (4294967296 == a) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always false}}
+ return 0;
+
+ if (a < 4294967296U) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always true}}
+ return 0;
+ if (4294967296U >= a) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always true}}
+ return 0;
+ if (a > 4294967296U) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always false}}
+ return 0;
+ if (4294967296U <= a) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always false}}
+ return 0;
+ if (a <= 4294967296U) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always true}}
+ return 0;
+ if (4294967296U > a) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always true}}
+ return 0;
+ if (a >= 4294967296U) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always false}}
+ return 0;
+ if (4294967296U < a) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always false}}
+ return 0;
+ if (a == 4294967296U) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always false}}
+ return 0;
+ if (4294967296U != a) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always true}}
+ return 0;
+ if (a != 4294967296U) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always true}}
+ return 0;
+ if (4294967296U == a) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always false}}
+ return 0;
+#else // SILENCE
+ if (a < 4294967296)
+ return 0;
+ if (4294967296 >= a)
+ return 0;
+ if (a > 4294967296)
+ return 0;
+ if (4294967296 <= a)
+ return 0;
+ if (a <= 4294967296)
+ return 0;
+ if (4294967296 > a)
+ return 0;
+ if (a >= 4294967296)
+ return 0;
+ if (4294967296 < a)
+ return 0;
+ if (a == 4294967296)
+ return 0;
+ if (4294967296 != a)
+ return 0;
+ if (a != 4294967296)
+ return 0;
+ if (4294967296 == a)
+ return 0;
+
+ if (a < 4294967296U)
+ return 0;
+ if (4294967296U >= a)
+ return 0;
+ if (a > 4294967296U)
+ return 0;
+ if (4294967296U <= a)
+ return 0;
+ if (a <= 4294967296U)
+ return 0;
+ if (4294967296U > a)
+ return 0;
+ if (a >= 4294967296U)
+ return 0;
+ if (4294967296U < a)
+ return 0;
+ if (a == 4294967296U)
+ return 0;
+ if (4294967296U != a)
+ return 0;
+ if (a != 4294967296U)
+ return 0;
+ if (4294967296U == a)
+ return 0;
+#endif
+#elif defined(SIGNED)
+#ifndef SILENCE
+ if (a < -2147483649) // expected-warning {{comparison of constant -2147483649 with expression of type 'enum A' is always false}}
+ return 0;
+ if (-2147483649 >= a) // expected-warning {{comparison of constant -2147483649 with expression of type 'enum A' is always false}}
+ return 0;
+ if (a > -2147483649) // expected-warning {{comparison of constant -2147483649 with expression of type 'enum A' is always true}}
+ return 0;
+ if (-2147483649 <= a) // expected-warning {{comparison of constant -2147483649 with expression of type 'enum A' is always true}}
+ return 0;
+ if (a <= -2147483649) // expected-warning {{comparison of constant -2147483649 with expression of type 'enum A' is always false}}
+ return 0;
+ if (-2147483649 > a) // expected-warning {{comparison of constant -2147483649 with expression of type 'enum A' is always false}}
+ return 0;
+ if (a >= -2147483649) // expected-warning {{comparison of constant -2147483649 with expression of type 'enum A' is always true}}
+ return 0;
+ if (-2147483649 < a) // expected-warning {{comparison of constant -2147483649 with expression of type 'enum A' is always true}}
+ return 0;
+ if (a == -2147483649) // expected-warning {{comparison of constant -2147483649 with expression of type 'enum A' is always false}}
+ return 0;
+ if (-2147483649 != a) // expected-warning {{comparison of constant -2147483649 with expression of type 'enum A' is always true}}
+ return 0;
+ if (a != -2147483649) // expected-warning {{comparison of constant -2147483649 with expression of type 'enum A' is always true}}
+ return 0;
+ if (-2147483649 == a) // expected-warning {{comparison of constant -2147483649 with expression of type 'enum A' is always false}}
+ return 0;
+
+ if (a < 2147483648) // expected-warning {{comparison of constant 2147483648 with expression of type 'enum A' is always true}}
+ return 0;
+ if (2147483648 >= a) // expected-warning {{comparison of constant 2147483648 with expression of type 'enum A' is always true}}
+ return 0;
+ if (a > 2147483648) // expected-warning {{comparison of constant 2147483648 with expression of type 'enum A' is always false}}
+ return 0;
+ if (2147483648 <= a) // expected-warning {{comparison of constant 2147483648 with expression of type 'enum A' is always false}}
+ return 0;
+ if (a <= 2147483648) // expected-warning {{comparison of constant 2147483648 with expression of type 'enum A' is always true}}
+ return 0;
+ if (2147483648 > a) // expected-warning {{comparison of constant 2147483648 with expression of type 'enum A' is always true}}
+ return 0;
+ if (a >= 2147483648) // expected-warning {{comparison of constant 2147483648 with expression of type 'enum A' is always false}}
+ return 0;
+ if (2147483648 < a) // expected-warning {{comparison of constant 2147483648 with expression of type 'enum A' is always false}}
+ return 0;
+ if (a == 2147483648) // expected-warning {{comparison of constant 2147483648 with expression of type 'enum A' is always false}}
+ return 0;
+ if (2147483648 != a) // expected-warning {{comparison of constant 2147483648 with expression of type 'enum A' is always true}}
+ return 0;
+ if (a != 2147483648) // expected-warning {{comparison of constant 2147483648 with expression of type 'enum A' is always true}}
+ return 0;
+ if (2147483648 == a) // expected-warning {{comparison of constant 2147483648 with expression of type 'enum A' is always false}}
+ return 0;
+#else // SILENCE
+ if (a < -2147483649)
+ return 0;
+ if (-2147483649 >= a)
+ return 0;
+ if (a > -2147483649)
+ return 0;
+ if (-2147483649 <= a)
+ return 0;
+ if (a <= -2147483649)
+ return 0;
+ if (-2147483649 > a)
+ return 0;
+ if (a >= -2147483649)
+ return 0;
+ if (-2147483649 < a)
+ return 0;
+ if (a == -2147483649)
+ return 0;
+ if (-2147483649 != a)
+ return 0;
+ if (a != -2147483649)
+ return 0;
+ if (-2147483649 == a)
+ return 0;
+
+ if (a < 2147483648)
+ return 0;
+ if (2147483648 >= a)
+ return 0;
+ if (a > 2147483648)
+ return 0;
+ if (2147483648 <= a)
+ return 0;
+ if (a <= 2147483648)
+ return 0;
+ if (2147483648 > a)
+ return 0;
+ if (a >= 2147483648)
+ return 0;
+ if (2147483648 < a)
+ return 0;
+ if (a == 2147483648)
+ return 0;
+ if (2147483648 != a)
+ return 0;
+ if (a != 2147483648)
+ return 0;
+ if (2147483648 == a)
+ return 0;
+#endif
+#endif
+}
+
+// https://bugs.llvm.org/show_bug.cgi?id=35009
+int PR35009() {
+ enum A { A_a = 2 };
+ enum A a;
+
+ // in C, this should not warn.
+
+ if (a < 1)
+ return 0;
+ if (1 >= a)
+ return 0;
+ if (a > 1)
+ return 0;
+ if (1 <= a)
+ return 0;
+ if (a <= 1)
+ return 0;
+ if (1 > a)
+ return 0;
+ if (a >= 1)
+ return 0;
+ if (1 < a)
+ return 0;
+ if (a == 1)
+ return 0;
+ if (1 != a)
+ return 0;
+ if (a != 1)
+ return 0;
+ if (1 == a)
+ return 0;
+
+ if (a < 1U)
+ return 0;
+ if (1U >= a)
+ return 0;
+ if (a > 1U)
+ return 0;
+ if (1U <= a)
+ return 0;
+ if (a <= 1U)
+ return 0;
+ if (1U > a)
+ return 0;
+ if (a >= 1U)
+ return 0;
+ if (1U < a)
+ return 0;
+ if (a == 1U)
+ return 0;
+ if (1U != a)
+ return 0;
+ if (a != 1U)
+ return 0;
+ if (1U == a)
+ return 0;
+
+ if (a < 2)
+ return 0;
+ if (2 >= a)
+ return 0;
+ if (a > 2)
+ return 0;
+ if (2 <= a)
+ return 0;
+ if (a <= 2)
+ return 0;
+ if (2 > a)
+ return 0;
+ if (a >= 2)
+ return 0;
+ if (2 < a)
+ return 0;
+ if (a == 2)
+ return 0;
+ if (2 != a)
+ return 0;
+ if (a != 2)
+ return 0;
+ if (2 == a)
+ return 0;
+
+ if (a < 2U)
+ return 0;
+ if (2U >= a)
+ return 0;
+ if (a > 2U)
+ return 0;
+ if (2U <= a)
+ return 0;
+ if (a <= 2U)
+ return 0;
+ if (2U > a)
+ return 0;
+ if (a >= 2U)
+ return 0;
+ if (2U < a)
+ return 0;
+ if (a == 2U)
+ return 0;
+ if (2U != a)
+ return 0;
+ if (a != 2U)
+ return 0;
+ if (2U == a)
+ return 0;
+
+ if (a < 3)
+ return 0;
+ if (3 >= a)
+ return 0;
+ if (a > 3)
+ return 0;
+ if (3 <= a)
+ return 0;
+ if (a <= 3)
+ return 0;
+ if (3 > a)
+ return 0;
+ if (a >= 3)
+ return 0;
+ if (3 < a)
+ return 0;
+ if (a == 3)
+ return 0;
+ if (3 != a)
+ return 0;
+ if (a != 3)
+ return 0;
+ if (3 == a)
+ return 0;
+
+ if (a < 3U)
+ return 0;
+ if (3U >= a)
+ return 0;
+ if (a > 3U)
+ return 0;
+ if (3U <= a)
+ return 0;
+ if (a <= 3U)
+ return 0;
+ if (3U > a)
+ return 0;
+ if (a >= 3U)
+ return 0;
+ if (3U < a)
+ return 0;
+ if (a == 3U)
+ return 0;
+ if (3U != a)
+ return 0;
+ if (a != 3U)
+ return 0;
+ if (3U == a)
+ return 0;
+
+ return 1;
+}
diff --git a/test/Sema/pointer-addition.c b/test/Sema/pointer-addition.c
index c71e96114b8a..562f05340f7c 100644
--- a/test/Sema/pointer-addition.c
+++ b/test/Sema/pointer-addition.c
@@ -1,4 +1,8 @@
-// RUN: %clang_cc1 %s -fsyntax-only -verify -pedantic -std=c11
+// RUN: %clang_cc1 %s -fsyntax-only -verify -pedantic -Wextra -std=c11
+// RUN: %clang_cc1 %s -fsyntax-only -triple i686-unknown-unknown -verify -pedantic -Wextra -std=c11
+// RUN: %clang_cc1 %s -fsyntax-only -triple x86_64-unknown-unknown -verify -pedantic -Wextra -std=c11
+
+#include <stdint.h>
typedef struct S S; // expected-note 4 {{forward declaration of 'struct S'}}
extern _Atomic(S*) e;
@@ -20,4 +24,9 @@ void a(S* b, void* c) {
d -= 1; // expected-warning {{arithmetic on a pointer to the function type 'void (S *, void *)' (aka 'void (struct S *, void *)') is a GNU extension}}
(void)(1 + d); // expected-warning {{arithmetic on a pointer to the function type 'void (S *, void *)' (aka 'void (struct S *, void *)') is a GNU extension}}
e++; // expected-error {{arithmetic on a pointer to an incomplete type}}
+ intptr_t i = (intptr_t)b;
+ char *f = (char*)0 + i; // expected-warning {{arithmetic on a null pointer treated as a cast from integer to pointer is a GNU extension}}
+ // Cases that don't match the GNU inttoptr idiom get a different warning.
+ f = (char*)0 - i; // expected-warning {{performing pointer arithmetic on a null pointer has undefined behavior}}
+ int *g = (int*)0 + i; // expected-warning {{performing pointer arithmetic on a null pointer has undefined behavior}}
}
diff --git a/test/Sema/pragma-ms_struct.c b/test/Sema/pragma-ms_struct.c
index a2591b6a4c44..e10d49e6761c 100644
--- a/test/Sema/pragma-ms_struct.c
+++ b/test/Sema/pragma-ms_struct.c
@@ -25,7 +25,7 @@ struct {
} __attribute__((__ms_struct__)) t1;
struct S {
- double __attribute__((ms_struct)) d; // expected-warning {{'ms_struct' attribute only applies to struct or union}}
+ double __attribute__((ms_struct)) d; // expected-warning {{'ms_struct' attribute only applies to structs, unions, and classes}}
unsigned long bf_1 : 12;
unsigned long : 0;
unsigned long bf_2 : 12;
@@ -36,7 +36,7 @@ enum
A = 0,
B,
C
-} __attribute__((ms_struct)) e1; // expected-warning {{'ms_struct' attribute only applies to struct or union}}
+} __attribute__((ms_struct)) e1; // expected-warning {{'ms_struct' attribute only applies to}}
// rdar://10513599
#pragma ms_struct on
diff --git a/test/Sema/pragma-pack.c b/test/Sema/pragma-pack.c
index e93ce42148ca..2ed0874bfd2d 100644
--- a/test/Sema/pragma-pack.c
+++ b/test/Sema/pragma-pack.c
@@ -25,3 +25,8 @@
#pragma pack(pop, 16)
/* expected-warning {{value of #pragma pack(show) == 16}} */ #pragma pack(show)
+
+// Warn about unbalanced pushes.
+#pragma pack (push,4) // expected-warning {{unterminated '#pragma pack (push, ...)' at end of file}}
+#pragma pack (push) // expected-warning {{unterminated '#pragma pack (push, ...)' at end of file}}
+#pragma pack () // expected-note {{did you intend to use '#pragma pack (pop)' instead of '#pragma pack()'?}}
diff --git a/test/Sema/preserve-call-conv.c b/test/Sema/preserve-call-conv.c
index f258f45ac582..6bd049ffdca2 100644
--- a/test/Sema/preserve-call-conv.c
+++ b/test/Sema/preserve-call-conv.c
@@ -1,5 +1,8 @@
// RUN: %clang_cc1 %s -fsyntax-only -triple x86_64-unknown-unknown -verify
// RUN: %clang_cc1 %s -fsyntax-only -triple arm64-unknown-unknown -verify
+// RUN: %clang_cc1 %s -fsyntax-only -triple x86_64-unknown-windows-msvc -verify
+// RUN: %clang_cc1 %s -fsyntax-only -triple aarch64-unknown-windows-msvc -verify
+
typedef void typedef_fun_t(int);
void __attribute__((preserve_most)) foo(void *ptr) {
diff --git a/test/Sema/sign-compare-enum.c b/test/Sema/sign-compare-enum.c
new file mode 100644
index 000000000000..8661bd502fe5
--- /dev/null
+++ b/test/Sema/sign-compare-enum.c
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -triple=x86_64-pc-linux-gnu -fsyntax-only -DUNSIGNED -verify -Wsign-compare %s
+// RUN: %clang_cc1 -triple=x86_64-pc-win32 -fsyntax-only -DSIGNED -verify -Wsign-compare %s
+// RUN: %clang_cc1 -triple=x86_64-pc-linux-gnu -fsyntax-only -DUNSIGNED -DSILENCE -verify %s
+// RUN: %clang_cc1 -triple=x86_64-pc-win32 -fsyntax-only -DSIGNED -DSILENCE -verify %s
+
+int main() {
+ enum A { A_a = 0, A_b = 1 };
+ static const int message[] = {0, 1};
+ enum A a;
+
+ if (a < 2)
+ return 0;
+
+#if defined(SIGNED) && !defined(SILENCE)
+ if (a < sizeof(message)/sizeof(message[0])) // expected-warning {{comparison of integers of different signs: 'enum A' and 'unsigned long long'}}
+ return 0;
+#else
+ // expected-no-diagnostics
+ if (a < 2U)
+ return 0;
+ if (a < sizeof(message)/sizeof(message[0]))
+ return 0;
+#endif
+}
diff --git a/test/Sema/struct-packed-align.c b/test/Sema/struct-packed-align.c
index abdcd8e6b9eb..aeba8d6fd938 100644
--- a/test/Sema/struct-packed-align.c
+++ b/test/Sema/struct-packed-align.c
@@ -1,5 +1,6 @@
// RUN: %clang_cc1 %s -fsyntax-only -verify
// RUN: %clang_cc1 %s -fsyntax-only -triple=x86_64-windows-coff -verify
+// RUN: %clang_cc1 %s -fsyntax-only -triple=x86_64-scei-ps4 -verify
// Packed structs.
struct s {
@@ -146,13 +147,24 @@ extern int n2[__alignof(struct nS) == 1 ? 1 : -1];
// See the documentation of -Wpacked-bitfield-compat for more information.
struct packed_chars {
char a:4;
+#ifdef __ORBIS__
+ // Test for pre-r254596 clang behavior on the PS4 target. PS4 must maintain
+ // ABI backwards compatibility.
+ char b:8 __attribute__ ((packed));
+ // expected-warning@-1 {{'packed' attribute ignored for field of type 'char'}}
+ char c:4;
+#else
char b:8 __attribute__ ((packed));
// expected-warning@-1 {{'packed' attribute was ignored on bit-fields with single-byte alignment in older versions of GCC and Clang}}
char c:4;
+#endif
};
-#if defined(_WIN32) && !defined(__declspec) // _MSC_VER is unavailable in cc1.
+#if (defined(_WIN32) || defined(__ORBIS__)) && !defined(__declspec) // _MSC_VER is unavailable in cc1.
// On Windows clang uses MSVC compatible layout in this case.
+//
+// Additionally, test for pre-r254596 clang behavior on the PS4 target. PS4
+// must maintain ABI backwards compatibility.
extern int o1[sizeof(struct packed_chars) == 3 ? 1 : -1];
extern int o2[__alignof(struct packed_chars) == 1 ? 1 : -1];
#else
diff --git a/test/Sema/suspicious-pragma-pack.c b/test/Sema/suspicious-pragma-pack.c
new file mode 100644
index 000000000000..d7c5faf06910
--- /dev/null
+++ b/test/Sema/suspicious-pragma-pack.c
@@ -0,0 +1,50 @@
+// RUN: %clang_cc1 -triple i686-apple-darwin9 -fsyntax-only -Wpragma-pack -I %S/Inputs -DSAFE -verify %s
+// RUN: %clang_cc1 -triple i686-apple-darwin9 -fsyntax-only -Wpragma-pack -I %S/Inputs -DPUSH_HERE -DSAFE -verify %s
+// RUN: %clang_cc1 -triple i686-apple-darwin9 -fsyntax-only -Wpragma-pack -I %S/Inputs -DPUSH_HERE -DPUSH_SET_HERE -verify %s
+// RUN: %clang_cc1 -triple i686-apple-darwin9 -fsyntax-only -Wpragma-pack -I %S/Inputs -DPUSH_HERE -DRESET_HERE -DSAFE -verify %s
+// RUN: %clang_cc1 -triple i686-apple-darwin9 -fsyntax-only -Wpragma-pack -I %S/Inputs -DPUSH_HERE -DSET_FIRST_HEADER -DWARN_MODIFIED_HEADER -verify %s
+// RUN: %clang_cc1 -triple i686-apple-darwin9 -fsyntax-only -Wpragma-pack -I %S/Inputs -DPUSH_HERE -DRESET_HERE -DSET_FIRST_HEADER -DWARN_MODIFIED_HEADER -verify %s
+// RUN: %clang_cc1 -triple i686-apple-darwin9 -fsyntax-only -Wpragma-pack -I %S/Inputs -DPUSH_HERE -DPUSH_SET_HERE -DSET_FIRST_HEADER -DWARN_MODIFIED_HEADER -verify %s
+// RUN: %clang_cc1 -triple i686-apple-darwin9 -fsyntax-only -Wpragma-pack -I %S/Inputs -DPUSH_HERE -DPUSH_SET_HERE -DSET_SECOND_HEADER -DWARN_MODIFIED_HEADER -verify %s
+// RUN: %clang_cc1 -triple i686-apple-darwin9 -fsyntax-only -Wpragma-pack -I %S/Inputs -DPUSH_HERE -DPUSH_SET_HERE -DSET_FIRST_HEADER -DSET_SECOND_HEADER -DWARN_MODIFIED_HEADER -verify %s
+
+// RUN: %clang_cc1 -triple i686-apple-darwin9 -fsyntax-only -Wpragma-pack -I %S/Inputs -DPUSH_POP_FIRST_HEADER -DSAFE -verify %s
+
+// RUN: %clang_cc1 -triple i686-apple-darwin9 -fsyntax-only -Wpragma-pack -I %S/Inputs -DPUSH_SET_HERE -DNO_RECORD_1 -DNO_RECORD_2 -DSAFE -verify %s
+// RUN: %clang_cc1 -triple i686-apple-darwin9 -fsyntax-only -Wpragma-pack-suspicious-include -I %S/Inputs -DPUSH_SET_HERE -DNO_RECORD_1 -verify %s
+// RUN: %clang_cc1 -triple i686-apple-darwin9 -fsyntax-only -Wpragma-pack -Wno-pragma-pack-suspicious-include -I %S/Inputs -DPUSH_SET_HERE -DNO_RECORD_1 -DSAFE -verify %s
+
+#ifdef SAFE
+// expected-no-diagnostics
+#endif
+
+#ifdef PUSH_HERE
+#pragma pack (push)
+#endif
+
+#ifdef PUSH_SET_HERE
+#pragma pack (push, 4)
+#ifndef SAFE
+// expected-note@-2 {{previous '#pragma pack' directive that modifies alignment is here}}
+// expected-warning@+9 {{non-default #pragma pack value changes the alignment of struct or union members in the included file}}
+#endif
+#endif
+
+#ifdef RESET_HERE
+#pragma pack (4)
+#pragma pack () // no warning after reset as the value is default.
+#endif
+
+#include "pragma-pack1.h"
+
+#ifdef WARN_MODIFIED_HEADER
+// expected-warning@-3 {{the current #pragma pack aligment value is modified in the included file}}
+#endif
+
+#ifdef PUSH_SET_HERE
+#pragma pack (pop)
+#endif
+
+#ifdef PUSH_HERE
+#pragma pack (pop)
+#endif
diff --git a/test/Sema/switch.c b/test/Sema/switch.c
index 7aa695d7cb91..a33300b41f54 100644
--- a/test/Sema/switch.c
+++ b/test/Sema/switch.c
@@ -372,6 +372,7 @@ void switch_on_ExtendedEnum1(enum ExtendedEnum1 e) {
case EE1_b: break;
case EE1_c: break; // no-warning
case EE1_d: break; // expected-warning {{case value not in enumerated type 'enum ExtendedEnum1'}}
+ // expected-warning@-1 {{comparison of two values with different enumeration types in switch statement ('enum ExtendedEnum1' and 'const enum ExtendedEnum1_unrelated')}}
}
}
diff --git a/test/Sema/tautological-constant-compare.c b/test/Sema/tautological-constant-compare.c
new file mode 100644
index 000000000000..c48aa9944453
--- /dev/null
+++ b/test/Sema/tautological-constant-compare.c
@@ -0,0 +1,585 @@
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -fsyntax-only -DTEST -verify %s
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -fsyntax-only -Wno-tautological-constant-compare -verify %s
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -fsyntax-only -DTEST -verify -x c++ %s
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -fsyntax-only -Wno-tautological-constant-compare -verify -x c++ %s
+
+int value(void);
+
+#define macro(val) val
+
+#ifdef __cplusplus
+template<typename T>
+void TFunc() {
+ // Make sure that we do warn for normal variables in template functions !
+ unsigned char c = value();
+#ifdef TEST
+ if (c > 255) // expected-warning {{comparison 'unsigned char' > 255 is always false}}
+ return;
+#else
+ if (c > 255)
+ return;
+#endif
+
+ if (c > macro(255))
+ return;
+
+ T v = value();
+ if (v > 255)
+ return;
+ if (v > 32767)
+ return;
+}
+#endif
+
+int main()
+{
+#ifdef __cplusplus
+ TFunc<unsigned char>();
+ TFunc<signed short>();
+#endif
+
+ short s = value();
+
+#ifdef TEST
+ if (s == 32767)
+ return 0;
+ if (s != 32767)
+ return 0;
+ if (s < 32767)
+ return 0;
+ if (s <= 32767) // expected-warning {{comparison 'short' <= 32767 is always true}}
+ return 0;
+ if (s > 32767) // expected-warning {{comparison 'short' > 32767 is always false}}
+ return 0;
+ if (s >= 32767)
+ return 0;
+
+ if (32767 == s)
+ return 0;
+ if (32767 != s)
+ return 0;
+ if (32767 < s) // expected-warning {{comparison 32767 < 'short' is always false}}
+ return 0;
+ if (32767 <= s)
+ return 0;
+ if (32767 > s)
+ return 0;
+ if (32767 >= s) // expected-warning {{comparison 32767 >= 'short' is always true}}
+ return 0;
+
+ // FIXME: assumes two's complement
+ if (s == -32768)
+ return 0;
+ if (s != -32768)
+ return 0;
+ if (s < -32768) // expected-warning {{comparison 'short' < -32768 is always false}}
+ return 0;
+ if (s <= -32768)
+ return 0;
+ if (s > -32768)
+ return 0;
+ if (s >= -32768) // expected-warning {{comparison 'short' >= -32768 is always true}}
+ return 0;
+
+ if (-32768 == s)
+ return 0;
+ if (-32768 != s)
+ return 0;
+ if (-32768 < s)
+ return 0;
+ if (-32768 <= s) // expected-warning {{comparison -32768 <= 'short' is always true}}
+ return 0;
+ if (-32768 > s) // expected-warning {{comparison -32768 > 'short' is always false}}
+ return 0;
+ if (-32768 >= s)
+ return 0;
+
+ // Note: both sides are promoted to unsigned long prior to the comparison, so
+ // it is perfectly possible for a short to compare greater than 32767UL.
+ if (s == 32767UL)
+ return 0;
+ if (s != 32767UL)
+ return 0;
+ if (s < 32767UL)
+ return 0;
+ if (s <= 32767UL)
+ return 0;
+ if (s > 32767UL)
+ return 0;
+ if (s >= 32767UL)
+ return 0;
+
+ if (32767UL == s)
+ return 0;
+ if (32767UL != s)
+ return 0;
+ if (32767UL < s)
+ return 0;
+ if (32767UL <= s)
+ return 0;
+ if (32767UL > s)
+ return 0;
+ if (32767UL >= s)
+ return 0;
+
+ if (s == 0UL)
+ return 0;
+ if (s != 0UL)
+ return 0;
+ if (s < 0UL) // expected-warning {{comparison of unsigned expression < 0 is always false}}
+ return 0;
+ if (s <= 0UL)
+ return 0;
+ if (s > 0UL)
+ return 0;
+ if (s >= 0UL) // expected-warning {{comparison of unsigned expression >= 0 is always true}}
+ return 0;
+
+ if (0UL == s)
+ return 0;
+ if (0UL != s)
+ return 0;
+ if (0UL < s)
+ return 0;
+ if (0UL <= s) // expected-warning {{comparison of 0 <= unsigned expression is always true}}
+ return 0;
+ if (0UL > s) // expected-warning {{comparison of 0 > unsigned expression is always false}}
+ return 0;
+ if (0UL >= s)
+ return 0;
+
+ enum { ULONG_MAX = (2UL * (unsigned long)__LONG_MAX__ + 1UL) };
+ if (s == 2UL * (unsigned long)__LONG_MAX__ + 1UL)
+ return 0;
+ if (s != 2UL * (unsigned long)__LONG_MAX__ + 1UL)
+ return 0;
+ if (s < 2UL * (unsigned long)__LONG_MAX__ + 1UL)
+ return 0;
+ if (s <= 2UL * (unsigned long)__LONG_MAX__ + 1UL) // expected-warning-re {{comparison 'short' <= {{.*}} is always true}}
+ return 0;
+ if (s > 2UL * (unsigned long)__LONG_MAX__ + 1UL) // expected-warning-re {{comparison 'short' > {{.*}} is always false}}
+ return 0;
+ if (s >= 2UL * (unsigned long)__LONG_MAX__ + 1UL)
+ return 0;
+
+ if (2UL * (unsigned long)__LONG_MAX__ + 1UL == s)
+ return 0;
+ if (2UL * (unsigned long)__LONG_MAX__ + 1UL != s)
+ return 0;
+ if (2UL * (unsigned long)__LONG_MAX__ + 1UL < s) // expected-warning-re {{comparison {{.*}} < 'short' is always false}}
+ return 0;
+ if (2UL * (unsigned long)__LONG_MAX__ + 1UL <= s)
+ return 0;
+ if (2UL * (unsigned long)__LONG_MAX__ + 1UL > s)
+ return 0;
+ if (2UL * (unsigned long)__LONG_MAX__ + 1UL >= s) // expected-warning-re {{comparison {{.*}} >= 'short' is always true}}
+ return 0;
+
+ // FIXME: assumes two's complement
+ if (s == -32768L)
+ return 0;
+ if (s != -32768L)
+ return 0;
+ if (s < -32768L) // expected-warning {{comparison 'short' < -32768 is always false}}
+ return 0;
+ if (s <= -32768L)
+ return 0;
+ if (s > -32768L)
+ return 0;
+ if (s >= -32768L) // expected-warning {{comparison 'short' >= -32768 is always true}}
+ return 0;
+
+ if (-32768L == s)
+ return 0;
+ if (-32768L != s)
+ return 0;
+ if (-32768L < s)
+ return 0;
+ if (-32768L <= s) // expected-warning {{comparison -32768 <= 'short' is always true}}
+ return 0;
+ if (-32768L > s) // expected-warning {{comparison -32768 > 'short' is always false}}
+ return 0;
+ if (-32768L >= s)
+ return 0;
+#else
+ // expected-no-diagnostics
+ if (s == 32767)
+ return 0;
+ if (s != 32767)
+ return 0;
+ if (s < 32767)
+ return 0;
+ if (s <= 32767)
+ return 0;
+ if (s > 32767)
+ return 0;
+ if (s >= 32767)
+ return 0;
+
+ if (32767 == s)
+ return 0;
+ if (32767 != s)
+ return 0;
+ if (32767 < s)
+ return 0;
+ if (32767 <= s)
+ return 0;
+ if (32767 > s)
+ return 0;
+ if (32767 >= s)
+ return 0;
+
+ // FIXME: assumes two's complement
+ if (s == -32768)
+ return 0;
+ if (s != -32768)
+ return 0;
+ if (s < -32768)
+ return 0;
+ if (s <= -32768)
+ return 0;
+ if (s > -32768)
+ return 0;
+ if (s >= -32768)
+ return 0;
+
+ if (-32768 == s)
+ return 0;
+ if (-32768 != s)
+ return 0;
+ if (-32768 < s)
+ return 0;
+ if (-32768 <= s)
+ return 0;
+ if (-32768 > s)
+ return 0;
+ if (-32768 >= s)
+ return 0;
+
+ if (s == 32767UL)
+ return 0;
+ if (s != 32767UL)
+ return 0;
+ if (s < 32767UL)
+ return 0;
+ if (s <= 32767UL)
+ return 0;
+ if (s > 32767UL)
+ return 0;
+ if (s >= 32767UL)
+ return 0;
+
+ if (32767UL == s)
+ return 0;
+ if (32767UL != s)
+ return 0;
+ if (32767UL < s)
+ return 0;
+ if (32767UL <= s)
+ return 0;
+ if (32767UL > s)
+ return 0;
+ if (32767UL >= s)
+ return 0;
+
+ // FIXME: assumes two's complement
+ if (s == -32768L)
+ return 0;
+ if (s != -32768L)
+ return 0;
+ if (s < -32768L)
+ return 0;
+ if (s <= -32768L)
+ return 0;
+ if (s > -32768L)
+ return 0;
+ if (s >= -32768L)
+ return 0;
+
+ if (-32768L == s)
+ return 0;
+ if (-32768L != s)
+ return 0;
+ if (-32768L < s)
+ return 0;
+ if (-32768L <= s)
+ return 0;
+ if (-32768L > s)
+ return 0;
+ if (-32768L >= s)
+ return 0;
+#endif
+
+ if (s == 0)
+ return 0;
+ if (s != 0)
+ return 0;
+ if (s < 0)
+ return 0;
+ if (s <= 0)
+ return 0;
+ if (s > 0)
+ return 0;
+ if (s >= 0)
+ return 0;
+
+ if (0 == s)
+ return 0;
+ if (0 != s)
+ return 0;
+ if (0 < s)
+ return 0;
+ if (0 <= s)
+ return 0;
+ if (0 > s)
+ return 0;
+ if (0 >= s)
+ return 0;
+
+ unsigned short us = value();
+
+#ifdef TEST
+ if (us == 65535)
+ return 0;
+ if (us != 65535)
+ return 0;
+ if (us < 65535)
+ return 0;
+ if (us <= 65535) // expected-warning {{comparison 'unsigned short' <= 65535 is always true}}
+ return 0;
+ if (us > 65535) // expected-warning {{comparison 'unsigned short' > 65535 is always false}}
+ return 0;
+ if (us >= 65535)
+ return 0;
+
+ if (65535 == us)
+ return 0;
+ if (65535 != us)
+ return 0;
+ if (65535 < us) // expected-warning {{comparison 65535 < 'unsigned short' is always false}}
+ return 0;
+ if (65535 <= us)
+ return 0;
+ if (65535 > us)
+ return 0;
+ if (65535 >= us) // expected-warning {{comparison 65535 >= 'unsigned short' is always true}}
+ return 0;
+
+ if (us == 65535UL)
+ return 0;
+ if (us != 65535UL)
+ return 0;
+ if (us < 65535UL)
+ return 0;
+ if (us <= 65535UL) // expected-warning {{comparison 'unsigned short' <= 65535 is always true}}
+ return 0;
+ if (us > 65535UL) // expected-warning {{comparison 'unsigned short' > 65535 is always false}}
+ return 0;
+ if (us >= 65535UL)
+ return 0;
+
+ if (65535UL == us)
+ return 0;
+ if (65535UL != us)
+ return 0;
+ if (65535UL < us) // expected-warning {{comparison 65535 < 'unsigned short' is always false}}
+ return 0;
+ if (65535UL <= us)
+ return 0;
+ if (65535UL > us)
+ return 0;
+ if (65535UL >= us) // expected-warning {{comparison 65535 >= 'unsigned short' is always true}}
+ return 0;
+#else
+ // expected-no-diagnostics
+ if (us == 65535)
+ return 0;
+ if (us != 65535)
+ return 0;
+ if (us < 65535)
+ return 0;
+ if (us <= 65535)
+ return 0;
+ if (us > 65535)
+ return 0;
+ if (us >= 65535)
+ return 0;
+
+ if (65535 == us)
+ return 0;
+ if (65535 != us)
+ return 0;
+ if (65535 < us)
+ return 0;
+ if (65535 <= us)
+ return 0;
+ if (65535 > us)
+ return 0;
+ if (65535 >= us)
+ return 0;
+
+ if (us == 65535UL)
+ return 0;
+ if (us != 65535UL)
+ return 0;
+ if (us < 65535UL)
+ return 0;
+ if (us <= 65535UL)
+ return 0;
+ if (us > 65535UL)
+ return 0;
+ if (us >= 65535UL)
+ return 0;
+
+ if (65535UL == us)
+ return 0;
+ if (65535UL != us)
+ return 0;
+ if (65535UL < us)
+ return 0;
+ if (65535UL <= us)
+ return 0;
+ if (65535UL > us)
+ return 0;
+ if (65535UL >= us)
+ return 0;
+#endif
+
+ if (us == 32767)
+ return 0;
+ if (us != 32767)
+ return 0;
+ if (us < 32767)
+ return 0;
+ if (us <= 32767)
+ return 0;
+ if (us > 32767)
+ return 0;
+ if (us >= 32767)
+ return 0;
+
+ if (32767 == us)
+ return 0;
+ if (32767 != us)
+ return 0;
+ if (32767 < us)
+ return 0;
+ if (32767 <= us)
+ return 0;
+ if (32767 > us)
+ return 0;
+ if (32767 >= us)
+ return 0;
+
+ if (us == 32767UL)
+ return 0;
+ if (us != 32767UL)
+ return 0;
+ if (us < 32767UL)
+ return 0;
+ if (us <= 32767UL)
+ return 0;
+ if (us > 32767UL)
+ return 0;
+ if (us >= 32767UL)
+ return 0;
+
+ if (32767UL == us)
+ return 0;
+ if (32767UL != us)
+ return 0;
+ if (32767UL < us)
+ return 0;
+ if (32767UL <= us)
+ return 0;
+ if (32767UL > us)
+ return 0;
+ if (32767UL >= us)
+ return 0;
+
+#if __SIZEOF_INT128__
+ __int128 i128;
+ if (i128 == -1) // used to crash
+ return 0;
+#endif
+
+
+ enum E {
+ yes,
+ no,
+ maybe
+ };
+ enum E e;
+
+ if (e == yes)
+ return 0;
+ if (e != yes)
+ return 0;
+ if (e < yes)
+ return 0;
+ if (e <= yes)
+ return 0;
+ if (e > yes)
+ return 0;
+ if (e >= yes)
+ return 0;
+
+ if (yes == e)
+ return 0;
+ if (yes != e)
+ return 0;
+ if (yes < e)
+ return 0;
+ if (yes <= e)
+ return 0;
+ if (yes > e)
+ return 0;
+ if (yes >= e)
+ return 0;
+
+ if (e == maybe)
+ return 0;
+ if (e != maybe)
+ return 0;
+ if (e < maybe)
+ return 0;
+ if (e <= maybe)
+ return 0;
+ if (e > maybe)
+ return 0;
+ if (e >= maybe)
+ return 0;
+
+ if (maybe == e)
+ return 0;
+ if (maybe != e)
+ return 0;
+ if (maybe < e)
+ return 0;
+ if (maybe <= e)
+ return 0;
+ if (maybe > e)
+ return 0;
+ if (maybe >= e)
+ return 0;
+
+ // For the time being, use the declared type of bit-fields rather than their
+ // length when determining whether a value is in-range.
+ // FIXME: Reconsider this.
+ struct A {
+ int a : 3;
+ unsigned b : 3;
+ long c : 3;
+ unsigned long d : 3;
+ } a;
+ if (a.a < 3) {}
+ if (a.a < 4) {}
+ if (a.b < 7) {}
+ if (a.b < 8) {}
+ if (a.c < 3) {}
+ if (a.c < 4) {}
+ if (a.d < 7) {}
+ if (a.d < 8) {}
+
+ return 1;
+}
diff --git a/test/Sema/tautological-constant-enum-compare.c b/test/Sema/tautological-constant-enum-compare.c
new file mode 100644
index 000000000000..539439b817dc
--- /dev/null
+++ b/test/Sema/tautological-constant-enum-compare.c
@@ -0,0 +1,406 @@
+// RUN: %clang_cc1 -triple=x86_64-pc-linux-gnu -fsyntax-only -DUNSIGNED -verify %s
+// RUN: %clang_cc1 -triple=x86_64-pc-win32 -fsyntax-only -DSIGNED -verify %s
+// RUN: %clang_cc1 -triple=x86_64-pc-linux-gnu -fsyntax-only -DUNSIGNED -DSILENCE -Wno-tautological-constant-compare -verify %s
+// RUN: %clang_cc1 -triple=x86_64-pc-win32 -fsyntax-only -DSIGNED -DSILENCE -Wno-tautological-constant-compare -verify %s
+
+int main() {
+ enum A { A_a = 2 };
+ enum A a;
+
+#ifdef SILENCE
+ // expected-no-diagnostics
+#else
+ // If we promote to unsigned, it doesn't matter whether the enum's underlying
+ // type was signed.
+ if (a < 0U) // expected-warning {{comparison of unsigned enum expression < 0 is always false}}
+ return 0;
+ if (0U >= a)
+ return 0;
+ if (a > 0U)
+ return 0;
+ if (0U <= a) // expected-warning {{comparison of 0 <= unsigned enum expression is always true}}
+ return 0;
+ if (a <= 0U)
+ return 0;
+ if (0U > a) // expected-warning {{comparison of 0 > unsigned enum expression is always false}}
+ return 0;
+ if (a >= 0U) // expected-warning {{comparison of unsigned enum expression >= 0 is always true}}
+ return 0;
+ if (0U < a)
+ return 0;
+
+ if (a < 4294967295U)
+ return 0;
+ if (4294967295U >= a) // expected-warning {{comparison 4294967295 >= 'enum A' is always true}}
+ return 0;
+ if (a > 4294967295U) // expected-warning {{comparison 'enum A' > 4294967295 is always false}}
+ return 0;
+ if (4294967295U <= a)
+ return 0;
+ if (a <= 4294967295U) // expected-warning {{comparison 'enum A' <= 4294967295 is always true}}
+ return 0;
+ if (4294967295U > a)
+ return 0;
+ if (a >= 4294967295U)
+ return 0;
+ if (4294967295U < a) // expected-warning {{comparison 4294967295 < 'enum A' is always false}}
+ return 0;
+
+ if (a < 2147483647U)
+ return 0;
+ if (2147483647U >= a)
+ return 0;
+ if (a > 2147483647U)
+ return 0;
+ if (2147483647U <= a)
+ return 0;
+ if (a <= 2147483647U)
+ return 0;
+ if (2147483647U > a)
+ return 0;
+ if (a >= 2147483647U)
+ return 0;
+ if (2147483647U < a)
+ return 0;
+#endif
+
+#if defined(UNSIGNED) && !defined(SILENCE)
+ if (a < 0) // expected-warning {{comparison of unsigned enum expression < 0 is always false}}
+ return 0;
+ if (0 >= a)
+ return 0;
+ if (a > 0)
+ return 0;
+ if (0 <= a) // expected-warning {{comparison of 0 <= unsigned enum expression is always true}}
+ return 0;
+ if (a <= 0)
+ return 0;
+ if (0 > a) // expected-warning {{comparison of 0 > unsigned enum expression is always false}}
+ return 0;
+ if (a >= 0) // expected-warning {{comparison of unsigned enum expression >= 0 is always true}}
+ return 0;
+ if (0 < a)
+ return 0;
+
+ if (a < 4294967295)
+ return 0;
+ if (4294967295 >= a) // expected-warning {{comparison 4294967295 >= 'enum A' is always true}}
+ return 0;
+ if (a > 4294967295) // expected-warning {{comparison 'enum A' > 4294967295 is always false}}
+ return 0;
+ if (4294967295 <= a)
+ return 0;
+ if (a <= 4294967295) // expected-warning {{comparison 'enum A' <= 4294967295 is always true}}
+ return 0;
+ if (4294967295 > a)
+ return 0;
+ if (a >= 4294967295)
+ return 0;
+ if (4294967295 < a) // expected-warning {{comparison 4294967295 < 'enum A' is always false}}
+ return 0;
+#else // SIGNED || SILENCE
+ if (a < 0)
+ return 0;
+ if (0 >= a)
+ return 0;
+ if (a > 0)
+ return 0;
+ if (0 <= a)
+ return 0;
+ if (a <= 0)
+ return 0;
+ if (0 > a)
+ return 0;
+ if (a >= 0)
+ return 0;
+ if (0 < a)
+ return 0;
+
+#ifndef SILENCE
+ if (a < 4294967295) // expected-warning {{comparison of constant 4294967295 with expression of type 'enum A' is always true}}
+ return 0;
+ if (4294967295 >= a) // expected-warning {{comparison of constant 4294967295 with expression of type 'enum A' is always true}}
+ return 0;
+ if (a > 4294967295) // expected-warning {{comparison of constant 4294967295 with expression of type 'enum A' is always false}}
+ return 0;
+ if (4294967295 <= a) // expected-warning {{comparison of constant 4294967295 with expression of type 'enum A' is always false}}
+ return 0;
+ if (a <= 4294967295) // expected-warning {{comparison of constant 4294967295 with expression of type 'enum A' is always true}}
+ return 0;
+ if (4294967295 > a) // expected-warning {{comparison of constant 4294967295 with expression of type 'enum A' is always true}}
+ return 0;
+ if (a >= 4294967295) // expected-warning {{comparison of constant 4294967295 with expression of type 'enum A' is always false}}
+ return 0;
+ if (4294967295 < a) // expected-warning {{comparison of constant 4294967295 with expression of type 'enum A' is always false}}
+ return 0;
+#else
+ if (a < 4294967295)
+ return 0;
+ if (4294967295 >= a)
+ return 0;
+ if (a > 4294967295)
+ return 0;
+ if (4294967295 <= a)
+ return 0;
+ if (a <= 4294967295)
+ return 0;
+ if (4294967295 > a)
+ return 0;
+ if (a >= 4294967295)
+ return 0;
+ if (4294967295 < a)
+ return 0;
+#endif
+#endif
+
+#if defined(SIGNED) && !defined(SILENCE)
+ if (a < -2147483648) // expected-warning {{comparison 'enum A' < -2147483648 is always false}}
+ return 0;
+ if (-2147483648 >= a)
+ return 0;
+ if (a > -2147483648)
+ return 0;
+ if (-2147483648 <= a) // expected-warning {{comparison -2147483648 <= 'enum A' is always true}}
+ return 0;
+ if (a <= -2147483648)
+ return 0;
+ if (-2147483648 > a) // expected-warning {{comparison -2147483648 > 'enum A' is always false}}
+ return 0;
+ if (a >= -2147483648) // expected-warning {{comparison 'enum A' >= -2147483648 is always true}}
+ return 0;
+ if (-2147483648 < a)
+ return 0;
+
+ if (a < 2147483647)
+ return 0;
+ if (2147483647 >= a) // expected-warning {{comparison 2147483647 >= 'enum A' is always true}}
+ return 0;
+ if (a > 2147483647) // expected-warning {{comparison 'enum A' > 2147483647 is always false}}
+ return 0;
+ if (2147483647 <= a)
+ return 0;
+ if (a <= 2147483647) // expected-warning {{comparison 'enum A' <= 2147483647 is always true}}
+ return 0;
+ if (2147483647 > a)
+ return 0;
+ if (a >= 2147483647)
+ return 0;
+ if (2147483647 < a) // expected-warning {{comparison 2147483647 < 'enum A' is always false}}
+ return 0;
+#elif defined(UNSIGNED) && !defined(SILENCE)
+#ifndef SILENCE
+ if (a < -2147483648) // expected-warning {{comparison of constant -2147483648 with expression of type 'enum A' is always false}}
+ return 0;
+ if (-2147483648 >= a) // expected-warning {{comparison of constant -2147483648 with expression of type 'enum A' is always false}}
+ return 0;
+ if (a > -2147483648) // expected-warning {{comparison of constant -2147483648 with expression of type 'enum A' is always true}}
+ return 0;
+ if (-2147483648 <= a) // expected-warning {{comparison of constant -2147483648 with expression of type 'enum A' is always true}}
+ return 0;
+ if (a <= -2147483648) // expected-warning {{comparison of constant -2147483648 with expression of type 'enum A' is always false}}
+ return 0;
+ if (-2147483648 > a) // expected-warning {{comparison of constant -2147483648 with expression of type 'enum A' is always false}}
+ return 0;
+ if (a >= -2147483648) // expected-warning {{comparison of constant -2147483648 with expression of type 'enum A' is always true}}
+ return 0;
+ if (-2147483648 < a) // expected-warning {{comparison of constant -2147483648 with expression of type 'enum A' is always true}}
+ return 0;
+#else
+ if (a < -2147483648)
+ return 0;
+ if (-2147483648 >= a)
+ return 0;
+ if (a > -2147483648)
+ return 0;
+ if (-2147483648 <= a)
+ return 0;
+ if (a <= -2147483648)
+ return 0;
+ if (-2147483648 > a)
+ return 0;
+ if (a >= -2147483648)
+ return 0;
+ if (-2147483648 < a)
+ return 0;
+#endif
+
+ if (a < 2147483647)
+ return 0;
+ if (2147483647 >= a)
+ return 0;
+ if (a > 2147483647)
+ return 0;
+ if (2147483647 <= a)
+ return 0;
+ if (a <= 2147483647)
+ return 0;
+ if (2147483647 > a)
+ return 0;
+ if (a >= 2147483647)
+ return 0;
+ if (2147483647 < a)
+ return 0;
+#endif
+
+ return 1;
+}
+
+// https://bugs.llvm.org/show_bug.cgi?id=35009
+int PR35009() {
+ enum A { A_a = 2 };
+ enum A a;
+
+ // in C, this should not warn.
+
+ if (a < 1)
+ return 0;
+ if (1 >= a)
+ return 0;
+ if (a > 1)
+ return 0;
+ if (1 <= a)
+ return 0;
+ if (a <= 1)
+ return 0;
+ if (1 > a)
+ return 0;
+ if (a >= 1)
+ return 0;
+ if (1 < a)
+ return 0;
+ if (a == 1)
+ return 0;
+ if (1 != a)
+ return 0;
+ if (a != 1)
+ return 0;
+ if (1 == a)
+ return 0;
+
+ if (a < 1U)
+ return 0;
+ if (1U >= a)
+ return 0;
+ if (a > 1U)
+ return 0;
+ if (1U <= a)
+ return 0;
+ if (a <= 1U)
+ return 0;
+ if (1U > a)
+ return 0;
+ if (a >= 1U)
+ return 0;
+ if (1U < a)
+ return 0;
+ if (a == 1U)
+ return 0;
+ if (1U != a)
+ return 0;
+ if (a != 1U)
+ return 0;
+ if (1U == a)
+ return 0;
+
+ if (a < 2)
+ return 0;
+ if (2 >= a)
+ return 0;
+ if (a > 2)
+ return 0;
+ if (2 <= a)
+ return 0;
+ if (a <= 2)
+ return 0;
+ if (2 > a)
+ return 0;
+ if (a >= 2)
+ return 0;
+ if (2 < a)
+ return 0;
+ if (a == 2)
+ return 0;
+ if (2 != a)
+ return 0;
+ if (a != 2)
+ return 0;
+ if (2 == a)
+ return 0;
+
+ if (a < 2U)
+ return 0;
+ if (2U >= a)
+ return 0;
+ if (a > 2U)
+ return 0;
+ if (2U <= a)
+ return 0;
+ if (a <= 2U)
+ return 0;
+ if (2U > a)
+ return 0;
+ if (a >= 2U)
+ return 0;
+ if (2U < a)
+ return 0;
+ if (a == 2U)
+ return 0;
+ if (2U != a)
+ return 0;
+ if (a != 2U)
+ return 0;
+ if (2U == a)
+ return 0;
+
+ if (a < 3)
+ return 0;
+ if (3 >= a)
+ return 0;
+ if (a > 3)
+ return 0;
+ if (3 <= a)
+ return 0;
+ if (a <= 3)
+ return 0;
+ if (3 > a)
+ return 0;
+ if (a >= 3)
+ return 0;
+ if (3 < a)
+ return 0;
+ if (a == 3)
+ return 0;
+ if (3 != a)
+ return 0;
+ if (a != 3)
+ return 0;
+ if (3 == a)
+ return 0;
+
+ if (a < 3U)
+ return 0;
+ if (3U >= a)
+ return 0;
+ if (a > 3U)
+ return 0;
+ if (3U <= a)
+ return 0;
+ if (a <= 3U)
+ return 0;
+ if (3U > a)
+ return 0;
+ if (a >= 3U)
+ return 0;
+ if (3U < a)
+ return 0;
+ if (a == 3U)
+ return 0;
+ if (3U != a)
+ return 0;
+ if (a != 3U)
+ return 0;
+ if (3U == a)
+ return 0;
+
+ return 1;
+}
diff --git a/test/Sema/tautological-unsigned-enum-zero-compare.c b/test/Sema/tautological-unsigned-enum-zero-compare.c
new file mode 100644
index 000000000000..a32cfcd8329f
--- /dev/null
+++ b/test/Sema/tautological-unsigned-enum-zero-compare.c
@@ -0,0 +1,126 @@
+// RUN: %clang_cc1 -triple=x86_64-pc-linux-gnu -fsyntax-only \
+// RUN: -verify=unsigned,unsigned-signed %s
+// RUN: %clang_cc1 -triple=x86_64-pc-win32 -fsyntax-only \
+// RUN: -verify=unsigned-signed %s
+// RUN: %clang_cc1 -triple=x86_64-pc-win32 -fsyntax-only \
+// RUN: -Wno-tautological-unsigned-enum-zero-compare \
+// RUN: -verify=silence %s
+
+// Okay, this is where it gets complicated.
+// Then default enum sigdness is target-specific.
+// On windows, it is signed by default. We do not want to warn in that case.
+
+int main() {
+ enum A { A_a = 0 };
+ enum A a;
+ enum B { B_a = -1 };
+ enum B b;
+
+ // silence-no-diagnostics
+
+ if (a < 0) // unsigned-warning {{comparison of unsigned enum expression < 0 is always false}}
+ return 0;
+ if (0 >= a)
+ return 0;
+ if (a > 0)
+ return 0;
+ if (0 <= a) // unsigned-warning {{comparison of 0 <= unsigned enum expression is always true}}
+ return 0;
+ if (a <= 0)
+ return 0;
+ if (0 > a) // unsigned-warning {{comparison of 0 > unsigned enum expression is always false}}
+ return 0;
+ if (a >= 0) // unsigned-warning {{comparison of unsigned enum expression >= 0 is always true}}
+ return 0;
+ if (0 < a)
+ return 0;
+
+ if (a < 0U) // unsigned-signed-warning {{comparison of unsigned enum expression < 0 is always false}}
+ return 0;
+ if (0U >= a)
+ return 0;
+ if (a > 0U)
+ return 0;
+ if (0U <= a) // unsigned-signed-warning {{comparison of 0 <= unsigned enum expression is always true}}
+ return 0;
+ if (a <= 0U)
+ return 0;
+ if (0U > a) // unsigned-signed-warning {{comparison of 0 > unsigned enum expression is always false}}
+ return 0;
+ if (a >= 0U) // unsigned-signed-warning {{comparison of unsigned enum expression >= 0 is always true}}
+ return 0;
+ if (0U < a)
+ return 0;
+
+ if (b < 0)
+ return 0;
+ if (0 >= b)
+ return 0;
+ if (b > 0)
+ return 0;
+ if (0 <= b)
+ return 0;
+ if (b <= 0)
+ return 0;
+ if (0 > b)
+ return 0;
+ if (b >= 0)
+ return 0;
+ if (0 < b)
+ return 0;
+
+ if (b < 0U) // unsigned-signed-warning {{comparison of unsigned enum expression < 0 is always false}}
+ return 0;
+ if (0U >= b)
+ return 0;
+ if (b > 0U)
+ return 0;
+ if (0U <= b) // unsigned-signed-warning {{comparison of 0 <= unsigned enum expression is always true}}
+ return 0;
+ if (b <= 0U)
+ return 0;
+ if (0U > b) // unsigned-signed-warning {{comparison of 0 > unsigned enum expression is always false}}
+ return 0;
+ if (b >= 0U) // unsigned-signed-warning {{comparison of unsigned enum expression >= 0 is always true}}
+ return 0;
+ if (0U < b)
+ return 0;
+
+ if (a == 0)
+ return 0;
+ if (0 != a)
+ return 0;
+ if (a != 0)
+ return 0;
+ if (0 == a)
+ return 0;
+
+ if (a == 0U)
+ return 0;
+ if (0U != a)
+ return 0;
+ if (a != 0U)
+ return 0;
+ if (0U == a)
+ return 0;
+
+ if (b == 0)
+ return 0;
+ if (0 != b)
+ return 0;
+ if (b != 0)
+ return 0;
+ if (0 == b)
+ return 0;
+
+ if (b == 0U)
+ return 0;
+ if (0U != b)
+ return 0;
+ if (b != 0U)
+ return 0;
+ if (0U == b)
+ return 0;
+
+ return 1;
+}
diff --git a/test/Sema/tautological-unsigned-enum-zero-compare.cpp b/test/Sema/tautological-unsigned-enum-zero-compare.cpp
new file mode 100644
index 000000000000..a733b6edfc03
--- /dev/null
+++ b/test/Sema/tautological-unsigned-enum-zero-compare.cpp
@@ -0,0 +1,147 @@
+// RUN: %clang_cc1 -std=c++11 -triple=x86_64-pc-linux-gnu -fsyntax-only \
+// RUN: -verify=unsigned,unsigned-signed %s
+// RUN: %clang_cc1 -std=c++11 -triple=x86_64-pc-win32 -fsyntax-only \
+// RUN: -verify=unsigned-signed %s
+// RUN: %clang_cc1 -std=c++11 -triple=x86_64-pc-win32 -fsyntax-only \
+// RUN: -Wno-tautological-unsigned-enum-zero-compare \
+// RUN: -verify=silence %s
+
+// silence-no-diagnostics
+
+int main() {
+ // On Windows, all enumerations have a fixed underlying type, which is 'int'
+ // if not otherwise specified, so A is identical to C on Windows. Otherwise,
+ // we follow the C++ rules, which say that the only valid values of A are 0
+ // and 1.
+ enum A { A_foo = 0, A_bar, };
+ enum A a;
+
+ enum B : unsigned { B_foo = 0, B_bar, };
+ enum B b;
+
+ enum C : signed { C_foo = 0, C_bar, };
+ enum C c;
+
+ if (a < 0) // unsigned-warning {{comparison of unsigned enum expression < 0 is always false}}
+ return 0;
+ if (0 >= a)
+ return 0;
+ if (a > 0)
+ return 0;
+ if (0 <= a) // unsigned-warning {{comparison of 0 <= unsigned enum expression is always true}}
+ return 0;
+ if (a <= 0)
+ return 0;
+ if (0 > a) // unsigned-warning {{comparison of 0 > unsigned enum expression is always false}}
+ return 0;
+ if (a >= 0) // unsigned-warning {{comparison of unsigned enum expression >= 0 is always true}}
+ return 0;
+ if (0 < a)
+ return 0;
+
+ // FIXME: As below, the issue here is that the enumeration is promoted to
+ // unsigned.
+ if (a < 0U) // unsigned-signed-warning {{comparison of unsigned enum expression < 0 is always false}}
+ return 0;
+ if (0U >= a)
+ return 0;
+ if (a > 0U)
+ return 0;
+ if (0U <= a) // unsigned-signed-warning {{comparison of 0 <= unsigned enum expression is always true}}
+ return 0;
+ if (a <= 0U)
+ return 0;
+ if (0U > a) // unsigned-signed-warning {{comparison of 0 > unsigned enum expression is always false}}
+ return 0;
+ if (a >= 0U) // unsigned-signed-warning {{comparison of unsigned enum expression >= 0 is always true}}
+ return 0;
+ if (0U < a)
+ return 0;
+
+ if (b < 0) // unsigned-signed-warning {{comparison of unsigned enum expression < 0 is always false}}
+ return 0;
+ if (0 >= b)
+ return 0;
+ if (b > 0)
+ return 0;
+ if (0 <= b) // unsigned-signed-warning {{comparison of 0 <= unsigned enum expression is always true}}
+ return 0;
+ if (b <= 0)
+ return 0;
+ if (0 > b) // unsigned-signed-warning {{comparison of 0 > unsigned enum expression is always false}}
+ return 0;
+ if (b >= 0) // unsigned-signed-warning {{comparison of unsigned enum expression >= 0 is always true}}
+ return 0;
+ if (0 < b)
+ return 0;
+
+ if (b < 0U) // unsigned-signed-warning {{comparison of unsigned enum expression < 0 is always false}}
+ return 0;
+ if (0U >= b)
+ return 0;
+ if (b > 0U)
+ return 0;
+ if (0U <= b) // unsigned-signed-warning {{comparison of 0 <= unsigned enum expression is always true}}
+ return 0;
+ if (b <= 0U)
+ return 0;
+ if (0U > b) // unsigned-signed-warning {{comparison of 0 > unsigned enum expression is always false}}
+ return 0;
+ if (b >= 0U) // unsigned-signed-warning {{comparison of unsigned enum expression >= 0 is always true}}
+ return 0;
+ if (0U < b)
+ return 0;
+
+ if (c < 0)
+ return 0;
+ if (0 >= c)
+ return 0;
+ if (c > 0)
+ return 0;
+ if (0 <= c)
+ return 0;
+ if (c <= 0)
+ return 0;
+ if (0 > c)
+ return 0;
+ if (c >= 0)
+ return 0;
+ if (0 < c)
+ return 0;
+
+ // FIXME: These diagnostics are terrible. The issue here is that the signed
+ // enumeration value was promoted to an unsigned type.
+ if (c < 0U) // unsigned-signed-warning {{comparison of unsigned enum expression < 0 is always false}}
+ return 0;
+ if (0U >= c)
+ return 0;
+ if (c > 0U)
+ return 0;
+ if (0U <= c) // unsigned-signed-warning {{comparison of 0 <= unsigned enum expression is always true}}
+ return 0;
+ if (c <= 0U)
+ return 0;
+ if (0U > c) // unsigned-signed-warning {{comparison of 0 > unsigned enum expression is always false}}
+ return 0;
+ if (c >= 0U) // unsigned-signed-warning {{comparison of unsigned enum expression >= 0 is always true}}
+ return 0;
+ if (0U < c)
+ return 0;
+
+ return 1;
+}
+
+namespace crash_enum_zero_width {
+int test() {
+ enum A : unsigned {
+ A_foo = 0
+ };
+ enum A a;
+
+ // used to crash in llvm::APSInt::getMaxValue()
+ if (a < 0) // unsigned-signed-warning {{comparison of unsigned enum expression < 0 is always false}}
+ return 0;
+
+ return 1;
+}
+} // namespace crash_enum_zero_width
diff --git a/test/Sema/tautological-unsigned-zero-compare.c b/test/Sema/tautological-unsigned-zero-compare.c
new file mode 100644
index 000000000000..b9ea02a731a3
--- /dev/null
+++ b/test/Sema/tautological-unsigned-zero-compare.c
@@ -0,0 +1,257 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -Wno-tautological-unsigned-zero-compare -verify=silence %s
+// RUN: %clang_cc1 -fsyntax-only -verify -x c++ %s
+// RUN: %clang_cc1 -fsyntax-only -Wno-tautological-unsigned-zero-compare -verify=silence -x c++ %s
+
+unsigned uvalue(void);
+signed int svalue(void);
+
+#define macro(val) val
+
+#ifdef __cplusplus
+template<typename T>
+void TFunc() {
+ // Make sure that we do warn for normal variables in template functions !
+ unsigned char c = svalue();
+ if (c < 0) // expected-warning {{comparison of unsigned expression < 0 is always false}}
+ return;
+
+ if (c < macro(0))
+ return;
+
+ T v = svalue();
+ if (v < 0)
+ return;
+}
+#endif
+
+int main()
+{
+#ifdef __cplusplus
+ TFunc<unsigned char>();
+ TFunc<unsigned short>();
+#endif
+
+ unsigned un = uvalue();
+
+ // silence-no-diagnostics
+
+ if (un == 0)
+ return 0;
+ if (un != 0)
+ return 0;
+ if (un < 0) // expected-warning {{comparison of unsigned expression < 0 is always false}}
+ return 0;
+ if (un <= 0)
+ return 0;
+ if (un > 0)
+ return 0;
+ if (un >= 0) // expected-warning {{comparison of unsigned expression >= 0 is always true}}
+ return 0;
+
+ if (0 == un)
+ return 0;
+ if (0 != un)
+ return 0;
+ if (0 < un)
+ return 0;
+ if (0 <= un) // expected-warning {{comparison of 0 <= unsigned expression is always true}}
+ return 0;
+ if (0 > un) // expected-warning {{comparison of 0 > unsigned expression is always false}}
+ return 0;
+ if (0 >= un)
+ return 0;
+
+ if (un == 0UL)
+ return 0;
+ if (un != 0UL)
+ return 0;
+ if (un < 0UL) // expected-warning {{comparison of unsigned expression < 0 is always false}}
+ return 0;
+ if (un <= 0UL)
+ return 0;
+ if (un > 0UL)
+ return 0;
+ if (un >= 0UL) // expected-warning {{comparison of unsigned expression >= 0 is always true}}
+ return 0;
+
+ if (0UL == un)
+ return 0;
+ if (0UL != un)
+ return 0;
+ if (0UL < un)
+ return 0;
+ if (0UL <= un) // expected-warning {{comparison of 0 <= unsigned expression is always true}}
+ return 0;
+ if (0UL > un) // expected-warning {{comparison of 0 > unsigned expression is always false}}
+ return 0;
+ if (0UL >= un)
+ return 0;
+
+
+ signed int a = svalue();
+
+ if (a == 0)
+ return 0;
+ if (a != 0)
+ return 0;
+ if (a < 0)
+ return 0;
+ if (a <= 0)
+ return 0;
+ if (a > 0)
+ return 0;
+ if (a >= 0)
+ return 0;
+
+ if (0 == a)
+ return 0;
+ if (0 != a)
+ return 0;
+ if (0 < a)
+ return 0;
+ if (0 <= a)
+ return 0;
+ if (0 > a)
+ return 0;
+ if (0 >= a)
+ return 0;
+
+ if (a == 0UL)
+ return 0;
+ if (a != 0UL)
+ return 0;
+ if (a < 0UL) // expected-warning {{comparison of unsigned expression < 0 is always false}}
+ return 0;
+ if (a <= 0UL)
+ return 0;
+ if (a > 0UL)
+ return 0;
+ if (a >= 0UL) // expected-warning {{comparison of unsigned expression >= 0 is always true}}
+ return 0;
+
+ if (0UL == a)
+ return 0;
+ if (0UL != a)
+ return 0;
+ if (0UL < a)
+ return 0;
+ if (0UL <= a) // expected-warning {{comparison of 0 <= unsigned expression is always true}}
+ return 0;
+ if (0UL > a) // expected-warning {{comparison of 0 > unsigned expression is always false}}
+ return 0;
+ if (0UL >= a)
+ return 0;
+
+
+ float fl = 0;
+
+ if (fl == 0)
+ return 0;
+ if (fl != 0)
+ return 0;
+ if (fl < 0)
+ return 0;
+ if (fl <= 0)
+ return 0;
+ if (fl > 0)
+ return 0;
+ if (fl >= 0)
+ return 0;
+
+ if (0 == fl)
+ return 0;
+ if (0 != fl)
+ return 0;
+ if (0 < fl)
+ return 0;
+ if (0 <= fl)
+ return 0;
+ if (0 > fl)
+ return 0;
+ if (0 >= fl)
+ return 0;
+
+ if (fl == 0UL)
+ return 0;
+ if (fl != 0UL)
+ return 0;
+ if (fl < 0UL)
+ return 0;
+ if (fl <= 0UL)
+ return 0;
+ if (fl > 0UL)
+ return 0;
+ if (fl >= 0UL)
+ return 0;
+
+ if (0UL == fl)
+ return 0;
+ if (0UL != fl)
+ return 0;
+ if (0UL < fl)
+ return 0;
+ if (0UL <= fl)
+ return 0;
+ if (0UL > fl)
+ return 0;
+ if (0UL >= fl)
+ return 0;
+
+
+ double dl = 0;
+
+ if (dl == 0)
+ return 0;
+ if (dl != 0)
+ return 0;
+ if (dl < 0)
+ return 0;
+ if (dl <= 0)
+ return 0;
+ if (dl > 0)
+ return 0;
+ if (dl >= 0)
+ return 0;
+
+ if (0 == dl)
+ return 0;
+ if (0 != dl)
+ return 0;
+ if (0 < dl)
+ return 0;
+ if (0 <= dl)
+ return 0;
+ if (0 > dl)
+ return 0;
+ if (0 >= dl)
+ return 0;
+
+ if (dl == 0UL)
+ return 0;
+ if (dl != 0UL)
+ return 0;
+ if (dl < 0UL)
+ return 0;
+ if (dl <= 0UL)
+ return 0;
+ if (dl > 0UL)
+ return 0;
+ if (dl >= 0UL)
+ return 0;
+
+ if (0UL == dl)
+ return 0;
+ if (0UL != dl)
+ return 0;
+ if (0UL < dl)
+ return 0;
+ if (0UL <= dl)
+ return 0;
+ if (0UL > dl)
+ return 0;
+ if (0UL >= dl)
+ return 0;
+
+ return 1;
+}
diff --git a/test/Sema/tls.c b/test/Sema/tls.c
index 6d10363305ff..38bd3f202246 100644
--- a/test/Sema/tls.c
+++ b/test/Sema/tls.c
@@ -19,8 +19,4 @@
// Haiku does not suppport TLS.
// RUN: not %clang_cc1 -triple i586-pc-haiku -fsyntax-only %s
-// Bitrig suppports TLS.
-// RUN: %clang_cc1 -triple x86_64-pc-bitrig -fsyntax-only %s
-// RUN: %clang_cc1 -triple armv6-unknown-bitrig -fsyntax-only %s
-
__thread int x;
diff --git a/test/Sema/transparent-union.c b/test/Sema/transparent-union.c
index dfbadcfe62c7..048112767480 100644
--- a/test/Sema/transparent-union.c
+++ b/test/Sema/transparent-union.c
@@ -102,7 +102,7 @@ union pr15134v2 {
union pr30520v { void b; } __attribute__((transparent_union)); // expected-error {{field has incomplete type 'void'}}
-union pr30520a { int b[]; } __attribute__((transparent_union)); // expected-error {{field has incomplete type 'int []'}}
+union pr30520a { int b[]; } __attribute__((transparent_union)); // expected-error {{flexible array member 'b' in a union is not allowed}}
// expected-note@+1 2 {{forward declaration of 'struct stb'}}
union pr30520s { struct stb b; } __attribute__((transparent_union)); // expected-error {{field has incomplete type 'struct stb'}}
diff --git a/test/Sema/types.c b/test/Sema/types.c
index 9981be50ad4f..f44057dc4029 100644
--- a/test/Sema/types.c
+++ b/test/Sema/types.c
@@ -75,7 +75,7 @@ typedef int __attribute__ ((ext_vector_type(8192))) x2; // expected-error {{vect
// no support for vector enum type
enum { e_2 } x3 __attribute__((vector_size(64))); // expected-error {{invalid vector element type}}
-int x4 __attribute__((ext_vector_type(64))); // expected-error {{'ext_vector_type' attribute only applies to types}}
+int x4 __attribute__((ext_vector_type(64))); // expected-error {{'ext_vector_type' attribute only applies to typedefs}}
// rdar://16492792
typedef __attribute__ ((ext_vector_type(32),__aligned__(32))) unsigned char uchar32;
diff --git a/test/Sema/unused-expr.c b/test/Sema/unused-expr.c
index 58ad8278f201..c574f5e4afee 100644
--- a/test/Sema/unused-expr.c
+++ b/test/Sema/unused-expr.c
@@ -96,7 +96,7 @@ int t6() {
return 0;
}
-int t7 __attribute__ ((warn_unused_result)); // expected-warning {{'warn_unused_result' attribute only applies to functions}}
+int t7 __attribute__ ((warn_unused_result)); // expected-warning {{'warn_unused_result' attribute only applies to Objective-C methods, enums, structs, unions, classes, functions, and function pointers}}
// PR4010
int (*fn4)(void) __attribute__ ((warn_unused_result));
diff --git a/test/Sema/vector_swizzle_length.c b/test/Sema/vector_swizzle_length.c
new file mode 100644
index 000000000000..5e6b1e7d67a1
--- /dev/null
+++ b/test/Sema/vector_swizzle_length.c
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -x c %s -verify -pedantic -fsyntax-only
+// expected-no-diagnostics
+
+typedef float float8 __attribute__((ext_vector_type(8)));
+
+void foo() {
+ float8 f2 = (float8){0, 0, 0, 0, 0, 0, 0, 0};
+ (void)f2.s01234;
+ (void)f2.xyzxy;
+}
diff --git a/test/Sema/warn-documentation.cpp b/test/Sema/warn-documentation.cpp
index ccf374ccd060..7ffaffc07849 100644
--- a/test/Sema/warn-documentation.cpp
+++ b/test/Sema/warn-documentation.cpp
@@ -1282,3 +1282,25 @@ struct HasMoreFields {
};
}
+
+/*!
+ * Function pointer typedef with variadic params.
+ *
+ * @param a
+ * works
+ *
+ * @param ...
+ * now should work too.
+ */
+typedef void (*VariadicFnType)(int a, ...);
+
+/*!
+ * Function pointer type alias with variadic params.
+ *
+ * @param a
+ * works
+ *
+ * @param ...
+ * now should work too.
+ */
+using VariadicFnType2 = void (*)(int a, ...);
diff --git a/test/Sema/warn-documentation.m b/test/Sema/warn-documentation.m
index 3c1a369c4b14..18ab5bd9e096 100644
--- a/test/Sema/warn-documentation.m
+++ b/test/Sema/warn-documentation.m
@@ -299,3 +299,14 @@ void (^_Nullable blockPointerVariableThatLeadsNowhere)();
@property void (^blockReturnsNothing)();
@end
+
+/*!
+ * Block typedef with variadic params.
+ *
+ * @param a
+ * works
+ *
+ * @param ...
+ * now should work too.
+ */
+typedef void (^VariadicBlockType)(int a, ...);
diff --git a/test/Sema/warn-thread-safety-analysis.c b/test/Sema/warn-thread-safety-analysis.c
index 425ce4c196a6..0a375b873e69 100644
--- a/test/Sema/warn-thread-safety-analysis.c
+++ b/test/Sema/warn-thread-safety-analysis.c
@@ -130,4 +130,4 @@ int main() {
// We had a problem where we'd skip all attributes that follow a late-parsed
// attribute in a single __attribute__.
-void run() __attribute__((guarded_by(mu1), guarded_by(mu1))); // expected-warning 2{{only applies to fields and global variables}}
+void run() __attribute__((guarded_by(mu1), guarded_by(mu1))); // expected-warning 2{{only applies to non-static data members and global variables}}
diff --git a/test/Sema/warn-unreachable-ms.c b/test/Sema/warn-unreachable-ms.c
new file mode 100644
index 000000000000..421415e932f0
--- /dev/null
+++ b/test/Sema/warn-unreachable-ms.c
@@ -0,0 +1,55 @@
+// RUN: %clang_cc1 %s -triple=i686-pc-win32 -fsyntax-only -verify -fms-extensions -Wunreachable-code
+
+void f();
+
+void g1() {
+ __try {
+ f();
+ __leave;
+ f(); // expected-warning{{will never be executed}}
+ } __except(1) {
+ f();
+ }
+
+ // Completely empty.
+ __try {
+ } __except(1) {
+ }
+
+ __try {
+ f();
+ return;
+ } __except(1) { // Filter expression should not be marked as unreachable.
+ // Empty __except body.
+ }
+}
+
+void g2() {
+ __try {
+ // Nested __try.
+ __try {
+ f();
+ __leave;
+ f(); // expected-warning{{will never be executed}}
+ } __except(2) {
+ }
+ f();
+ __leave;
+ f(); // expected-warning{{will never be executed}}
+ } __except(1) {
+ f();
+ }
+}
+
+void g3() {
+ __try {
+ __try {
+ f();
+ } __except (1) {
+ __leave; // should exit outer try
+ }
+ __leave;
+ f(); // expected-warning{{never be executed}}
+ } __except (1) {
+ }
+}
diff --git a/test/Sema/wchar.c b/test/Sema/wchar.c
index 74151edede03..e84fe3e5526b 100644
--- a/test/Sema/wchar.c
+++ b/test/Sema/wchar.c
@@ -1,5 +1,5 @@
// RUN: %clang_cc1 %s -fsyntax-only -verify
-// RUN: %clang_cc1 %s -fsyntax-only -fshort-wchar -verify -DSHORT_WCHAR
+// RUN: %clang_cc1 %s -fsyntax-only -fwchar-type=short -fno-signed-wchar -verify -DSHORT_WCHAR
typedef __WCHAR_TYPE__ wchar_t;
diff --git a/test/Sema/xray-always-instrument-attr.c b/test/Sema/xray-always-instrument-attr.c
index 3c063e21a68f..b52369010287 100644
--- a/test/Sema/xray-always-instrument-attr.c
+++ b/test/Sema/xray-always-instrument-attr.c
@@ -1,6 +1,6 @@
// RUN: %clang_cc1 %s -verify -fsyntax-only -std=c11
void foo() __attribute__((xray_always_instrument));
-struct __attribute__((xray_always_instrument)) a { int x; }; // expected-warning {{'xray_always_instrument' attribute only applies to functions and methods}}
+struct __attribute__((xray_always_instrument)) a { int x; }; // expected-warning {{'xray_always_instrument' attribute only applies to functions and Objective-C methods}}
void bar() __attribute__((xray_always_instrument("not-supported"))); // expected-error {{'xray_always_instrument' attribute takes no arguments}}
diff --git a/test/Sema/xray-always-instrument-attr.cpp b/test/Sema/xray-always-instrument-attr.cpp
index 8d42837ec6bf..d6a33955cd74 100644
--- a/test/Sema/xray-always-instrument-attr.cpp
+++ b/test/Sema/xray-always-instrument-attr.cpp
@@ -1,7 +1,7 @@
// RUN: %clang_cc1 %s -verify -fsyntax-only -std=c++11 -x c++
void foo [[clang::xray_always_instrument]] ();
-struct [[clang::xray_always_instrument]] a { int x; }; // expected-warning {{'xray_always_instrument' attribute only applies to functions and methods}}
+struct [[clang::xray_always_instrument]] a { int x; }; // expected-warning {{'xray_always_instrument' attribute only applies to functions and Objective-C methods}}
class b {
void c [[clang::xray_always_instrument]] ();
diff --git a/test/Sema/xray-log-args-oob.c b/test/Sema/xray-log-args-oob.c
index a6be0f81cb47..585f5fd172ee 100644
--- a/test/Sema/xray-log-args-oob.c
+++ b/test/Sema/xray-log-args-oob.c
@@ -1,6 +1,6 @@
// RUN: %clang_cc1 %s -verify -fsyntax-only -std=c11
void foo(int) __attribute__((xray_log_args(1)));
-struct __attribute__((xray_log_args(1))) a { int x; }; // expected-warning {{'xray_log_args' attribute only applies to functions and methods}}
+struct __attribute__((xray_log_args(1))) a { int x; }; // expected-warning {{'xray_log_args' attribute only applies to functions and Objective-C methods}}
void fop() __attribute__((xray_log_args(1))); // expected-error {{'xray_log_args' attribute parameter 1 is out of bounds}}
diff --git a/test/Sema/xray-log-args-oob.cpp b/test/Sema/xray-log-args-oob.cpp
index 414bce0c334a..82f3be30c6de 100644
--- a/test/Sema/xray-log-args-oob.cpp
+++ b/test/Sema/xray-log-args-oob.cpp
@@ -1,6 +1,6 @@
// RUN: %clang_cc1 %s -verify -fsyntax-only -std=c++11 -x c++
void foo [[clang::xray_log_args(1)]] (int);
-struct [[clang::xray_log_args(1)]] a { int x; }; // expected-warning {{'xray_log_args' attribute only applies to functions and methods}}
+struct [[clang::xray_log_args(1)]] a { int x; }; // expected-warning {{'xray_log_args' attribute only applies to functions and Objective-C methods}}
void fop [[clang::xray_log_args(1)]] (); // expected-error {{'xray_log_args' attribute parameter 1 is out of bounds}}
diff --git a/test/Sema/zero-initializer.c b/test/Sema/zero-initializer.c
new file mode 100644
index 000000000000..0ab410d4c6d5
--- /dev/null
+++ b/test/Sema/zero-initializer.c
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -std=c99 -Wmissing-field-initializers -Wmissing-braces -verify %s
+
+// Tests that using {0} in struct initialization or assignment is supported
+struct foo { int x; int y; };
+struct bar { struct foo a; struct foo b; };
+struct A { int a; };
+struct B { struct A a; };
+struct C { struct B b; };
+struct D { struct C c; int n; };
+
+int main(void)
+{
+ struct foo f = { 0 }; // no-warning
+ struct foo g = { 9 }; // expected-warning {{missing field 'y' initializer}}
+ struct foo h = { 9, 9 }; // no-warning
+ struct bar i = { 0 }; // no-warning
+ struct bar j = { 0, 0 }; // expected-warning {{suggest braces around initialization of subobject}} expected-warning {{missing field 'b' initializer}}
+ struct bar k = { { 9, 9 }, { 9, 9 } }; // no-warning
+ struct bar l = { { 9, 9 }, { 0 } }; // no-warning
+ struct bar m = { { 0 }, { 0 } }; // no-warning
+ struct bar n = { { 0 }, { 9, 9 } }; // no-warning
+ struct bar o = { { 9 }, { 9, 9 } }; // expected-warning {{missing field 'y' initializer}}
+ struct C p = { 0 }; // no-warning
+ struct C q = { 9 }; // warning suppressed for struct with single element
+ struct D r = { 9 }; // expected-warning {{suggest braces around initialization of subobject}} expected-warning {{missing field 'n' initializer}}
+ f = (struct foo ) { 0 }; // no-warning
+ g = (struct foo ) { 9 }; // expected-warning {{missing field 'y' initializer}}
+ h = (struct foo ) { 9, 9 }; // no-warning
+ i = (struct bar) { 0 }; // no-warning
+ j = (struct bar) { 0, 0 }; // expected-warning {{suggest braces around initialization of subobject}} expected-warning {{missing field 'b' initializer}}
+ k = (struct bar) { { 9, 9 }, { 9, 9 } }; // no-warning
+ l = (struct bar) { { 9, 9 }, { 0 } }; // no-warning
+ m = (struct bar) { { 0 }, { 0 } }; // no-warning
+ n = (struct bar) { { 0 }, { 9, 9 } }; // no-warning
+ o = (struct bar) { { 9 }, { 9, 9 } }; // expected-warning {{missing field 'y' initializer}}
+ p = (struct C) { 0 }; // no-warning
+ q = (struct C) { 9 }; // warning suppressed for struct with single element
+ r = (struct D) { 9 }; // expected-warning {{suggest braces around initialization of subobject}} expected-warning {{missing field 'n' initializer}}
+
+ return 0;
+}
diff --git a/test/SemaCUDA/call-stack-for-deferred-err.cu b/test/SemaCUDA/call-stack-for-deferred-err.cu
index ddcaabf4ef53..35f71dd0f124 100644
--- a/test/SemaCUDA/call-stack-for-deferred-err.cu
+++ b/test/SemaCUDA/call-stack-for-deferred-err.cu
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fcuda-is-device -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple nvptx64-nvidia-cuda -fcuda-is-device -fsyntax-only -verify %s
#include "Inputs/cuda.h"
diff --git a/test/SemaCUDA/error-includes-mode.cu b/test/SemaCUDA/error-includes-mode.cu
new file mode 100644
index 000000000000..257fdeceef65
--- /dev/null
+++ b/test/SemaCUDA/error-includes-mode.cu
@@ -0,0 +1,7 @@
+// RUN: not %clang_cc1 -fsyntax-only %s 2>&1 | FileCheck --check-prefix HOST %s
+// RUN: not %clang_cc1 -triple nvptx-unknown-unknown -target-cpu sm_35 \
+// RUN: -fcuda-is-device -fsyntax-only %s 2>&1 | FileCheck --check-prefix SM35 %s
+
+// HOST: 1 error generated when compiling for host
+// SM35: 1 error generated when compiling for sm_35
+error;
diff --git a/test/SemaCUDA/launch_bounds.cu b/test/SemaCUDA/launch_bounds.cu
index 468954a3aab1..0ca0c0145d8b 100644
--- a/test/SemaCUDA/launch_bounds.cu
+++ b/test/SemaCUDA/launch_bounds.cu
@@ -15,7 +15,7 @@ __launch_bounds__(128, -7) void TestNegArg2(void); // expected-warning {{'launch
__launch_bounds__(1, 2, 3) void Test3Args(void); // expected-error {{'launch_bounds' attribute takes no more than 2 arguments}}
__launch_bounds__() void TestNoArgs(void); // expected-error {{'launch_bounds' attribute takes at least 1 argument}}
-int TestNoFunction __launch_bounds__(128, 7); // expected-warning {{'launch_bounds' attribute only applies to functions and methods}}
+int TestNoFunction __launch_bounds__(128, 7); // expected-warning {{'launch_bounds' attribute only applies to Objective-C methods, functions, and function pointers}}
__launch_bounds__(true) void TestBool(void);
__launch_bounds__(128.0) void TestFP(void); // expected-error {{'launch_bounds' attribute requires parameter 0 to be an integer constant}}
diff --git a/test/SemaCUDA/no-call-stack-for-immediate-errs.cu b/test/SemaCUDA/no-call-stack-for-immediate-errs.cu
index 6dc98695c1e3..f7e9eb7e9211 100644
--- a/test/SemaCUDA/no-call-stack-for-immediate-errs.cu
+++ b/test/SemaCUDA/no-call-stack-for-immediate-errs.cu
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fcuda-is-device -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple nvptx64-nvidia-cuda -fcuda-is-device -fsyntax-only -verify %s
#include "Inputs/cuda.h"
diff --git a/test/SemaCUDA/vla.cu b/test/SemaCUDA/vla.cu
index f0d1ba595d93..b65ae5e5fe21 100644
--- a/test/SemaCUDA/vla.cu
+++ b/test/SemaCUDA/vla.cu
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -fcuda-is-device -fsyntax-only -verify %s
-// RUN: %clang_cc1 -fsyntax-only -verify -DHOST %s
+// RUN: %clang_cc1 -triple nvptx64-nvidia-cuda -fcuda-is-device -verify %s
+// RUN: %clang_cc1 -triple nvptx64-nvidia-cuda -verify -DHOST %s
#include "Inputs/cuda.h"
diff --git a/test/SemaCXX/Inputs/warn-zero-nullptr.h b/test/SemaCXX/Inputs/warn-zero-nullptr.h
new file mode 100644
index 000000000000..9b86c4b7b0ec
--- /dev/null
+++ b/test/SemaCXX/Inputs/warn-zero-nullptr.h
@@ -0,0 +1,3 @@
+#define NULL (0)
+#define SYSTEM_MACRO (0)
+#define OTHER_SYSTEM_MACRO (NULL)
diff --git a/test/SemaCXX/MicrosoftExtensions.cpp b/test/SemaCXX/MicrosoftExtensions.cpp
index 38949e11376d..c605dcb912f6 100644
--- a/test/SemaCXX/MicrosoftExtensions.cpp
+++ b/test/SemaCXX/MicrosoftExtensions.cpp
@@ -504,6 +504,20 @@ struct S {
int S::fn() { return 0; } // expected-warning {{is missing exception specification}}
}
+class PR34109_class {
+ PR34109_class() {}
+ virtual ~PR34109_class() {}
+};
+
+void operator delete(void *) throw();
+// expected-note@-1 {{previous declaration is here}}
+__declspec(dllexport) void operator delete(void *) throw();
+// expected-error@-1 {{redeclaration of 'operator delete' cannot add 'dllexport' attribute}}
+
+void PR34109(int* a) {
+ delete a;
+}
+
#elif TEST2
// Check that __unaligned is not recognized if MS extensions are not enabled
diff --git a/test/SemaCXX/accessible-base.cpp b/test/SemaCXX/accessible-base.cpp
index 6bf06ce12602..27969858506d 100644
--- a/test/SemaCXX/accessible-base.cpp
+++ b/test/SemaCXX/accessible-base.cpp
@@ -1,10 +1,11 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -DMS -fms-compatibility -Wmicrosoft-inaccessible-base -fsyntax-only -verify %s
struct A {
int a;
};
-struct X1 : virtual A
+struct X1 : virtual A
{};
struct Y1 : X1, virtual A
@@ -13,7 +14,7 @@ struct Y1 : X1, virtual A
struct Y2 : X1, A // expected-warning{{direct base 'A' is inaccessible due to ambiguity:\n struct Y2 -> struct X1 -> struct A\n struct Y2 -> struct A}}
{};
-struct X2 : A
+struct X2 : A
{};
struct Z1 : X2, virtual A // expected-warning{{direct base 'A' is inaccessible due to ambiguity:\n struct Z1 -> struct X2 -> struct A\n struct Z1 -> struct A}}
@@ -21,3 +22,30 @@ struct Z1 : X2, virtual A // expected-warning{{direct base 'A' is inaccessible d
struct Z2 : X2, A // expected-warning{{direct base 'A' is inaccessible due to ambiguity:\n struct Z2 -> struct X2 -> struct A\n struct Z2 -> struct A}}
{};
+
+A *y2_to_a(Y2 *p) {
+#ifdef MS
+ // expected-warning@+4 {{accessing inaccessible direct base 'A' of 'Y2' is a Microsoft extension}}
+#else
+ // expected-error@+2 {{ambiguous conversion}}
+#endif
+ return p;
+}
+
+A *z1_to_a(Z1 *p) {
+#ifdef MS
+ // expected-warning@+4 {{accessing inaccessible direct base 'A' of 'Z1' is a Microsoft extension}}
+#else
+ // expected-error@+2 {{ambiguous conversion}}
+#endif
+ return p;
+}
+
+A *z1_to_a(Z2 *p) {
+#ifdef MS
+ // expected-warning@+4 {{accessing inaccessible direct base 'A' of 'Z2' is a Microsoft extension}}
+#else
+ // expected-error@+2 {{ambiguous conversion}}
+#endif
+ return p;
+}
diff --git a/test/SemaCXX/address-packed.cpp b/test/SemaCXX/address-packed.cpp
index 308c4858cd50..f0d1496fd892 100644
--- a/test/SemaCXX/address-packed.cpp
+++ b/test/SemaCXX/address-packed.cpp
@@ -112,3 +112,12 @@ void g1() {
S<float> s3;
s3.get(); // expected-note {{in instantiation of member function 'S<float>::get'}}
}
+
+// PR35509
+typedef long L1;
+struct Incomplete;
+struct S2 {
+ L1 d;
+ Incomplete *e() const;
+} __attribute__((packed));
+Incomplete *S2::e() const { return (Incomplete *)&d; } // no-warning
diff --git a/test/SemaCXX/aggregate-initialization.cpp b/test/SemaCXX/aggregate-initialization.cpp
index 7b6abd22acc7..514473f9bcb1 100644
--- a/test/SemaCXX/aggregate-initialization.cpp
+++ b/test/SemaCXX/aggregate-initialization.cpp
@@ -1,6 +1,6 @@
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++14 %s
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c++1z %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++17 %s
// Verify that using an initializer list for a non-aggregate looks for
// constructors..
@@ -150,3 +150,33 @@ namespace ProtectedBaseCtor {
// expected-error@-5 {{protected constructor}}
// expected-note@-30 {{here}}
}
+
+namespace IdiomaticStdArrayInitDoesNotWarn {
+#pragma clang diagnostic push
+#pragma clang diagnostic warning "-Wmissing-braces"
+ template<typename T, int N> struct StdArray {
+ T contents[N];
+ };
+ StdArray<int, 3> x = {1, 2, 3};
+
+ template<typename T, int N> struct ArrayAndSomethingElse {
+ T contents[N];
+ int something_else;
+ };
+ ArrayAndSomethingElse<int, 3> y = {1, 2, 3}; // expected-warning {{suggest braces}}
+
+#if __cplusplus >= 201703L
+ template<typename T, int N> struct ArrayAndBaseClass : StdArray<int, 3> {
+ T contents[N];
+ };
+ ArrayAndBaseClass<int, 3> z = {1, 2, 3}; // expected-warning {{suggest braces}}
+
+ // It's not clear whether we should be warning in this case. If this
+ // pattern becomes idiomatic, it would be reasonable to suppress the
+ // warning here too.
+ template<typename T, int N> struct JustABaseClass : StdArray<T, N> {};
+ JustABaseClass<int, 3> w = {1, 2, 3}; // expected-warning {{suggest braces}}
+#endif
+
+#pragma clang diagnostic pop
+}
diff --git a/test/SemaCXX/attr-cxx-disabled.cpp b/test/SemaCXX/attr-cxx-disabled.cpp
new file mode 100644
index 000000000000..a1a7533bd854
--- /dev/null
+++ b/test/SemaCXX/attr-cxx-disabled.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -fsyntax-only -fno-double-square-bracket-attributes -verify -pedantic -std=c++11 -DERRORS %s
+// RUN: %clang_cc1 -fsyntax-only -fdouble-square-bracket-attributes -verify -pedantic -std=c++11 %s
+
+struct [[]] S {};
+
+#ifdef ERRORS
+// expected-error@-3 {{declaration of anonymous struct must be a definition}}
+// expected-warning@-4 {{declaration does not declare anything}}
+#else
+// expected-no-diagnostics
+#endif
+
diff --git a/test/SemaCXX/attr-lto-visibility-public.cpp b/test/SemaCXX/attr-lto-visibility-public.cpp
index 2f9ed87f6ee0..42e0f79279d9 100644
--- a/test/SemaCXX/attr-lto-visibility-public.cpp
+++ b/test/SemaCXX/attr-lto-visibility-public.cpp
@@ -1,13 +1,13 @@
// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
-int i [[clang::lto_visibility_public]]; // expected-warning {{'lto_visibility_public' attribute only applies to struct, union or class}}
-typedef int t [[clang::lto_visibility_public]]; // expected-warning {{'lto_visibility_public' attribute only applies to struct, union or class}}
-[[clang::lto_visibility_public]] void f(); // expected-warning {{'lto_visibility_public' attribute only applies to struct, union or class}}
+int i [[clang::lto_visibility_public]]; // expected-warning {{'lto_visibility_public' attribute only applies to structs, unions, and classes}}
+typedef int t [[clang::lto_visibility_public]]; // expected-warning {{'lto_visibility_public' attribute only applies to}}
+[[clang::lto_visibility_public]] void f(); // expected-warning {{'lto_visibility_public' attribute only applies to}}
void f() [[clang::lto_visibility_public]]; // expected-error {{'lto_visibility_public' attribute cannot be applied to types}}
struct [[clang::lto_visibility_public]] s1 {
- int i [[clang::lto_visibility_public]]; // expected-warning {{'lto_visibility_public' attribute only applies to struct, union or class}}
- [[clang::lto_visibility_public]] void f(); // expected-warning {{'lto_visibility_public' attribute only applies to struct, union or class}}
+ int i [[clang::lto_visibility_public]]; // expected-warning {{'lto_visibility_public' attribute only applies to}}
+ [[clang::lto_visibility_public]] void f(); // expected-warning {{'lto_visibility_public' attribute only applies to}}
};
struct [[clang::lto_visibility_public(1)]] s2 { // expected-error {{'lto_visibility_public' attribute takes no arguments}}
diff --git a/test/SemaCXX/attr-mode-tmpl.cpp b/test/SemaCXX/attr-mode-tmpl.cpp
index d83bb3989050..f665b1ba4912 100644
--- a/test/SemaCXX/attr-mode-tmpl.cpp
+++ b/test/SemaCXX/attr-mode-tmpl.cpp
@@ -72,7 +72,7 @@ struct TemplatedStruct {
// expected-warning@-1{{deprecated}}
// Check attribute on methods - it is invalid.
- __attribute__((mode(QI))) T g1() { return 0; } // expected-error{{'mode' attribute only applies to variables, enums, fields and typedefs}}
+ __attribute__((mode(QI))) T g1() { return 0; } // expected-error{{'mode' attribute only applies to variables, enums, typedefs, and non-static data members}}
};
diff --git a/test/SemaCXX/attr-no-sanitize.cpp b/test/SemaCXX/attr-no-sanitize.cpp
index 965def6f0254..02bc9a9e7f8f 100644
--- a/test/SemaCXX/attr-no-sanitize.cpp
+++ b/test/SemaCXX/attr-no-sanitize.cpp
@@ -16,10 +16,15 @@ int f3() __attribute__((no_sanitize("address")));
// PRINT: int f4() {{\[\[}}clang::no_sanitize("thread")]]
[[clang::no_sanitize("thread")]] int f4();
+// DUMP-LABEL: FunctionDecl {{.*}} f4
+// DUMP: NoSanitizeAttr {{.*}} hwaddress
+// PRINT: int f4() {{\[\[}}clang::no_sanitize("hwaddress")]]
+[[clang::no_sanitize("hwaddress")]] int f4();
+
// DUMP-LABEL: FunctionDecl {{.*}} f5
-// DUMP: NoSanitizeAttr {{.*}} address thread
-// PRINT: int f5() __attribute__((no_sanitize("address", "thread")))
-int f5() __attribute__((no_sanitize("address", "thread")));
+// DUMP: NoSanitizeAttr {{.*}} address thread hwaddress
+// PRINT: int f5() __attribute__((no_sanitize("address", "thread", "hwaddress")))
+int f5() __attribute__((no_sanitize("address", "thread", "hwaddress")));
// DUMP-LABEL: FunctionDecl {{.*}} f6
// DUMP: NoSanitizeAttr {{.*}} unknown
diff --git a/test/SemaCXX/attr-require-constant-initialization.cpp b/test/SemaCXX/attr-require-constant-initialization.cpp
index 0df9f2e88029..2dd72ea6dba9 100644
--- a/test/SemaCXX/attr-require-constant-initialization.cpp
+++ b/test/SemaCXX/attr-require-constant-initialization.cpp
@@ -56,12 +56,12 @@ struct StoresNonLit {
#if defined(TEST_ONE) // Test semantics of attribute
// Test diagnostics when attribute is applied to non-static declarations.
-void test_func_local(ATTR int param) { // expected-error {{only applies to variables with static or thread}}
- ATTR int x = 42; // expected-error {{only applies to variables with static or thread}}
+void test_func_local(ATTR int param) { // expected-error {{only applies to global variables}}
+ ATTR int x = 42; // expected-error {{only applies to}}
ATTR extern int y;
}
-struct ATTR class_mem { // expected-error {{only applies to variables with static or thread}}
- ATTR int x; // expected-error {{only applies to variables with static or thread}}
+struct ATTR class_mem { // expected-error {{only applies to}}
+ ATTR int x; // expected-error {{only applies to}}
};
// [basic.start.static]p2.1
diff --git a/test/SemaCXX/attr-weak.cpp b/test/SemaCXX/attr-weak.cpp
index 8ba3a954282d..51deb664ce6e 100644
--- a/test/SemaCXX/attr-weak.cpp
+++ b/test/SemaCXX/attr-weak.cpp
@@ -3,7 +3,7 @@
static int test0 __attribute__((weak)); // expected-error {{weak declaration cannot have internal linkage}}
static void test1() __attribute__((weak)); // expected-error {{weak declaration cannot have internal linkage}}
-namespace test2 __attribute__((weak)) { // expected-warning {{'weak' attribute only applies to variables, functions and classes}}
+namespace test2 __attribute__((weak)) { // expected-warning {{'weak' attribute only applies to variables, functions, and classes}}
}
namespace {
diff --git a/test/SemaCXX/builtin-assume-aligned-tmpl.cpp b/test/SemaCXX/builtin-assume-aligned-tmpl.cpp
index 0909070c5e11..61b85557d6b2 100644
--- a/test/SemaCXX/builtin-assume-aligned-tmpl.cpp
+++ b/test/SemaCXX/builtin-assume-aligned-tmpl.cpp
@@ -57,7 +57,7 @@ void test22() {
atest4<int, 5>();
}
-// expected-warning@+1 {{'assume_aligned' attribute only applies to functions and methods}}
+// expected-warning@+1 {{'assume_aligned' attribute only applies to Objective-C methods and functions}}
class __attribute__((assume_aligned(32))) x {
int y;
};
diff --git a/test/SemaCXX/compare-cxx2a.cpp b/test/SemaCXX/compare-cxx2a.cpp
new file mode 100644
index 000000000000..61d35021cc13
--- /dev/null
+++ b/test/SemaCXX/compare-cxx2a.cpp
@@ -0,0 +1,166 @@
+// Force x86-64 because some of our heuristics are actually based
+// on integer sizes.
+
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -fsyntax-only -pedantic -verify -Wsign-compare -std=c++2a %s
+
+void test0(long a, unsigned long b) {
+ enum EnumA {A};
+ enum EnumB {B};
+ enum EnumC {C = 0x10000};
+ // (a,b)
+
+ // FIXME: <=> should never produce -Wsign-compare warnings. All the possible error
+ // cases involve narrowing conversions and so are ill-formed.
+ (void)(a <=> (unsigned long) b); // expected-warning {{comparison of integers of different signs}}
+ (void)(a <=> (unsigned int) b);
+ (void)(a <=> (unsigned short) b);
+ (void)(a <=> (unsigned char) b);
+ (void)((long) a <=> b); // expected-warning {{comparison of integers of different signs}}
+ (void)((int) a <=> b); // expected-warning {{comparison of integers of different signs}}
+ (void)((short) a <=> b); // expected-warning {{comparison of integers of different signs}}
+ (void)((signed char) a <=> b); // expected-warning {{comparison of integers of different signs}}
+ (void)((long) a <=> (unsigned long) b); // expected-warning {{comparison of integers of different signs}}
+ (void)((int) a <=> (unsigned int) b); // expected-warning {{comparison of integers of different signs}}
+ (void)((short) a <=> (unsigned short) b);
+ (void)((signed char) a <=> (unsigned char) b);
+
+#if 0
+ // (A,b)
+ (void)(A <=> (unsigned long) b);
+ (void)(A <=> (unsigned int) b);
+ (void)(A <=> (unsigned short) b);
+ (void)(A <=> (unsigned char) b);
+ (void)((long) A <=> b);
+ (void)((int) A <=> b);
+ (void)((short) A <=> b);
+ (void)((signed char) A <=> b);
+ (void)((long) A <=> (unsigned long) b);
+ (void)((int) A <=> (unsigned int) b);
+ (void)((short) A <=> (unsigned short) b);
+ (void)((signed char) A <=> (unsigned char) b);
+
+ // (a,B)
+ (void)(a <=> (unsigned long) B);
+ (void)(a <=> (unsigned int) B);
+ (void)(a <=> (unsigned short) B);
+ (void)(a <=> (unsigned char) B);
+ (void)((long) a <=> B);
+ (void)((int) a <=> B);
+ (void)((short) a <=> B);
+ (void)((signed char) a <=> B);
+ (void)((long) a <=> (unsigned long) B);
+ (void)((int) a <=> (unsigned int) B);
+ (void)((short) a <=> (unsigned short) B);
+ (void)((signed char) a <=> (unsigned char) B);
+
+ // (C,b)
+ (void)(C <=> (unsigned long) b);
+ (void)(C <=> (unsigned int) b);
+ (void)(C <=> (unsigned short) b); // expected-warning {{comparison of constant 'C' (65536) with expression of type 'unsigned short' is always 'std::strong_ordering::greater'}}
+ (void)(C <=> (unsigned char) b); // expected-warning {{comparison of constant 'C' (65536) with expression of type 'unsigned char' is always 'std::strong_ordering::greater'}}
+ (void)((long) C <=> b);
+ (void)((int) C <=> b);
+ (void)((short) C <=> b);
+ (void)((signed char) C <=> b);
+ (void)((long) C <=> (unsigned long) b);
+ (void)((int) C <=> (unsigned int) b);
+ (void)((short) C <=> (unsigned short) b);
+ (void)((signed char) C <=> (unsigned char) b);
+
+ // (a,C)
+ (void)(a <=> (unsigned long) C);
+ (void)(a <=> (unsigned int) C);
+ (void)(a <=> (unsigned short) C);
+ (void)(a <=> (unsigned char) C);
+ (void)((long) a <=> C);
+ (void)((int) a <=> C);
+ (void)((short) a <=> C); // expected-warning {{comparison of constant 'C' (65536) with expression of type 'short' is always 'std::strong_ordering::less'}}
+ (void)((signed char) a <=> C); // expected-warning {{comparison of constant 'C' (65536) with expression of type 'signed char' is always 'std::strong_ordering::less'}}
+ (void)((long) a <=> (unsigned long) C);
+ (void)((int) a <=> (unsigned int) C);
+ (void)((short) a <=> (unsigned short) C);
+ (void)((signed char) a <=> (unsigned char) C);
+#endif
+
+ // (0x80000,b)
+ (void)(0x80000 <=> (unsigned long) b);
+ (void)(0x80000 <=> (unsigned int) b);
+ (void)(0x80000 <=> (unsigned short) b); // expected-warning {{result of comparison of constant 524288 with expression of type 'unsigned short' is always 'std::strong_ordering::greater'}}
+ (void)(0x80000 <=> (unsigned char) b); // expected-warning {{result of comparison of constant 524288 with expression of type 'unsigned char' is always 'std::strong_ordering::greater'}}
+ (void)((long) 0x80000 <=> b);
+ (void)((int) 0x80000 <=> b);
+ (void)((short) 0x80000 <=> b);
+ (void)((signed char) 0x80000 <=> b);
+ (void)((long) 0x80000 <=> (unsigned long) b);
+ (void)((int) 0x80000 <=> (unsigned int) b);
+ (void)((short) 0x80000 <=> (unsigned short) b);
+ (void)((signed char) 0x80000 <=> (unsigned char) b);
+
+ // (a,0x80000)
+ (void)(a <=> (unsigned long) 0x80000); // expected-warning {{comparison of integers of different signs}}
+ (void)(a <=> (unsigned int) 0x80000);
+ (void)(a <=> (unsigned short) 0x80000);
+ (void)(a <=> (unsigned char) 0x80000);
+ (void)((long) a <=> 0x80000);
+ (void)((int) a <=> 0x80000);
+ (void)((short) a <=> 0x80000); // expected-warning {{comparison of constant 524288 with expression of type 'short' is always 'std::strong_ordering::less'}}
+ (void)((signed char) a <=> 0x80000); // expected-warning {{comparison of constant 524288 with expression of type 'signed char' is always 'std::strong_ordering::less'}}
+ (void)((long) a <=> (unsigned long) 0x80000); // expected-warning {{comparison of integers of different signs}}
+ (void)((int) a <=> (unsigned int) 0x80000); // expected-warning {{comparison of integers of different signs}}
+ (void)((short) a <=> (unsigned short) 0x80000);
+ (void)((signed char) a <=> (unsigned char) 0x80000);
+}
+
+void test5(bool b) {
+ (void) (b <=> -10); // expected-warning{{comparison of constant -10 with expression of type 'bool' is always 'std::strong_ordering::greater'}}
+ (void) (b <=> -1); // expected-warning{{comparison of constant -1 with expression of type 'bool' is always 'std::strong_ordering::greater'}}
+ (void) (b <=> 0);
+ (void) (b <=> 1);
+ (void) (b <=> 2); // expected-warning{{comparison of constant 2 with expression of type 'bool' is always 'std::strong_ordering::less'}}
+ (void) (b <=> 10); // expected-warning{{comparison of constant 10 with expression of type 'bool' is always 'std::strong_ordering::less'}}
+}
+
+void test6(signed char sc) {
+ (void)(sc <=> 200); // expected-warning{{comparison of constant 200 with expression of type 'signed char' is always 'std::strong_ordering::less'}}
+ (void)(200 <=> sc); // expected-warning{{comparison of constant 200 with expression of type 'signed char' is always 'std::strong_ordering::greater'}}
+}
+
+// Test many signedness combinations.
+void test7(unsigned long other) {
+ // Common unsigned, other unsigned, constant unsigned
+ (void)((unsigned)other <=> (unsigned long)(0x1'ffff'ffff)); // expected-warning{{less}}
+ (void)((unsigned)other <=> (unsigned long)(0xffff'ffff));
+ (void)((unsigned long)other <=> (unsigned)(0x1'ffff'ffff));
+ (void)((unsigned long)other <=> (unsigned)(0xffff'ffff));
+
+ // Common unsigned, other signed, constant unsigned
+ (void)((int)other <=> (unsigned long)(0xffff'ffff'ffff'ffff)); // expected-warning{{different signs}}
+ (void)((int)other <=> (unsigned long)(0x0000'0000'ffff'ffff)); // expected-warning{{different signs}}
+ (void)((int)other <=> (unsigned long)(0x0000'0000'0fff'ffff)); // expected-warning{{different signs}}
+ (void)((int)other <=> (unsigned)(0x8000'0000)); // expected-warning{{different signs}}
+
+ // Common unsigned, other unsigned, constant signed
+ (void)((unsigned long)other <=> (int)(0xffff'ffff)); // expected-warning{{different signs}}
+
+ // Common unsigned, other signed, constant signed
+ // Should not be possible as the common type should also be signed.
+
+ // Common signed, other signed, constant signed
+ (void)((int)other <=> (long)(0xffff'ffff)); // expected-warning{{less}}
+ (void)((int)other <=> (long)(0xffff'ffff'0000'0000)); // expected-warning{{greater}}
+ (void)((int)other <=> (long)(0x0fff'ffff));
+ (void)((int)other <=> (long)(0xffff'ffff'f000'0000));
+
+ // Common signed, other signed, constant unsigned
+ (void)((int)other <=> (unsigned char)(0xffff));
+ (void)((int)other <=> (unsigned char)(0xff));
+
+ // Common signed, other unsigned, constant signed
+ (void)((unsigned char)other <=> (int)(0xff));
+ (void)((unsigned char)other <=> (int)(0xffff)); // expected-warning{{less}}
+
+ // Common signed, other unsigned, constant unsigned
+ (void)((unsigned char)other <=> (unsigned short)(0xff));
+ (void)((unsigned char)other <=> (unsigned short)(0x100)); // expected-warning{{less}}
+ (void)((unsigned short)other <=> (unsigned char)(0xff));
+}
diff --git a/test/SemaCXX/compare.cpp b/test/SemaCXX/compare.cpp
index 0528b044fb1f..d852180c0663 100644
--- a/test/SemaCXX/compare.cpp
+++ b/test/SemaCXX/compare.cpp
@@ -73,7 +73,7 @@ int test0(long a, unsigned long b) {
((int) a == (unsigned int) B) +
((short) a == (unsigned short) B) +
((signed char) a == (unsigned char) B) +
- (a < (unsigned long) B) + // expected-warning {{comparison of integers of different signs}}
+ (a < (unsigned long) B) + // expected-warning {{comparison of unsigned expression < 0 is always false}}
(a < (unsigned int) B) +
(a < (unsigned short) B) +
(a < (unsigned char) B) +
@@ -81,8 +81,8 @@ int test0(long a, unsigned long b) {
((int) a < B) +
((short) a < B) +
((signed char) a < B) +
- ((long) a < (unsigned long) B) + // expected-warning {{comparison of integers of different signs}}
- ((int) a < (unsigned int) B) + // expected-warning {{comparison of integers of different signs}}
+ ((long) a < (unsigned long) B) + // expected-warning {{comparison of unsigned expression < 0 is always false}}
+ ((int) a < (unsigned int) B) + // expected-warning {{comparison of unsigned expression < 0 is always false}}
((short) a < (unsigned short) B) +
((signed char) a < (unsigned char) B) +
@@ -245,8 +245,8 @@ void test4(short s) {
// unsigned.
const unsigned B = -1;
void (s < B); // expected-warning{{comparison of integers of different signs: 'short' and 'const unsigned int'}}
- void (s > B); // expected-warning{{comparison of integers of different signs: 'short' and 'const unsigned int'}}
- void (s <= B); // expected-warning{{comparison of integers of different signs: 'short' and 'const unsigned int'}}
+ void (s > B); // expected-warning{{comparison 'short' > 4294967295 is always false}}
+ void (s <= B); // expected-warning{{comparison 'short' <= 4294967295 is always true}}
void (s >= B); // expected-warning{{comparison of integers of different signs: 'short' and 'const unsigned int'}}
void (s == B); // expected-warning{{comparison of integers of different signs: 'short' and 'const unsigned int'}}
void (s != B); // expected-warning{{comparison of integers of different signs: 'short' and 'const unsigned int'}}
@@ -423,3 +423,19 @@ namespace templates {
testx<B>();
}
}
+
+namespace tautological_enum {
+ enum E { a, b, c } e;
+
+ // FIXME: We should warn about constructing this out-of-range numeration value.
+ const E invalid = (E)-1;
+ // ... but we should not warn about comparing against it.
+ bool x = e == invalid;
+
+ // We should not warn about relational comparisons for enumerators, even if
+ // they're tautological.
+ bool y = e >= a && e <= b;
+ const E first_in_range = a;
+ const E last_in_range = b;
+ bool z = e >= first_in_range && e <= last_in_range;
+}
diff --git a/test/SemaCXX/complex-conversion.cpp b/test/SemaCXX/complex-conversion.cpp
new file mode 100644
index 000000000000..e8f09958165c
--- /dev/null
+++ b/test/SemaCXX/complex-conversion.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T> void take(T);
+
+void func(float Real, _Complex float Complex) {
+ Real += Complex; // expected-error {{assigning to 'float' from incompatible type '_Complex float'}}
+ Real += (float)Complex;
+
+ Real = Complex; // expected-error {{implicit conversion from '_Complex float' to 'float' is not permitted in C++}}
+ Real = (float)Complex;
+
+ take<float>(Complex); // expected-error {{implicit conversion from '_Complex float' to 'float' is not permitted in C++}}
+ take<double>(1.0i); // expected-error {{implicit conversion from '_Complex double' to 'double' is not permitted in C++}}
+ take<_Complex float>(Complex);
+
+ // Conversion to bool doesn't actually discard the imaginary part.
+ take<bool>(Complex);
+}
diff --git a/test/SemaCXX/complex-overload.cpp b/test/SemaCXX/complex-overload.cpp
index 1381968751af..9373e44de950 100644
--- a/test/SemaCXX/complex-overload.cpp
+++ b/test/SemaCXX/complex-overload.cpp
@@ -4,9 +4,10 @@ char *foo(float);
void test_foo_1(float fv, double dv, float _Complex fc, double _Complex dc) {
char *cp1 = foo(fv);
char *cp2 = foo(dv);
- // Note: GCC and EDG reject these two, but they are valid C99 conversions
- char *cp3 = foo(fc);
- char *cp4 = foo(dc);
+ // Note: GCC and EDG reject these two, they are valid C99 conversions but
+ // shouldn't be accepted in C++ because the result is surprising.
+ char *cp3 = foo(fc); // expected-error {{implicit conversion from '_Complex float' to 'float' is not permitted in C++}}
+ char *cp4 = foo(dc); // expected-error {{implicit conversion from '_Complex double' to 'float' is not permitted in C++}}
}
int *foo(float _Complex);
diff --git a/test/SemaCXX/constant-expression-cxx11.cpp b/test/SemaCXX/constant-expression-cxx11.cpp
index 3fda2d0a7fd0..51dd6199e63a 100644
--- a/test/SemaCXX/constant-expression-cxx11.cpp
+++ b/test/SemaCXX/constant-expression-cxx11.cpp
@@ -328,7 +328,7 @@ struct Str {
extern char externalvar[];
constexpr bool constaddress = (void *)externalvar == (void *)0x4000UL; // expected-error {{must be initialized by a constant expression}} expected-note {{reinterpret_cast}}
-constexpr bool litaddress = "foo" == "foo"; // expected-error {{must be initialized by a constant expression}} expected-warning {{unspecified}}
+constexpr bool litaddress = "foo" == "foo"; // expected-error {{must be initialized by a constant expression}}
static_assert(0 != "foo", "");
}
@@ -364,7 +364,7 @@ void foo() {
constexpr B b3 { { 1 }, { 2 } }; // expected-error {{constant expression}} expected-note {{reference to temporary}} expected-note {{here}}
}
-constexpr B &&b4 = ((1, 2), 3, 4, B { {10}, {{20}} }); // expected-warning 4{{unused}}
+constexpr B &&b4 = ((1, 2), 3, 4, B { {10}, {{20}} });
static_assert(&b4 != &b2, "");
// Proposed DR: copy-elision doesn't trigger lifetime extension.
@@ -604,6 +604,33 @@ static_assert(NATDCArray{}[1][1].n == 0, "");
}
+// Per current CWG direction, we reject any cases where pointer arithmetic is
+// not statically known to be valid.
+namespace ArrayOfUnknownBound {
+ extern int arr[];
+ constexpr int *a = arr;
+ constexpr int *b = &arr[0];
+ static_assert(a == b, "");
+ constexpr int *c = &arr[1]; // expected-error {{constant}} expected-note {{indexing of array without known bound}}
+ constexpr int *d = &a[1]; // expected-error {{constant}} expected-note {{indexing of array without known bound}}
+ constexpr int *e = a + 1; // expected-error {{constant}} expected-note {{indexing of array without known bound}}
+
+ struct X {
+ int a;
+ int b[]; // expected-warning {{C99}}
+ };
+ extern X x;
+ constexpr int *xb = x.b; // expected-error {{constant}} expected-note {{not supported}}
+
+ struct Y { int a; };
+ extern Y yarr[];
+ constexpr Y *p = yarr;
+ constexpr int *q = &p->a;
+
+ extern const int carr[]; // expected-note {{here}}
+ constexpr int n = carr[0]; // expected-error {{constant}} expected-note {{non-constexpr variable}}
+}
+
namespace DependentValues {
struct I { int n; typedef I V[10]; };
@@ -1904,6 +1931,22 @@ namespace Bitfields {
};
static_assert(X::f(3) == -1, "3 should truncate to -1");
}
+
+ struct HasUnnamedBitfield {
+ unsigned a;
+ unsigned : 20;
+ unsigned b;
+
+ constexpr HasUnnamedBitfield() : a(), b() {}
+ constexpr HasUnnamedBitfield(unsigned a, unsigned b) : a(a), b(b) {}
+ };
+
+ void testUnnamedBitfield() {
+ const HasUnnamedBitfield zero{};
+ int a = 1 / zero.b; // expected-warning {{division by zero is undefined}}
+ const HasUnnamedBitfield oneZero{1, 0};
+ int b = 1 / oneZero.b; // expected-warning {{division by zero is undefined}}
+ }
}
namespace ZeroSizeTypes {
@@ -1949,7 +1992,7 @@ namespace NeverConstantTwoWays {
constexpr int n = // expected-error {{must be initialized by a constant expression}}
(int *)(long)&n == &n ? // expected-note {{reinterpret_cast}}
- 1 / 0 : // expected-warning {{division by zero}}
+ 1 / 0 :
0;
}
diff --git a/test/SemaCXX/constant-expression-cxx1y.cpp b/test/SemaCXX/constant-expression-cxx1y.cpp
index 0c0cb0ec58a1..12fec0851691 100644
--- a/test/SemaCXX/constant-expression-cxx1y.cpp
+++ b/test/SemaCXX/constant-expression-cxx1y.cpp
@@ -988,3 +988,36 @@ constexpr void Void(int n) {
void();
}
constexpr int void_test = (Void(0), 1);
+
+namespace PR19741 {
+constexpr void addone(int &m) { m++; }
+
+struct S {
+ int m = 0;
+ constexpr S() { addone(m); }
+};
+constexpr bool evalS() {
+ constexpr S s;
+ return s.m == 1;
+}
+static_assert(evalS(), "");
+
+struct Nested {
+ struct First { int x = 42; };
+ union {
+ First first;
+ int second;
+ };
+ int x;
+ constexpr Nested(int x) : first(), x(x) { x = 4; }
+ constexpr Nested() : Nested(42) {
+ addone(first.x);
+ x = 3;
+ }
+};
+constexpr bool evalNested() {
+ constexpr Nested N;
+ return N.first.x == 43;
+}
+static_assert(evalNested(), "");
+} // namespace PR19741
diff --git a/test/SemaCXX/constant-expression-cxx2a.cpp b/test/SemaCXX/constant-expression-cxx2a.cpp
new file mode 100644
index 000000000000..935cbefc7cb9
--- /dev/null
+++ b/test/SemaCXX/constant-expression-cxx2a.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -std=c++2a -verify %s -fcxx-exceptions -triple=x86_64-linux-gnu
+
+namespace ThreeWayComparison {
+ struct A {
+ int n;
+ constexpr friend int operator<=>(const A &a, const A &b) {
+ return a.n < b.n ? -1 : a.n > b.n ? 1 : 0;
+ }
+ };
+ static_assert(A{1} <=> A{2} < 0);
+ static_assert(A{2} <=> A{1} > 0);
+ static_assert(A{2} <=> A{2} == 0);
+
+ // Note: not yet supported.
+ static_assert(1 <=> 2 < 0); // expected-error {{invalid operands}}
+ static_assert(2 <=> 1 > 0); // expected-error {{invalid operands}}
+ static_assert(1 <=> 1 == 0); // expected-error {{invalid operands}}
+ constexpr int k = (1 <=> 1, 0);
+ // expected-error@-1 {{constexpr variable 'k' must be initialized by a constant expression}}
+ // expected-warning@-2 {{three-way comparison result unused}}
+
+ constexpr void f() { // expected-error {{constant expression}}
+ void(1 <=> 1); // expected-note {{constant expression}}
+ }
+
+ // TODO: defaulted operator <=>
+}
diff --git a/test/SemaCXX/constexpr-array-unknown-bound.cpp b/test/SemaCXX/constexpr-array-unknown-bound.cpp
new file mode 100644
index 000000000000..395c4cbd127b
--- /dev/null
+++ b/test/SemaCXX/constexpr-array-unknown-bound.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 %s -Wno-uninitialized -std=c++1z -fsyntax-only -verify
+
+const extern int arr[];
+constexpr auto p = arr; // ok
+constexpr int f(int i) {return p[i];} // expected-note {{read of dereferenced one-past-the-end pointer}}
+
+constexpr int arr[] {1, 2, 3};
+constexpr auto p2 = arr + 2; // ok
+constexpr int x = f(2); // ok
+constexpr int y = f(3); // expected-error {{constant expression}}
+// expected-note-re@-1 {{in call to 'f({{.*}})'}}
+
+// FIXME: consider permitting this case
+struct A {int m[];} a;
+constexpr auto p3 = a.m; // expected-error {{constant expression}} expected-note {{without known bound}}
+constexpr auto p4 = a.m + 1; // expected-error {{constant expression}} expected-note {{without known bound}}
+
+void g(int i) {
+ int arr[i];
+ constexpr auto *p = arr + 2; // expected-error {{constant expression}} expected-note {{without known bound}}
+
+ // FIXME: Give a better diagnostic here. The issue is that computing
+ // sizeof(*arr2) within the array indexing fails due to the VLA.
+ int arr2[2][i];
+ constexpr int m = ((void)arr2[2], 0); // expected-error {{constant expression}}
+}
diff --git a/test/SemaCXX/coroutines.cpp b/test/SemaCXX/coroutines.cpp
index 6394829f356a..65e17abb11fe 100644
--- a/test/SemaCXX/coroutines.cpp
+++ b/test/SemaCXX/coroutines.cpp
@@ -66,6 +66,12 @@ struct suspend_never {
void await_resume() {}
};
+struct auto_await_suspend {
+ bool await_ready();
+ template <typename F> auto await_suspend(F) {}
+ void await_resume();
+};
+
struct DummyVoidTag {};
DummyVoidTag no_specialization() { // expected-error {{this function cannot be a coroutine: 'std::experimental::coroutine_traits<DummyVoidTag>' has no member named 'promise_type'}}
co_await a;
@@ -159,6 +165,10 @@ void yield() {
co_yield yield; // expected-error {{no member named 'await_ready' in 'not_awaitable'}}
}
+void check_auto_await_suspend() {
+ co_await auto_await_suspend{}; // Should compile successfully.
+}
+
void coreturn(int n) {
co_await a;
if (n == 0)
diff --git a/test/SemaCXX/cxx0x-compat.cpp b/test/SemaCXX/cxx0x-compat.cpp
index 8f7aaab6a438..b9ccadd85c2d 100644
--- a/test/SemaCXX/cxx0x-compat.cpp
+++ b/test/SemaCXX/cxx0x-compat.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -fsyntax-only -std=c++98 -Wc++11-compat -verify %s
-// RUN: %clang_cc1 -fsyntax-only -std=c++17 -Wc++11-compat -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++98 -Wc++11-compat-pedantic -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++17 -Wc++11-compat-pedantic -verify %s
#if __cplusplus < 201103L
@@ -52,4 +52,7 @@ static_assert(true); // expected-warning {{incompatible with C++ standards befor
template<int ...N> int f() { return (N + ...); } // expected-warning {{incompatible with C++ standards before C++17}}
+namespace [[]] NS_with_attr {} // expected-warning {{incompatible with C++ standards before C++17}}
+enum { e [[]] }; // expected-warning {{incompatible with C++ standards before C++17}}
+
#endif
diff --git a/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp b/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
index 9b8fadd2f522..860a4aa6c6ff 100644
--- a/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
+++ b/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
@@ -136,13 +136,19 @@ void auto_deduction() {
auto l3 {1};
static_assert(same_type<decltype(l), std::initializer_list<int>>::value, "");
static_assert(same_type<decltype(l3), int>::value, "");
- auto bl = {1, 2.0}; // expected-error {{cannot deduce}}
+ auto bl = {1, 2.0}; // expected-error {{deduced conflicting types ('int' vs 'double') for initializer list element type}}
+
+ void f1(int), f1(float), f2(int), f3(float);
+ auto fil = {f1, f2};
+ auto ffl = {f1, f3};
+ auto fl = {f1, f2, f3}; // expected-error {{deduced conflicting types ('void (*)(int)' vs 'void (*)(float)') for initializer list element type}}
for (int i : {1, 2, 3, 4}) {}
+ for (int j : {1.0, 2.0, 3.0f, 4.0}) {} // expected-error {{deduced conflicting types ('double' vs 'float') for initializer list element type}}
}
void dangle() {
- new auto{1, 2, 3}; // expected-error {{cannot use list-initialization}}
+ new auto{1, 2, 3}; // expected-error {{new expression for type 'auto' contains multiple constructor arguments}}
new std::initializer_list<int>{1, 2, 3}; // expected-warning {{at the end of the full-expression}}
}
diff --git a/test/SemaCXX/cxx11-ast-print.cpp b/test/SemaCXX/cxx11-ast-print.cpp
index 9c617af4e95f..17dcbcb3f7b0 100644
--- a/test/SemaCXX/cxx11-ast-print.cpp
+++ b/test/SemaCXX/cxx11-ast-print.cpp
@@ -55,4 +55,8 @@ struct B : A {
;
// CHECK-NOT: ;
+void g(int n) {
+ int buffer[n]; // CHECK: int buffer[n];
+ [&buffer]() {}(); // CHECK: [&buffer]
+}
diff --git a/test/SemaCXX/cxx17-compat.cpp b/test/SemaCXX/cxx17-compat.cpp
new file mode 100644
index 000000000000..3b814340c6da
--- /dev/null
+++ b/test/SemaCXX/cxx17-compat.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++17 -pedantic -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++2a -Wc++17-compat-pedantic -verify %s
+
+struct A {};
+int (A::*pa)() const&;
+int use_pa = (A().*pa)();
+#if __cplusplus <= 201703L
+ // expected-warning@-2 {{invoking a pointer to a 'const &' member function on an rvalue is a C++2a extension}}
+#else
+ // expected-warning@-4 {{invoking a pointer to a 'const &' member function on an rvalue is incompatible with C++ standards before C++2a}}
+#endif
+
+struct B {
+ void b() {
+ (void) [=, this] {};
+#if __cplusplus <= 201703L
+ // expected-warning@-2 {{explicit capture of 'this' with a capture default of '=' is a C++2a extension}}
+#else
+ // expected-warning@-4 {{explicit capture of 'this' with a capture default of '=' is incompatible with C++ standards before C++2a}}
+#endif
+ }
+
+ int n : 5 = 0;
+#if __cplusplus <= 201703L
+ // expected-warning@-2 {{default member initializer for bit-field is a C++2a extension}}
+#else
+ // expected-warning@-4 {{default member initializer for bit-field is incompatible with C++ standards before C++2a}}
+#endif
+};
diff --git a/test/SemaCXX/cxx1y-generic-lambdas-capturing.cpp b/test/SemaCXX/cxx1y-generic-lambdas-capturing.cpp
index dc3adca62fd3..eaed45acd11b 100644
--- a/test/SemaCXX/cxx1y-generic-lambdas-capturing.cpp
+++ b/test/SemaCXX/cxx1y-generic-lambdas-capturing.cpp
@@ -1380,3 +1380,145 @@ XT<int> xt{};
void PR33318(int i) {
[&](auto) { static_assert(&i != nullptr, ""); }(0); // expected-warning 2{{always true}} expected-note {{instantiation}}
}
+
+// Check to make sure that we don't capture when member-calls are made to members that are not of 'this' class.
+namespace PR34266 {
+// https://bugs.llvm.org/show_bug.cgi?id=34266
+namespace ns1 {
+struct A {
+ static void bar(int) { }
+ static void bar(double) { }
+};
+
+struct B
+{
+ template<class T>
+ auto f() {
+ auto L = [=] {
+ T{}.bar(3.0);
+ T::bar(3);
+
+ };
+ ASSERT_NO_CAPTURES(L);
+ return L;
+ };
+};
+
+void test() {
+ B{}.f<A>();
+}
+} // end ns1
+
+namespace ns2 {
+struct A {
+ static void bar(int) { }
+ static void bar(double) { }
+};
+
+struct B
+{
+ using T = A;
+ auto f() {
+ auto L = [=](auto a) {
+ T{}.bar(a);
+ T::bar(a);
+
+ };
+ ASSERT_NO_CAPTURES(L);
+ return L;
+ };
+};
+
+void test() {
+ B{}.f()(3.0);
+ B{}.f()(3);
+}
+} // end ns2
+
+namespace ns3 {
+struct A {
+ void bar(int) { }
+ static void bar(double) { }
+};
+
+struct B
+{
+ using T = A;
+ auto f() {
+ auto L = [=](auto a) {
+ T{}.bar(a);
+ T::bar(a); // This call ignores the instance member function because the implicit object argument fails to convert.
+
+ };
+ ASSERT_NO_CAPTURES(L);
+ return L;
+ };
+};
+
+void test() {
+ B{}.f()(3.0);
+ B{}.f()(3);
+}
+
+} // end ns3
+
+
+namespace ns4 {
+struct A {
+ void bar(int) { }
+ static void bar(double) { }
+};
+
+struct B : A
+{
+ using T = A;
+ auto f() {
+ auto L = [=](auto a) {
+ T{}.bar(a);
+ T::bar(a);
+
+ };
+ // just check to see if the size if >= 2 bytes (which should be the case if we capture anything)
+ ASSERT_CLOSURE_SIZE(L, 2);
+ return L;
+ };
+};
+
+void test() {
+ B{}.f()(3.0);
+ B{}.f()(3);
+}
+
+} // end ns4
+
+namespace ns5 {
+struct A {
+ void bar(int) { }
+ static void bar(double) { }
+};
+
+struct B
+{
+ template<class T>
+ auto f() {
+ auto L = [&](auto a) {
+ T{}.bar(a);
+ T::bar(a);
+
+ };
+
+ ASSERT_NO_CAPTURES(L);
+ return L;
+ };
+};
+
+void test() {
+ B{}.f<A>()(3.0);
+ B{}.f<A>()(3);
+}
+
+} // end ns5
+
+
+
+} // end PR34266
diff --git a/test/SemaCXX/cxx1y-generic-lambdas-variadics.cpp b/test/SemaCXX/cxx1y-generic-lambdas-variadics.cpp
index b0b86e387721..b8022d209122 100644
--- a/test/SemaCXX/cxx1y-generic-lambdas-variadics.cpp
+++ b/test/SemaCXX/cxx1y-generic-lambdas-variadics.cpp
@@ -98,3 +98,27 @@ namespace variadic_expansion {
}
#endif
+namespace PR33082 {
+ template<int ...I> void a() {
+ int arr[] = { [](auto ...K) { (void)I; } ... }; // expected-error {{no viable conversion}} expected-note {{candidate}}
+ }
+
+ template<typename ...T> struct Pack {};
+ template<typename ...T, typename ...U> void b(Pack<U...>, T ...t) {
+ int arr[] = {[t...]() { // expected-error 2{{cannot initialize an array element of type 'int' with}}
+ U u;
+ return u;
+ }()...};
+ }
+
+ void c() {
+ int arr[] = {[](auto... v) {
+ v; // expected-error {{unexpanded parameter pack 'v'}}
+ }...}; // expected-error {{pack expansion does not contain any unexpanded parameter packs}}
+ }
+
+ void run() {
+ a<1>(); // expected-note {{instantiation of}}
+ b(Pack<int*, float*>(), 1, 2, 3); // expected-note {{instantiation of}}
+ }
+}
diff --git a/test/SemaCXX/cxx1y-init-captures.cpp b/test/SemaCXX/cxx1y-init-captures.cpp
index d681954707d0..4b82452ed592 100644
--- a/test/SemaCXX/cxx1y-init-captures.cpp
+++ b/test/SemaCXX/cxx1y-init-captures.cpp
@@ -206,3 +206,11 @@ void test(double weight) {
find(weight); // expected-note {{in instantiation of function template specialization}}
}
}
+
+namespace init_capture_undeclared_identifier {
+ auto a = [x = y]{}; // expected-error{{use of undeclared identifier 'y'}}
+
+ int typo_foo; // expected-note 2 {{'typo_foo' declared here}}
+ auto b = [x = typo_boo]{}; // expected-error{{use of undeclared identifier 'typo_boo'; did you mean 'typo_foo'}}
+ auto c = [x(typo_boo)]{}; // expected-error{{use of undeclared identifier 'typo_boo'; did you mean 'typo_foo'}}
+}
diff --git a/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp b/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp
index 9232a8b6eba0..9080f67fe0e1 100644
--- a/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp
+++ b/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -std=c++1z -verify %s -DERRORS
-// RUN: %clang_cc1 -std=c++1z -verify %s -UERRORS
+// RUN: %clang_cc1 -std=c++1z -verify %s -DERRORS -Wundefined-func-template
+// RUN: %clang_cc1 -std=c++1z -verify %s -UERRORS -Wundefined-func-template
// This test is split into two because we only produce "undefined internal"
// warnings if we didn't produce any errors.
diff --git a/test/SemaCXX/cxx1z-copy-omission.cpp b/test/SemaCXX/cxx1z-copy-omission.cpp
index e2b8fd796174..a7133d79b463 100644
--- a/test/SemaCXX/cxx1z-copy-omission.cpp
+++ b/test/SemaCXX/cxx1z-copy-omission.cpp
@@ -2,11 +2,11 @@
struct Noncopyable {
Noncopyable();
- Noncopyable(const Noncopyable &) = delete; // expected-note 1+{{deleted}}
+ Noncopyable(const Noncopyable &) = delete; // expected-note 1+{{deleted}} expected-note 1+ {{not viable}}
virtual ~Noncopyable();
};
struct Derived : Noncopyable {};
-struct NoncopyableAggr {
+struct NoncopyableAggr { // expected-note 3{{candidate}}
Noncopyable nc;
};
struct Indestructible {
@@ -38,11 +38,39 @@ Noncopyable nrvo() {
Noncopyable nc1 = make();
Noncopyable nc2 = Noncopyable();
Noncopyable nc3 = Derived(); // expected-error {{deleted constructor}}
+Noncopyable nc4((Noncopyable()));
+Noncopyable nc5 = {Noncopyable()};
+Noncopyable nc6{Noncopyable()};
NoncopyableAggr nca1 = NoncopyableAggr{};
NoncopyableAggr nca2 = NoncopyableAggr{{}};
NoncopyableAggr nca3 = NoncopyableAggr{NoncopyableAggr{Noncopyable()}};
+template<typename T> struct Convert { operator T(); }; // expected-note 1+{{candidate}}
+Noncopyable conv1 = Convert<Noncopyable>();
+Noncopyable conv2((Convert<Noncopyable>()));
+Noncopyable conv3 = {Convert<Noncopyable>()};
+Noncopyable conv4{Convert<Noncopyable>()};
+
+Noncopyable ref_conv1 = Convert<Noncopyable&>(); // expected-error {{deleted constructor}}
+Noncopyable ref_conv2((Convert<Noncopyable&>())); // expected-error {{deleted constructor}}
+Noncopyable ref_conv3 = {Convert<Noncopyable&>()}; // expected-error {{deleted constructor}}
+Noncopyable ref_conv4{Convert<Noncopyable&>()}; // expected-error {{deleted constructor}}
+
+Noncopyable derived_conv1 = Convert<Derived>(); // expected-error {{deleted constructor}}
+Noncopyable derived_conv2((Convert<Derived>())); // expected-error {{deleted constructor}}
+Noncopyable derived_conv3 = {Convert<Derived>()}; // expected-error {{deleted constructor}}
+Noncopyable derived_conv4{Convert<Derived>()}; // expected-error {{deleted constructor}}
+
+NoncopyableAggr nc_aggr1 = Convert<NoncopyableAggr>();
+NoncopyableAggr nc_aggr2((Convert<NoncopyableAggr>()));
+NoncopyableAggr nc_aggr3 = {Convert<NoncopyableAggr>()}; // expected-error {{no viable conversion}}
+NoncopyableAggr nc_aggr4{Convert<NoncopyableAggr>()}; // expected-error {{no viable conversion}}
+NoncopyableAggr nc_aggr5 = Convert<Noncopyable>(); // expected-error {{no viable}}
+NoncopyableAggr nc_aggr6((Convert<Noncopyable>())); // expected-error {{no matching constructor}}
+NoncopyableAggr nc_aggr7 = {Convert<Noncopyable>()};
+NoncopyableAggr nc_aggr8{Convert<Noncopyable>()};
+
void test_expressions(bool b) {
auto lambda = [a = make()] {};
@@ -132,3 +160,12 @@ struct AsDelegating final {
// classes?
AsDelegating(int n) : AsDelegating(make(n)) {} // expected-error {{deleted}}
};
+
+namespace CtorTemplateBeatsNonTemplateConversionFn {
+ struct Foo { template <typename Derived> Foo(const Derived &); };
+ template <typename Derived> struct Base { operator Foo() const = delete; }; // expected-note {{deleted}}
+ struct Derived : Base<Derived> {};
+
+ Foo f(Derived d) { return d; } // expected-error {{invokes a deleted function}}
+ Foo g(Derived d) { return Foo(d); } // ok, calls constructor
+}
diff --git a/test/SemaCXX/cxx1z-init-statement-template.cpp b/test/SemaCXX/cxx1z-init-statement-template.cpp
new file mode 100644
index 000000000000..cedd2c720d90
--- /dev/null
+++ b/test/SemaCXX/cxx1z-init-statement-template.cpp
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -std=c++1z -verify -emit-llvm-only %s
+// expected-no-diagnostics
+
+// rdar://problem/33888545
+template <unsigned int BUFFER_SIZE> class Buffer {};
+
+class A {
+public:
+ int status;
+};
+
+template <unsigned int N> A parse(Buffer<N> buffer);
+
+template<unsigned int N>
+void init_in_if(Buffer<N> buffer) {
+ if (A a = parse(buffer); a.status > 0) {
+ }
+}
+
+template<unsigned int N>
+void init_in_switch(Buffer<N> buffer) {
+ switch (A a = parse(buffer); a.status) {
+ default:
+ break;
+ }
+}
+
+void test() {
+ Buffer<10> buffer;
+ init_in_if(buffer);
+ init_in_switch(buffer);
+}
diff --git a/test/SemaCXX/cxx1z-noexcept-function-type.cpp b/test/SemaCXX/cxx1z-noexcept-function-type.cpp
index 6578eb89b0ba..814b04c6e42f 100644
--- a/test/SemaCXX/cxx1z-noexcept-function-type.cpp
+++ b/test/SemaCXX/cxx1z-noexcept-function-type.cpp
@@ -1,5 +1,5 @@
// RUN: %clang_cc1 -std=c++14 -verify -fexceptions -fcxx-exceptions %s
-// RUN: %clang_cc1 -std=c++1z -verify -fexceptions -fcxx-exceptions %s -Wno-dynamic-exception-spec
+// RUN: %clang_cc1 -std=c++17 -verify -fexceptions -fcxx-exceptions %s -Wno-dynamic-exception-spec
// RUN: %clang_cc1 -std=c++14 -verify -fexceptions -fcxx-exceptions -Wno-c++1z-compat-mangling -DNO_COMPAT_MANGLING %s
// RUN: %clang_cc1 -std=c++14 -verify -fexceptions -fcxx-exceptions -Wno-noexcept-type -DNO_COMPAT_MANGLING %s
diff --git a/test/SemaCXX/cxx2a-destroying-delete.cpp b/test/SemaCXX/cxx2a-destroying-delete.cpp
new file mode 100644
index 000000000000..6115774e3836
--- /dev/null
+++ b/test/SemaCXX/cxx2a-destroying-delete.cpp
@@ -0,0 +1,122 @@
+// RUN: %clang_cc1 -std=c++2a -verify %s
+
+namespace std {
+ using size_t = decltype(sizeof(0));
+ enum class align_val_t : size_t;
+
+ struct destroying_delete_t {
+ struct __construct { explicit __construct() = default; };
+ explicit destroying_delete_t(__construct) {}
+ };
+
+ inline constexpr destroying_delete_t destroying_delete(destroying_delete_t::__construct());
+}
+
+void operator delete(void*, std::destroying_delete_t); // ok, just a placement delete
+
+struct A;
+void operator delete(A*, std::destroying_delete_t); // expected-error {{first parameter of 'operator delete' must have type 'void *'}}
+
+struct A {
+ void operator delete(A*, std::destroying_delete_t);
+ void operator delete(A*, std::destroying_delete_t, std::size_t);
+ void operator delete(A*, std::destroying_delete_t, std::align_val_t);
+ void operator delete(A*, std::destroying_delete_t, std::size_t, std::align_val_t);
+ void operator delete(A*, std::destroying_delete_t, int); // expected-error {{destroying operator delete can have only an optional size and optional alignment parameter}}
+ // FIXME: It's probably a language defect that we permit usual operator delete to be variadic.
+ void operator delete(A*, std::destroying_delete_t, std::size_t, ...);
+
+ void operator delete(struct X*, std::destroying_delete_t, std::size_t, ...); // expected-error {{first parameter of 'operator delete' must have type 'A *'}}
+
+ void operator delete(void*, std::size_t);
+};
+
+void delete_A(A *a) { delete a; }
+
+namespace convert_param {
+ struct A {
+ void operator delete(
+ A*,
+ std::destroying_delete_t);
+ };
+ struct B : private A { using A::operator delete; }; // expected-note 2{{declared private here}}
+ struct C : B {};
+ void delete_C(C *c) { delete c; } // expected-error {{cannot cast 'convert_param::C' to its private base class 'convert_param::A'}}
+
+ // expected-error@-7 {{cannot cast 'convert_param::D' to its private base class 'convert_param::A'}}
+ struct D : B { virtual ~D() {} }; // expected-note {{while checking implicit 'delete this' for virtual destructor}}
+}
+
+namespace delete_selection {
+ struct B {
+ void operator delete(void*) = delete;
+ void operator delete(B *, std::destroying_delete_t) = delete; // expected-note {{deleted}}
+ };
+ void delete_B(B *b) { delete b; } // expected-error {{deleted}}
+
+ struct C {
+ C();
+ void *operator new(std::size_t);
+ void operator delete(void*) = delete;
+ void operator delete(C *, std::destroying_delete_t) = delete;
+ };
+ // FIXME: This should be ill-formed, but we incorrectly decide that overload
+ // resolution failed (because it selected a deleted function) and thus no
+ // 'operator delete' should be called.
+ C *new_C() { return new C; }
+
+ struct D {
+ void operator delete(D *, std::destroying_delete_t) = delete; // expected-note {{deleted}}
+ void operator delete(D *, std::destroying_delete_t, std::align_val_t) = delete;
+ };
+ void delete_D(D *d) { delete d; } // expected-error {{deleted}}
+
+ struct alignas(__STDCPP_DEFAULT_NEW_ALIGNMENT__ * 2) E {
+ void operator delete(E *, std::destroying_delete_t) = delete;
+ void operator delete(E *, std::destroying_delete_t, std::align_val_t) = delete; // expected-note {{deleted}}
+ };
+ void delete_E(E *e) { delete e; } // expected-error {{deleted}}
+
+ struct F {
+ void operator delete(F *, std::destroying_delete_t) = delete; // expected-note {{deleted}}
+ void operator delete(F *, std::destroying_delete_t, std::size_t) = delete;
+ };
+ void delete_F(F *f) { delete f; } // expected-error {{deleted}}
+
+ struct G {
+ void operator delete(G *, std::destroying_delete_t, std::align_val_t) = delete;
+ void operator delete(G *, std::destroying_delete_t, std::size_t) = delete; // expected-note {{deleted}}
+ };
+ void delete_G(G *g) { delete g; } // expected-error {{deleted}}
+
+ struct H {
+ void operator delete(H *, std::destroying_delete_t, std::align_val_t) = delete; // expected-note {{deleted}}
+ void operator delete(H *, std::destroying_delete_t, std::size_t, std::align_val_t) = delete;
+ };
+ void delete_H(H *h) { delete h; } // expected-error {{deleted}}
+
+ struct alignas(__STDCPP_DEFAULT_NEW_ALIGNMENT__ * 2) I {
+ void operator delete(I *, std::destroying_delete_t, std::size_t) = delete;
+ void operator delete(I *, std::destroying_delete_t, std::size_t, std::align_val_t) = delete; // expected-note {{deleted}}
+ };
+ void delete_I(I *i) { delete i; } // expected-error {{deleted}}
+}
+
+namespace first_param_conversion {
+ struct A {
+ void operator delete(A *, std::destroying_delete_t);
+ };
+ void f(const volatile A *a) {
+ delete a; // ok
+ }
+
+ struct B {
+ void operator delete(B *, std::destroying_delete_t);
+ };
+ struct C : B {};
+ struct D : B {};
+ struct E : C, D {};
+ void g(E *e) {
+ delete e; // expected-error {{ambiguous conversion from derived class 'first_param_conversion::E' to base class 'first_param_conversion::B':}}
+ }
+}
diff --git a/test/SemaCXX/cxx2a-lambda-equals-this.cpp b/test/SemaCXX/cxx2a-lambda-equals-this.cpp
new file mode 100644
index 000000000000..ce6916322e5d
--- /dev/null
+++ b/test/SemaCXX/cxx2a-lambda-equals-this.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -std=c++2a -verify %s
+// expected-no-diagnostics
+
+// This test does two things.
+// Deleting the copy constructor ensures that an [=, this] capture doesn't copy the object.
+// Accessing a member variable from the lambda ensures that the capture actually works.
+class A {
+ A(const A &) = delete;
+ int i;
+
+ void func() {
+ auto L = [=, this]() -> int { return i; };
+ L();
+ }
+};
diff --git a/test/SemaCXX/cxx2a-pointer-to-const-ref-member.cpp b/test/SemaCXX/cxx2a-pointer-to-const-ref-member.cpp
new file mode 100644
index 000000000000..e9cbb1a18532
--- /dev/null
+++ b/test/SemaCXX/cxx2a-pointer-to-const-ref-member.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -std=c++2a %s -verify
+
+struct X {
+ void ref() & {}
+ void cref() const& {}
+};
+
+void test() {
+ X{}.ref(); // expected-error{{cannot initialize object parameter of type 'X' with an expression of type 'X'}}
+ X{}.cref(); // expected-no-error
+
+ (X{}.*&X::ref)(); // expected-error-re{{pointer-to-member function type 'void (X::*)() {{.*}}&' can only be called on an lvalue}}
+ (X{}.*&X::cref)(); // expected-no-error
+}
diff --git a/test/SemaCXX/cxx2a-three-way-comparison.cpp b/test/SemaCXX/cxx2a-three-way-comparison.cpp
new file mode 100644
index 000000000000..eb1480ce6102
--- /dev/null
+++ b/test/SemaCXX/cxx2a-three-way-comparison.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -std=c++2a -verify %s
+
+struct A {};
+constexpr int operator<=>(A a, A b) { return 42; }
+static_assert(operator<=>(A(), A()) == 42);
+
+int operator<=>(); // expected-error {{overloaded 'operator<=>' must have at least one parameter of class or enumeration type}}
+int operator<=>(A); // expected-error {{overloaded 'operator<=>' must be a binary operator}}
+int operator<=>(int, int); // expected-error {{overloaded 'operator<=>' must have at least one parameter of class or enumeration type}}
+int operator<=>(A, A, A); // expected-error {{overloaded 'operator<=>' must be a binary operator}}
+int operator<=>(A, A, ...); // expected-error {{overloaded 'operator<=>' cannot be variadic}}
+int operator<=>(int, A = {}); // expected-error {{parameter of overloaded 'operator<=>' cannot have a default argument}}
+
+struct B {
+ int &operator<=>(int);
+ friend int operator<=>(A, B);
+
+ friend int operator<=>(int, int); // expected-error {{overloaded 'operator<=>' must have at least one parameter of class or enumeration type}}
+ void operator<=>(); // expected-error {{overloaded 'operator<=>' must be a binary operator}};
+ void operator<=>(A, ...); // expected-error {{overloaded 'operator<=>' cannot be variadic}}
+ void operator<=>(A, A); // expected-error {{overloaded 'operator<=>' must be a binary operator}};
+};
+
+int &r = B().operator<=>(0);
diff --git a/test/SemaCXX/cxx98-compat-flags.cpp b/test/SemaCXX/cxx98-compat-flags.cpp
index 62d687c49cf7..5e0796433534 100644
--- a/test/SemaCXX/cxx98-compat-flags.cpp
+++ b/test/SemaCXX/cxx98-compat-flags.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -fsyntax-only -std=c++11 -Wc++98-compat-pedantic -verify %s
-// RUN: %clang_cc1 -fsyntax-only -std=c++11 -Wc++98-compat-pedantic -Wno-bind-to-temporary-copy -Wno-unnamed-type-template-args -Wno-local-type-template-args -Werror %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++17 -Wc++98-compat-pedantic -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++17 -Wc++98-compat-pedantic -Wno-bind-to-temporary-copy -Wno-unnamed-type-template-args -Wno-local-type-template-args -Wno-binary-literal -Werror %s
template<typename T> int TemplateFn(T) { return 0; }
void LocalTemplateArg() {
@@ -32,4 +32,6 @@ namespace CopyCtorIssues {
const NoViable &b = NoViable(); // expected-warning {{copying variable of type 'CopyCtorIssues::NoViable' when binding a reference to a temporary would find no viable constructor in C++98}}
const Ambiguous &c = Ambiguous(); // expected-warning {{copying variable of type 'CopyCtorIssues::Ambiguous' when binding a reference to a temporary would find ambiguous constructors in C++98}}
const Deleted &d = Deleted(); // expected-warning {{copying variable of type 'CopyCtorIssues::Deleted' when binding a reference to a temporary would invoke a deleted constructor in C++98}}
+
+ int n = 0b00100101001; // expected-warning {{binary integer literals are incompatible with C++ standards before C++14}}
}
diff --git a/test/SemaCXX/decl-expr-ambiguity.cpp b/test/SemaCXX/decl-expr-ambiguity.cpp
index 1b1f7dc8a70e..1e31d701d0c1 100644
--- a/test/SemaCXX/decl-expr-ambiguity.cpp
+++ b/test/SemaCXX/decl-expr-ambiguity.cpp
@@ -48,13 +48,20 @@ void f() {
struct RAII {
RAII();
+ RAII(int);
~RAII();
};
+struct NotRAII {
+ NotRAII();
+ NotRAII(int);
+};
+
void func();
void func2(short);
namespace N {
struct S;
+ int n;
void emptyParens() {
RAII raii(); // expected-warning {{function declaration}} expected-note {{remove parentheses to declare a variable}}
@@ -69,6 +76,23 @@ namespace N {
void nonEmptyParens() {
int f = 0, // g = 0; expected-note {{change this ',' to a ';' to call 'func2'}}
func2(short(f)); // expected-warning {{function declaration}} expected-note {{add a pair of parentheses}}
+
+ RAII(n); // expected-warning {{parentheses were disambiguated as redundant parentheses around declaration of variable named 'n'}}
+ // expected-note@-1 {{add a variable name to declare a 'RAII' initialized with 'n'}}
+ // expected-note@-2 {{add enclosing parentheses to perform a function-style cast}}
+ // expected-note@-3 {{remove parentheses to silence this warning}}
+
+ RAII(undeclared1);
+#pragma clang diagnostic push
+#pragma clang diagnostic warning "-Wredundant-parens"
+ RAII(undeclared2); // expected-warning {{redundant parentheses surrounding declarator}}
+#pragma clang diagnostic pop
+
+ {
+ NotRAII(n); // expected-warning {{parentheses were disambiguated as redundant parentheses around declaration of variable named 'n'}}
+ // expected-note@-1 {{add enclosing parentheses to perform a function-style cast}}
+ // expected-note@-2 {{remove parentheses to silence this warning}}
+ }
}
}
diff --git a/test/SemaCXX/decomposed-condition.cpp b/test/SemaCXX/decomposed-condition.cpp
new file mode 100644
index 000000000000..ab011f6ae4ba
--- /dev/null
+++ b/test/SemaCXX/decomposed-condition.cpp
@@ -0,0 +1,99 @@
+// RUN: %clang_cc1 -std=c++1z -Wno-binding-in-condition -verify %s
+
+struct X {
+ bool flag;
+ int data;
+ constexpr explicit operator bool() const {
+ return flag;
+ }
+ constexpr operator int() const {
+ return data;
+ }
+};
+
+namespace CondInIf {
+constexpr int f(X x) {
+ if (auto [ok, d] = x)
+ return d + int(ok);
+ else
+ return d * int(ok);
+ ok = {}; // expected-error {{use of undeclared identifier 'ok'}}
+ d = {}; // expected-error {{use of undeclared identifier 'd'}}
+}
+
+static_assert(f({true, 2}) == 3);
+static_assert(f({false, 2}) == 0);
+
+constexpr char g(char const (&x)[2]) {
+ if (auto &[a, b] = x)
+ return a;
+ else
+ return b;
+
+ if (auto [a, b] = x) // expected-error {{an array type is not allowed here}}
+ ;
+}
+
+static_assert(g("x") == 'x');
+} // namespace CondInIf
+
+namespace CondInSwitch {
+constexpr int f(int n) {
+ switch (X s = {true, n}; auto [ok, d] = s) {
+ s = {};
+ case 0:
+ return int(ok);
+ case 1:
+ return d * 10;
+ case 2:
+ return d * 40;
+ default:
+ return 0;
+ }
+ ok = {}; // expected-error {{use of undeclared identifier 'ok'}}
+ d = {}; // expected-error {{use of undeclared identifier 'd'}}
+ s = {}; // expected-error {{use of undeclared identifier 's'}}
+}
+
+static_assert(f(0) == 1);
+static_assert(f(1) == 10);
+static_assert(f(2) == 80);
+} // namespace CondInSwitch
+
+namespace CondInWhile {
+constexpr int f(int n) {
+ int m = 1;
+ while (auto [ok, d] = X{n > 1, n}) {
+ m *= d;
+ --n;
+ }
+ return m;
+ return ok; // expected-error {{use of undeclared identifier 'ok'}}
+}
+
+static_assert(f(0) == 1);
+static_assert(f(1) == 1);
+static_assert(f(4) == 24);
+} // namespace CondInWhile
+
+namespace CondInFor {
+constexpr int f(int n) {
+ int a = 1, b = 1;
+ for (X x = {true, n}; auto &[ok, d] = x; --d) {
+ if (d < 2)
+ ok = false;
+ else {
+ int x = b;
+ b += a;
+ a = x;
+ }
+ }
+ return b;
+ return d; // expected-error {{use of undeclared identifier 'd'}}
+}
+
+static_assert(f(0) == 1);
+static_assert(f(1) == 1);
+static_assert(f(2) == 2);
+static_assert(f(5) == 8);
+} // namespace CondInFor
diff --git a/test/SemaCXX/deleted-operator.cpp b/test/SemaCXX/deleted-operator.cpp
index f71e83aa2587..64b2b22e5661 100644
--- a/test/SemaCXX/deleted-operator.cpp
+++ b/test/SemaCXX/deleted-operator.cpp
@@ -8,8 +8,8 @@ struct PR10757 {
int PR10757f() {
PR10757 a1;
// FIXME: We get a ridiculous number of "built-in candidate" notes here...
- if(~a1) {} // expected-error {{overload resolution selected deleted operator}} expected-note 8 {{built-in candidate}}
- if(a1==a1) {} // expected-error {{overload resolution selected deleted operator}} expected-note 144 {{built-in candidate}}
+ if(~a1) {} // expected-error {{overload resolution selected deleted operator}} expected-note 6-8 {{built-in candidate}}
+ if(a1==a1) {} // expected-error {{overload resolution selected deleted operator}} expected-note 1-144 {{built-in candidate}}
}
struct DelOpDel {
diff --git a/test/SemaCXX/deprecated.cpp b/test/SemaCXX/deprecated.cpp
index 26f30c91b098..773085bf2b96 100644
--- a/test/SemaCXX/deprecated.cpp
+++ b/test/SemaCXX/deprecated.cpp
@@ -20,7 +20,12 @@ void i() throw(...);
// expected-warning@-8 {{dynamic exception specifications are deprecated}} expected-note@-8 {{use 'noexcept(false)' instead}}
#endif
-void stuff() {
+void stuff(register int q) {
+#if __cplusplus > 201402L
+ // expected-error@-2 {{ISO C++17 does not allow 'register' storage class specifier}}
+#elif __cplusplus >= 201103L && !defined(NO_DEPRECATED_FLAGS)
+ // expected-warning@-4 {{'register' storage class specifier is deprecated}}
+#endif
register int n;
#if __cplusplus > 201402L
// expected-error@-2 {{ISO C++17 does not allow 'register' storage class specifier}}
@@ -93,3 +98,6 @@ namespace DeprecatedCopy {
void g() { c1 = c2; } // expected-note {{implicit copy assignment operator for 'DeprecatedCopy::Dtor' first required here}}
}
#endif
+
+# 1 "/usr/include/system-header.h" 1 3
+void system_header_function(void) throw();
diff --git a/test/SemaCXX/destructor.cpp b/test/SemaCXX/destructor.cpp
index 49cdc50f3c13..00d2fc552978 100644
--- a/test/SemaCXX/destructor.cpp
+++ b/test/SemaCXX/destructor.cpp
@@ -1,5 +1,36 @@
// RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -fsyntax-only -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -fcxx-exceptions -verify %s
// RUN: %clang_cc1 -std=c++11 -triple %ms_abi_triple -DMSABI -fsyntax-only -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -verify %s
+
+#if defined(BE_THE_HEADER)
+
+// Wdelete-non-virtual-dtor should warn about the delete from smart pointer
+// classes in system headers (std::unique_ptr...) too.
+
+#pragma clang system_header
+namespace dnvd {
+
+struct SystemB {
+ virtual void foo();
+};
+
+template <typename T>
+class simple_ptr {
+public:
+ simple_ptr(T* t): _ptr(t) {}
+ ~simple_ptr() { delete _ptr; } // \
+ // expected-warning {{delete called on non-final 'dnvd::B' that has virtual functions but non-virtual destructor}} \
+ // expected-warning {{delete called on non-final 'dnvd::D' that has virtual functions but non-virtual destructor}}
+ T& operator*() const { return *_ptr; }
+private:
+ T* _ptr;
+};
+}
+
+#else
+
+#define BE_THE_HEADER
+#include __FILE__
+
class A {
public:
~A();
@@ -213,18 +244,6 @@ struct VD: VB {};
struct VF final: VB {};
template <typename T>
-class simple_ptr {
-public:
- simple_ptr(T* t): _ptr(t) {}
- ~simple_ptr() { delete _ptr; } // \
- // expected-warning {{delete called on non-final 'dnvd::B' that has virtual functions but non-virtual destructor}} \
- // expected-warning {{delete called on non-final 'dnvd::D' that has virtual functions but non-virtual destructor}}
- T& operator*() const { return *_ptr; }
-private:
- T* _ptr;
-};
-
-template <typename T>
class simple_ptr2 {
public:
simple_ptr2(T* t): _ptr(t) {}
@@ -235,6 +254,7 @@ private:
};
void use(B&);
+void use(SystemB&);
void use(VB&);
void nowarnstack() {
@@ -335,10 +355,28 @@ void warn0() {
}
}
+// Taken from libc++, slightly simplified.
+template <class>
+struct __is_destructible_apply { typedef int type; };
+struct __two {char __lx[2];};
+template <typename _Tp>
+struct __is_destructor_wellformed {
+ template <typename _Tp1>
+ static char __test(typename __is_destructible_apply<
+ decltype(_Tp1().~_Tp1())>::type);
+ template <typename _Tp1>
+ static __two __test (...);
+
+ static const bool value = sizeof(__test<_Tp>(12)) == sizeof(char);
+};
+
void warn0_explicit_dtor(B* b, B& br, D* d) {
b->~B(); // expected-warning {{destructor called on non-final 'dnvd::B' that has virtual functions but non-virtual destructor}} expected-note{{qualify call to silence this warning}}
b->B::~B(); // No warning when the call isn't virtual.
+ // No warning in unevaluated contexts.
+ (void)__is_destructor_wellformed<B>::value;
+
br.~B(); // expected-warning {{destructor called on non-final 'dnvd::B' that has virtual functions but non-virtual destructor}} expected-note{{qualify call to silence this warning}}
br.B::~B();
@@ -367,6 +405,10 @@ void nowarn1() {
simple_ptr<VF> vf(new VF());
use(*vf);
}
+ {
+ simple_ptr<SystemB> sb(new SystemB());
+ use(*sb);
+ }
}
void warn1() {
@@ -451,3 +493,4 @@ void foo1() {
x.foo1();
}
}
+#endif // BE_THE_HEADER
diff --git a/test/SemaCXX/dllexport.cpp b/test/SemaCXX/dllexport.cpp
index a3fed70ec958..c09a531c19b7 100644
--- a/test/SemaCXX/dllexport.cpp
+++ b/test/SemaCXX/dllexport.cpp
@@ -17,18 +17,18 @@ struct External { int v; };
// Invalid usage.
__declspec(dllexport) typedef int typedef1;
-// expected-warning@-1{{'dllexport' attribute only applies to variables, functions and classes}}
+// expected-warning@-1{{'dllexport' attribute only applies to functions, variables, classes, and Objective-C interfaces}}
typedef __declspec(dllexport) int typedef2;
-// expected-warning@-1{{'dllexport' attribute only applies to variables, functions and classes}}
+// expected-warning@-1{{'dllexport' attribute only applies to}}
typedef int __declspec(dllexport) typedef3;
-// expected-warning@-1{{'dllexport' attribute only applies to variables, functions and classes}}
+// expected-warning@-1{{'dllexport' attribute only applies to}}
typedef __declspec(dllexport) void (*FunTy)();
-// expected-warning@-1{{'dllexport' attribute only applies to variables, functions and classes}}
+// expected-warning@-1{{'dllexport' attribute only applies to}}
enum __declspec(dllexport) Enum {};
-// expected-warning@-1{{'dllexport' attribute only applies to variables, functions and classes}}
+// expected-warning@-1{{'dllexport' attribute only applies to}}
#if __has_feature(cxx_strong_enums)
enum class __declspec(dllexport) EnumClass {};
-// expected-warning@-1{{'dllexport' attribute only applies to variables, functions and classes}}
+// expected-warning@-1{{'dllexport' attribute only applies to}}
#endif
@@ -565,7 +565,7 @@ private:
__declspec(dllexport) void privateDef();
public:
- __declspec(dllexport) int Field; // expected-warning{{'dllexport' attribute only applies to variables, functions and classes}}
+ __declspec(dllexport) int Field; // expected-warning{{'dllexport' attribute only applies to}}
__declspec(dllexport) static int StaticField;
__declspec(dllexport) static int StaticFieldDef;
__declspec(dllexport) static const int StaticConstField;
@@ -977,7 +977,7 @@ private:
__declspec(dllexport) void privateDef();
public:
- __declspec(dllexport) int Field; // expected-warning{{'dllexport' attribute only applies to variables, functions and classes}}
+ __declspec(dllexport) int Field; // expected-warning{{'dllexport' attribute only applies to}}
__declspec(dllexport) static int StaticField;
__declspec(dllexport) static int StaticFieldDef;
__declspec(dllexport) static const int StaticConstField;
diff --git a/test/SemaCXX/dllimport.cpp b/test/SemaCXX/dllimport.cpp
index 1c59ccad6e14..04c33e9fb5c8 100644
--- a/test/SemaCXX/dllimport.cpp
+++ b/test/SemaCXX/dllimport.cpp
@@ -16,18 +16,18 @@ namespace { struct Internal {}; }
// Invalid usage.
__declspec(dllimport) typedef int typedef1;
-// expected-warning@-1{{'dllimport' attribute only applies to variables, functions and classes}}
+// expected-warning@-1{{'dllimport' attribute only applies to functions, variables, classes, and Objective-C interfaces}}
typedef __declspec(dllimport) int typedef2;
-// expected-warning@-1{{'dllimport' attribute only applies to variables, functions and classes}}
+// expected-warning@-1{{'dllimport' attribute only applies to}}
typedef int __declspec(dllimport) typedef3;
-// expected-warning@-1{{'dllimport' attribute only applies to variables, functions and classes}}
+// expected-warning@-1{{'dllimport' attribute only applies to}}
typedef __declspec(dllimport) void (*FunTy)();
-// expected-warning@-1{{'dllimport' attribute only applies to variables, functions and classes}}
+// expected-warning@-1{{'dllimport' attribute only applies to}}
enum __declspec(dllimport) Enum {};
-// expected-warning@-1{{'dllimport' attribute only applies to variables, functions and classes}}
+// expected-warning@-1{{'dllimport' attribute only applies to}}
#if __has_feature(cxx_strong_enums)
enum class __declspec(dllimport) EnumClass {};
-// expected-warning@-1{{'dllimport' attribute only applies to variables, functions and classes}}
+// expected-warning@-1{{'dllimport' attribute only applies to}}
#endif
@@ -574,7 +574,7 @@ private:
__declspec(dllimport) void privateDecl();
public:
- __declspec(dllimport) int Field; // expected-warning{{'dllimport' attribute only applies to variables, functions and classes}}
+ __declspec(dllimport) int Field; // expected-warning{{'dllimport' attribute only applies to}}
__declspec(dllimport) static int StaticField;
__declspec(dllimport) static int StaticFieldDef; // expected-note{{attribute is here}}
__declspec(dllimport) static const int StaticConstField;
@@ -1147,7 +1147,7 @@ private:
__declspec(dllimport) void privateDecl();
public:
- __declspec(dllimport) int Field; // expected-warning{{'dllimport' attribute only applies to variables, functions and classes}}
+ __declspec(dllimport) int Field; // expected-warning{{'dllimport' attribute only applies to}}
__declspec(dllimport) static int StaticField;
__declspec(dllimport) static int StaticFieldDef; // expected-note{{attribute is here}}
__declspec(dllimport) static const int StaticConstField;
diff --git a/test/SemaCXX/enum-scoped.cpp b/test/SemaCXX/enum-scoped.cpp
index 3114bca9347d..1fcafb1dd0fd 100644
--- a/test/SemaCXX/enum-scoped.cpp
+++ b/test/SemaCXX/enum-scoped.cpp
@@ -309,3 +309,8 @@ namespace test11 {
bool f() { return !f1(); } // expected-error {{invalid argument type 'test11::E2' (aka 'test11::E') to unary expression}}
}
+
+namespace PR35586 {
+ enum C { R, G, B };
+ enum B { F = (enum C) -1, T}; // this should compile cleanly, it used to assert.
+};
diff --git a/test/SemaCXX/enum.cpp b/test/SemaCXX/enum.cpp
index 6b0824b75144..cfe5760112f6 100644
--- a/test/SemaCXX/enum.cpp
+++ b/test/SemaCXX/enum.cpp
@@ -110,3 +110,13 @@ enum { overflow = 123456 * 234567 };
// expected-warning@-2 {{not an integral constant expression}}
// expected-note@-3 {{value 28958703552 is outside the range of representable values}}
#endif
+
+// PR28903
+struct PR28903 {
+ enum {
+ PR28903_A = (enum { // expected-error-re {{'PR28903::(anonymous enum at {{.*}})' cannot be defined in an enumeration}}
+ PR28903_B,
+ PR28903_C = PR28903_B
+ })
+ };
+};
diff --git a/test/SemaCXX/flexible-array-test.cpp b/test/SemaCXX/flexible-array-test.cpp
index 2d74fa52452e..f2105ca36130 100644
--- a/test/SemaCXX/flexible-array-test.cpp
+++ b/test/SemaCXX/flexible-array-test.cpp
@@ -66,6 +66,11 @@ union B {
char c[];
};
+class C {
+ char c[]; // expected-error {{flexible array member 'c' with type 'char []' is not at the end of class}}
+ int s; // expected-note {{next field declaration is here}}
+};
+
namespace rdar9065507 {
struct StorageBase {
diff --git a/test/SemaCXX/has_unique_object_reps_member_ptr.cpp b/test/SemaCXX/has_unique_object_reps_member_ptr.cpp
new file mode 100644
index 000000000000..b8e27f82ff38
--- /dev/null
+++ b/test/SemaCXX/has_unique_object_reps_member_ptr.cpp
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -triple x86_64-linux-pc -DIS64 -fsyntax-only -verify -std=c++17 %s
+// RUN: %clang_cc1 -triple x86_64-windows-pc -DIS64 -fsyntax-only -verify -std=c++17 %s
+// RUN: %clang_cc1 -triple i386-linux-pc -fsyntax-only -verify -std=c++17 %s
+// RUN: %clang_cc1 -triple i386-windows-pc -DW32 -fsyntax-only -verify -std=c++17 %s
+// expected-no-diagnostics
+
+struct Base {};
+struct A : virtual Base {
+ virtual void n() {}
+};
+
+auto p = &A::n;
+static_assert(__has_unique_object_representations(decltype(p)));
+
+struct B {
+ decltype(p) x;
+ int b;
+#ifdef IS64
+ // required on 64 bit to fill out the tail padding.
+ int c;
+#endif
+};
+static_assert(__has_unique_object_representations(B));
+
+struct C { // has padding on Win32, but nothing else.
+ decltype(p) x;
+};
+#ifdef W32
+static_assert(!__has_unique_object_representations(C));
+#else
+static_assert(__has_unique_object_representations(C));
+#endif
diff --git a/test/SemaCXX/imaginary-constants.cpp b/test/SemaCXX/imaginary-constants.cpp
new file mode 100644
index 000000000000..bbff92755a1f
--- /dev/null
+++ b/test/SemaCXX/imaginary-constants.cpp
@@ -0,0 +1,44 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -include %s -std=gnu++98
+// RUN: %clang_cc1 -fsyntax-only -verify %s -include %s -std=c++11
+// RUN: %clang_cc1 -fsyntax-only -verify %s -include %s -std=c++14 -DCXX14=1
+
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+
+_Complex int val1 = 2i;
+_Complex long val2 = 2il;
+_Complex long long val3 = 2ill;
+_Complex float val4 = 2.0if;
+_Complex double val5 = 2.0i;
+_Complex long double val6 = 2.0il;
+
+#if CXX14
+
+#pragma clang system_header
+
+namespace std {
+ template<typename T> struct complex {};
+ complex<float> operator""if(unsigned long long);
+ complex<float> operator""if(long double);
+
+ complex<double> operator"" i(unsigned long long);
+ complex<double> operator"" i(long double);
+
+ complex<long double> operator"" il(unsigned long long);
+ complex<long double> operator"" il(long double);
+}
+
+using namespace std;
+
+complex<float> f1 = 2.0if;
+complex<float> f2 = 2if;
+complex<double> d1 = 2.0i;
+complex<double> d2 = 2i;
+complex<long double> l1 = 2.0il;
+complex<long double> l2 = 2il;
+
+#endif
+
+#endif
diff --git a/test/SemaCXX/implicit-exception-spec.cpp b/test/SemaCXX/implicit-exception-spec.cpp
index f400c222de83..c21f773e94c6 100644
--- a/test/SemaCXX/implicit-exception-spec.cpp
+++ b/test/SemaCXX/implicit-exception-spec.cpp
@@ -121,7 +121,7 @@ namespace PotentiallyConstructed {
T &a = *p;
static_assert(noexcept(a = a) == D, "");
static_assert(noexcept(a = static_cast<T&&>(a)) == E, "");
- static_assert(noexcept(delete &a) == F, ""); // expected-warning 2{{abstract}}
+ static_assert(noexcept(delete &a) == F, "");
// These are last because the first failure here causes instantiation to bail out.
static_assert(noexcept(new (nothrow) T()) == A, ""); // expected-error 2{{abstract}}
diff --git a/test/SemaCXX/init-expr-crash.cpp b/test/SemaCXX/init-expr-crash.cpp
new file mode 100644
index 000000000000..407da78e60b0
--- /dev/null
+++ b/test/SemaCXX/init-expr-crash.cpp
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify -std=c++11
+
+// Test reproduces a pair of crashes that were caused by code attempting
+// to materialize a default constructor's exception specifier.
+
+template <class T> struct A {
+ static T tab[];
+
+ const int M = UNDEFINED; // expected-error {{use of undeclared identifier}}
+
+ int main()
+ {
+ A<char> a;
+
+ return 0;
+ }
+};
+
+template <class T> struct B {
+ static T tab[];
+
+ // expected-error@+1 {{invalid application of 'sizeof' to an incomplete type}}
+ const int N = sizeof(B<char>::tab) / sizeof(char);
+
+ int main()
+ {
+ B<char> b;
+
+ return 0;
+ }
+};
diff --git a/test/SemaCXX/integer-overflow.cpp b/test/SemaCXX/integer-overflow.cpp
index a119f0eabe3a..6abc95614496 100644
--- a/test/SemaCXX/integer-overflow.cpp
+++ b/test/SemaCXX/integer-overflow.cpp
@@ -164,7 +164,7 @@ uint64_t check_integer_overflows(int i) { //expected-note {{declared here}}
// expected-warning@+3 {{array index 536870912 is past the end of the array (which contains 10 elements)}}
// expected-note@+1 {{array 'a' declared here}}
uint64_t a[10];
- a[4608 * 1024 * 1024] = 1i;
+ a[4608 * 1024 * 1024] = 1;
// expected-warning@+1 2{{overflow in expression; result is 536870912 with type 'int'}}
return ((4608 * 1024 * 1024) + ((uint64_t)(4608 * 1024 * 1024)));
diff --git a/test/SemaCXX/internal_linkage.cpp b/test/SemaCXX/internal_linkage.cpp
index d5cc6767392d..921a90ab4a41 100644
--- a/test/SemaCXX/internal_linkage.cpp
+++ b/test/SemaCXX/internal_linkage.cpp
@@ -5,7 +5,7 @@ int f() __attribute__((internal_linkage));
class A;
class __attribute__((internal_linkage)) A {
public:
- int x __attribute__((internal_linkage)); // expected-warning{{'internal_linkage' attribute only applies to variables, functions and classes}}
+ int x __attribute__((internal_linkage)); // expected-warning{{'internal_linkage' attribute only applies to variables, functions, and classes}}
static int y __attribute__((internal_linkage));
void f1() __attribute__((internal_linkage));
void f2() __attribute__((internal_linkage)) {}
@@ -16,7 +16,7 @@ public:
~A() __attribute__((internal_linkage)) {}
A& operator=(const A&) __attribute__((internal_linkage)) { return *this; }
struct {
- int z __attribute__((internal_linkage)); // expected-warning{{'internal_linkage' attribute only applies to variables, functions and classes}}
+ int z __attribute__((internal_linkage)); // expected-warning{{'internal_linkage' attribute only applies to}}
};
};
@@ -24,14 +24,14 @@ __attribute__((internal_linkage)) void A::f4() {} // expected-error{{'internal_l
__attribute__((internal_linkage)) int A::zz; // expected-error{{'internal_linkage' attribute does not appear on the first declaration of 'zz'}}
-namespace Z __attribute__((internal_linkage)) { // expected-warning{{'internal_linkage' attribute only applies to variables, functions and classes}}
+namespace Z __attribute__((internal_linkage)) { // expected-warning{{'internal_linkage' attribute only applies to}}
}
__attribute__((internal_linkage("foo"))) int g() {} // expected-error{{'internal_linkage' attribute takes no arguments}}
[[clang::internal_linkage]] int h() {}
-enum struct __attribute__((internal_linkage)) E { // expected-warning{{'internal_linkage' attribute only applies to variables, functions and classes}}
+enum struct __attribute__((internal_linkage)) E { // expected-warning{{'internal_linkage' attribute only applies to}}
a = 1,
b = 2
};
diff --git a/test/SemaCXX/linkage2.cpp b/test/SemaCXX/linkage2.cpp
index a7eb15f7c6be..6f43af39f7c5 100644
--- a/test/SemaCXX/linkage2.cpp
+++ b/test/SemaCXX/linkage2.cpp
@@ -143,9 +143,10 @@ namespace test13 {
}
namespace test14 {
+ // Anonymous namespace implies internal linkage, so 'static' has no effect.
namespace {
- void a(void); // expected-note {{previous declaration is here}}
- static void a(void) {} // expected-error {{static declaration of 'a' follows non-static declaration}}
+ void a(void);
+ static void a(void) {}
}
}
@@ -217,3 +218,34 @@ namespace PR18964 {
unsigned &*foo; //expected-error{{'foo' declared as a pointer to a reference of type}}
extern struct {} *foo; // don't assert
}
+
+namespace typedef_name_for_linkage {
+ template<typename T> struct Use {};
+
+ struct A { A(); A(const A&); ~A(); };
+
+ typedef struct {
+ A a;
+ } B;
+
+ struct C {
+ typedef struct {
+ A a;
+ } D;
+ };
+
+ typedef struct {
+ void f() { static int n; struct Inner {};}
+ } E;
+
+ // FIXME: Ideally this would be accepted in all modes. In C++98, we trigger a
+ // linkage calculation to drive the "internal linkage type as template
+ // argument" warning.
+ typedef struct {
+ void f() { struct Inner {}; Use<Inner> ui; }
+ } F;
+#if __cplusplus < 201103L
+ // expected-error@-2 {{unsupported: typedef changes linkage of anonymous type, but linkage was already computed}}
+ // expected-note@-5 {{use a tag name here}}
+#endif
+}
diff --git a/test/SemaCXX/member-init.cpp b/test/SemaCXX/member-init.cpp
index c296baa5bce7..82750878e584 100644
--- a/test/SemaCXX/member-init.cpp
+++ b/test/SemaCXX/member-init.cpp
@@ -1,7 +1,7 @@
// RUN: %clang_cc1 -fsyntax-only -fcxx-exceptions -verify -std=c++11 -Wall %s
struct Bitfield {
- int n : 3 = 7; // expected-error {{bit-field member cannot have an in-class initializer}}
+ int n : 3 = 7; // expected-warning {{C++2a extension}} expected-warning {{changes value from 7 to -1}}
};
int a;
diff --git a/test/SemaCXX/microsoft-varargs.cpp b/test/SemaCXX/microsoft-varargs.cpp
index 35f31a97c4f1..5b0f90eb5ca0 100644
--- a/test/SemaCXX/microsoft-varargs.cpp
+++ b/test/SemaCXX/microsoft-varargs.cpp
@@ -20,3 +20,8 @@ int builtin(int i, ...) {
return __builtin_va_arg(ap, int);
}
+void test___va_start_ignore_const(const char *format, ...) {
+ va_list args;
+ ((void)(__va_start(&args, (&const_cast<char &>(reinterpret_cast<const volatile char &>(format))), ((sizeof(format) + 4 - 1) & ~(4 - 1)), (&const_cast<char &>(reinterpret_cast<const volatile char &>(format))))));
+}
+
diff --git a/test/SemaCXX/microsoft-vs-float128.cpp b/test/SemaCXX/microsoft-vs-float128.cpp
new file mode 100644
index 000000000000..d271e470032d
--- /dev/null
+++ b/test/SemaCXX/microsoft-vs-float128.cpp
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -fms-compatibility -fms-extensions -fsyntax-only -verify -std=c++11 %s
+// RUN: %clang_cc1 -triple i686-pc-win32 -fms-compatibility -fms-extensions -fsyntax-only -verify -std=c++11 -DMS %s
+
+template <bool> struct enable_if {};
+template<> struct enable_if<true> { typedef void type; };
+
+template <typename, typename> struct is_same { static constexpr bool value = false; };
+template <typename T> struct is_same<T, T> { static constexpr bool value = true; };
+
+
+
+
+struct S {
+ // The only numeric types S can be converted to is __int128 and __float128.
+ template <typename T, typename = typename enable_if<
+ !((__is_integral(T) && sizeof(T) != 16) ||
+ is_same<T, float>::value ||
+ is_same<T, double>::value ||
+ is_same<T, long double>::value)>::type>
+ operator T() { return T(); }
+};
+
+void f() {
+#ifdef MS
+ // When targeting Win32, __float128 and __int128 do not exist, so the S
+ // object cannot be converted to anything usable in the expression.
+ // expected-error@+2{{invalid operands to binary expression ('S' and 'double')}}
+#endif
+ double d = S() + 1.0;
+#ifndef MS
+ // expected-error@-2{{use of overloaded operator '+' is ambiguous}}
+ // expected-note@-3 36{{built-in candidate operator+}}
+#endif
+}
diff --git a/test/SemaCXX/missing-members.cpp b/test/SemaCXX/missing-members.cpp
index 96bed074db85..61dddcbe5026 100644
--- a/test/SemaCXX/missing-members.cpp
+++ b/test/SemaCXX/missing-members.cpp
@@ -37,3 +37,17 @@ struct S : A::B::C {
using A::B::C::f; // expected-error {{no member named 'f' in 'A::B::C'}}
};
+
+struct S1 {};
+
+struct S2 : S1 {};
+
+struct S3 : S2 {
+ void run();
+};
+
+struct S4: S3 {};
+
+void test(S4 *ptr) {
+ ptr->S1::run(); // expected-error {{no member named 'run' in 'S1'}}
+}
diff --git a/test/SemaCXX/modules-ts.cppm b/test/SemaCXX/modules-ts.cppm
index 2ea4958bffda..c07ee82e313c 100644
--- a/test/SemaCXX/modules-ts.cppm
+++ b/test/SemaCXX/modules-ts.cppm
@@ -1,7 +1,7 @@
-// RUN: %clang_cc1 -std=c++1z -fmodules-ts -emit-module-interface %s -o %t.pcm -verify -DTEST=0
-// RUN: %clang_cc1 -std=c++1z -fmodules-ts -emit-module-interface %s -o %t.pcm -verify -DTEST=1
-// RUN: %clang_cc1 -std=c++1z -fmodules-ts -emit-module-interface %s -fmodule-file=%t.pcm -o %t.pcm -verify -DTEST=2
-// RUN: %clang_cc1 -std=c++1z -fmodules-ts -emit-module-interface %s -fmodule-file=%t.pcm -o %t.pcm -verify -Dfoo=bar -DTEST=3
+// RUN: %clang_cc1 -std=c++1z -fmodules-ts -emit-module-interface %s -o %t.0.pcm -verify -DTEST=0
+// RUN: %clang_cc1 -std=c++1z -fmodules-ts -emit-module-interface %s -o %t.1.pcm -verify -DTEST=1
+// RUN: %clang_cc1 -std=c++1z -fmodules-ts -emit-module-interface %s -fmodule-file=%t.0.pcm -o %t.2.pcm -verify -DTEST=2
+// RUN: %clang_cc1 -std=c++1z -fmodules-ts -emit-module-interface %s -fmodule-file=%t.0.pcm -o %t.3.pcm -verify -Dfoo=bar -DTEST=3
#if TEST == 0
// expected-no-diagnostics
@@ -14,14 +14,14 @@ export module foo;
#endif
static int m;
-#if TEST == 2 // FIXME: 'm' has internal linkage, so there should be no error here
+#if TEST == 2
// expected-error@-2 {{redefinition of '}}
// expected-note@-3 {{unguarded header; consider using #ifdef guards or #pragma once}}
// FIXME: We should drop the "header from" in this diagnostic.
// expected-note-re@modules-ts.cppm:1 {{'{{.*}}modules-ts.cppm' included multiple times, additional include site in header from module 'foo'}}
#endif
int n;
-#if TEST >= 2
+#if TEST == 2
// expected-error@-2 {{redefinition of '}}
// expected-note@-3 {{unguarded header; consider using #ifdef guards or #pragma once}}
// FIXME: We should drop the "header from" in this diagnostic.
@@ -52,15 +52,11 @@ export {} // expected-error {{export declaration cannot be empty}}
export { ; }
export { static_assert(true); }
-// FIXME: These diagnostics are not very good.
-export import foo; // expected-error {{expected unqualified-id}}
-export { import foo; } // expected-error {{expected unqualified-id}}
-
int use_b = b;
int use_n = n; // FIXME: this should not be visible, because it is not exported
extern int n;
-static_assert(&n == p); // FIXME: these are not the same entity
+static_assert(&n != p);
#endif
diff --git a/test/SemaCXX/ms-interface.cpp b/test/SemaCXX/ms-interface.cpp
index 4a1c13ddcbba..66ce376e2a94 100644
--- a/test/SemaCXX/ms-interface.cpp
+++ b/test/SemaCXX/ms-interface.cpp
@@ -77,3 +77,32 @@ class C1 : I6<C> {
class C2 : I6<I> {
};
+
+
+// MSVC makes a special case in that an interface is allowed to have a data
+// member if it is a property.
+__interface HasProp {
+ __declspec(property(get = Get, put = Put)) int data;
+ int Get(void);
+ void Put(int);
+};
+
+struct __declspec(uuid("00000000-0000-0000-C000-000000000046"))
+ IUnknown {
+ void foo();
+ __declspec(property(get = Get, put = Put), deprecated) int data;
+ int Get(void);
+ void Put(int);
+};
+
+struct IFaceStruct : IUnknown {
+ __declspec(property(get = Get2, put = Put2), deprecated) int data2;
+ int Get2(void);
+ void Put2(int);
+};
+
+__interface IFaceInheritsStruct : IFaceStruct {};
+static_assert(!__is_interface_class(HasProp), "oops");
+static_assert(!__is_interface_class(IUnknown), "oops");
+static_assert(!__is_interface_class(IFaceStruct), "oops");
+static_assert(!__is_interface_class(IFaceInheritsStruct), "oops");
diff --git a/test/SemaCXX/ms-iunknown-inline-def.cpp b/test/SemaCXX/ms-iunknown-inline-def.cpp
new file mode 100644
index 000000000000..70f1107c2e31
--- /dev/null
+++ b/test/SemaCXX/ms-iunknown-inline-def.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -fms-extensions %s
+
+struct __declspec(uuid("00000000-0000-0000-C000-000000000046")) IUnknown {
+ void foo() {}
+};
+
+// expected-error@+1{{interface type cannot inherit from}}
+__interface HasError : public IUnknown {};
diff --git a/test/SemaCXX/ms-iunknown-outofline-def.cpp b/test/SemaCXX/ms-iunknown-outofline-def.cpp
new file mode 100644
index 000000000000..b6e74d0eb604
--- /dev/null
+++ b/test/SemaCXX/ms-iunknown-outofline-def.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -fms-extensions %s
+
+struct __declspec(uuid("00000000-0000-0000-C000-000000000046")) IUnknown {
+ void foo();
+};
+
+__interface NoError : public IUnknown {};
+void IUnknown::foo() {}
+// expected-error@+1{{interface type cannot inherit from}}
+__interface HasError : public IUnknown {};
diff --git a/test/SemaCXX/ms-iunknown-template-function.cpp b/test/SemaCXX/ms-iunknown-template-function.cpp
new file mode 100644
index 000000000000..8f741a18eaac
--- /dev/null
+++ b/test/SemaCXX/ms-iunknown-template-function.cpp
@@ -0,0 +1,39 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -fms-extensions %s
+// expected-no-diagnostics
+typedef long HRESULT;
+typedef unsigned long ULONG;
+typedef struct _GUID {
+ unsigned long Data1;
+ unsigned short Data2;
+ unsigned short Data3;
+ unsigned char Data4[8];
+} GUID;
+typedef GUID IID;
+
+// remove stdcall, since the warnings have nothing to do with
+// what is being tested.
+#define __stdcall
+
+extern "C" {
+extern "C++" {
+struct __declspec(uuid("00000000-0000-0000-C000-000000000046"))
+ IUnknown {
+public:
+ virtual HRESULT __stdcall QueryInterface(
+ const IID &riid,
+ void **ppvObject) = 0;
+
+ virtual ULONG __stdcall AddRef(void) = 0;
+
+ virtual ULONG __stdcall Release(void) = 0;
+
+ template <class Q>
+ HRESULT __stdcall QueryInterface(Q **pp) {
+ return QueryInterface(__uuidof(Q), (void **)pp);
+ }
+};
+}
+}
+
+__interface ISfFileIOPropertyPage : public IUnknown{};
+
diff --git a/test/SemaCXX/ms-iunknown.cpp b/test/SemaCXX/ms-iunknown.cpp
new file mode 100644
index 000000000000..df761d56a800
--- /dev/null
+++ b/test/SemaCXX/ms-iunknown.cpp
@@ -0,0 +1,50 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -fms-extensions %s
+
+extern "C++" struct __declspec(uuid("00000000-0000-0000-C000-000000000046")) IUnknown {
+ void foo();
+ // Definitions aren't allowed, unless they are a template.
+ template<typename T>
+ void bar(T t){}
+};
+
+struct IPropertyPageBase : public IUnknown {};
+struct IPropertyPage : public IPropertyPageBase {};
+__interface ISfFileIOPropertyPage : public IPropertyPage {};
+
+
+namespace NS {
+ struct __declspec(uuid("00000000-0000-0000-C000-000000000046")) IUnknown {};
+ // expected-error@+1 {{interface type cannot inherit from}}
+ __interface IPropertyPageBase : public IUnknown {};
+}
+
+namespace NS2 {
+extern "C++" struct __declspec(uuid("00000000-0000-0000-C000-000000000046")) IUnknown {};
+// expected-error@+1 {{interface type cannot inherit from}}
+__interface IPropertyPageBase : public IUnknown{};
+}
+
+// expected-error@+1 {{interface type cannot inherit from}}
+__interface IPropertyPageBase2 : public NS::IUnknown {};
+
+__interface temp_iface {};
+struct bad_base : temp_iface {};
+// expected-error@+1 {{interface type cannot inherit from}}
+__interface bad_inherit : public bad_base{};
+
+struct mult_inher_base : temp_iface, IUnknown {};
+// expected-error@+1 {{interface type cannot inherit from}}
+__interface bad_inherit2 : public mult_inher_base{};
+
+struct PageBase : public IUnknown {};
+struct Page3 : public PageBase {};
+struct Page4 : public PageBase {};
+__interface PropertyPage : public Page4 {};
+
+struct Page5 : public Page3, Page4{};
+// expected-error@+1 {{interface type cannot inherit from}}
+__interface PropertyPage2 : public Page5 {};
+
+__interface IF1 {};
+__interface PP : IUnknown, IF1{};
+__interface PP2 : PP, Page3, Page4{};
diff --git a/test/SemaCXX/new-array-size-conv.cpp b/test/SemaCXX/new-array-size-conv.cpp
index dbdd4bd8951e..36b2f23a0e97 100644
--- a/test/SemaCXX/new-array-size-conv.cpp
+++ b/test/SemaCXX/new-array-size-conv.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -pedantic -verify %s
+// RUN: %clang_cc1 -fsyntax-only -pedantic -verify -std=gnu++98 %s
// RUN: %clang_cc1 -fsyntax-only -pedantic -verify -std=c++98 %s
// RUN: %clang_cc1 -fsyntax-only -pedantic -verify -std=c++11 %s
diff --git a/test/SemaCXX/new-delete.cpp b/test/SemaCXX/new-delete.cpp
index cb0d030d99c2..870a5921d253 100644
--- a/test/SemaCXX/new-delete.cpp
+++ b/test/SemaCXX/new-delete.cpp
@@ -80,12 +80,21 @@ void bad_news(int *ip)
(void)new int[1.1];
#if __cplusplus <= 199711L
// expected-error@-2 {{array size expression must have integral or enumeration type, not 'double'}}
-#else
+#elif __cplusplus <= 201103L
// expected-error@-4 {{array size expression must have integral or unscoped enumeration type, not 'double'}}
+#else
+ // expected-warning@-6 {{implicit conversion from 'double' to 'unsigned int' changes value from 1.1 to 1}}
#endif
- (void)new int[1][i]; // expected-error {{only the first dimension}} expected-note {{read of non-const variable 'i' is not allowed in a constant expression}}
- (void)new (int[1][i]); // expected-error {{only the first dimension}} expected-note {{read of non-const variable 'i' is not allowed in a constant expression}}
+ (void)new int[1][i]; // expected-note {{read of non-const variable 'i' is not allowed in a constant expression}}
+ (void)new (int[1][i]); // expected-note {{read of non-const variable 'i' is not allowed in a constant expression}}
+#if __cplusplus <= 201103L
+ // expected-error@-3 {{only the first dimension}}
+ // expected-error@-3 {{only the first dimension}}
+#else
+ // expected-error@-6 {{array size is not a constant expression}}
+ // expected-error@-6 {{array size is not a constant expression}}
+#endif
(void)new (int[i]); // expected-warning {{when type is in parentheses}}
(void)new int(*(S*)0); // expected-error {{no viable conversion from 'S' to 'int'}}
(void)new int(1, 2); // expected-error {{excess elements in scalar initializer}}
@@ -94,13 +103,20 @@ void bad_news(int *ip)
(void)new const int; // expected-error {{default initialization of an object of const type 'const int'}}
(void)new float*(ip); // expected-error {{cannot initialize a new value of type 'float *' with an lvalue of type 'int *'}}
// Undefined, but clang should reject it directly.
- (void)new int[-1]; // expected-error {{array size is negative}}
+ (void)new int[-1];
+#if __cplusplus <= 201103L
+ // expected-error@-2 {{array size is negative}}
+#else
+ // expected-error@-4 {{array is too large}}
+#endif
(void)new int[2000000000]; // expected-error {{array is too large}}
(void)new int[*(S*)0];
#if __cplusplus <= 199711L
// expected-error@-2 {{array size expression must have integral or enumeration type, not 'S'}}
-#else
+#elif __cplusplus <= 201103L
// expected-error@-4 {{array size expression must have integral or unscoped enumeration type, not 'S'}}
+#else
+ // expected-error@-6 {{converting 'S' to incompatible type}}
#endif
(void)::S::new int; // expected-error {{expected unqualified-id}}
diff --git a/test/SemaCXX/no-warn-user-defined-literals-in-system-headers.cpp b/test/SemaCXX/no-warn-user-defined-literals-in-system-headers.cpp
new file mode 100644
index 000000000000..ee5b0c47b9ff
--- /dev/null
+++ b/test/SemaCXX/no-warn-user-defined-literals-in-system-headers.cpp
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wsystem-headers -isystem %S %s
+
+#include <no-warn-user-defined-literals-in-system-headers.h>
+
+void operator "" bar(long double); // expected-warning{{user-defined literal suffixes not starting with '_' are reserved}}
diff --git a/test/SemaCXX/no-warn-user-defined-literals-in-system-headers.h b/test/SemaCXX/no-warn-user-defined-literals-in-system-headers.h
new file mode 100644
index 000000000000..d1e2583168f1
--- /dev/null
+++ b/test/SemaCXX/no-warn-user-defined-literals-in-system-headers.h
@@ -0,0 +1,2 @@
+// Header for no-warn-user-defined-literals-in-system-headers.cpp
+void operator "" foo (const char *);
diff --git a/test/SemaCXX/nothrow-as-noexcept-ctor.cpp b/test/SemaCXX/nothrow-as-noexcept-ctor.cpp
new file mode 100644
index 000000000000..7cca414d7a6a
--- /dev/null
+++ b/test/SemaCXX/nothrow-as-noexcept-ctor.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 %s -fcxx-exceptions -fsyntax-only -Wexceptions -verify -std=c++14
+
+// expected-no-diagnostics
+struct Base {
+ __attribute__((nothrow)) Base() {}
+};
+
+struct Derived : Base {
+ Derived() noexcept = default;
+};
+
+struct Base2 {
+ Base2() noexcept {}
+};
+
+struct Derived2 : Base2 {
+ __attribute__((nothrow)) Derived2() = default;
+};
+
+struct Base3 {
+ __attribute__((nothrow)) Base3() {}
+};
+
+struct Derived3 : Base3 {
+ __attribute__((nothrow)) Derived3() = default;
+};
diff --git a/test/SemaCXX/nullptr-arithmetic.cpp b/test/SemaCXX/nullptr-arithmetic.cpp
new file mode 100644
index 000000000000..9963c8858ee8
--- /dev/null
+++ b/test/SemaCXX/nullptr-arithmetic.cpp
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify -pedantic -Wextra -std=c++11
+// RUN: %clang_cc1 %s -fsyntax-only -triple i686-unknown-unknown -verify -pedantic -Wextra -std=c++11
+// RUN: %clang_cc1 %s -fsyntax-only -triple x86_64-unknown-unknown -verify -pedantic -Wextra -std=c++11
+
+#include <stdint.h>
+
+void f(intptr_t offset) {
+ // A zero offset from a nullptr is OK.
+ char *f = (char*)nullptr + 0;
+ int *g = (int*)0 + 0;
+ f = (char*)nullptr - 0;
+ g = (int*)nullptr - 0;
+ // adding other values is undefined.
+ f = (char*)nullptr + offset; // expected-warning {{arithmetic on a null pointer treated as a cast from integer to pointer is a GNU extension}}
+ // Cases that don't match the GNU inttoptr idiom get a different warning.
+ f = (char*)0 - offset; // expected-warning {{performing pointer arithmetic on a null pointer has undefined behavior if the offset is nonzero}}
+ g = (int*)0 + offset; // expected-warning {{performing pointer arithmetic on a null pointer has undefined behavior if the offset is nonzero}}
+}
+
+// Value-dependent pointer arithmetic should not produce a nullptr warning.
+template<char *P>
+char* g(intptr_t offset) {
+ return P + offset;
+}
+
+// Value-dependent offsets should not produce a nullptr warning.
+template<intptr_t N>
+char *h() {
+ return (char*)nullptr + N;
+}
diff --git a/test/SemaCXX/overload-call.cpp b/test/SemaCXX/overload-call.cpp
index 0e3a9ee50bb2..0c4bba5027f7 100644
--- a/test/SemaCXX/overload-call.cpp
+++ b/test/SemaCXX/overload-call.cpp
@@ -658,3 +658,11 @@ namespace StringLiteralToCharAmbiguity {
// expected-note@-5 {{candidate function}}
#endif
}
+
+namespace ProduceNotesAfterSFINAEFailure {
+ struct A {
+ template<typename T, typename U = typename T::x> A(T); // expected-warning 0-1{{extension}}
+ };
+ void f(void*, A); // expected-note {{candidate function not viable}}
+ void g() { f(1, 2); } // expected-error {{no matching function}}
+}
diff --git a/test/SemaCXX/overloaded-operator.cpp b/test/SemaCXX/overloaded-operator.cpp
index 369e9eb802a5..dff9350cc984 100644
--- a/test/SemaCXX/overloaded-operator.cpp
+++ b/test/SemaCXX/overloaded-operator.cpp
@@ -531,3 +531,57 @@ namespace NoADLForMemberOnlyOperators {
b3 / 0; // expected-note {{in instantiation of}} expected-error {{invalid operands to}}
}
}
+
+
+namespace PR27027 {
+ template <class T> void operator+(T, T) = delete; // expected-note 4 {{candidate}}
+ template <class T> void operator+(T) = delete; // expected-note 4 {{candidate}}
+
+ struct A {} a_global;
+ void f() {
+ A a;
+ +a; // expected-error {{overload resolution selected deleted operator '+'}}
+ a + a; // expected-error {{overload resolution selected deleted operator '+'}}
+ bool operator+(A);
+ extern bool operator+(A, A);
+ +a; // OK
+ a + a;
+ }
+ bool test_global_1 = +a_global; // expected-error {{overload resolution selected deleted operator '+'}}
+ bool test_global_2 = a_global + a_global; // expected-error {{overload resolution selected deleted operator '+'}}
+}
+
+namespace LateADLInNonDependentExpressions {
+ struct A {};
+ struct B : A {};
+ int &operator+(A, A);
+ int &operator!(A);
+ int &operator+=(A, A);
+ int &operator<<(A, A);
+ int &operator++(A);
+ int &operator++(A, int);
+ int &operator->*(A, A);
+
+ template<typename T> void f() {
+ // An instantiation-dependent value of type B.
+ // These are all non-dependent operator calls of type int&.
+#define idB ((void()), B())
+ int &a = idB + idB,
+ &b = !idB,
+ &c = idB += idB,
+ &d = idB << idB,
+ &e = ++idB,
+ &f = idB++,
+ &g = idB ->* idB;
+ }
+
+ // These should not be found by ADL in the template instantiation.
+ float &operator+(B, B);
+ float &operator!(B);
+ float &operator+=(B, B);
+ float &operator<<(B, B);
+ float &operator++(B);
+ float &operator++(B, int);
+ float &operator->*(B, B);
+ template void f<int>();
+}
diff --git a/test/SemaCXX/short-wchar-sign.cpp b/test/SemaCXX/short-wchar-sign.cpp
index 7ce21c523cd7..a43e68a086aa 100644
--- a/test/SemaCXX/short-wchar-sign.cpp
+++ b/test/SemaCXX/short-wchar-sign.cpp
@@ -1,5 +1,5 @@
// RUN: %clang_cc1 -triple i386-mingw32 -fsyntax-only -pedantic -verify %s
-// RUN: %clang_cc1 -fshort-wchar -fsyntax-only -pedantic -verify %s
+// RUN: %clang_cc1 -fwchar-type=short -fno-signed-wchar -fsyntax-only -pedantic -verify %s
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -pedantic -verify %s
// expected-no-diagnostics
diff --git a/test/SemaCXX/static-assert.cpp b/test/SemaCXX/static-assert.cpp
index 196375c3d687..846303807a02 100644
--- a/test/SemaCXX/static-assert.cpp
+++ b/test/SemaCXX/static-assert.cpp
@@ -51,3 +51,20 @@ StaticAssertProtected<X> sap2; // expected-note {{instantiation}}
static_assert(true); // expected-warning {{C++17 extension}}
static_assert(false); // expected-error-re {{failed{{$}}}} expected-warning {{extension}}
+
+
+// Diagnostics for static_assert with multiple conditions
+template<typename T> struct first_trait {
+ static const bool value = false;
+};
+
+template<>
+struct first_trait<X> {
+ static const bool value = true;
+};
+
+template<typename T> struct second_trait {
+ static const bool value = false;
+};
+
+static_assert(first_trait<X>::value && second_trait<X>::value, "message"); // expected-error{{static_assert failed due to requirement 'second_trait<X>::value' "message"}}
diff --git a/test/SemaCXX/template-default-param-through-using.cpp b/test/SemaCXX/template-default-param-through-using.cpp
new file mode 100644
index 000000000000..4bf26d581160
--- /dev/null
+++ b/test/SemaCXX/template-default-param-through-using.cpp
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// expected-no-diagnostics
+namespace llvm {
+ template<typename T > struct StringSet;
+ template<int I > struct Int;
+ template <typename Inner, template <typename> class Outer>
+ struct TemplTempl;
+}
+
+namespace lld {
+ using llvm::StringSet;
+ using llvm::Int;
+ using llvm::TemplTempl;
+};
+
+namespace llvm {
+ template<typename T > struct StringSet;
+}
+
+template<typename T> struct Temp{};
+
+namespace llvm {
+ template<typename T = int> struct StringSet{};
+ template<int I = 5> struct Int{};
+ template <typename Inner, template <typename> class Outer = Temp>
+ struct TemplTempl{};
+};
+
+namespace lld {
+ StringSet<> s;
+ Int<> i;
+ TemplTempl<int> tt;
+}
diff --git a/test/SemaCXX/type-traits.cpp b/test/SemaCXX/type-traits.cpp
index 5879a77dd5a8..b334e507554f 100644
--- a/test/SemaCXX/type-traits.cpp
+++ b/test/SemaCXX/type-traits.cpp
@@ -2352,3 +2352,320 @@ void is_trivially_destructible_test() {
{ int arr[F(__is_trivially_destructible(void))]; }
{ int arr[F(__is_trivially_destructible(const volatile void))]; }
}
+
+// Instantiation of __has_unique_object_representations
+template <typename T>
+struct has_unique_object_representations {
+ static const bool value = __has_unique_object_representations(T);
+};
+
+static_assert(!has_unique_object_representations<void>::value, "void is never unique");
+static_assert(!has_unique_object_representations<const void>::value, "void is never unique");
+static_assert(!has_unique_object_representations<volatile void>::value, "void is never unique");
+static_assert(!has_unique_object_representations<const volatile void>::value, "void is never unique");
+
+static_assert(has_unique_object_representations<int>::value, "integrals are");
+static_assert(has_unique_object_representations<const int>::value, "integrals are");
+static_assert(has_unique_object_representations<volatile int>::value, "integrals are");
+static_assert(has_unique_object_representations<const volatile int>::value, "integrals are");
+
+static_assert(has_unique_object_representations<void *>::value, "as are pointers");
+static_assert(has_unique_object_representations<const void *>::value, "as are pointers");
+static_assert(has_unique_object_representations<volatile void *>::value, "are pointers");
+static_assert(has_unique_object_representations<const volatile void *>::value, "as are pointers");
+
+static_assert(has_unique_object_representations<int *>::value, "as are pointers");
+static_assert(has_unique_object_representations<const int *>::value, "as are pointers");
+static_assert(has_unique_object_representations<volatile int *>::value, "as are pointers");
+static_assert(has_unique_object_representations<const volatile int *>::value, "as are pointers");
+
+class C {};
+using FP = int (*)(int);
+using PMF = int (C::*)(int);
+using PMD = int C::*;
+
+static_assert(has_unique_object_representations<FP>::value, "even function pointers");
+static_assert(has_unique_object_representations<const FP>::value, "even function pointers");
+static_assert(has_unique_object_representations<volatile FP>::value, "even function pointers");
+static_assert(has_unique_object_representations<const volatile FP>::value, "even function pointers");
+
+static_assert(has_unique_object_representations<PMF>::value, "and pointer to members");
+static_assert(has_unique_object_representations<const PMF>::value, "and pointer to members");
+static_assert(has_unique_object_representations<volatile PMF>::value, "and pointer to members");
+static_assert(has_unique_object_representations<const volatile PMF>::value, "and pointer to members");
+
+static_assert(has_unique_object_representations<PMD>::value, "and pointer to members");
+static_assert(has_unique_object_representations<const PMD>::value, "and pointer to members");
+static_assert(has_unique_object_representations<volatile PMD>::value, "and pointer to members");
+static_assert(has_unique_object_representations<const volatile PMD>::value, "and pointer to members");
+
+static_assert(has_unique_object_representations<bool>::value, "yes, all integral types");
+static_assert(has_unique_object_representations<char>::value, "yes, all integral types");
+static_assert(has_unique_object_representations<signed char>::value, "yes, all integral types");
+static_assert(has_unique_object_representations<unsigned char>::value, "yes, all integral types");
+static_assert(has_unique_object_representations<short>::value, "yes, all integral types");
+static_assert(has_unique_object_representations<unsigned short>::value, "yes, all integral types");
+static_assert(has_unique_object_representations<int>::value, "yes, all integral types");
+static_assert(has_unique_object_representations<unsigned int>::value, "yes, all integral types");
+static_assert(has_unique_object_representations<long>::value, "yes, all integral types");
+static_assert(has_unique_object_representations<unsigned long>::value, "yes, all integral types");
+static_assert(has_unique_object_representations<long long>::value, "yes, all integral types");
+static_assert(has_unique_object_representations<unsigned long long>::value, "yes, all integral types");
+static_assert(has_unique_object_representations<wchar_t>::value, "yes, all integral types");
+static_assert(has_unique_object_representations<char16_t>::value, "yes, all integral types");
+static_assert(has_unique_object_representations<char32_t>::value, "yes, all integral types");
+
+static_assert(!has_unique_object_representations<void>::value, "but not void!");
+static_assert(!has_unique_object_representations<decltype(nullptr)>::value, "or nullptr_t");
+static_assert(!has_unique_object_representations<float>::value, "definitely not Floating Point");
+static_assert(!has_unique_object_representations<double>::value, "definitely not Floating Point");
+static_assert(!has_unique_object_representations<long double>::value, "definitely not Floating Point");
+
+struct NoPadding {
+ int a;
+ int b;
+};
+
+static_assert(has_unique_object_representations<NoPadding>::value, "types without padding are");
+
+struct InheritsFromNoPadding : NoPadding {
+ int c;
+ int d;
+};
+
+static_assert(has_unique_object_representations<InheritsFromNoPadding>::value, "types without padding are");
+
+struct VirtuallyInheritsFromNoPadding : virtual NoPadding {
+ int c;
+ int d;
+};
+
+static_assert(!has_unique_object_representations<VirtuallyInheritsFromNoPadding>::value, "No virtual inheritence");
+
+struct Padding {
+ char a;
+ int b;
+};
+
+//static_assert(!has_unique_object_representations<Padding>::value, "but not with padding");
+
+struct InheritsFromPadding : Padding {
+ int c;
+ int d;
+};
+
+static_assert(!has_unique_object_representations<InheritsFromPadding>::value, "or its subclasses");
+
+struct TailPadding {
+ int a;
+ char b;
+};
+
+static_assert(!has_unique_object_representations<TailPadding>::value, "even at the end");
+
+struct TinyStruct {
+ char a;
+};
+
+static_assert(has_unique_object_representations<TinyStruct>::value, "Should be no padding");
+
+struct InheritsFromTinyStruct : TinyStruct {
+ int b;
+};
+
+static_assert(!has_unique_object_representations<InheritsFromTinyStruct>::value, "Inherit causes padding");
+
+union NoPaddingUnion {
+ int a;
+ unsigned int b;
+};
+
+static_assert(has_unique_object_representations<NoPaddingUnion>::value, "unions follow the same rules as structs");
+
+union PaddingUnion {
+ int a;
+ long long b;
+};
+
+static_assert(!has_unique_object_representations<PaddingUnion>::value, "unions follow the same rules as structs");
+
+struct NotTriviallyCopyable {
+ int x;
+ NotTriviallyCopyable(const NotTriviallyCopyable &) {}
+};
+
+static_assert(!has_unique_object_representations<NotTriviallyCopyable>::value, "must be trivially copyable");
+
+struct HasNonUniqueMember {
+ float x;
+};
+
+static_assert(!has_unique_object_representations<HasNonUniqueMember>::value, "all members must be unique");
+
+enum ExampleEnum { xExample,
+ yExample };
+enum LLEnum : long long { xLongExample,
+ yLongExample };
+
+static_assert(has_unique_object_representations<ExampleEnum>::value, "Enums are integrals, so unique!");
+static_assert(has_unique_object_representations<LLEnum>::value, "Enums are integrals, so unique!");
+
+enum class ExampleEnumClass { xExample,
+ yExample };
+enum class LLEnumClass : long long { xLongExample,
+ yLongExample };
+
+static_assert(has_unique_object_representations<ExampleEnumClass>::value, "Enums are integrals, so unique!");
+static_assert(has_unique_object_representations<LLEnumClass>::value, "Enums are integrals, so unique!");
+
+// because references aren't trivially copyable.
+static_assert(!has_unique_object_representations<int &>::value, "No references!");
+static_assert(!has_unique_object_representations<const int &>::value, "No references!");
+static_assert(!has_unique_object_representations<volatile int &>::value, "No references!");
+static_assert(!has_unique_object_representations<const volatile int &>::value, "No references!");
+static_assert(!has_unique_object_representations<Empty>::value, "No empty types!");
+
+class Compressed : Empty {
+ int x;
+};
+
+static_assert(has_unique_object_representations<Compressed>::value, "But inheriting from one is ok");
+
+class EmptyInheritor : Compressed {};
+
+static_assert(has_unique_object_representations<EmptyInheritor>::value, "As long as the base has items, empty is ok");
+
+class Dynamic {
+ virtual void A();
+ int i;
+};
+
+static_assert(!has_unique_object_representations<Dynamic>::value, "Dynamic types are not valid");
+
+class InheritsDynamic : Dynamic {
+ int j;
+};
+
+static_assert(!has_unique_object_representations<InheritsDynamic>::value, "Dynamic types are not valid");
+
+static_assert(has_unique_object_representations<int[42]>::value, "Arrays are fine, as long as their value type is");
+static_assert(has_unique_object_representations<int[]>::value, "Arrays are fine, as long as their value type is");
+static_assert(has_unique_object_representations<int[][42]>::value, "Arrays are fine, as long as their value type is");
+static_assert(!has_unique_object_representations<double[42]>::value, "So no array of doubles!");
+static_assert(!has_unique_object_representations<double[]>::value, "So no array of doubles!");
+static_assert(!has_unique_object_representations<double[][42]>::value, "So no array of doubles!");
+
+struct __attribute__((aligned(16))) WeirdAlignment {
+ int i;
+};
+union __attribute__((aligned(16))) WeirdAlignmentUnion {
+ int i;
+};
+static_assert(!has_unique_object_representations<WeirdAlignment>::value, "Alignment causes padding");
+static_assert(!has_unique_object_representations<WeirdAlignmentUnion>::value, "Alignment causes padding");
+static_assert(!has_unique_object_representations<WeirdAlignment[42]>::value, "Also no arrays that have padding");
+
+static_assert(!has_unique_object_representations<int(int)>::value, "Functions are not unique");
+static_assert(!has_unique_object_representations<int(int) const>::value, "Functions are not unique");
+static_assert(!has_unique_object_representations<int(int) volatile>::value, "Functions are not unique");
+static_assert(!has_unique_object_representations<int(int) const volatile>::value, "Functions are not unique");
+static_assert(!has_unique_object_representations<int(int) &>::value, "Functions are not unique");
+static_assert(!has_unique_object_representations<int(int) const &>::value, "Functions are not unique");
+static_assert(!has_unique_object_representations<int(int) volatile &>::value, "Functions are not unique");
+static_assert(!has_unique_object_representations<int(int) const volatile &>::value, "Functions are not unique");
+static_assert(!has_unique_object_representations<int(int) &&>::value, "Functions are not unique");
+static_assert(!has_unique_object_representations<int(int) const &&>::value, "Functions are not unique");
+static_assert(!has_unique_object_representations<int(int) volatile &&>::value, "Functions are not unique");
+static_assert(!has_unique_object_representations<int(int) const volatile &&>::value, "Functions are not unique");
+
+static_assert(!has_unique_object_representations<int(int, ...)>::value, "Functions are not unique");
+static_assert(!has_unique_object_representations<int(int, ...) const>::value, "Functions are not unique");
+static_assert(!has_unique_object_representations<int(int, ...) volatile>::value, "Functions are not unique");
+static_assert(!has_unique_object_representations<int(int, ...) const volatile>::value, "Functions are not unique");
+static_assert(!has_unique_object_representations<int(int, ...) &>::value, "Functions are not unique");
+static_assert(!has_unique_object_representations<int(int, ...) const &>::value, "Functions are not unique");
+static_assert(!has_unique_object_representations<int(int, ...) volatile &>::value, "Functions are not unique");
+static_assert(!has_unique_object_representations<int(int, ...) const volatile &>::value, "Functions are not unique");
+static_assert(!has_unique_object_representations<int(int, ...) &&>::value, "Functions are not unique");
+static_assert(!has_unique_object_representations<int(int, ...) const &&>::value, "Functions are not unique");
+static_assert(!has_unique_object_representations<int(int, ...) volatile &&>::value, "Functions are not unique");
+static_assert(!has_unique_object_representations<int(int, ...) const volatile &&>::value, "Functions are not unique");
+
+void foo(){
+ static auto lambda = []() {};
+ static_assert(!has_unique_object_representations<decltype(lambda)>::value, "Lambdas follow struct rules");
+ int i;
+ static auto lambda2 = [i]() {};
+ static_assert(has_unique_object_representations<decltype(lambda2)>::value, "Lambdas follow struct rules");
+}
+
+struct PaddedBitfield {
+ char c : 6;
+ char d : 1;
+};
+
+struct UnPaddedBitfield {
+ char c : 6;
+ char d : 2;
+};
+
+struct AlignedPaddedBitfield {
+ char c : 6;
+ __attribute__((aligned(1)))
+ char d : 2;
+};
+
+static_assert(!has_unique_object_representations<PaddedBitfield>::value, "Bitfield padding");
+static_assert(has_unique_object_representations<UnPaddedBitfield>::value, "Bitfield padding");
+static_assert(!has_unique_object_representations<AlignedPaddedBitfield>::value, "Bitfield padding");
+
+struct BoolBitfield {
+ bool b : 8;
+};
+
+static_assert(has_unique_object_representations<BoolBitfield>::value, "Bitfield bool");
+
+struct BoolBitfield2 {
+ bool b : 16;
+};
+
+static_assert(!has_unique_object_representations<BoolBitfield2>::value, "Bitfield bool");
+
+struct GreaterSizeBitfield {
+ //expected-warning@+1 {{width of bit-field 'n'}}
+ int n : 1024;
+};
+
+static_assert(sizeof(GreaterSizeBitfield) == 128, "Bitfield Size");
+static_assert(!has_unique_object_representations<GreaterSizeBitfield>::value, "Bitfield padding");
+
+struct StructWithRef {
+ int &I;
+};
+
+static_assert(has_unique_object_representations<StructWithRef>::value, "References are still unique");
+
+struct NotUniqueBecauseTailPadding {
+ int &r;
+ char a;
+};
+struct CanBeUniqueIfNoPadding : NotUniqueBecauseTailPadding {
+ char b[7];
+};
+
+static_assert(!has_unique_object_representations<NotUniqueBecauseTailPadding>::value,
+ "non trivial");
+// Can be unique on Itanium, since the is child class' data is 'folded' into the
+// parent's tail padding.
+static_assert(sizeof(CanBeUniqueIfNoPadding) != 16 ||
+ has_unique_object_representations<CanBeUniqueIfNoPadding>::value,
+ "inherit from std layout");
+
+namespace ErrorType {
+ struct S; //expected-note{{forward declaration of 'ErrorType::S'}}
+
+ struct T {
+ S t; //expected-error{{field has incomplete type 'ErrorType::S'}}
+ };
+ bool b = __has_unique_object_representations(T);
+};
diff --git a/test/SemaCXX/typo-correction-crash.cpp b/test/SemaCXX/typo-correction-crash.cpp
index 0b8383dbafef..b7b9c73a0cbd 100644
--- a/test/SemaCXX/typo-correction-crash.cpp
+++ b/test/SemaCXX/typo-correction-crash.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -std=c++14 -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++17 -verify %s
auto check1() {
return 1;
return s; // expected-error {{use of undeclared identifier 's'}}
@@ -19,3 +19,5 @@ struct FooRecord { };
FooRecord::NestedNamespace::type x; // expected-error {{no member named 'NestedNamespace' in 'FooRecord'; did you mean 'BarNamespace::NestedNamespace'?}}
void cast_expr(int g) { +int(n)(g); } // expected-error {{undeclared identifier 'n'}}
+
+void bind() { for (const auto& [test,_] : _test_) { }; } // expected-error {{undeclared identifier '_test_'}}
diff --git a/test/SemaCXX/unavailable_aligned_allocation.cpp b/test/SemaCXX/unavailable_aligned_allocation.cpp
index 2ae5d2e2c704..2000e0b6a319 100644
--- a/test/SemaCXX/unavailable_aligned_allocation.cpp
+++ b/test/SemaCXX/unavailable_aligned_allocation.cpp
@@ -1,6 +1,12 @@
// RUN: %clang_cc1 -triple x86_64-apple-macosx10.12.0 -fexceptions -faligned-alloc-unavailable -std=c++1z -verify %s
// RUN: %clang_cc1 -triple x86_64-apple-macosx10.12.0 -fexceptions -std=c++1z -verify -DNO_ERRORS %s
// RUN: %clang_cc1 -triple x86_64-apple-macosx10.12.0 -fexceptions -faligned-allocation -faligned-alloc-unavailable -std=c++14 -verify %s
+// RUN: %clang_cc1 -triple arm64-apple-ios10.0.0 -fexceptions -faligned-alloc-unavailable -std=c++1z -verify -DIOS %s
+// RUN: %clang_cc1 -triple arm64-apple-ios10.0.0 -fexceptions -std=c++1z -verify -DNO_ERRORS %s
+// RUN: %clang_cc1 -triple arm64-apple-tvos10.0.0 -fexceptions -faligned-alloc-unavailable -std=c++1z -verify -DTVOS %s
+// RUN: %clang_cc1 -triple arm64-apple-tvos10.0.0 -fexceptions -std=c++1z -verify -DNO_ERRORS %s
+// RUN: %clang_cc1 -triple armv7k-apple-watchos3.0.0 -fexceptions -faligned-alloc-unavailable -std=c++1z -verify -DWATCHOS %s
+// RUN: %clang_cc1 -triple armv7k-apple-watchos3.0.0 -fexceptions -std=c++1z -verify -DNO_ERRORS %s
namespace std {
typedef decltype(sizeof(0)) size_t;
@@ -56,44 +62,68 @@ void testOveraligned() {
#ifdef NO_ERRORS
// expected-no-diagnostics
#else
-// expected-error@-16 {{aligned allocation function of type 'void *(unsigned long, enum std::align_val_t)' possibly unavailable on}}
+// expected-error@-16 {{aligned allocation function of type 'void *(unsigned long, enum std::align_val_t)' is only available on}}
// expected-note@-17 {{if you supply your own aligned allocation functions}}
-// expected-error@-18 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' possibly unavailable on}}
+// expected-error@-18 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is only available on}}
// expected-note@-19 {{if you supply your own aligned allocation functions}}
-// expected-error@-20 {{aligned allocation function of type 'void *(unsigned long, enum std::align_val_t)' possibly unavailable on}}
+// expected-error@-20 {{aligned allocation function of type 'void *(unsigned long, enum std::align_val_t)' is only available on}}
// expected-note@-21 {{if you supply your own aligned allocation functions}}
-// expected-error@-22 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' possibly unavailable on}}
+// expected-error@-22 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is only available on}}
// expected-note@-23 {{if you supply your own aligned allocation functions}}
-// expected-error@-24 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' possibly unavailable on}}
+// expected-error@-24 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is only available on}}
// expected-note@-25 {{if you supply your own aligned allocation functions}}
-// expected-error@-26 {{aligned allocation function of type 'void *(std::size_t, std::align_val_t, const std::nothrow_t &) noexcept' possibly unavailable on}}
+// expected-error@-26 {{aligned allocation function of type 'void *(std::size_t, std::align_val_t, const std::nothrow_t &) noexcept' is only available on}}
// expected-note@-27 {{if you supply your own aligned allocation functions}}
-// expected-error@-28 {{aligned deallocation function of type 'void (void *, std::align_val_t, const std::nothrow_t &) noexcept' possibly unavailable on}}
+// expected-error@-28 {{aligned deallocation function of type 'void (void *, std::align_val_t, const std::nothrow_t &) noexcept' is only available on}}
// expected-note@-29 {{if you supply your own aligned allocation functions}}
-// expected-error@-29 {{aligned allocation function of type 'void *(unsigned long, enum std::align_val_t)' possibly unavailable on}}
+// expected-error@-29 {{aligned allocation function of type 'void *(unsigned long, enum std::align_val_t)' is only available on}}
// expected-note@-30 {{if you supply your own aligned allocation functions}}
-// expected-error@-31 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' possibly unavailable on}}
+// expected-error@-31 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is only available on}}
// expected-note@-32 {{if you supply your own aligned allocation functions}}
-// expected-error@-33 {{aligned allocation function of type 'void *(unsigned long, enum std::align_val_t)' possibly unavailable on}}
+// expected-error@-33 {{aligned allocation function of type 'void *(unsigned long, enum std::align_val_t)' is only available on}}
// expected-note@-34 {{if you supply your own aligned allocation functions}}
-// expected-error@-35 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' possibly unavailable on}}
+// expected-error@-35 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is only available on}}
// expected-note@-36 {{if you supply your own aligned allocation functions}}
-// expected-error@-37 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' possibly unavailable on}}
+// expected-error@-37 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is only available on}}
// expected-note@-38 {{if you supply your own aligned allocation functions}}
-// expected-error@-39 {{aligned allocation function of type 'void *(std::size_t, std::align_val_t, const std::nothrow_t &) noexcept' possibly unavailable on}}
+// expected-error@-39 {{aligned allocation function of type 'void *(std::size_t, std::align_val_t, const std::nothrow_t &) noexcept' is only available on}}
// expected-note@-40 {{if you supply your own aligned allocation functions}}
-// expected-error@-41 {{aligned deallocation function of type 'void (void *, std::align_val_t, const std::nothrow_t &) noexcept' possibly unavailable on}}
+// expected-error@-41 {{aligned deallocation function of type 'void (void *, std::align_val_t, const std::nothrow_t &) noexcept' is only available on}}
// expected-note@-42 {{if you supply your own aligned allocation functions}}
#endif
+void testOveralignedCheckOS() {
+ auto *p = new OveralignedS;
+}
+
+#ifdef NO_ERRORS
+// expected-no-diagnostics
+#else
+#if defined(IOS)
+// expected-error@-7 {{aligned allocation function of type 'void *(unsigned long, enum std::align_val_t)' is only available on iOS 11 or newer}}
+// expected-error@-8 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is only available on iOS 11 or newer}}}
+#elif defined(TVOS)
+// expected-error@-10 {{aligned allocation function of type 'void *(unsigned long, enum std::align_val_t)' is only available on tvOS 11 or newer}}}
+// expected-error@-11 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is only available on tvOS 11 or newer}}}
+#elif defined(WATCHOS)
+// expected-error@-13 {{aligned allocation function of type 'void *(unsigned long, enum std::align_val_t)' is only available on watchOS 4 or newer}}}
+// expected-error@-14 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is only available on watchOS 4 or newer}}}
+#else
+// expected-error@-16 {{aligned allocation function of type 'void *(unsigned long, enum std::align_val_t)' is only available on macOS 10.13 or newer}}}
+// expected-error@-17 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is only available on macOS 10.13 or newer}}}
+#endif
+
+// expected-note@-20 2 {{if you supply your own aligned allocation functions}}
+#endif
+
// No errors if user-defined aligned allocation functions are available.
void *operator new(std::size_t __sz, std::align_val_t) {
static char array[256];
diff --git a/test/SemaCXX/undefined-internal.cpp b/test/SemaCXX/undefined-internal.cpp
index 32151b71ea17..60fa202384de 100644
--- a/test/SemaCXX/undefined-internal.cpp
+++ b/test/SemaCXX/undefined-internal.cpp
@@ -187,6 +187,10 @@ namespace OverloadUse {
void f();
void f(int); // expected-warning {{function 'OverloadUse::(anonymous namespace)::f' has internal linkage but is not defined}}
void f(int, int); // expected-warning {{function 'OverloadUse::(anonymous namespace)::f' has internal linkage but is not defined}}
+#if __cplusplus < 201103L
+ // expected-note@-3 {{here}}
+ // expected-note@-3 {{here}}
+#endif
}
template<void x()> void t() { x(); }
template<void x(int)> void t(int*) { x(10); }
@@ -194,6 +198,10 @@ namespace OverloadUse {
void g(int n) {
t<f>(&n); // expected-note {{used here}}
t<f>(&n, &n); // expected-note {{used here}}
+#if __cplusplus < 201103L
+ // expected-warning@-3 {{non-type template argument referring to function 'f' with internal linkage}}
+ // expected-warning@-3 {{non-type template argument referring to function 'f' with internal linkage}}
+#endif
}
}
diff --git a/test/SemaCXX/underlying_type.cpp b/test/SemaCXX/underlying_type.cpp
index dd019ae6e277..87f3b92802ad 100644
--- a/test/SemaCXX/underlying_type.cpp
+++ b/test/SemaCXX/underlying_type.cpp
@@ -62,3 +62,17 @@ enum E {};
void PR26014() { f<E>(0); } // should not yield an ambiguity error.
template<typename ...T> void f(__underlying_type(T) v); // expected-error {{declaration type contains unexpanded parameter pack 'T'}}
+
+namespace PR23421 {
+template <class T>
+using underlying_type_t = __underlying_type(T);
+// Should not crash.
+template <class T>
+struct make_unsigned_impl { using type = underlying_type_t<T>; };
+using AnotherType = make_unsigned_impl<E>::type;
+
+// also should not crash.
+template <typename T>
+__underlying_type(T) ft();
+auto x = &ft<E>;
+}
diff --git a/test/SemaCXX/unknown-type-name.cpp b/test/SemaCXX/unknown-type-name.cpp
index 2a9748e3ab67..9086c9acc438 100644
--- a/test/SemaCXX/unknown-type-name.cpp
+++ b/test/SemaCXX/unknown-type-name.cpp
@@ -95,7 +95,10 @@ template<typename T> int A<T>::h(T::type x, char) {} // expected-error{{missing
template<typename T> int h(T::type, int); // expected-error{{missing 'typename'}}
template<typename T> int h(T::type x, char); // expected-error{{missing 'typename'}}
-template<typename T> int junk1(T::junk); // expected-warning{{variable templates are a C++14 extension}}
+template<typename T> int junk1(T::junk);
+#if __cplusplus <= 201103L
+// expected-warning@-2 {{variable templates are a C++14 extension}}
+#endif
template<typename T> int junk2(T::junk) throw(); // expected-error{{missing 'typename'}}
template<typename T> int junk3(T::junk) = delete; // expected-error{{missing 'typename'}}
#if __cplusplus <= 199711L
@@ -106,7 +109,11 @@ template<typename T> int junk4(T::junk j); // expected-error{{missing 'typename'
// FIXME: We can tell this was intended to be a function because it does not
// have a dependent nested name specifier.
-template<typename T> int i(T::type, int()); // expected-warning{{variable templates are a C++14 extension}}
+template<typename T> int i(T::type, int());
+#if __cplusplus <= 201103L
+// expected-warning@-2 {{variable templates are a C++14 extension}}
+#endif
+
// FIXME: We know which type specifier should have been specified here. Provide
// a fix-it to add 'typename A<T>::type'
diff --git a/test/SemaCXX/unused.cpp b/test/SemaCXX/unused.cpp
index ba9ab2363b06..abaf611b0df8 100644
--- a/test/SemaCXX/unused.cpp
+++ b/test/SemaCXX/unused.cpp
@@ -6,7 +6,7 @@
// PR4103 : Make sure we don't get a bogus unused expression warning
namespace PR4103 {
class APInt {
- char foo;
+ char foo; // expected-warning {{private field 'foo' is not used}}
};
class APSInt : public APInt {
char bar; // expected-warning {{private field 'bar' is not used}}
diff --git a/test/SemaCXX/varargs.cpp b/test/SemaCXX/varargs.cpp
index f9027c247993..f2f53dc2001f 100644
--- a/test/SemaCXX/varargs.cpp
+++ b/test/SemaCXX/varargs.cpp
@@ -8,7 +8,7 @@ void f(const string& s, ...) { // expected-note {{parameter of type 'const stri
__builtin_va_start(ap, s); // expected-warning {{passing an object of reference type to 'va_start' has undefined behavior}}
}
-void g(register int i, ...) {
+void g(register int i, ...) { // expected-warning 0-1{{deprecated}}
__builtin_va_start(ap, i); // UB in C, OK in C++
}
diff --git a/test/SemaCXX/vartemplate-lambda.cpp b/test/SemaCXX/vartemplate-lambda.cpp
index 5b91e232e3a6..6744968bcc4d 100644
--- a/test/SemaCXX/vartemplate-lambda.cpp
+++ b/test/SemaCXX/vartemplate-lambda.cpp
@@ -8,7 +8,7 @@ template<typename T> auto v1 = [](int a = T(1)) { return a; }();
struct S {
template<class T>
- static constexpr T t = [](int f = T(7)){return f;}(); // expected-error{{constexpr variable 't<int>' must be initialized by a constant expression}} expected-error{{a lambda expression may not appear inside of a constant expression}} expected-note{{cannot be used in a constant expression}}
+ static constexpr T t = [](int f = T(7)){return f;}(); // expected-error{{constexpr variable 't<int>' must be initialized by a constant expression}} expected-note{{cannot be used in a constant expression}}
};
template <typename X>
diff --git a/test/SemaCXX/warn-absolute-value.cpp b/test/SemaCXX/warn-absolute-value.cpp
index 8a8a6fd67d34..9a23054fd1c2 100644
--- a/test/SemaCXX/warn-absolute-value.cpp
+++ b/test/SemaCXX/warn-absolute-value.cpp
@@ -448,94 +448,16 @@ void test_long_double(long double x) {
}
void test_complex_float(_Complex float x) {
- (void)abs(x);
- // expected-warning@-1 {{using integer absolute value function 'abs' when argument is of complex type}}
- // expected-note@-2 {{use function 'cabsf' instead}}
- // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:12}:"cabsf"
- (void)labs(x);
- // expected-warning@-1 {{using integer absolute value function 'labs' when argument is of complex type}}
- // expected-note@-2 {{use function 'cabsf' instead}}
- // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"cabsf"
- (void)llabs(x);
- // expected-warning@-1 {{using integer absolute value function 'llabs' when argument is of complex type}}
- // expected-note@-2 {{use function 'cabsf' instead}}
- // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"cabsf"
-
- (void)fabsf(x);
- // expected-warning@-1 {{using floating point absolute value function 'fabsf' when argument is of complex type}}
- // expected-note@-2 {{use function 'cabsf' instead}}
- // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"cabsf"
- (void)fabs(x);
- // expected-warning@-1 {{using floating point absolute value function 'fabs' when argument is of complex type}}
- // expected-note@-2 {{use function 'cabsf' instead}}
- // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"cabsf"
- (void)fabsl(x);
- // expected-warning@-1 {{using floating point absolute value function 'fabsl' when argument is of complex type}}
- // expected-note@-2 {{use function 'cabsf' instead}}
- // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"cabsf"
-
(void)cabsf(x);
(void)cabs(x);
(void)cabsl(x);
- (void)__builtin_abs(x);
- // expected-warning@-1 {{using integer absolute value function '__builtin_abs' when argument is of complex type}}
- // expected-note@-2 {{use function '__builtin_cabsf' instead}}
- // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:22}:"__builtin_cabsf"
- (void)__builtin_labs(x);
- // expected-warning@-1 {{using integer absolute value function '__builtin_labs' when argument is of complex type}}
- // expected-note@-2 {{use function '__builtin_cabsf' instead}}
- // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"__builtin_cabsf"
- (void)__builtin_llabs(x);
- // expected-warning@-1 {{using integer absolute value function '__builtin_llabs' when argument is of complex type}}
- // expected-note@-2 {{use function '__builtin_cabsf' instead}}
- // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_cabsf"
-
- (void)__builtin_fabsf(x);
- // expected-warning@-1 {{using floating point absolute value function '__builtin_fabsf' when argument is of complex type}}
- // expected-note@-2 {{use function '__builtin_cabsf' instead}}
- // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_cabsf"
- (void)__builtin_fabs(x);
- // expected-warning@-1 {{using floating point absolute value function '__builtin_fabs' when argument is of complex type}}
- // expected-note@-2 {{use function '__builtin_cabsf' instead}}
- // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"__builtin_cabsf"
- (void)__builtin_fabsl(x);
- // expected-warning@-1 {{using floating point absolute value function '__builtin_fabsl' when argument is of complex type}}
- // expected-note@-2 {{use function '__builtin_cabsf' instead}}
- // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_cabsf"
-
(void)__builtin_cabsf(x);
(void)__builtin_cabs(x);
(void)__builtin_cabsl(x);
}
void test_complex_double(_Complex double x) {
- (void)abs(x);
- // expected-warning@-1 {{using integer absolute value function 'abs' when argument is of complex type}}
- // expected-note@-2 {{use function 'cabs' instead}}
- // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:12}:"cabs"
- (void)labs(x);
- // expected-warning@-1 {{using integer absolute value function 'labs' when argument is of complex type}}
- // expected-note@-2 {{use function 'cabs' instead}}
- // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"cabs"
- (void)llabs(x);
- // expected-warning@-1 {{using integer absolute value function 'llabs' when argument is of complex type}}
- // expected-note@-2 {{use function 'cabs' instead}}
- // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"cabs"
-
- (void)fabsf(x);
- // expected-warning@-1 {{using floating point absolute value function 'fabsf' when argument is of complex type}}
- // expected-note@-2 {{use function 'cabs' instead}}
- // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"cabs"
- (void)fabs(x);
- // expected-warning@-1 {{using floating point absolute value function 'fabs' when argument is of complex type}}
- // expected-note@-2 {{use function 'cabs' instead}}
- // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"cabs"
- (void)fabsl(x);
- // expected-warning@-1 {{using floating point absolute value function 'fabsl' when argument is of complex type}}
- // expected-note@-2 {{use function 'cabs' instead}}
- // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"cabs"
-
(void)cabsf(x);
// expected-warning@-1 {{absolute value function 'cabsf' given an argument of type '_Complex double' but has parameter of type '_Complex float' which may cause truncation of value}}
// expected-note@-2 {{use function 'cabs' instead}}
@@ -543,31 +465,6 @@ void test_complex_double(_Complex double x) {
(void)cabs(x);
(void)cabsl(x);
- (void)__builtin_abs(x);
- // expected-warning@-1 {{using integer absolute value function '__builtin_abs' when argument is of complex type}}
- // expected-note@-2 {{use function '__builtin_cabs' instead}}
- // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:22}:"__builtin_cabs"
- (void)__builtin_labs(x);
- // expected-warning@-1 {{using integer absolute value function '__builtin_labs' when argument is of complex type}}
- // expected-note@-2 {{use function '__builtin_cabs' instead}}
- // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"__builtin_cabs"
- (void)__builtin_llabs(x);
- // expected-warning@-1 {{using integer absolute value function '__builtin_llabs' when argument is of complex type}}
- // expected-note@-2 {{use function '__builtin_cabs' instead}}
- // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_cabs"
-
- (void)__builtin_fabsf(x);
- // expected-warning@-1 {{using floating point absolute value function '__builtin_fabsf' when argument is of complex type}}
- // expected-note@-2 {{use function '__builtin_cabs' instead}}
- // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_cabs"
- (void)__builtin_fabs(x);
- // expected-warning@-1 {{using floating point absolute value function '__builtin_fabs' when argument is of complex type}}
- // expected-note@-2 {{use function '__builtin_cabs' instead}}
- // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"__builtin_cabs"
- (void)__builtin_fabsl(x);
- // expected-warning@-1 {{using floating point absolute value function '__builtin_fabsl' when argument is of complex type}}
- // expected-note@-2 {{use function '__builtin_cabs' instead}}
- // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_cabs"
(void)__builtin_cabsf(x);
// expected-warning@-1 {{absolute value function '__builtin_cabsf' given an argument of type '_Complex double' but has parameter of type '_Complex float' which may cause truncation of value}}
@@ -578,32 +475,6 @@ void test_complex_double(_Complex double x) {
}
void test_complex_long_double(_Complex long double x) {
- (void)abs(x);
- // expected-warning@-1 {{using integer absolute value function 'abs' when argument is of complex type}}
- // expected-note@-2 {{use function 'cabsl' instead}}
- // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:12}:"cabsl"
- (void)labs(x);
- // expected-warning@-1 {{using integer absolute value function 'labs' when argument is of complex type}}
- // expected-note@-2 {{use function 'cabsl' instead}}
- // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"cabsl"
- (void)llabs(x);
- // expected-warning@-1 {{using integer absolute value function 'llabs' when argument is of complex type}}
- // expected-note@-2 {{use function 'cabsl' instead}}
- // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"cabsl"
-
- (void)fabsf(x);
- // expected-warning@-1 {{using floating point absolute value function 'fabsf' when argument is of complex type}}
- // expected-note@-2 {{use function 'cabsl' instead}}
- // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"cabsl"
- (void)fabs(x);
- // expected-warning@-1 {{using floating point absolute value function 'fabs' when argument is of complex type}}
- // expected-note@-2 {{use function 'cabsl' instead}}
- // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"cabsl"
- (void)fabsl(x);
- // expected-warning@-1 {{using floating point absolute value function 'fabsl' when argument is of complex type}}
- // expected-note@-2 {{use function 'cabsl' instead}}
- // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"cabsl"
-
(void)cabsf(x);
// expected-warning@-1 {{absolute value function 'cabsf' given an argument of type '_Complex long double' but has parameter of type '_Complex float' which may cause truncation of value}}
// expected-note@-2 {{use function 'cabsl' instead}}
@@ -614,32 +485,6 @@ void test_complex_long_double(_Complex long double x) {
// CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"cabsl"
(void)cabsl(x);
- (void)__builtin_abs(x);
- // expected-warning@-1 {{using integer absolute value function '__builtin_abs' when argument is of complex type}}
- // expected-note@-2 {{use function '__builtin_cabsl' instead}}
- // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:22}:"__builtin_cabsl"
- (void)__builtin_labs(x);
- // expected-warning@-1 {{using integer absolute value function '__builtin_labs' when argument is of complex type}}
- // expected-note@-2 {{use function '__builtin_cabsl' instead}}
- // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"__builtin_cabsl"
- (void)__builtin_llabs(x);
- // expected-warning@-1 {{using integer absolute value function '__builtin_llabs' when argument is of complex type}}
- // expected-note@-2 {{use function '__builtin_cabsl' instead}}
- // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_cabsl"
-
- (void)__builtin_fabsf(x);
- // expected-warning@-1 {{using floating point absolute value function '__builtin_fabsf' when argument is of complex type}}
- // expected-note@-2 {{use function '__builtin_cabsl' instead}}
- // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_cabsl"
- (void)__builtin_fabs(x);
- // expected-warning@-1 {{using floating point absolute value function '__builtin_fabs' when argument is of complex type}}
- // expected-note@-2 {{use function '__builtin_cabsl' instead}}
- // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"__builtin_cabsl"
- (void)__builtin_fabsl(x);
- // expected-warning@-1 {{using floating point absolute value function '__builtin_fabsl' when argument is of complex type}}
- // expected-note@-2 {{use function '__builtin_cabsl' instead}}
- // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_cabsl"
-
(void)__builtin_cabsf(x);
// expected-warning@-1 {{absolute value function '__builtin_cabsf' given an argument of type '_Complex long double' but has parameter of type '_Complex float' which may cause truncation of value}}
// expected-note@-2 {{use function '__builtin_cabsl' instead}}
diff --git a/test/SemaCXX/warn-consumed-parsing.cpp b/test/SemaCXX/warn-consumed-parsing.cpp
index 179604141b7b..722a60bf9863 100644
--- a/test/SemaCXX/warn-consumed-parsing.cpp
+++ b/test/SemaCXX/warn-consumed-parsing.cpp
@@ -22,15 +22,15 @@ class AttrTester0 {
void callableWhen() __attribute__ ((callable_when())); // expected-error {{'callable_when' attribute takes at least 1 argument}}
};
-int var0 SET_TYPESTATE(consumed); // expected-warning {{'set_typestate' attribute only applies to methods}}
-int var1 TEST_TYPESTATE(consumed); // expected-warning {{'test_typestate' attribute only applies to methods}}
-int var2 CALLABLE_WHEN("consumed"); // expected-warning {{'callable_when' attribute only applies to methods}}
+int var0 SET_TYPESTATE(consumed); // expected-warning {{'set_typestate' attribute only applies to functions}}
+int var1 TEST_TYPESTATE(consumed); // expected-warning {{'test_typestate' attribute only applies to}}
+int var2 CALLABLE_WHEN("consumed"); // expected-warning {{'callable_when' attribute only applies to}}
int var3 CONSUMABLE(consumed); // expected-warning {{'consumable' attribute only applies to classes}}
int var4 RETURN_TYPESTATE(consumed); // expected-warning {{'return_typestate' attribute only applies to functions}}
-void function0() SET_TYPESTATE(consumed); // expected-warning {{'set_typestate' attribute only applies to methods}}
-void function1() TEST_TYPESTATE(consumed); // expected-warning {{'test_typestate' attribute only applies to methods}}
-void function2() CALLABLE_WHEN("consumed"); // expected-warning {{'callable_when' attribute only applies to methods}}
+void function0() SET_TYPESTATE(consumed); // expected-warning {{'set_typestate' attribute only applies to}}
+void function1() TEST_TYPESTATE(consumed); // expected-warning {{'test_typestate' attribute only applies to}}
+void function2() CALLABLE_WHEN("consumed"); // expected-warning {{'callable_when' attribute only applies to}}
void function3() CONSUMABLE(consumed); // expected-warning {{'consumable' attribute only applies to classes}}
class CONSUMABLE(unknown) AttrTester1 {
diff --git a/test/SemaCXX/warn-enum-compare.cpp b/test/SemaCXX/warn-enum-compare.cpp
index 0c287948cd09..21dea5dfcb00 100644
--- a/test/SemaCXX/warn-enum-compare.cpp
+++ b/test/SemaCXX/warn-enum-compare.cpp
@@ -1,9 +1,12 @@
-// RUN: %clang_cc1 %s -fsyntax-only -verify
+// RUN: %clang_cc1 %s -fsyntax-only -verify -triple %itanium_abi_triple
+// RUN: %clang_cc1 %s -fsyntax-only -verify -triple %ms_abi_triple -DMSABI
enum Foo { FooA, FooB, FooC };
enum Bar { BarD, BarE, BarF };
enum { AnonAA = 42, AnonAB = 43 };
enum { AnonBA = 44, AnonBB = 45 };
+enum { Anon1, Anon2, Anon3 };
+typedef enum { TD1, TD2 } TD;
namespace name1 {
enum Foo {F1, F2, F3};
@@ -29,6 +32,7 @@ void test () {
name1::Foo a;
oneFoo b;
twoFoo c;
+ TD td;
while (x == FooA);
while (y == BarD);
@@ -39,8 +43,10 @@ void test () {
while (b == c);
while (B1 == name1::B2);
while (B2 == name2::B1);
+#ifndef MSABI
while (x == AnonAA); // expected-warning {{comparison of constant 'AnonAA' (42) with expression of type 'Foo' is always false}}
while (AnonBB == y); // expected-warning {{comparison of constant 'AnonBB' (45) with expression of type 'Bar' is always false}}
+#endif
while (AnonAA == AnonAB);
while (AnonAB == AnonBA);
while (AnonBB == AnonAA);
@@ -65,6 +71,11 @@ void test () {
while ((((((B1))))) == (((name1::B2))));
while (B2 == ((((((name2::B1)))))));
+ while (td == Anon1);
+#ifndef MSABI
+ while (td == AnonAA); // expected-warning {{comparison of constant 'AnonAA' (42) with expression of type 'TD' is always false}}
+#endif
+
while (B1 == B2); // expected-warning {{comparison of two values with different enumeration types ('name1::Baz' and 'name2::Baz')}}
while (name1::B2 == name2::B3); // expected-warning {{comparison of two values with different enumeration types ('name1::Baz' and 'name2::Baz')}}
while (z == name2::B2); // expected-warning {{comparison of two values with different enumeration types ('name1::Baz' and 'name2::Baz')}}
@@ -209,4 +220,65 @@ void test () {
while (getBar() > x); // expected-warning {{comparison of two values with different enumeration types ('Bar' and 'Foo')}}
while (getBar() < x); // expected-warning {{comparison of two values with different enumeration types ('Bar' and 'Foo')}}
+ while (td == FooA); // expected-warning {{comparison of two values with different enumeration types ('TD' and 'Foo')}}
+ while (td == BarD); // expected-warning {{comparison of two values with different enumeration types ('TD' and 'Bar')}}
+ while (name1::F1 == td); // expected-warning {{comparison of two values with different enumeration types ('name1::Foo' and 'TD')}}
+ while (name2::B1 == td); // expected-warning {{comparison of two values with different enumeration types ('name2::Baz' and 'TD')}}
+ while (td == a); // expected-warning {{comparison of two values with different enumeration types ('TD' and 'name1::Foo')}}
+ while (td == b); // expected-warning {{comparison of two values with different enumeration types ('TD' and 'oneFoo' (aka 'name1::Foo'))}}
+ while (td == c); // expected-warning {{comparison of two values with different enumeration types ('TD' and 'twoFoo' (aka 'name1::Foo'))}}
+ while (td == x); // expected-warning {{comparison of two values with different enumeration types ('TD' and 'Foo')}}
+ while (td == y); // expected-warning {{comparison of two values with different enumeration types ('TD' and 'Bar')}}
+ while (td == z); // expected-warning {{comparison of two values with different enumeration types ('TD' and 'name1::Baz')}}
+
+ while (a == TD1); // expected-warning {{comparison of two values with different enumeration types ('name1::Foo' and 'TD')}}
+ while (b == TD2); // expected-warning {{comparison of two values with different enumeration types ('oneFoo' (aka 'name1::Foo') and 'TD')}}
+ while (c == TD1); // expected-warning {{comparison of two values with different enumeration types ('twoFoo' (aka 'name1::Foo') and 'TD')}}
+ while (x == TD2); // expected-warning {{comparison of two values with different enumeration types ('Foo' and 'TD')}}
+ while (y == TD1); // expected-warning {{comparison of two values with different enumeration types ('Bar' and 'TD')}}
+ while (z == TD2); // expected-warning {{comparison of two values with different enumeration types ('name1::Baz' and 'TD')}}
+
+ switch (a) {
+ case name1::F1: break;
+ case name1::F3: break;
+ case name2::B2: break; // expected-warning {{comparison of two values with different enumeration types in switch statement ('name1::Foo' and 'name2::Baz')}}
+ }
+
+ switch (x) {
+ case FooB: break;
+ case FooC: break;
+ case BarD: break; // expected-warning {{comparison of two values with different enumeration types in switch statement ('Foo' and 'Bar')}}
+ }
+
+ switch(getBar()) {
+ case BarE: break;
+ case BarF: break;
+ case FooA: break; // expected-warning {{comparison of two values with different enumeration types in switch statement ('Bar' and 'Foo')}}
+ }
+
+ switch(x) {
+ case AnonAA: break; // expected-warning {{case value not in enumerated type 'Foo'}}
+ case FooA: break;
+ case FooB: break;
+ case FooC: break;
+ }
+
+ switch (td) {
+ case TD1: break;
+ case FooB: break; // expected-warning {{comparison of two values with different enumeration types in switch statement ('TD' and 'Foo')}}
+ case BarF: break; // expected-warning {{comparison of two values with different enumeration types in switch statement ('TD' and 'Bar')}}
+ // expected-warning@-1 {{case value not in enumerated type 'TD'}}
+ case AnonAA: break; // expected-warning {{case value not in enumerated type 'TD'}}
+ }
+
+ switch (td) {
+ case Anon1: break;
+ case TD2: break;
+ }
+
+ switch (a) {
+ case TD1: break; // expected-warning {{comparison of two values with different enumeration types in switch statement ('name1::Foo' and 'TD')}}
+ case TD2: break; // expected-warning {{comparison of two values with different enumeration types in switch statement ('name1::Foo' and 'TD')}}
+ case name1::F3: break;
+ }
}
diff --git a/test/SemaCXX/warn-global-constructors.cpp b/test/SemaCXX/warn-global-constructors.cpp
index 856826414a8b..430f239a3ed7 100644
--- a/test/SemaCXX/warn-global-constructors.cpp
+++ b/test/SemaCXX/warn-global-constructors.cpp
@@ -126,3 +126,22 @@ namespace pr20420 {
void *array_storage[1];
const int &global_reference = *(int *)array_storage;
}
+
+namespace bitfields {
+ struct HasUnnamedBitfield {
+ unsigned a;
+ unsigned : 20;
+ unsigned b;
+
+ constexpr HasUnnamedBitfield() : a(), b() {}
+ constexpr HasUnnamedBitfield(unsigned a, unsigned b) : a(a), b(b) {}
+ explicit HasUnnamedBitfield(unsigned a) {}
+ };
+
+ const HasUnnamedBitfield zeroConst{};
+ HasUnnamedBitfield zeroMutable{};
+ const HasUnnamedBitfield explicitConst{1, 2};
+ HasUnnamedBitfield explicitMutable{1, 2};
+ const HasUnnamedBitfield nonConstexprConst{1}; // expected-warning {{global constructor}}
+ HasUnnamedBitfield nonConstexprMutable{1}; // expected-warning {{global constructor}}
+}
diff --git a/test/SemaCXX/warn-sign-conversion-cpp11.cpp b/test/SemaCXX/warn-sign-conversion-cpp11.cpp
new file mode 100644
index 000000000000..e18b7f564543
--- /dev/null
+++ b/test/SemaCXX/warn-sign-conversion-cpp11.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wsign-conversion -std=c++11 %s
+
+unsigned int test() {
+ short foo;
+ return foo; // expected-warning {{implicit conversion changes signedness}}
+
+}
+
+unsigned int test3() {
+ // For a non-defined enum, use the underlying type.
+ enum u8 : signed char;
+ u8 foo{static_cast<u8>(0)};
+ return foo; // expected-warning {{implicit conversion changes signedness}}
+
+}
+unsigned int test2() {
+ // For a non-defined enum, use the underlying type.
+ enum u8 : unsigned char;
+ u8 foo{static_cast<u8>(0)};
+ return foo;
+}
diff --git a/test/SemaCXX/warn-thread-safety-analysis.cpp b/test/SemaCXX/warn-thread-safety-analysis.cpp
index bbb4f9b48d36..fc1ea5e9e996 100644
--- a/test/SemaCXX/warn-thread-safety-analysis.cpp
+++ b/test/SemaCXX/warn-thread-safety-analysis.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wthread-safety -Wthread-safety-beta -Wno-thread-safety-negative -fcxx-exceptions %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wthread-safety -Wthread-safety-beta -Wno-thread-safety-negative -fcxx-exceptions -DUSE_ASSERT_CAPABILITY=0 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wthread-safety -Wthread-safety-beta -Wno-thread-safety-negative -fcxx-exceptions -DUSE_ASSERT_CAPABILITY=1 %s
// FIXME: should also run %clang_cc1 -fsyntax-only -verify -Wthread-safety -std=c++11 -Wc++98-compat %s
// FIXME: should also run %clang_cc1 -fsyntax-only -verify -Wthread-safety %s
@@ -13,8 +14,15 @@
#define ACQUIRED_BEFORE(...) __attribute__((acquired_before(__VA_ARGS__)))
#define EXCLUSIVE_LOCK_FUNCTION(...) __attribute__((exclusive_lock_function(__VA_ARGS__)))
#define SHARED_LOCK_FUNCTION(...) __attribute__((shared_lock_function(__VA_ARGS__)))
+
+#if USE_ASSERT_CAPABILITY
+#define ASSERT_EXCLUSIVE_LOCK(...) __attribute__((assert_capability(__VA_ARGS__)))
+#define ASSERT_SHARED_LOCK(...) __attribute__((assert_shared_capability(__VA_ARGS__)))
+#else
#define ASSERT_EXCLUSIVE_LOCK(...) __attribute__((assert_exclusive_lock(__VA_ARGS__)))
#define ASSERT_SHARED_LOCK(...) __attribute__((assert_shared_lock(__VA_ARGS__)))
+#endif
+
#define EXCLUSIVE_TRYLOCK_FUNCTION(...) __attribute__((exclusive_trylock_function(__VA_ARGS__)))
#define SHARED_TRYLOCK_FUNCTION(...) __attribute__((shared_trylock_function(__VA_ARGS__)))
#define UNLOCK_FUNCTION(...) __attribute__((unlock_function(__VA_ARGS__)))
@@ -3675,9 +3683,14 @@ class Foo {
SHARED_TRYLOCK_FUNCTION(true, mu2_);
void assertBoth() ASSERT_EXCLUSIVE_LOCK(mu1_)
ASSERT_EXCLUSIVE_LOCK(mu2_);
+
+ void alsoAssertBoth() ASSERT_EXCLUSIVE_LOCK(mu1_, mu2_);
+
void assertShared() ASSERT_SHARED_LOCK(mu1_)
ASSERT_SHARED_LOCK(mu2_);
+ void alsoAssertShared() ASSERT_SHARED_LOCK(mu1_, mu2_);
+
void test();
void testAssert();
void testAssertShared();
@@ -3741,17 +3754,33 @@ void Foo::test() {
// Force duplication of attributes
void Foo::assertBoth() { }
+void Foo::alsoAssertBoth() { }
void Foo::assertShared() { }
+void Foo::alsoAssertShared() { }
void Foo::testAssert() {
- assertBoth();
- a = 0;
- b = 0;
+ {
+ assertBoth();
+ a = 0;
+ b = 0;
+ }
+ {
+ alsoAssertBoth();
+ a = 0;
+ b = 0;
+ }
}
void Foo::testAssertShared() {
- assertShared();
- int zz = a + b;
+ {
+ assertShared();
+ int zz = a + b;
+ }
+
+ {
+ alsoAssertShared();
+ int zz = a + b;
+ }
}
@@ -4398,11 +4427,11 @@ namespace pt_guard_attribute_type {
int j PT_GUARDED_VAR; // expected-warning {{'pt_guarded_var' only applies to pointer types; type here is 'int'}}
void test() {
- int i PT_GUARDED_BY(sls_mu); // expected-warning {{'pt_guarded_by' attribute only applies to fields and global variables}}
- int j PT_GUARDED_VAR; // expected-warning {{'pt_guarded_var' attribute only applies to fields and global variables}}
+ int i PT_GUARDED_BY(sls_mu); // expected-warning {{'pt_guarded_by' attribute only applies to non-static data members and global variables}}
+ int j PT_GUARDED_VAR; // expected-warning {{'pt_guarded_var' attribute only applies to non-static data members and global variables}}
- typedef int PT_GUARDED_BY(sls_mu) bad1; // expected-warning {{'pt_guarded_by' attribute only applies to fields and global variables}}
- typedef int PT_GUARDED_VAR bad2; // expected-warning {{'pt_guarded_var' attribute only applies to fields and global variables}}
+ typedef int PT_GUARDED_BY(sls_mu) bad1; // expected-warning {{'pt_guarded_by' attribute only applies to}}
+ typedef int PT_GUARDED_VAR bad2; // expected-warning {{'pt_guarded_var' attribute only applies to}}
}
} // end namespace pt_guard_attribute_type
@@ -5204,3 +5233,18 @@ class acquired_before_empty_str {
} // expected-warning {{mutex 'lock_' is still held at the end of function}}
Mutex lock_ ACQUIRED_BEFORE("");
};
+
+namespace PR34800 {
+struct A {
+ operator int() const;
+};
+struct B {
+ bool g() __attribute__((locks_excluded(h))); // expected-warning {{'locks_excluded' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'int'}}
+ int h;
+};
+struct C {
+ B *operator[](int);
+};
+C c;
+void f() { c[A()]->g(); }
+} // namespace PR34800
diff --git a/test/SemaCXX/warn-thread-safety-parsing.cpp b/test/SemaCXX/warn-thread-safety-parsing.cpp
index ae32bfe9c913..ac357e8dae37 100644
--- a/test/SemaCXX/warn-thread-safety-parsing.cpp
+++ b/test/SemaCXX/warn-thread-safety-parsing.cpp
@@ -154,18 +154,18 @@ class GVFoo {
};
class GUARDED_VAR GV { // \
- // expected-warning {{'guarded_var' attribute only applies to fields and global variables}}
+ // expected-warning {{'guarded_var' attribute only applies to non-static data members and global variables}}
};
void gv_function() GUARDED_VAR; // \
- // expected-warning {{'guarded_var' attribute only applies to fields and global variables}}
+ // expected-warning {{'guarded_var' attribute only applies to}}
void gv_function_params(int gv_lvar GUARDED_VAR); // \
- // expected-warning {{'guarded_var' attribute only applies to fields and global variables}}
+ // expected-warning {{'guarded_var' attribute only applies to}}
int gv_testfn(int y){
int x GUARDED_VAR = y; // \
- // expected-warning {{'guarded_var' attribute only applies to fields and global variables}}
+ // expected-warning {{'guarded_var' attribute only applies to}}
return x;
}
@@ -194,7 +194,7 @@ class PGVFoo {
};
class PT_GUARDED_VAR PGV { // \
- // expected-warning {{'pt_guarded_var' attribute only applies to fields and global variables}}
+ // expected-warning {{'pt_guarded_var' attribute only applies to non-static data members and global variables}}
};
int *pgv_var_args __attribute__((pt_guarded_var(1))); // \
@@ -202,14 +202,14 @@ int *pgv_var_args __attribute__((pt_guarded_var(1))); // \
void pgv_function() PT_GUARDED_VAR; // \
- // expected-warning {{'pt_guarded_var' attribute only applies to fields and global variables}}
+ // expected-warning {{'pt_guarded_var' attribute only applies to}}
void pgv_function_params(int *gv_lvar PT_GUARDED_VAR); // \
- // expected-warning {{'pt_guarded_var' attribute only applies to fields and global variables}}
+ // expected-warning {{'pt_guarded_var' attribute only applies to}}
void pgv_testfn(int y){
int *x PT_GUARDED_VAR = new int(0); // \
- // expected-warning {{'pt_guarded_var' attribute only applies to fields and global variables}}
+ // expected-warning {{'pt_guarded_var' attribute only applies to}}
delete x;
}
@@ -231,28 +231,28 @@ class __attribute__((lockable (1))) LTestClass_args { // \
};
void l_test_function() LOCKABLE; // \
- // expected-warning {{'lockable' attribute only applies to struct, union or class}}
+ // expected-warning {{'lockable' attribute only applies to structs, unions, and classes}}
int l_testfn(int y) {
int x LOCKABLE = y; // \
- // expected-warning {{'lockable' attribute only applies to struct, union or class}}
+ // expected-warning {{'lockable' attribute only applies to}}
return x;
}
int l_test_var LOCKABLE; // \
- // expected-warning {{'lockable' attribute only applies to struct, union or class}}
+ // expected-warning {{'lockable' attribute only applies to}}
class LFoo {
private:
int test_field LOCKABLE; // \
- // expected-warning {{'lockable' attribute only applies to struct, union or class}}
+ // expected-warning {{'lockable' attribute only applies to}}
void test_method() LOCKABLE; // \
- // expected-warning {{'lockable' attribute only applies to struct, union or class}}
+ // expected-warning {{'lockable' attribute only applies to}}
};
void l_function_params(int lvar LOCKABLE); // \
- // expected-warning {{'lockable' attribute only applies to struct, union or class}}
+ // expected-warning {{'lockable' attribute only applies to}}
//-----------------------------------------//
@@ -271,28 +271,28 @@ class __attribute__((scoped_lockable (1))) SLTestClass_args { // \
};
void sl_test_function() SCOPED_LOCKABLE; // \
- // expected-warning {{'scoped_lockable' attribute only applies to struct, union or class}}
+ // expected-warning {{'scoped_lockable' attribute only applies to structs, unions, and classes}}
int sl_testfn(int y) {
int x SCOPED_LOCKABLE = y; // \
- // expected-warning {{'scoped_lockable' attribute only applies to struct, union or class}}
+ // expected-warning {{'scoped_lockable' attribute only applies to}}
return x;
}
int sl_test_var SCOPED_LOCKABLE; // \
- // expected-warning {{'scoped_lockable' attribute only applies to struct, union or class}}
+ // expected-warning {{'scoped_lockable' attribute only applies to}}
class SLFoo {
private:
int test_field SCOPED_LOCKABLE; // \
- // expected-warning {{'scoped_lockable' attribute only applies to struct, union or class}}
+ // expected-warning {{'scoped_lockable' attribute only applies to}}
void test_method() SCOPED_LOCKABLE; // \
- // expected-warning {{'scoped_lockable' attribute only applies to struct, union or class}}
+ // expected-warning {{'scoped_lockable' attribute only applies to}}
};
void sl_function_params(int lvar SCOPED_LOCKABLE); // \
- // expected-warning {{'scoped_lockable' attribute only applies to struct, union or class}}
+ // expected-warning {{'scoped_lockable' attribute only applies to}}
//-----------------------------------------//
@@ -325,18 +325,18 @@ class GBFoo {
};
class GUARDED_BY(mu1) GB { // \
- // expected-warning {{'guarded_by' attribute only applies to fields and global variables}}
+ // expected-warning {{'guarded_by' attribute only applies to non-static data members and global variables}}
};
void gb_function() GUARDED_BY(mu1); // \
- // expected-warning {{'guarded_by' attribute only applies to fields and global variables}}
+ // expected-warning {{'guarded_by' attribute only applies to}}
void gb_function_params(int gv_lvar GUARDED_BY(mu1)); // \
- // expected-warning {{'guarded_by' attribute only applies to fields and global variables}}
+ // expected-warning {{'guarded_by' attribute only applies to}}
int gb_testfn(int y){
int x GUARDED_BY(mu1) = y; // \
- // expected-warning {{'guarded_by' attribute only applies to fields and global variables}}
+ // expected-warning {{'guarded_by' attribute only applies to}}
return x;
}
@@ -351,7 +351,8 @@ int gb_var_arg_5 GUARDED_BY(&mu1);
int gb_var_arg_6 GUARDED_BY(muRef);
int gb_var_arg_7 GUARDED_BY(muDoubleWrapper.getWrapper()->getMu());
int gb_var_arg_8 GUARDED_BY(muPointer);
-
+int gb_var_arg_9 GUARDED_BY(!&mu1);
+int gb_var_arg_10 GUARDED_BY(!&*&mu1);
// illegal attribute arguments
int gb_var_arg_bad_1 GUARDED_BY(1); // \
@@ -396,18 +397,18 @@ class PGBFoo {
};
class PT_GUARDED_BY(mu1) PGB { // \
- // expected-warning {{'pt_guarded_by' attribute only applies to fields and global variables}}
+ // expected-warning {{'pt_guarded_by' attribute only applies to non-static data members and global variables}}
};
void pgb_function() PT_GUARDED_BY(mu1); // \
- // expected-warning {{'pt_guarded_by' attribute only applies to fields and global variables}}
+ // expected-warning {{'pt_guarded_by' attribute only applies to}}
void pgb_function_params(int gv_lvar PT_GUARDED_BY(mu1)); // \
- // expected-warning {{'pt_guarded_by' attribute only applies to fields and global variables}}
+ // expected-warning {{'pt_guarded_by' attribute only applies to}}
void pgb_testfn(int y){
int *x PT_GUARDED_BY(mu1) = new int(0); // \
- // expected-warning {{'pt_guarded_by' attribute only applies to fields and global variables}}
+ // expected-warning {{'pt_guarded_by' attribute only applies to}}
delete x;
}
@@ -458,18 +459,18 @@ class AAFoo {
};
class ACQUIRED_AFTER(mu1) AA { // \
- // expected-warning {{'acquired_after' attribute only applies to fields and global variables}}
+ // expected-warning {{'acquired_after' attribute only applies to non-static data members and global variables}}
};
void aa_function() ACQUIRED_AFTER(mu1); // \
- // expected-warning {{'acquired_after' attribute only applies to fields and global variables}}
+ // expected-warning {{'acquired_after' attribute only applies to}}
void aa_function_params(int gv_lvar ACQUIRED_AFTER(mu1)); // \
- // expected-warning {{'acquired_after' attribute only applies to fields and global variables}}
+ // expected-warning {{'acquired_after' attribute only applies to}}
void aa_testfn(int y){
Mutex x ACQUIRED_AFTER(mu1) = Mutex(); // \
- // expected-warning {{'acquired_after' attribute only applies to fields and global variables}}
+ // expected-warning {{'acquired_after' attribute only applies to}}
}
//Check argument parsing.
@@ -518,18 +519,18 @@ class ABFoo {
};
class ACQUIRED_BEFORE(mu1) AB { // \
- // expected-warning {{'acquired_before' attribute only applies to fields and global variables}}
+ // expected-warning {{'acquired_before' attribute only applies to non-static data members and global variables}}
};
void ab_function() ACQUIRED_BEFORE(mu1); // \
- // expected-warning {{'acquired_before' attribute only applies to fields and global variables}}
+ // expected-warning {{'acquired_before' attribute only applies to}}
void ab_function_params(int gv_lvar ACQUIRED_BEFORE(mu1)); // \
- // expected-warning {{'acquired_before' attribute only applies to fields and global variables}}
+ // expected-warning {{'acquired_before' attribute only applies to}}
void ab_testfn(int y){
Mutex x ACQUIRED_BEFORE(mu1) = Mutex(); // \
- // expected-warning {{'acquired_before' attribute only applies to fields and global variables}}
+ // expected-warning {{'acquired_before' attribute only applies to}}
}
// Note: illegal int ab_int ACQUIRED_BEFORE(mu1) will
diff --git a/test/SemaCXX/warn-throw-out-noexcept-func.cpp b/test/SemaCXX/warn-throw-out-noexcept-func.cpp
index 67ffbd93940a..a6c23ddc6c8f 100644
--- a/test/SemaCXX/warn-throw-out-noexcept-func.cpp
+++ b/test/SemaCXX/warn-throw-out-noexcept-func.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -fdelayed-template-parsing -fcxx-exceptions -fsyntax-only -Wexceptions -verify -std=c++11
+// RUN: %clang_cc1 %s -fdelayed-template-parsing -fcxx-exceptions -fsyntax-only -Wexceptions -verify -fdeclspec -std=c++11
struct A_ShouldDiag {
~A_ShouldDiag(); // implicitly noexcept(true)
};
@@ -14,6 +14,15 @@ struct R_ShouldDiag : A_ShouldDiag {
~R_ShouldDiag() { // expected-note {{destructor has a implicit non-throwing exception specification}}
throw 1; // expected-warning {{has a non-throwing exception specification but}}
}
+ __attribute__((nothrow)) R_ShouldDiag() {// expected-note {{function declared non-throwing here}}
+ throw 1;// expected-warning {{has a non-throwing exception specification but}}
+ }
+ void __attribute__((nothrow)) SomeThrow() {// expected-note {{function declared non-throwing here}}
+ throw 1; // expected-warning {{has a non-throwing exception specification but}}
+ }
+ void __declspec(nothrow) SomeDeclspecThrow() {// expected-note {{function declared non-throwing here}}
+ throw 1; // expected-warning {{has a non-throwing exception specification but}}
+ }
};
struct M_ShouldNotDiag {
@@ -230,13 +239,30 @@ void n_ShouldNotDiag() noexcept {
} catch (const S &s) {
}
}
-void o_ShouldDiag() noexcept { //expected-note {{function declared non-throwing here}}
+// As seen in p34973, this should not throw the warning. If there is an active
+// exception, catch(...) catches everything.
+void o_ShouldNotDiag() noexcept {
try {
- throw; //expected-warning {{has a non-throwing exception specification but}}
+ throw;
} catch (...) {
}
}
+void p_ShouldDiag() noexcept { //expected-note {{function declared non-throwing here}}
+ try {
+ throw; //expected-warning {{has a non-throwing exception specification but}}
+ } catch (int){
+ }
+}
+
+void q_ShouldNotDiag() noexcept {
+ try {
+ throw;
+ } catch (int){
+ } catch (...){
+ }
+}
+
#define NOEXCEPT noexcept
void with_macro() NOEXCEPT { //expected-note {{function declared non-throwing here}}
throw 1; // expected-warning {{has a non-throwing exception specification but}}
diff --git a/test/SemaCXX/warn-unreachable.cpp b/test/SemaCXX/warn-unreachable.cpp
index b08467ab51e6..08118147b751 100644
--- a/test/SemaCXX/warn-unreachable.cpp
+++ b/test/SemaCXX/warn-unreachable.cpp
@@ -49,22 +49,26 @@ void test3() {
(halt()); // expected-warning {{will never be executed}}
}
-void test4() {
+namespace Test4 {
struct S {
int mem;
} s;
S &foor();
- halt(), foor()// expected-warning {{will never be executed}}
- .mem;
+ void test4() {
+ halt(), foor()// expected-warning {{will never be executed}}
+ .mem;
+ }
}
-void test5() {
+namespace Test5 {
struct S {
int mem;
} s;
S &foonr() __attribute__((noreturn));
- foonr()
- .mem; // expected-warning {{will never be executed}}
+ void test5() {
+ foonr()
+ .mem; // expected-warning {{will never be executed}}
+ }
}
void test6() {
diff --git a/test/SemaCXX/warn-unused-attribute.cpp b/test/SemaCXX/warn-unused-attribute.cpp
index f52de3b931b0..dffda31f4646 100644
--- a/test/SemaCXX/warn-unused-attribute.cpp
+++ b/test/SemaCXX/warn-unused-attribute.cpp
@@ -15,6 +15,6 @@ int main(void) {
TestNormal normal;
used.use();
- int i __attribute__((warn_unused)) = 12; // expected-warning {{'warn_unused' attribute only applies to struct, union or class}}
+ int i __attribute__((warn_unused)) = 12; // expected-warning {{'warn_unused' attribute only applies to structs, unions, and classes}}
return i;
}
diff --git a/test/SemaCXX/warn-unused-lambda-capture.cpp b/test/SemaCXX/warn-unused-lambda-capture.cpp
index 6ad8e26604a4..52ec390b0bba 100644
--- a/test/SemaCXX/warn-unused-lambda-capture.cpp
+++ b/test/SemaCXX/warn-unused-lambda-capture.cpp
@@ -191,3 +191,12 @@ void test_templated() {
void test_use_template() {
test_templated<int>(); // expected-note{{in instantiation of function template specialization 'test_templated<int>' requested here}}
}
+
+namespace pr35555 {
+int a;
+void b() {
+ int c[a];
+ auto vla_used = [&c] { return c[0]; };
+ auto vla_unused = [&c] {}; // expected-warning{{lambda capture 'c' is not used}}
+}
+} // namespace pr35555
diff --git a/test/SemaCXX/warn-unused-private-field.cpp b/test/SemaCXX/warn-unused-private-field.cpp
index fb34fa98eaf6..fe44122a1d05 100644
--- a/test/SemaCXX/warn-unused-private-field.cpp
+++ b/test/SemaCXX/warn-unused-private-field.cpp
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -fsyntax-only -Wunused-private-field -Wused-but-marked-unused -Wno-uninitialized -verify -std=c++11 %s
+// RUN: %clang_cc1 -fsyntax-only -Wunused-private-field -Wused-but-marked-unused -Wno-uninitialized -verify -std=c++17 %s
class NotFullyDefined {
public:
@@ -246,3 +247,19 @@ namespace pr13543 {
X x[4]; // no-warning
};
}
+
+class implicit_special_member {
+public:
+ static implicit_special_member make() { return implicit_special_member(); }
+
+private:
+ int n; // expected-warning{{private field 'n' is not used}}
+};
+
+class defaulted_special_member {
+public:
+ defaulted_special_member(const defaulted_special_member&) = default;
+
+private:
+ int n; // expected-warning{{private field 'n' is not used}}
+};
diff --git a/test/SemaCXX/warn-unused-variables.cpp b/test/SemaCXX/warn-unused-variables.cpp
index d7be785b35a6..a7ac9afc36ad 100644
--- a/test/SemaCXX/warn-unused-variables.cpp
+++ b/test/SemaCXX/warn-unused-variables.cpp
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -fsyntax-only -Wunused-variable -Wunused-label -Wno-c++1y-extensions -verify %s
+// RUN: %clang_cc1 -fsyntax-only -Wunused-variable -Wunused-label -Wno-c++1y-extensions -verify -std=c++11 %s
template<typename T> void f() {
T t;
t = 17;
@@ -194,3 +195,45 @@ void test() {
}
}
+
+#if __cplusplus >= 201103L
+namespace with_constexpr {
+template <typename T>
+struct Literal {
+ T i;
+ Literal() = default;
+ constexpr Literal(T i) : i(i) {}
+};
+
+struct NoLiteral {
+ int i;
+ NoLiteral() = default;
+ constexpr NoLiteral(int i) : i(i) {}
+ ~NoLiteral() {}
+};
+
+static Literal<int> gl1; // expected-warning {{unused variable 'gl1'}}
+static Literal<int> gl2(1); // expected-warning {{unused variable 'gl2'}}
+static const Literal<int> gl3(0); // expected-warning {{unused variable 'gl3'}}
+
+template <typename T>
+void test(int i) {
+ Literal<int> l1; // expected-warning {{unused variable 'l1'}}
+ Literal<int> l2(42); // expected-warning {{unused variable 'l2'}}
+ Literal<int> l3(i); // no-warning
+ Literal<T> l4(0); // no-warning
+ NoLiteral nl1; // no-warning
+ NoLiteral nl2(42); // no-warning
+}
+}
+
+namespace crash {
+struct a {
+ a(const char *);
+};
+template <typename b>
+void c() {
+ a d(b::e ? "" : "");
+}
+}
+#endif
diff --git a/test/SemaCXX/warn-zero-nullptr.cpp b/test/SemaCXX/warn-zero-nullptr.cpp
index edd2a759b70f..45f05fa5703b 100644
--- a/test/SemaCXX/warn-zero-nullptr.cpp
+++ b/test/SemaCXX/warn-zero-nullptr.cpp
@@ -1,4 +1,10 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -Wzero-as-null-pointer-constant -std=c++11
+// RUN: %clang_cc1 -fsyntax-only -verify %s -isystem %S/Inputs -Wzero-as-null-pointer-constant -std=c++11
+// RUN: %clang_cc1 -fsyntax-only -verify %s -isystem %S/Inputs -DSYSTEM_WARNINGS -Wzero-as-null-pointer-constant -Wsystem-headers -std=c++11
+
+#include <warn-zero-nullptr.h>
+
+#define MACRO (0)
+#define MCRO(x) (x)
struct S {};
@@ -15,8 +21,12 @@ void* p2 = __null; // expected-warning{{zero as null pointer constant}}
void (*fp2)() = __null; // expected-warning{{zero as null pointer constant}}
int (S::*mp2) = __null; // expected-warning{{zero as null pointer constant}}
-void f0(void* v = 0); // expected-warning{{zero as null pointer constant}}
-void f1(void* v);
+void f0(void* v = MACRO); // expected-warning{{zero as null pointer constant}}
+void f1(void* v = NULL); // expected-warning{{zero as null pointer constant}}
+void f2(void* v = MCRO(0)); // expected-warning{{zero as null pointer constant}}
+void f3(void* v = MCRO(NULL)); // expected-warning{{zero as null pointer constant}}
+void f4(void* v = 0); // expected-warning{{zero as null pointer constant}}
+void f5(void* v);
void g() {
f1(0); // expected-warning{{zero as null pointer constant}}
@@ -25,3 +35,58 @@ void g() {
// Warn on these too. Matches gcc and arguably makes sense.
void* pp = (decltype(nullptr))0; // expected-warning{{zero as null pointer constant}}
void* pp2 = static_cast<decltype(nullptr)>(0); // expected-warning{{zero as null pointer constant}}
+
+// Shouldn't warn.
+namespace pr34362 {
+struct A { operator int*() { return nullptr; } };
+void func() { if (nullptr == A()) {} }
+void func2() { if ((nullptr) == A()) {} }
+}
+
+template <typename T> void TmplFunc0(T var) {}
+void Func0Test() {
+ TmplFunc0<int>(0);
+ TmplFunc0<int*>(0); // expected-warning {{zero as null pointer constant}}
+ TmplFunc0<void*>(0); // expected-warning {{zero as null pointer constant}}
+}
+
+// FIXME: this one probably should not warn.
+template <typename T> void TmplFunc1(int a, T default_value = 0) {} // expected-warning{{zero as null pointer constant}} expected-warning{{zero as null pointer constant}}
+void FuncTest() {
+ TmplFunc1<int>(0);
+ TmplFunc1<int*>(0); // expected-note {{in instantiation of default function argument expression for 'TmplFunc1<int *>' required here}}
+ TmplFunc1<void*>(0); // expected-note {{in instantiation of default function argument expression for 'TmplFunc1<void *>' required here}}
+}
+
+template<typename T>
+class TemplateClass0 {
+ public:
+ explicit TemplateClass0(T var) {}
+};
+void TemplateClass0Test() {
+ TemplateClass0<int> a(0);
+ TemplateClass0<int*> b(0); // expected-warning {{zero as null pointer constant}}
+ TemplateClass0<void*> c(0); // expected-warning {{zero as null pointer constant}}
+}
+
+template<typename T>
+class TemplateClass1 {
+ public:
+// FIXME: this one should *NOT* warn.
+ explicit TemplateClass1(int a, T default_value = 0) {} // expected-warning{{zero as null pointer constant}} expected-warning{{zero as null pointer constant}}
+};
+void IgnoreSubstTemplateType1() {
+ TemplateClass1<int> a(1);
+ TemplateClass1<int*> b(1); // expected-note {{in instantiation of default function argument expression for 'TemplateClass1<int *>' required here}}
+ TemplateClass1<void*> c(1); // expected-note {{in instantiation of default function argument expression for 'TemplateClass1<void *>' required here}}
+}
+
+#ifndef SYSTEM_WARNINGS
+// Do not warn on *any* other macros from system headers, even if they
+// expand to/their expansion contains NULL.
+void* sys_init = SYSTEM_MACRO;
+void* sys_init2 = OTHER_SYSTEM_MACRO;
+#else
+void* sys_init = SYSTEM_MACRO; // expected-warning {{zero as null pointer constant}}
+void* sys_init2 = OTHER_SYSTEM_MACRO; // expected-warning {{zero as null pointer constant}}
+#endif
diff --git a/test/SemaObjC/Inputs/empty.h b/test/SemaObjC/Inputs/empty.h
new file mode 100644
index 000000000000..6b3def4d7ae4
--- /dev/null
+++ b/test/SemaObjC/Inputs/empty.h
@@ -0,0 +1 @@
+struct S { int x; };
diff --git a/test/SemaObjC/arc-nsconsumed-errors.m b/test/SemaObjC/arc-nsconsumed-errors.m
index 62e74aabaffd..fd0d388ca9c6 100644
--- a/test/SemaObjC/arc-nsconsumed-errors.m
+++ b/test/SemaObjC/arc-nsconsumed-errors.m
@@ -1,6 +1,8 @@
-// RUN: %clang_cc1 -fsyntax-only -fobjc-arc -verify -fblocks -triple x86_64-apple-darwin10.0.0 %s
+// RUN: %clang_cc1 -fsyntax-only -fobjc-arc -verify -fblocks -triple x86_64-apple-darwin10.0.0 -DOBJCARC %s
+// RUN: %clang_cc1 -fsyntax-only -verify -fblocks -triple x86_64-apple-darwin10.0.0 %s
// rdar://10187884
+#ifdef OBJCARC
typedef void (^blk)(id arg1, __attribute((ns_consumed)) id arg2);
typedef void (^blk1)(__attribute((ns_consumed))id arg1, __attribute((ns_consumed)) id arg2);
blk a = ^void (__attribute((ns_consumed)) id arg1, __attribute((ns_consumed)) id arg2){}; // expected-error {{incompatible block pointer types initializing}}
@@ -18,3 +20,12 @@ blk1 b2 = ^void (id arg1, __attribute((ns_consumed)) id arg2){}; // expected-err
blk1 c3 = ^void (__attribute((ns_consumed)) id arg1, __attribute((ns_consumed)) id arg2){};
blk1 d4 = ^void (id arg1, id arg2) {}; // expected-error {{incompatible block pointer types initializing}}
+#else
+@interface Sub
+-(void) m:(id)p; // expected-note {{parameter declared here}}
+@end
+
+@interface Super : Sub
+-(void) m:(__attribute__((ns_consumed)) id)p; // expected-warning {{overriding method has mismatched ns_consumed attribute on its parameter}}
+@end
+#endif
diff --git a/test/SemaObjC/arc-property-lifetime.m b/test/SemaObjC/arc-property-lifetime.m
index cfa32d1028d9..b4b34036c7cd 100644
--- a/test/SemaObjC/arc-property-lifetime.m
+++ b/test/SemaObjC/arc-property-lifetime.m
@@ -172,7 +172,7 @@ void foo(Baz *f) {
// rdar://11253688
@interface Boom
{
- const void * innerPointerIvar __attribute__((objc_returns_inner_pointer)); // expected-error {{'objc_returns_inner_pointer' attribute only applies to methods and properties}}
+ const void * innerPointerIvar __attribute__((objc_returns_inner_pointer)); // expected-error {{'objc_returns_inner_pointer' attribute only applies to Objective-C methods and Objective-C properties}}
}
@property (readonly) Boom * NotInnerPointer __attribute__((objc_returns_inner_pointer)); // expected-warning {{'objc_returns_inner_pointer' attribute only applies to properties that return a non-retainable pointer}}
- (Boom *) NotInnerPointerMethod __attribute__((objc_returns_inner_pointer)); // expected-warning {{'objc_returns_inner_pointer' attribute only applies to methods that return a non-retainable pointer}}
diff --git a/test/SemaObjC/attr-availability.m b/test/SemaObjC/attr-availability.m
index 1245ac7409b8..da1a664e9122 100644
--- a/test/SemaObjC/attr-availability.m
+++ b/test/SemaObjC/attr-availability.m
@@ -196,7 +196,7 @@ __attribute__((availability(macosx, introduced = 10.8))) @interface PartialI2
@end
#if defined(WARN_PARTIAL)
-// expected-warning@+2 {{'PartialI2' is partial: introduced in macOS 10.8}} expected-note@+2 {{annotate 'partialinter1' with an availability attribute to silence}}
+// expected-warning@+2 {{'PartialI2' is only available on macOS 10.8 or newer}} expected-note@+2 {{annotate 'partialinter1' with an availability attribute to silence}}
#endif
void partialinter1(PartialI2* p) {
}
@@ -204,7 +204,7 @@ void partialinter1(PartialI2* p) {
@class PartialI2;
#ifdef WARN_PARTIAL
-// expected-warning@+2 {{'PartialI2' is partial: introduced in macOS 10.8}} expected-note@+2 {{annotate 'partialinter2' with an availability attribute to silence}}
+// expected-warning@+2 {{'PartialI2' is only available on macOS 10.8 or newer}} expected-note@+2 {{annotate 'partialinter2' with an availability attribute to silence}}
#endif
void partialinter2(PartialI2* p) {
}
diff --git a/test/SemaObjC/block-literal-with-attribute.m b/test/SemaObjC/block-literal-with-attribute.m
new file mode 100644
index 000000000000..2a8057927ee5
--- /dev/null
+++ b/test/SemaObjC/block-literal-with-attribute.m
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -fsyntax-only %s -verify -fblocks -fobjc-arc
+// RUN: %clang_cc1 -fsyntax-only %s -verify -fblocks
+
+__auto_type block = ^ id __attribute__((ns_returns_retained)) (id filter) {
+ return filter; // ok
+};
+__auto_type block2 = ^ __attribute__((ns_returns_retained)) id (id filter) {
+ return filter; // ok
+};
+__auto_type block3 = ^ id (id filter) __attribute__((ns_returns_retained)) {
+ return filter; // ok
+};
+
+// expected-no-diagnostics
diff --git a/test/SemaObjC/default-synthesize-1.m b/test/SemaObjC/default-synthesize-1.m
index 731aa863e103..573434b3b324 100644
--- a/test/SemaObjC/default-synthesize-1.m
+++ b/test/SemaObjC/default-synthesize-1.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -Wobjc-missing-property-synthesis -verify -Wno-objc-root-class %s
+// RUN: %clang_cc1 -fsyntax-only -Wobjc-missing-property-synthesis -verify -Wno-objc-root-class -triple=x86_64-apple-macos10.10 %s
// rdar://11295716
@interface NSObject
@@ -141,3 +141,17 @@
return _description; // expected-error {{use of undeclared identifier '_description'}}
}
@end
+
+@interface DontWarnOnUnavailable
+
+// No warning expected:
+@property (nonatomic, readonly) int un1 __attribute__((unavailable));
+@property (readwrite) int un2 __attribute__((availability(macos, unavailable)));
+
+@property (readwrite) int un3 __attribute__((availability(ios, unavailable))); // expected-warning {{auto property synthesis is synthesizing property not explicitly synthesized}}
+
+@end
+
+@implementation DontWarnOnUnavailable // expected-note {{detected while default synthesizing properties in class implementation}}
+
+@end
diff --git a/test/SemaObjC/dllexport.m b/test/SemaObjC/dllexport.m
index e90b982c15c0..11cd1fbe14e6 100644
--- a/test/SemaObjC/dllexport.m
+++ b/test/SemaObjC/dllexport.m
@@ -1,17 +1,17 @@
// RUN: %clang_cc1 -triple i686-windows -fdeclspec -fsyntax-only -verify %s
__declspec(dllexport) typedef int typedef1;
-// expected-warning@-1{{'dllexport' attribute only applies to functions, variables, and Objective-C interfaces}}
+// expected-warning@-1{{'dllexport' attribute only applies to functions, variables, classes, and Objective-C interfaces}}
typedef __declspec(dllexport) int typedef2;
-// expected-warning@-1{{'dllexport' attribute only applies to functions, variables, and Objective-C interfaces}}
+// expected-warning@-1{{'dllexport' attribute only applies to}}
typedef int __declspec(dllexport) typedef3;
-// expected-warning@-1{{'dllexport' attribute only applies to functions, variables, and Objective-C interfaces}}
+// expected-warning@-1{{'dllexport' attribute only applies to}}
typedef __declspec(dllexport) void (*FunTy)();
-// expected-warning@-1{{'dllexport' attribute only applies to functions, variables, and Objective-C interfaces}}
+// expected-warning@-1{{'dllexport' attribute only applies to}}
enum __declspec(dllexport) E { Val };
-// expected-warning@-1{{'dllexport' attribute only applies to functions, variables, and Objective-C interfaces}}
+// expected-warning@-1{{'dllexport' attribute only applies to}}
struct __declspec(dllexport) Record {};
-// expected-warning@-1{{'dllexport' attribute only applies to functions, variables, and Objective-C interfaces}}
+// expected-warning@-1{{'dllexport' attribute only applies to}}
__declspec(dllexport)
__attribute__((__objc_root_class__))
diff --git a/test/SemaObjC/dllimport.m b/test/SemaObjC/dllimport.m
index b8360773c69b..ea87aea9b8da 100644
--- a/test/SemaObjC/dllimport.m
+++ b/test/SemaObjC/dllimport.m
@@ -1,17 +1,17 @@
// RUN: %clang_cc1 -triple i686-windows -fdeclspec -fsyntax-only -verify %s
__declspec(dllimport) typedef int typedef1;
-// expected-warning@-1{{'dllimport' attribute only applies to functions, variables, and Objective-C interfaces}}
+// expected-warning@-1{{'dllimport' attribute only applies to functions, variables, classes, and Objective-C interfaces}}
typedef __declspec(dllimport) int typedef2;
-// expected-warning@-1{{'dllimport' attribute only applies to functions, variables, and Objective-C interfaces}}
+// expected-warning@-1{{'dllimport' attribute only applies to}}
typedef int __declspec(dllimport) typedef3;
-// expected-warning@-1{{'dllimport' attribute only applies to functions, variables, and Objective-C interfaces}}
+// expected-warning@-1{{'dllimport' attribute only applies to}}
typedef __declspec(dllimport) void (*FunTy)();
-// expected-warning@-1{{'dllimport' attribute only applies to functions, variables, and Objective-C interfaces}}
+// expected-warning@-1{{'dllimport' attribute only applies to}}
enum __declspec(dllimport) E { Val };
-// expected-warning@-1{{'dllimport' attribute only applies to functions, variables, and Objective-C interfaces}}
+// expected-warning@-1{{'dllimport' attribute only applies to}}
struct __declspec(dllimport) Record {};
-// expected-warning@-1{{'dllimport' attribute only applies to functions, variables, and Objective-C interfaces}}
+// expected-warning@-1{{'dllimport' attribute only applies to}}
__declspec(dllimport)
__attribute__((__objc_root_class__))
diff --git a/test/SemaObjC/flexible-array-arc.m b/test/SemaObjC/flexible-array-arc.m
new file mode 100644
index 000000000000..1490329b183c
--- /dev/null
+++ b/test/SemaObjC/flexible-array-arc.m
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -fsyntax-only -fobjc-arc -verify -Wno-objc-root-class %s
+// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class -DNOARC %s
+#ifdef NOARC
+// expected-no-diagnostics
+#endif
+
+@interface RetainableArray {
+ id flexible[];
+#ifndef NOARC
+ // expected-error@-2 {{ARC forbids flexible array members with retainable object type}}
+#endif
+}
+@end
+@implementation RetainableArray
+@end
+
+// Emit diagnostic only if have @implementation.
+@interface RetainableArrayWithoutImpl {
+ id flexible[];
+}
+@end
+
+// With ARC flexible array member objects can be only __unsafe_unretained
+@interface UnsafeUnretainedArray {
+ __unsafe_unretained id flexible[];
+}
+@end
+@implementation UnsafeUnretainedArray
+@end
+
+@interface NotObjCLifetimeTypeArray {
+ char flexible[];
+}
+@end
+@implementation NotObjCLifetimeTypeArray
+@end
diff --git a/test/SemaObjC/flexible-array.m b/test/SemaObjC/flexible-array.m
new file mode 100644
index 000000000000..68e32d851f62
--- /dev/null
+++ b/test/SemaObjC/flexible-array.m
@@ -0,0 +1,288 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s
+
+// # Flexible array member.
+// ## Instance variables only in interface.
+@interface LastIvar {
+ char flexible[];
+}
+@end
+
+@interface NotLastIvar {
+ char flexible[]; // expected-error {{flexible array member 'flexible' with type 'char []' is not at the end of class}}
+ int last; // expected-note {{next instance variable declaration is here}}
+}
+@end
+
+// ## Instance variables in implementation.
+@interface LastIvarInImpl
+@end
+@implementation LastIvarInImpl {
+ char flexible[]; // expected-warning {{field 'flexible' with variable sized type 'char []' is not visible to subclasses and can conflict with their instance variables}}
+}
+@end
+
+@interface NotLastIvarInImpl
+@end
+@implementation NotLastIvarInImpl {
+ char flexible[]; // expected-error {{flexible array member 'flexible' with type 'char []' is not at the end of class}}
+ // expected-warning@-1 {{field 'flexible' with variable sized type 'char []' is not visible to subclasses and can conflict with their instance variables}}
+ int last; // expected-note {{next instance variable declaration is here}}
+}
+@end
+
+@implementation NotLastIvarInImplWithoutInterface { // expected-warning {{cannot find interface declaration for 'NotLastIvarInImplWithoutInterface'}}
+ char flexible[]; // expected-error {{flexible array member 'flexible' with type 'char []' is not at the end of class}}
+ // expected-warning@-1 {{field 'flexible' with variable sized type 'char []' is not visible to subclasses and can conflict with their instance variables}}
+ int last; // expected-note {{next instance variable declaration is here}}
+}
+@end
+
+@interface LastIvarInClass_OtherIvarInImpl {
+ char flexible[]; // expected-error {{flexible array member 'flexible' with type 'char []' is not at the end of class}}
+}
+@end
+@implementation LastIvarInClass_OtherIvarInImpl {
+ int last; // expected-note {{next instance variable declaration is here}}
+}
+@end
+
+// ## Non-instance variables in implementation.
+@interface LastIvarInClass_UnrelatedVarInImpl {
+ char flexible[];
+}
+@end
+@implementation LastIvarInClass_UnrelatedVarInImpl
+int nonIvar;
+@end
+
+// ## Instance variables in class extension.
+@interface LastIvarInExtension
+@end
+@interface LastIvarInExtension() {
+ char flexible[]; // expected-warning {{field 'flexible' with variable sized type 'char []' is not visible to subclasses and can conflict with their instance variables}}
+}
+@end
+
+@interface NotLastIvarInExtension
+@end
+@interface NotLastIvarInExtension() {
+ char flexible[]; // expected-error {{flexible array member 'flexible' with type 'char []' is not at the end of class}}
+ // expected-warning@-1 {{field 'flexible' with variable sized type 'char []' is not visible to subclasses and can conflict with their instance variables}}
+ int last; // expected-note {{next instance variable declaration is here}}
+}
+@end
+
+@interface LastIvarInClass_OtherIvarInExtension {
+ char flexible[]; // expected-error {{flexible array member 'flexible' with type 'char []' is not at the end of class}}
+}
+@end
+@interface LastIvarInClass_OtherIvarInExtension() {
+ int last; // expected-note {{next instance variable declaration is here}}
+}
+@end
+
+@interface LastIvarInExtension_OtherIvarInExtension
+@end
+@interface LastIvarInExtension_OtherIvarInExtension() {
+ int last; // expected-note {{next instance variable declaration is here}}
+}
+@end
+@interface LastIvarInExtension_OtherIvarInExtension()
+// Extension without ivars to test we see through such extensions.
+@end
+@interface LastIvarInExtension_OtherIvarInExtension() {
+ char flexible[]; // expected-error {{flexible array member 'flexible' with type 'char []' is not at the end of class}}
+ // expected-warning@-1 {{field 'flexible' with variable sized type 'char []' is not visible to subclasses and can conflict with their instance variables}}
+}
+@end
+
+@interface LastIvarInExtension_OtherIvarInImpl
+@end
+@interface LastIvarInExtension_OtherIvarInImpl() {
+ char flexible[]; // expected-error {{flexible array member 'flexible' with type 'char []' is not at the end of class}}
+ // expected-warning@-1 {{field 'flexible' with variable sized type 'char []' is not visible to subclasses and can conflict with their instance variables}}
+}
+@end
+@implementation LastIvarInExtension_OtherIvarInImpl {
+ int last; // expected-note {{next instance variable declaration is here}}
+}
+@end
+
+// ## Instance variables in named categories.
+@interface IvarInNamedCategory
+@end
+@interface IvarInNamedCategory(Category) {
+ char flexible[]; // expected-error {{instance variables may not be placed in categories}}
+}
+@end
+
+// ## Synthesized instance variable.
+@interface LastIvarAndProperty {
+ char _flexible[];
+}
+@property char flexible[]; // expected-error {{property cannot have array or function type 'char []'}}
+@end
+
+// ## Synthesize other instance variables.
+@interface LastIvar_ExplicitlyNamedPropertyBackingIvarPreceding {
+ int _elementsCount;
+ char flexible[];
+}
+@property int count;
+@end
+@implementation LastIvar_ExplicitlyNamedPropertyBackingIvarPreceding
+@synthesize count = _elementsCount;
+@end
+
+@interface LastIvar_ImplicitlyNamedPropertyBackingIvarPreceding {
+ int count;
+ char flexible[];
+}
+@property int count;
+@end
+@implementation LastIvar_ImplicitlyNamedPropertyBackingIvarPreceding
+@synthesize count;
+@end
+
+@interface NotLastIvar_ExplicitlyNamedPropertyBackingIvarLast {
+ char flexible[]; // expected-error {{flexible array member 'flexible' with type 'char []' is not at the end of class}}
+}
+@property int count;
+@end
+@implementation NotLastIvar_ExplicitlyNamedPropertyBackingIvarLast
+@synthesize count = _elementsCount; // expected-note {{next synthesized instance variable is here}}
+@end
+
+@interface NotLastIvar_ImplicitlyNamedPropertyBackingIvarLast {
+ char flexible[]; // expected-error {{flexible array member 'flexible' with type 'char []' is not at the end of class}}
+}
+@property int count; // expected-note {{next synthesized instance variable is here}}
+@end
+@implementation NotLastIvar_ImplicitlyNamedPropertyBackingIvarLast
+// Test auto-synthesize.
+//@synthesize count;
+@end
+
+
+// # Variable sized types.
+struct Packet {
+ unsigned int size;
+ char data[];
+};
+
+// ## Instance variables only in interface.
+@interface LastStructIvar {
+ struct Packet flexible;
+}
+@end
+
+@interface NotLastStructIvar {
+ struct Packet flexible; // expected-error {{field 'flexible' with variable sized type 'struct Packet' is not at the end of class}}
+ int last; // expected-note {{next instance variable declaration is here}}
+}
+@end
+
+// ## Instance variables in implementation.
+@interface LastStructIvarInImpl
+@end
+@implementation LastStructIvarInImpl {
+ struct Packet flexible; // expected-warning {{field 'flexible' with variable sized type 'struct Packet' is not visible to subclasses and can conflict with their instance variables}}
+}
+@end
+
+@interface NotLastStructIvarInImpl
+@end
+@implementation NotLastStructIvarInImpl {
+ struct Packet flexible; // expected-error {{field 'flexible' with variable sized type 'struct Packet' is not at the end of class}}
+ // expected-warning@-1 {{field 'flexible' with variable sized type 'struct Packet' is not visible to subclasses and can conflict with their instance variables}}
+ int last; // expected-note {{next instance variable declaration is here}}
+}
+@end
+
+@interface LastStructIvarInClass_OtherIvarInImpl {
+ struct Packet flexible; // expected-error {{field 'flexible' with variable sized type 'struct Packet' is not at the end of class}}
+}
+@end
+@implementation LastStructIvarInClass_OtherIvarInImpl {
+ int last; // expected-note {{next instance variable declaration is here}}
+}
+@end
+
+// ## Synthesized instance variable.
+@interface LastSynthesizeStructIvar
+@property int first;
+@property struct Packet flexible; // expected-error {{synthesized property with variable size type 'struct Packet' requires an existing instance variable}}
+@end
+@implementation LastSynthesizeStructIvar
+@end
+
+@interface NotLastSynthesizeStructIvar
+@property struct Packet flexible; // expected-error {{synthesized property with variable size type 'struct Packet' requires an existing instance variable}}
+@property int last;
+@end
+@implementation NotLastSynthesizeStructIvar
+@end
+
+@interface LastStructIvarWithExistingIvarAndSynthesizedProperty {
+ struct Packet _flexible;
+}
+@property struct Packet flexible;
+@end
+@implementation LastStructIvarWithExistingIvarAndSynthesizedProperty
+@end
+
+
+// # Subclasses.
+@interface FlexibleArrayMemberBase {
+ char flexible[]; // expected-note6 {{'flexible' declared here}}
+}
+@end
+
+@interface NoIvarAdditions : FlexibleArrayMemberBase
+@end
+@implementation NoIvarAdditions
+@end
+
+@interface AddedIvarInInterface : FlexibleArrayMemberBase {
+ int last; // expected-warning {{field 'last' can overwrite instance variable 'flexible' with variable sized type 'char []' in superclass 'FlexibleArrayMemberBase'}}
+}
+@end
+
+@interface AddedIvarInImplementation : FlexibleArrayMemberBase
+@end
+@implementation AddedIvarInImplementation {
+ int last; // expected-warning {{field 'last' can overwrite instance variable 'flexible' with variable sized type 'char []' in superclass 'FlexibleArrayMemberBase'}}
+}
+@end
+
+@interface AddedIvarInExtension : FlexibleArrayMemberBase
+@end
+@interface AddedIvarInExtension() {
+ int last; // expected-warning {{field 'last' can overwrite instance variable 'flexible' with variable sized type 'char []' in superclass 'FlexibleArrayMemberBase'}}
+}
+@end
+
+@interface SynthesizedIvar : FlexibleArrayMemberBase
+@property int count;
+@end
+@implementation SynthesizedIvar
+@synthesize count; // expected-warning {{field 'count' can overwrite instance variable 'flexible' with variable sized type 'char []' in superclass 'FlexibleArrayMemberBase'}}
+@end
+
+@interface WarnInSubclassOnlyOnce : FlexibleArrayMemberBase {
+ int last; // expected-warning {{field 'last' can overwrite instance variable 'flexible' with variable sized type 'char []' in superclass 'FlexibleArrayMemberBase'}}
+}
+@end
+@interface WarnInSubclassOnlyOnce() {
+ int laster;
+}
+@end
+@implementation WarnInSubclassOnlyOnce {
+ int lastest;
+}
+@end
+
+@interface AddedIvarInSubSubClass : NoIvarAdditions {
+ int last; // expected-warning {{field 'last' can overwrite instance variable 'flexible' with variable sized type 'char []' in superclass 'FlexibleArrayMemberBase'}}
+}
+@end
diff --git a/test/SemaObjC/format-arg-attribute.m b/test/SemaObjC/format-arg-attribute.m
index 8ad34e38738c..67c9c2e3d4c9 100644
--- a/test/SemaObjC/format-arg-attribute.m
+++ b/test/SemaObjC/format-arg-attribute.m
@@ -9,9 +9,9 @@ extern void fc1 (const NSString *) __attribute__((format_arg)); // expected-err
extern void fc2 (const NSString *) __attribute__((format_arg())); // expected-error {{'format_arg' attribute takes one argument}}
extern void fc3 (const NSString *) __attribute__((format_arg(1, 2))); // expected-error {{'format_arg' attribute takes one argument}}
-struct s1 { int i; } __attribute__((format_arg(1))); // expected-warning {{'format_arg' attribute only applies to non-K&R-style functions}}
-union u1 { int i; } __attribute__((format_arg(1))); // expected-warning {{'format_arg' attribute only applies to non-K&R-style functions}}
-enum e1 { E1V0 } __attribute__((format_arg(1))); // expected-warning {{'format_arg' attribute only applies to non-K&R-style functions}}
+struct s1 { int i; } __attribute__((format_arg(1))); // expected-warning {{'format_arg' attribute only applies to Objective-C methods and non-K&R-style functions}}
+union u1 { int i; } __attribute__((format_arg(1))); // expected-warning {{'format_arg' attribute only applies to}}
+enum e1 { E1V0 } __attribute__((format_arg(1))); // expected-warning {{'format_arg' attribute only applies to}}
extern NSString *ff3 (const NSString *) __attribute__((format_arg(3-2)));
extern NSString *ff4 (const NSString *) __attribute__((format_arg(foo))); // expected-error {{use of undeclared identifier 'foo'}}
diff --git a/test/SemaObjC/ivar-sem-check-1.m b/test/SemaObjC/ivar-sem-check-1.m
index de038f5487b5..48e0a54b628b 100644
--- a/test/SemaObjC/ivar-sem-check-1.m
+++ b/test/SemaObjC/ivar-sem-check-1.m
@@ -6,14 +6,15 @@ typedef int FOO();
@interface INTF
{
struct F {} JJ;
- int arr[]; // expected-error {{field has incomplete type}}
+ int arr[]; // expected-error {{flexible array member 'arr' with type 'int []' is not at the end of class}}
struct S IC; // expected-error {{field has incomplete type}}
+ // expected-note@-1 {{next instance variable declaration is here}}
struct T { // expected-note {{previous definition is here}}
struct T {} X; // expected-error {{nested redefinition of 'T'}}
}YYY;
FOO BADFUNC; // expected-error {{field 'BADFUNC' declared as a function}}
int kaka; // expected-note {{previous declaration is here}}
int kaka; // expected-error {{duplicate member 'kaka'}}
- char ch[]; // expected-error {{field has incomplete type}}
+ char ch[];
}
@end
diff --git a/test/SemaObjC/objc-asm-attribute-neg-test.m b/test/SemaObjC/objc-asm-attribute-neg-test.m
index 2fb6643adde4..98f39fb90013 100644
--- a/test/SemaObjC/objc-asm-attribute-neg-test.m
+++ b/test/SemaObjC/objc-asm-attribute-neg-test.m
@@ -15,15 +15,15 @@ __attribute__((objc_runtime_name("MySecretNamespace.Protocol")))
__attribute__((objc_runtime_name("MySecretNamespace.Message")))
@interface Message <Protocol> {
-__attribute__((objc_runtime_name("MySecretNamespace.Message"))) // expected-error {{'objc_runtime_name' attribute only applies to interface or protocol declarations}}
+__attribute__((objc_runtime_name("MySecretNamespace.Message"))) // expected-error {{'objc_runtime_name' attribute only applies to Objective-C interfaces and Objective-C protocols}}
id MyIVAR;
}
__attribute__((objc_runtime_name("MySecretNamespace.Message")))
@property int MyProperty; // expected-error {{prefix attribute must be followed by an interface or protocol}}}}
-- (int) getMyProperty __attribute__((objc_runtime_name("MySecretNamespace.Message"))); // expected-error {{'objc_runtime_name' attribute only applies to interface or protocol declarations}}
+- (int) getMyProperty __attribute__((objc_runtime_name("MySecretNamespace.Message"))); // expected-error {{'objc_runtime_name' attribute only applies to}}
-- (void) setMyProperty : (int) arg __attribute__((objc_runtime_name("MySecretNamespace.Message"))); // expected-error {{'objc_runtime_name' attribute only applies to interface or protocol declarations}}
+- (void) setMyProperty : (int) arg __attribute__((objc_runtime_name("MySecretNamespace.Message"))); // expected-error {{'objc_runtime_name' attribute only applies to}}
@end
diff --git a/test/SemaObjC/objcbridge-attribute-arc.m b/test/SemaObjC/objcbridge-attribute-arc.m
index 3bcfdf48e794..f7473cc0f32a 100644
--- a/test/SemaObjC/objcbridge-attribute-arc.m
+++ b/test/SemaObjC/objcbridge-attribute-arc.m
@@ -32,7 +32,7 @@ typedef XXX *CFUColor2Ref;
@interface I
{
- __attribute__((objc_bridge(NSError))) void * color; // expected-error {{'objc_bridge' attribute only applies to structs, unions, and typedefs}};
+ __attribute__((objc_bridge(NSError))) void * color; // expected-error {{'objc_bridge' attribute only applies to structs, unions, classes, and typedefs}};
}
@end
diff --git a/test/SemaObjC/objcbridge-attribute.m b/test/SemaObjC/objcbridge-attribute.m
index 9cab64ec6b28..c93543caa679 100644
--- a/test/SemaObjC/objcbridge-attribute.m
+++ b/test/SemaObjC/objcbridge-attribute.m
@@ -38,7 +38,7 @@ typedef struct Opaque *OpaqueRef __attribute__((objc_bridge(id))); // expected-e
@interface I
{
- __attribute__((objc_bridge(NSError))) void * color; // expected-error {{'objc_bridge' attribute only applies to structs, unions, and typedefs}};
+ __attribute__((objc_bridge(NSError))) void * color; // expected-error {{'objc_bridge' attribute only applies to structs, unions, classes, and typedefs}};
}
@end
diff --git a/test/SemaObjC/property-implement-readonly-with-custom-setter.m b/test/SemaObjC/property-implement-readonly-with-custom-setter.m
new file mode 100644
index 000000000000..7ac138076751
--- /dev/null
+++ b/test/SemaObjC/property-implement-readonly-with-custom-setter.m
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s
+// rdar://34192541
+
+@class NSString;
+
+@protocol MyProtocol
+@property (nonatomic, strong, readonly) NSString *myString;
+@end
+
+@interface MyClass <MyProtocol>
+// Don't warn about this setter:
+@property (nonatomic, strong, setter=setMYString:) NSString *myString;
+
+
+@property (nonatomic, strong, readonly) NSString *overridenInClass; // expected-note {{property declared here}}
+@end
+
+@interface MySubClass: MyClass
+@property (nonatomic, strong, setter=setMYOverride:) NSString *overridenInClass;
+// expected-warning@-1 {{'setter' attribute on property 'overridenInClass' does not match the property inherited from 'MyClass'}}
+@end
diff --git a/test/SemaObjC/suspicious-pragma-pack.m b/test/SemaObjC/suspicious-pragma-pack.m
new file mode 100644
index 000000000000..0befcaa86dc6
--- /dev/null
+++ b/test/SemaObjC/suspicious-pragma-pack.m
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -Wpragma-pack-suspicious-include -triple i686-apple-darwin9 -fsyntax-only -I%S/Inputs -verify %s
+
+#pragma pack (push, 1) // expected-note {{previous '#pragma pack' directive that modifies alignment is here}}
+#import "empty.h" // expected-warning {{non-default #pragma pack value changes the alignment of struct or union members in the included file}}
+
+#pragma pack (pop)
diff --git a/test/SemaObjC/transfer-boxed-string-nullability.m b/test/SemaObjC/transfer-boxed-string-nullability.m
new file mode 100644
index 000000000000..42604ef4a6a5
--- /dev/null
+++ b/test/SemaObjC/transfer-boxed-string-nullability.m
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -fblocks -fobjc-arc -Wnullable-to-nonnull-conversion -fsyntax-only -verify -Wno-objc-root-class %s
+// RUN: %clang_cc1 -fblocks -fobjc-arc -Wnullable-to-nonnull-conversion -fsyntax-only -verify -Wno-objc-root-class -DNOWARN %s
+
+@interface NSString
+
++ (NSString*
+#ifndef NOWARN
+ _Nullable
+#else
+ _Nonnull
+#endif
+) stringWithUTF8String:(const char*)x;
+
+@end
+
+void takesNonNull(NSString * _Nonnull ptr);
+
+void testBoxedString() {
+ const char *str = "hey";
+ takesNonNull([NSString stringWithUTF8String:str]);
+ takesNonNull(@(str));
+#ifndef NOWARN
+ // expected-warning@-3 {{implicit conversion from nullable pointer 'NSString * _Nullable' to non-nullable pointer type 'NSString * _Nonnull'}}
+ // expected-warning@-3 {{implicit conversion from nullable pointer 'NSString * _Nullable' to non-nullable pointer type 'NSString * _Nonnull'}}
+#else
+ // expected-no-diagnostics
+#endif
+}
diff --git a/test/SemaObjC/typo-correction.m b/test/SemaObjC/typo-correction.m
index f19ec1a1fa3c..47e0ab0960af 100644
--- a/test/SemaObjC/typo-correction.m
+++ b/test/SemaObjC/typo-correction.m
@@ -51,3 +51,23 @@ __attribute__ (( __objc_root_class__ ))
}
@end
+// rdar://problem/33102722
+// Typo correction for a property when it has as correction candidates
+// synthesized ivar and a class name, both at the same edit distance.
+@class TypoCandidate;
+
+__attribute__ (( __objc_root_class__ ))
+@interface PropertyType
+@property int x;
+@end
+
+__attribute__ (( __objc_root_class__ ))
+@interface InterfaceC
+@property(assign) PropertyType *typoCandidate; // expected-note {{'_typoCandidate' declared here}}
+@end
+
+@implementation InterfaceC
+-(void)method {
+ typoCandidate.x = 0; // expected-error {{use of undeclared identifier 'typoCandidate'; did you mean '_typoCandidate'?}}
+}
+@end
diff --git a/test/SemaObjC/unguarded-availability-new.m b/test/SemaObjC/unguarded-availability-new.m
index 9c44b164d541..474730f0d362 100644
--- a/test/SemaObjC/unguarded-availability-new.m
+++ b/test/SemaObjC/unguarded-availability-new.m
@@ -96,16 +96,16 @@ typedef int AVAILABLE_NEXT new_int;
FUNC_AVAILABLE new_int x;
#ifndef NO_WARNING
#ifdef MAC
- // expected-warning@-3 {{'new_int' is partial: introduced in macOS 10.14}} expected-note@-3 {{annotate 'x' with an availability attribute to silence}}
+ // expected-warning@-3 {{'new_int' is only available on macOS 10.14 or newer}} expected-note@-3 {{annotate 'x' with an availability attribute to silence this warning}}
#endif
#ifdef IOS
- // expected-warning@-6 {{'new_int' is partial: introduced in iOS 12}} expected-note@-6 {{annotate 'x' with an availability attribute to silence}}
+ // expected-warning@-6 {{'new_int' is only available on iOS 12 or newer}} expected-note@-6 {{annotate 'x' with an availability attribute to silence this warning}}
#endif
#ifdef TVOS
- // expected-warning@-9 {{'new_int' is partial: introduced in tvOS 13}} expected-note@-9 {{annotate 'x' with an availability attribute to silence}}
+ // expected-warning@-9 {{'new_int' is only available on tvOS 13 or newer}} expected-note@-9 {{annotate 'x' with an availability attribute to silence this warning}}
#endif
#ifdef WATCHOS
- // expected-warning@-12 {{'new_int' is partial: introduced in watchOS 5}} expected-note@-12 {{annotate 'x' with an availability attribute to silence}}
+ // expected-warning@-12 {{'new_int' is only available on watchOS 5}} expected-note@-12 {{annotate 'x' with an availability attribute to silence this warning}}
#endif
#endif
diff --git a/test/SemaObjC/unguarded-availability.m b/test/SemaObjC/unguarded-availability.m
index 139b79158afe..b34cd0f9822c 100644
--- a/test/SemaObjC/unguarded-availability.m
+++ b/test/SemaObjC/unguarded-availability.m
@@ -74,7 +74,7 @@ void use_typedef() {
__attribute__((objc_root_class))
AVAILABLE_10_11 @interface Class_10_11 { // expected-note{{annotate 'Class_10_11' with an availability attribute to silence}}
int_10_11 foo;
- int_10_12 bar; // expected-warning {{'int_10_12' is partial: introduced in macOS 10.12}}
+ int_10_12 bar; // expected-warning {{'int_10_12' is only available on macOS 10.12 or newer}}
}
- (void)method1;
- (void)method2;
@@ -127,7 +127,7 @@ void test_blocks() {
};
}
-void test_params(int_10_12 x); // expected-warning {{'int_10_12' is partial: introduced in macOS 10.12}} expected-note{{annotate 'test_params' with an availability attribute to silence}}
+void test_params(int_10_12 x); // expected-warning {{'int_10_12' is only available on macOS 10.12 or newer}} expected-note{{annotate 'test_params' with an availability attribute to silence this warning}}
void test_params2(int_10_12 x) AVAILABLE_10_12; // no warn
@@ -238,29 +238,29 @@ void functionInFunction() {
#endif
struct InStruct { // expected-note{{annotate 'InStruct' with an availability attribute to silence}}
- new_int mem; // expected-warning{{'new_int' is partial}}
+ new_int mem; // expected-warning{{'new_int' is only available on macOS 10.12 or newer}}
- struct { new_int mem; } anon; // expected-warning{{'new_int' is partial}} expected-note{{annotate anonymous struct with an availability attribute}}
+ struct { new_int mem; } anon; // expected-warning{{'new_int' is only available on macOS 10.12 or newer}} expected-note{{annotate anonymous struct with an availability attribute to silence}}
};
#ifdef OBJCPP
static constexpr int AVAILABLE_10_12 SomeConstexprValue = 2; // expected-note{{marked partial here}}
typedef enum { // expected-note{{annotate anonymous enum with an availability attribute}}
- SomeValue = SomeConstexprValue // expected-warning{{'SomeConstexprValue' is partial}}
+ SomeValue = SomeConstexprValue // expected-warning{{'SomeConstexprValue' is only available on macOS 10.12 or newer}}
} SomeEnum;
#endif
@interface InInterface
--(new_int)meth; // expected-warning{{'new_int' is partial}} expected-note{{annotate 'meth' with an availability attribute}}
+-(new_int)meth; // expected-warning{{'new_int' is only available on macOS 10.12 or newer}} expected-note{{annotate 'meth' with an availability attribute}}
@end
@interface Proper // expected-note{{annotate 'Proper' with an availability attribute}}
-@property (class) new_int x; // expected-warning{{'new_int' is partial}}
+@property (class) new_int x; // expected-warning{{'new_int' is only available}}
@end
void with_local_struct() {
struct local { // expected-note{{annotate 'local' with an availability attribute}}
- new_int x; // expected-warning{{'new_int' is partial}}
+ new_int x; // expected-warning{{'new_int' is only available}}
};
}
@@ -273,7 +273,7 @@ AVAILABLE_10_12
@protocol ProtocolWithNewProtocolRequirement <NewProtocol> // expected-note {{annotate 'ProtocolWithNewProtocolRequirement' with an availability attribute to silence}}
-@property(copy) id<NewProtocol> prop; // expected-warning {{'NewProtocol' is partial: introduced in macOS 10.12}}
+@property(copy) id<NewProtocol> prop; // expected-warning {{'NewProtocol' is only available on macOS 10.12 or newer}}
@end
@@ -287,3 +287,27 @@ AVAILABLE_10_12
@interface BaseClass (CategoryWithNewProtocolRequirement) <NewProtocol>
@end
+
+typedef enum {
+ AK_Dodo __attribute__((availability(macos, deprecated=10.3))), // expected-note 3 {{marked deprecated here}}
+ AK_Cat __attribute__((availability(macos, introduced=10.4))),
+ AK_CyborgCat __attribute__((availability(macos, introduced=10.12))), // expected-note {{marked partial here}}
+} Animals;
+
+void switchAnimals(Animals a) {
+ switch (a) {
+ case AK_Dodo: break; // expected-warning{{'AK_Dodo' is deprecated}}
+ case AK_Cat: break;
+ case AK_Cat|AK_CyborgCat: break; // expected-warning{{case value not in enum}}
+ case AK_CyborgCat: break; // no warn
+ }
+
+ switch (a) {
+ case AK_Dodo...AK_CyborgCat: // expected-warning {{'AK_Dodo' is depr}}
+ break;
+ }
+
+ (void)AK_Dodo; // expected-warning{{'AK_Dodo' is deprecated}}
+ (void)AK_Cat; // no warning
+ (void)AK_CyborgCat; // expected-warning{{'AK_CyborgCat' is only available on macOS 10.12 or newer}} expected-note {{@available}}
+}
diff --git a/test/SemaObjC/warn-messaging-id.mm b/test/SemaObjC/warn-messaging-id.mm
new file mode 100644
index 000000000000..8112cfa3d521
--- /dev/null
+++ b/test/SemaObjC/warn-messaging-id.mm
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class -Wobjc-messaging-id %s
+
+@interface CallMeMaybe
+
+- (void)doThing:(int)intThing;
+
+@property int thing;
+
+@end
+
+template<typename T>
+void instantiate(const T &x) {
+ [x setThing: 22]; // expected-warning {{messaging unqualified id}}
+}
+
+void fn() {
+ id myObject;
+ [myObject doThing: 10]; // expected-warning {{messaging unqualified id}}
+ [myObject setThing: 11]; // expected-warning {{messaging unqualified id}}
+ instantiate(myObject); // expected-note {{in instantiation}}
+}
diff --git a/test/SemaObjC/warn-retain-cycle.m b/test/SemaObjC/warn-retain-cycle.m
index 4398d29e4a8c..f27f1f8e041f 100644
--- a/test/SemaObjC/warn-retain-cycle.m
+++ b/test/SemaObjC/warn-retain-cycle.m
@@ -198,3 +198,15 @@ __block void(^myBlock)(void) = ^{
};
}
+
+typedef void (^a_block_t)(void);
+
+@interface HonorNoEscape
+- (void)addStuffUsingBlock:(__attribute__((noescape)) a_block_t)block;
+@end
+
+void testNoEscape(HonorNoEscape *obj) {
+ [obj addStuffUsingBlock:^{
+ (void)obj; // ok.
+ }];
+}
diff --git a/test/SemaObjCXX/Inputs/nullability-completeness-cferror.h b/test/SemaObjCXX/Inputs/nullability-completeness-cferror.h
new file mode 100644
index 000000000000..4988a7491c25
--- /dev/null
+++ b/test/SemaObjCXX/Inputs/nullability-completeness-cferror.h
@@ -0,0 +1,13 @@
+@class NSError;
+
+#pragma clang assume_nonnull begin
+
+#ifdef USE_MUTABLE
+typedef struct __attribute__((objc_bridge_mutable(NSError))) __CFError * CFErrorRef;
+#else
+typedef struct __attribute__((objc_bridge(NSError))) __CFError * CFErrorRef;
+#endif
+
+void func1(CFErrorRef *error);
+
+#pragma clang assume_nonnull end
diff --git a/test/SemaObjCXX/Inputs/nullability-consistency-2.h b/test/SemaObjCXX/Inputs/nullability-consistency-2.h
index 72f22e2ce473..84a1369618af 100644
--- a/test/SemaObjCXX/Inputs/nullability-consistency-2.h
+++ b/test/SemaObjCXX/Inputs/nullability-consistency-2.h
@@ -6,9 +6,9 @@ void g2(int (^block)(int, int)); // expected-warning{{block pointer is missing a
void g3(const
id // expected-warning{{missing a nullability type specifier}}
+ volatile
// expected-note@-1 {{insert '_Nullable' if the pointer may be null}}
// expected-note@-2 {{insert '_Nonnull' if the pointer should never be null}}
- volatile
* // expected-warning{{missing a nullability type specifier}}
// expected-note@-1 {{insert '_Nullable' if the pointer may be null}}
// expected-note@-2 {{insert '_Nonnull' if the pointer should never be null}}
diff --git a/test/SemaObjCXX/block-variable-move.mm b/test/SemaObjCXX/block-variable-move.mm
new file mode 100644
index 000000000000..e26dffc5d040
--- /dev/null
+++ b/test/SemaObjCXX/block-variable-move.mm
@@ -0,0 +1,43 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -fobjc-arc -verify -fblocks -Wpessimizing-move -Wredundant-move %s
+
+// definitions for std::move
+namespace std {
+inline namespace foo {
+template <class T> struct remove_reference { typedef T type; };
+template <class T> struct remove_reference<T&> { typedef T type; };
+template <class T> struct remove_reference<T&&> { typedef T type; };
+
+template <class T> typename remove_reference<T>::type &&move(T &&t);
+}
+}
+
+class MoveOnly {
+public:
+ MoveOnly() { }
+ MoveOnly(MoveOnly &&) = default; // expected-note 2 {{copy constructor is implicitly deleted}}
+ MoveOnly &operator=(MoveOnly &&) = default;
+ ~MoveOnly();
+};
+
+void copyInit() {
+ __block MoveOnly temp;
+ MoveOnly temp2 = temp; // expected-error {{call to implicitly-deleted copy constructor of 'MoveOnly'}}
+ MoveOnly temp3 = std::move(temp); // ok
+}
+
+MoveOnly errorOnCopy() {
+ __block MoveOnly temp;
+ return temp; // expected-error {{call to implicitly-deleted copy constructor of 'MoveOnly'}}
+}
+
+MoveOnly dontWarnOnMove() {
+ __block MoveOnly temp;
+ return std::move(temp); // ok
+}
+
+class MoveOnlySub : public MoveOnly {};
+
+MoveOnly dontWarnOnMoveSubclass() {
+ __block MoveOnlySub temp;
+ return std::move(temp); // ok
+}
diff --git a/test/SemaObjCXX/flexible-array.mm b/test/SemaObjCXX/flexible-array.mm
new file mode 100644
index 000000000000..5537876c3039
--- /dev/null
+++ b/test/SemaObjCXX/flexible-array.mm
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s
+
+// Test only flexible array member functionality specific to C++.
+
+union VariableSizeUnion {
+ int s;
+ char c[];
+};
+
+@interface LastUnionIvar {
+ VariableSizeUnion flexible;
+}
+@end
+
+@interface NotLastUnionIvar {
+ VariableSizeUnion flexible; // expected-error {{field 'flexible' with variable sized type 'VariableSizeUnion' is not at the end of class}}
+ int last; // expected-note {{next instance variable declaration is here}}
+}
+@end
+
+
+class VariableSizeClass {
+public:
+ int s;
+ char c[];
+};
+
+@interface LastClassIvar {
+ VariableSizeClass flexible;
+}
+@end
+
+@interface NotLastClassIvar {
+ VariableSizeClass flexible; // expected-error {{field 'flexible' with variable sized type 'VariableSizeClass' is not at the end of class}}
+ int last; // expected-note {{next instance variable declaration is here}}
+}
+@end
diff --git a/test/SemaObjCXX/noescape.mm b/test/SemaObjCXX/noescape.mm
new file mode 100644
index 000000000000..6c5d9897aaf0
--- /dev/null
+++ b/test/SemaObjCXX/noescape.mm
@@ -0,0 +1,90 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -fblocks -std=c++11 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -fblocks -std=c++1z %s
+
+typedef void (^BlockTy)();
+
+struct S {
+ int i;
+ void m();
+};
+
+void noescapeFunc0(id, __attribute__((noescape)) BlockTy);
+void noescapeFunc1(id, [[clang::noescape]] BlockTy);
+void noescapeFunc2(__attribute__((noescape)) int *); // expected-note {{previous declaration is here}}
+void noescapeFunc3(__attribute__((noescape)) id);
+void noescapeFunc4(__attribute__((noescape)) int &);
+void noescapeFunc2(int *); // expected-error {{conflicting types for 'noescapeFunc2'}}
+
+void invalidFunc0(int __attribute__((noescape))); // expected-warning {{'noescape' attribute only applies to pointer arguments}}
+void invalidFunc1(int __attribute__((noescape(0)))); // expected-error {{'noescape' attribute takes no arguments}}
+void invalidFunc2(int0 *__attribute__((noescape))); // expected-error {{use of undeclared identifier 'int0'; did you mean 'int'?}}
+void invalidFunc3(__attribute__((noescape)) int (S::*Ty)); // expected-warning {{'noescape' attribute only applies to pointer arguments}}
+void invalidFunc4(__attribute__((noescape)) void (S::*Ty)()); // expected-warning {{'noescape' attribute only applies to pointer arguments}}
+int __attribute__((noescape)) g; // expected-warning {{'noescape' attribute only applies to parameters}}
+
+struct S1 {
+ virtual void m0(int *__attribute__((noescape))); // expected-note {{parameter of overridden method is annotated with __attribute__((noescape))}}
+};
+
+struct S2 : S1 {
+ void m0(int *__attribute__((noescape))) override;
+};
+
+struct S3 : S1 {
+ void m0(int *) override; // expected-warning {{parameter of overriding method should be annotated with __attribute__((noescape))}}
+};
+
+__attribute__((objc_root_class))
+@interface C0
+-(void) m0:(int*)__attribute__((noescape)) p; // expected-note {{parameter of overridden method is annotated with __attribute__((noescape))}}
+@end
+
+@implementation C0
+-(void) m0:(int*)__attribute__((noescape)) p {}
+@end
+
+@interface C1 : C0
+-(void) m0:(int*)__attribute__((noescape)) p;
+@end
+
+@implementation C1 : C0
+-(void) m0:(int*)__attribute__((noescape)) p {}
+@end
+
+@interface C2 : C0
+-(void) m0:(int*) p; // expected-warning {{parameter of overriding method should be annotated with __attribute__((noescape))}}
+@end
+
+@implementation C2 : C0
+-(void) m0:(int*) p {}
+@end
+
+void func0(int *);
+void (*fnptr0)(int *);
+void (*fnptr1)(__attribute__((noescape)) int *);
+template<void (*fn)(int*)> struct S4 {};
+template<void (*fn)(int* __attribute__((noescape)))> struct S5 {};
+
+#if __cplusplus < 201406
+ // expected-note@-4 {{template parameter is declared here}}
+ // expected-note@-4 {{template parameter is declared here}}
+#endif
+
+void test0() {
+ fnptr0 = &func0;
+ fnptr0 = &noescapeFunc2;
+ fnptr1 = &func0; // expected-error {{assigning to 'void (*)(__attribute__((noescape)) int *)' from incompatible type 'void (*)(int *)'}}
+ fnptr1 = &noescapeFunc2;
+ S4<&func0> e0;
+ S4<&noescapeFunc2> e1;
+ S5<&func0> ne0;
+
+#if __cplusplus < 201406
+ // expected-error@-4 {{non-type template argument of type 'void (*)(__attribute__((noescape)) int *)' cannot be converted to a value of type 'void (*)(int *)'}}
+ // expected-error@-4 {{non-type template argument of type 'void (*)(int *)' cannot be converted to a value of type 'void (*)(__attribute__((noescape)) int *)'}}
+#else
+ // expected-error@-6 {{value of type 'void (*)(int *)' is not implicitly convertible to 'void (*)(__attribute__((noescape)) int *)'}}
+#endif
+
+ S5<&noescapeFunc2> ne1;
+}
diff --git a/test/SemaObjCXX/nullability-completeness-cferror.mm b/test/SemaObjCXX/nullability-completeness-cferror.mm
new file mode 100644
index 000000000000..4cea9fba9272
--- /dev/null
+++ b/test/SemaObjCXX/nullability-completeness-cferror.mm
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -fsyntax-only -I %S/Inputs -x objective-c -Wnullability-completeness -Werror -verify %s
+// RUN: %clang_cc1 -fsyntax-only -I %S/Inputs -x objective-c -Wnullability-completeness -Werror -verify -DUSE_MUTABLE %s
+// expected-no-diagnostics
+
+#include "nullability-completeness-cferror.h"
diff --git a/test/SemaObjCXX/typo-correction.mm b/test/SemaObjCXX/typo-correction.mm
index 5e33bfb8cbf0..3f8a082a84a2 100644
--- a/test/SemaObjCXX/typo-correction.mm
+++ b/test/SemaObjCXX/typo-correction.mm
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -verify -fsyntax-only
+// RUN: %clang_cc1 %s -verify -fsyntax-only -Wno-objc-root-class
class ClassA {};
@@ -36,3 +36,54 @@ void invalidNameInIvarAndPropertyBase() {
float a = ((InvalidNameInIvarAndPropertyBase*)node)->_a; // expected-error {{use of undeclared identifier 'node'}}
float b = ((InvalidNameInIvarAndPropertyBase*)node)._b; // expected-error {{use of undeclared identifier 'node'}}
}
+
+// rdar://problem/33102722
+// Typo correction for a property when it has as correction candidates
+// synthesized ivar and a class name, both at the same edit distance.
+@class TypoCandidate;
+
+@interface PropertyType : NSObject
+@property int x;
+@end
+
+@interface InterfaceC : NSObject
+@property(assign) PropertyType *typoCandidate; // expected-note {{'_typoCandidate' declared here}}
+@end
+
+@implementation InterfaceC
+-(void)method {
+ typoCandidate.x = 0; // expected-error {{use of undeclared identifier 'typoCandidate'; did you mean '_typoCandidate'?}}
+}
+@end
+
+// rdar://35172419
+// The scope of 'do-while' ends before typo-correction takes place.
+
+struct Mat2 { int rows; };
+
+@implementation ImplNoInt // expected-warning {{cannot find interface declaration for 'ImplNoInt'}}
+
+- (void)typoCorrentInDoWhile {
+ Mat2 tlMat1; // expected-note {{'tlMat1' declared here}}
+ // Create many scopes to exhaust the cache.
+ do {
+ for (int index = 0; index < 2; index++) {
+ if (true) {
+ for (int specialTileType = 1; specialTileType < 5; specialTileType++) {
+ for (int i = 0; i < 10; i++) {
+ for (double scale = 0.95; scale <= 1.055; scale += 0.05) {
+ for (int j = 0; j < 10; j++) {
+ if (1 > 0.9) {
+ for (int sptile = 1; sptile < 5; sptile++) {
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ } while (tlMat.rows); // expected-error {{use of undeclared identifier 'tlMat'; did you mean 'tlMat1'}}
+}
+
+@end
diff --git a/test/SemaOpenCL/address-spaces.cl b/test/SemaOpenCL/address-spaces.cl
index 7026d1bc086d..97dd1f4f90b3 100644
--- a/test/SemaOpenCL/address-spaces.cl
+++ b/test/SemaOpenCL/address-spaces.cl
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only
+// RUN: %clang_cc1 %s -cl-std=CL2.0 -verify -pedantic -fsyntax-only
__constant int ci = 1;
@@ -7,9 +8,15 @@ __kernel void foo(__global int *gip) {
__local int lj = 2; // expected-error {{'__local' variable cannot have an initializer}}
int *ip;
+#if __OPENCL_C_VERSION__ < 200
ip = gip; // expected-error {{assigning '__global int *' to 'int *' changes address space of pointer}}
ip = &li; // expected-error {{assigning '__local int *' to 'int *' changes address space of pointer}}
ip = &ci; // expected-error {{assigning '__constant int *' to 'int *' changes address space of pointer}}
+#else
+ ip = gip;
+ ip = &li;
+ ip = &ci; // expected-error {{assigning '__constant int *' to '__generic int *' changes address space of pointer}}
+#endif
}
void explicit_cast(global int* g, local int* l, constant int* c, private int* p, const constant int *cc)
@@ -40,3 +47,19 @@ void ok_explicit_casts(global int *g, global int* g2, local int* l, local int* l
l = (local int*) l2;
p = (private int*) p2;
}
+
+__private int func_return_priv(void); //expected-error {{return value cannot be qualified with address space}}
+__global int func_return_global(void); //expected-error {{return value cannot be qualified with address space}}
+__local int func_return_local(void); //expected-error {{return value cannot be qualified with address space}}
+__constant int func_return_constant(void); //expected-error {{return value cannot be qualified with address space}}
+#if __OPENCL_C_VERSION__ >= 200
+__generic int func_return_generic(void); //expected-error {{return value cannot be qualified with address space}}
+#endif
+
+void func_multiple_addr(void) {
+ typedef __private int private_int_t;
+ __local __private int var1; // expected-error {{multiple address spaces specified for type}}
+ __local __private int *var2; // expected-error {{multiple address spaces specified for type}}
+ __local private_int_t var3; // expected-error {{multiple address spaces specified for type}}
+ __local private_int_t *var4; // expected-error {{multiple address spaces specified for type}}
+}
diff --git a/test/SemaOpenCL/atomic-ops.cl b/test/SemaOpenCL/atomic-ops.cl
new file mode 100644
index 000000000000..2ec6cde21176
--- /dev/null
+++ b/test/SemaOpenCL/atomic-ops.cl
@@ -0,0 +1,195 @@
+// RUN: %clang_cc1 %s -cl-std=CL2.0 -verify -fsyntax-only -triple=spir64
+// RUN: %clang_cc1 %s -cl-std=CL2.0 -verify -fsyntax-only -triple=amdgcn-amdhsa-amd-opencl
+
+// Basic parsing/Sema tests for __opencl_atomic_*
+
+#pragma OPENCL EXTENSION cl_khr_int64_base_atomics : enable
+#pragma OPENCL EXTENSION cl_khr_int64_extended_atomics : enable
+
+typedef __INTPTR_TYPE__ intptr_t;
+typedef int int8 __attribute__((ext_vector_type(8)));
+
+typedef enum memory_order {
+ memory_order_relaxed = __ATOMIC_RELAXED,
+ memory_order_acquire = __ATOMIC_ACQUIRE,
+ memory_order_release = __ATOMIC_RELEASE,
+ memory_order_acq_rel = __ATOMIC_ACQ_REL,
+ memory_order_seq_cst = __ATOMIC_SEQ_CST
+} memory_order;
+
+typedef enum memory_scope {
+ memory_scope_work_item = __OPENCL_MEMORY_SCOPE_WORK_ITEM,
+ memory_scope_work_group = __OPENCL_MEMORY_SCOPE_WORK_GROUP,
+ memory_scope_device = __OPENCL_MEMORY_SCOPE_DEVICE,
+ memory_scope_all_svm_devices = __OPENCL_MEMORY_SCOPE_ALL_SVM_DEVICES,
+#if defined(cl_intel_subgroups) || defined(cl_khr_subgroups)
+ memory_scope_sub_group = __OPENCL_MEMORY_SCOPE_SUB_GROUP
+#endif
+} memory_scope;
+
+struct S { char c[3]; };
+
+char i8;
+short i16;
+int i32;
+int8 i64;
+
+atomic_int gn;
+void f(atomic_int *i, const atomic_int *ci,
+ atomic_intptr_t *p, atomic_float *d,
+ int *I, const int *CI,
+ intptr_t *P, float *D, struct S *s1, struct S *s2,
+ global atomic_int *i_g, local atomic_int *i_l, private atomic_int *i_p,
+ constant atomic_int *i_c) {
+ __opencl_atomic_init(I, 5); // expected-error {{address argument to atomic operation must be a pointer to _Atomic type ('__generic int *' invalid)}}
+ __opencl_atomic_init(ci, 5); // expected-error {{address argument to atomic operation must be a pointer to non-const _Atomic type ('const __generic atomic_int *' (aka 'const __generic _Atomic(int) *') invalid)}}
+
+ __opencl_atomic_load(0); // expected-error {{too few arguments to function call, expected 3, have 1}}
+ __opencl_atomic_load(0, 0, 0, 0); // expected-error {{too many arguments to function call, expected 3, have 4}}
+ __opencl_atomic_store(0,0,0,0); // expected-error {{address argument to atomic builtin must be a pointer}}
+ __opencl_atomic_store((int *)0, 0, 0, 0); // expected-error {{address argument to atomic operation must be a pointer to _Atomic type ('__generic int *' invalid)}}
+ __opencl_atomic_store(i, 0, memory_order_relaxed, memory_scope_work_group);
+ __opencl_atomic_store(ci, 0, memory_order_relaxed, memory_scope_work_group); // expected-error {{address argument to atomic operation must be a pointer to non-const _Atomic type ('const __generic atomic_int *' (aka 'const __generic _Atomic(int) *') invalid)}}
+ __opencl_atomic_store(i_g, 0, memory_order_relaxed, memory_scope_work_group);
+ __opencl_atomic_store(i_l, 0, memory_order_relaxed, memory_scope_work_group);
+ __opencl_atomic_store(i_p, 0, memory_order_relaxed, memory_scope_work_group);
+ __opencl_atomic_store(i_c, 0, memory_order_relaxed, memory_scope_work_group); // expected-error {{address argument to atomic operation must be a pointer to non-constant _Atomic type ('__constant atomic_int *' (aka '__constant _Atomic(int) *') invalid)}}
+
+ __opencl_atomic_load(i, memory_order_seq_cst, memory_scope_work_group);
+ __opencl_atomic_load(p, memory_order_seq_cst, memory_scope_work_group);
+ __opencl_atomic_load(d, memory_order_seq_cst, memory_scope_work_group);
+ __opencl_atomic_load(ci, memory_order_seq_cst, memory_scope_work_group); // expected-error {{address argument to atomic operation must be a pointer to non-const _Atomic type ('const __generic atomic_int *' (aka 'const __generic _Atomic(int) *') invalid)}}
+
+ __opencl_atomic_store(i, 1, memory_order_seq_cst, memory_scope_work_group);
+ __opencl_atomic_store(p, 1, memory_order_seq_cst, memory_scope_work_group);
+ (int)__opencl_atomic_store(d, 1, memory_order_seq_cst, memory_scope_work_group); // expected-error {{operand of type 'void' where arithmetic or pointer type is required}}
+
+ int exchange_1 = __opencl_atomic_exchange(i, 1, memory_order_seq_cst, memory_scope_work_group);
+ int exchange_2 = __opencl_atomic_exchange(I, 1, memory_order_seq_cst, memory_scope_work_group); // expected-error {{address argument to atomic operation must be a pointer to _Atomic}}
+
+ __opencl_atomic_fetch_add(i, 1, memory_order_seq_cst, memory_scope_work_group);
+ __opencl_atomic_fetch_add(p, 1, memory_order_seq_cst, memory_scope_work_group);
+ __opencl_atomic_fetch_add(d, 1, memory_order_seq_cst, memory_scope_work_group); // expected-error {{address argument to atomic operation must be a pointer to atomic integer or pointer ('__generic atomic_float *' (aka '__generic _Atomic(float) *') invalid)}}
+ __opencl_atomic_fetch_and(i, 1, memory_order_seq_cst, memory_scope_work_group);
+ __opencl_atomic_fetch_and(p, 1, memory_order_seq_cst, memory_scope_work_group);
+ __opencl_atomic_fetch_and(d, 1, memory_order_seq_cst, memory_scope_work_group); // expected-error {{address argument to bitwise atomic operation must be a pointer to atomic integer ('__generic atomic_float *' (aka '__generic _Atomic(float) *') invalid)}}
+
+ __opencl_atomic_fetch_min(i, 1, memory_order_seq_cst, memory_scope_work_group);
+ __opencl_atomic_fetch_max(i, 1, memory_order_seq_cst, memory_scope_work_group);
+ __opencl_atomic_fetch_min(d, 1, memory_order_seq_cst, memory_scope_work_group); // expected-error {{address argument to atomic operation must be a pointer to atomic integer or pointer ('__generic atomic_float *' (aka '__generic _Atomic(float) *') invalid)}}
+ __opencl_atomic_fetch_max(d, 1, memory_order_seq_cst, memory_scope_work_group); // expected-error {{address argument to atomic operation must be a pointer to atomic integer or pointer ('__generic atomic_float *' (aka '__generic _Atomic(float) *') invalid)}}
+
+ bool cmpexch_1 = __opencl_atomic_compare_exchange_strong(i, I, 1, memory_order_seq_cst, memory_order_seq_cst, memory_scope_work_group);
+ bool cmpexch_2 = __opencl_atomic_compare_exchange_strong(p, P, 1, memory_order_seq_cst, memory_order_seq_cst, memory_scope_work_group);
+ bool cmpexch_3 = __opencl_atomic_compare_exchange_strong(d, I, 1, memory_order_seq_cst, memory_order_seq_cst, memory_scope_work_group); // expected-warning {{incompatible pointer types passing '__generic int *' to parameter of type '__generic float *'}}
+ (void)__opencl_atomic_compare_exchange_strong(i, CI, 1, memory_order_seq_cst, memory_order_seq_cst, memory_scope_work_group); // expected-warning {{passing 'const __generic int *' to parameter of type '__generic int *' discards qualifiers}}
+
+ bool cmpexchw_1 = __opencl_atomic_compare_exchange_weak(i, I, 1, memory_order_seq_cst, memory_order_seq_cst, memory_scope_work_group);
+ bool cmpexchw_2 = __opencl_atomic_compare_exchange_weak(p, P, 1, memory_order_seq_cst, memory_order_seq_cst, memory_scope_work_group);
+ bool cmpexchw_3 = __opencl_atomic_compare_exchange_weak(d, I, 1, memory_order_seq_cst, memory_order_seq_cst, memory_scope_work_group); // expected-warning {{incompatible pointer types passing '__generic int *' to parameter of type '__generic float *'}}
+ (void)__opencl_atomic_compare_exchange_weak(i, CI, 1, memory_order_seq_cst, memory_order_seq_cst, memory_scope_work_group); // expected-warning {{passing 'const __generic int *' to parameter of type '__generic int *' discards qualifiers}}
+
+ // Pointers to different address spaces are allowed.
+ bool cmpexch_10 = __opencl_atomic_compare_exchange_strong((global atomic_int *)0x308, (constant int *)0x309, 1, memory_order_seq_cst, memory_order_seq_cst, memory_scope_work_group);
+
+ __opencl_atomic_init(ci, 0); // expected-error {{address argument to atomic operation must be a pointer to non-const _Atomic type ('const __generic atomic_int *' (aka 'const __generic _Atomic(int) *') invalid)}}
+ __opencl_atomic_store(ci, 0, memory_order_release, memory_scope_work_group); // expected-error {{address argument to atomic operation must be a pointer to non-const _Atomic type ('const __generic atomic_int *' (aka 'const __generic _Atomic(int) *') invalid)}}
+ __opencl_atomic_load(ci, memory_order_acquire, memory_scope_work_group); // expected-error {{address argument to atomic operation must be a pointer to non-const _Atomic type ('const __generic atomic_int *' (aka 'const __generic _Atomic(int) *') invalid)}}
+
+ __opencl_atomic_init(&gn, 456);
+ __opencl_atomic_init(&gn, (void*)0); // expected-warning{{incompatible pointer to integer conversion passing '__generic void *' to parameter of type 'int'}}
+}
+
+void memory_checks(atomic_int *Ap, int *p, int val) {
+ // non-integer memory order argument is casted to integer type.
+ (void)__opencl_atomic_load(Ap, 1.0f, memory_scope_work_group);
+ float forder;
+ (void)__opencl_atomic_load(Ap, forder, memory_scope_work_group);
+ struct S s;
+ (void)__opencl_atomic_load(Ap, s, memory_scope_work_group); // expected-error {{passing 'struct S' to parameter of incompatible type 'int'}}
+
+ (void)__opencl_atomic_load(Ap, memory_order_relaxed, memory_scope_work_group);
+ (void)__opencl_atomic_load(Ap, memory_order_acquire, memory_scope_work_group);
+ (void)__opencl_atomic_load(Ap, memory_order_consume, memory_scope_work_group); // expected-error {{use of undeclared identifier 'memory_order_consume'}}
+ (void)__opencl_atomic_load(Ap, memory_order_release, memory_scope_work_group); // expected-warning {{memory order argument to atomic operation is invalid}}
+ (void)__opencl_atomic_load(Ap, memory_order_acq_rel, memory_scope_work_group); // expected-warning {{memory order argument to atomic operation is invalid}}
+ (void)__opencl_atomic_load(Ap, memory_order_seq_cst, memory_scope_work_group);
+
+ (void)__opencl_atomic_store(Ap, val, memory_order_relaxed, memory_scope_work_group);
+ (void)__opencl_atomic_store(Ap, val, memory_order_acquire, memory_scope_work_group); // expected-warning {{memory order argument to atomic operation is invalid}}
+ (void)__opencl_atomic_store(Ap, val, memory_order_release, memory_scope_work_group);
+ (void)__opencl_atomic_store(Ap, val, memory_order_acq_rel, memory_scope_work_group); // expected-warning {{memory order argument to atomic operation is invalid}}
+ (void)__opencl_atomic_store(Ap, val, memory_order_seq_cst, memory_scope_work_group);
+
+ (void)__opencl_atomic_fetch_add(Ap, 1, memory_order_relaxed, memory_scope_work_group);
+ (void)__opencl_atomic_fetch_add(Ap, 1, memory_order_acquire, memory_scope_work_group);
+ (void)__opencl_atomic_fetch_add(Ap, 1, memory_order_release, memory_scope_work_group);
+ (void)__opencl_atomic_fetch_add(Ap, 1, memory_order_acq_rel, memory_scope_work_group);
+ (void)__opencl_atomic_fetch_add(Ap, 1, memory_order_seq_cst, memory_scope_work_group);
+
+ (void)__opencl_atomic_init(Ap, val);
+
+ (void)__opencl_atomic_fetch_sub(Ap, val, memory_order_relaxed, memory_scope_work_group);
+ (void)__opencl_atomic_fetch_sub(Ap, val, memory_order_acquire, memory_scope_work_group);
+ (void)__opencl_atomic_fetch_sub(Ap, val, memory_order_release, memory_scope_work_group);
+ (void)__opencl_atomic_fetch_sub(Ap, val, memory_order_acq_rel, memory_scope_work_group);
+ (void)__opencl_atomic_fetch_sub(Ap, val, memory_order_seq_cst, memory_scope_work_group);
+
+ (void)__opencl_atomic_fetch_and(Ap, val, memory_order_relaxed, memory_scope_work_group);
+ (void)__opencl_atomic_fetch_and(Ap, val, memory_order_acquire, memory_scope_work_group);
+ (void)__opencl_atomic_fetch_and(Ap, val, memory_order_release, memory_scope_work_group);
+ (void)__opencl_atomic_fetch_and(Ap, val, memory_order_acq_rel, memory_scope_work_group);
+ (void)__opencl_atomic_fetch_and(Ap, val, memory_order_seq_cst, memory_scope_work_group);
+
+ (void)__opencl_atomic_fetch_or(Ap, val, memory_order_relaxed, memory_scope_work_group);
+ (void)__opencl_atomic_fetch_or(Ap, val, memory_order_acquire, memory_scope_work_group);
+ (void)__opencl_atomic_fetch_or(Ap, val, memory_order_release, memory_scope_work_group);
+ (void)__opencl_atomic_fetch_or(Ap, val, memory_order_acq_rel, memory_scope_work_group);
+ (void)__opencl_atomic_fetch_or(Ap, val, memory_order_seq_cst, memory_scope_work_group);
+
+ (void)__opencl_atomic_fetch_xor(Ap, val, memory_order_relaxed, memory_scope_work_group);
+ (void)__opencl_atomic_fetch_xor(Ap, val, memory_order_acquire, memory_scope_work_group);
+ (void)__opencl_atomic_fetch_xor(Ap, val, memory_order_release, memory_scope_work_group);
+ (void)__opencl_atomic_fetch_xor(Ap, val, memory_order_acq_rel, memory_scope_work_group);
+ (void)__opencl_atomic_fetch_xor(Ap, val, memory_order_seq_cst, memory_scope_work_group);
+
+ (void)__opencl_atomic_exchange(Ap, val, memory_order_relaxed, memory_scope_work_group);
+ (void)__opencl_atomic_exchange(Ap, val, memory_order_acquire, memory_scope_work_group);
+ (void)__opencl_atomic_exchange(Ap, val, memory_order_release, memory_scope_work_group);
+ (void)__opencl_atomic_exchange(Ap, val, memory_order_acq_rel, memory_scope_work_group);
+ (void)__opencl_atomic_exchange(Ap, val, memory_order_seq_cst, memory_scope_work_group);
+
+ (void)__opencl_atomic_compare_exchange_strong(Ap, p, val, memory_order_relaxed, memory_order_relaxed, memory_scope_work_group);
+ (void)__opencl_atomic_compare_exchange_strong(Ap, p, val, memory_order_acquire, memory_order_relaxed, memory_scope_work_group);
+ (void)__opencl_atomic_compare_exchange_strong(Ap, p, val, memory_order_release, memory_order_relaxed, memory_scope_work_group);
+ (void)__opencl_atomic_compare_exchange_strong(Ap, p, val, memory_order_acq_rel, memory_order_relaxed, memory_scope_work_group);
+ (void)__opencl_atomic_compare_exchange_strong(Ap, p, val, memory_order_seq_cst, memory_order_relaxed, memory_scope_work_group);
+
+ (void)__opencl_atomic_compare_exchange_weak(Ap, p, val, memory_order_relaxed, memory_order_relaxed, memory_scope_work_group);
+ (void)__opencl_atomic_compare_exchange_weak(Ap, p, val, memory_order_acquire, memory_order_relaxed, memory_scope_work_group);
+ (void)__opencl_atomic_compare_exchange_weak(Ap, p, val, memory_order_release, memory_order_relaxed, memory_scope_work_group);
+ (void)__opencl_atomic_compare_exchange_weak(Ap, p, val, memory_order_acq_rel, memory_order_relaxed, memory_scope_work_group);
+ (void)__opencl_atomic_compare_exchange_weak(Ap, p, val, memory_order_seq_cst, memory_order_relaxed, memory_scope_work_group);
+}
+
+void synchscope_checks(atomic_int *Ap, int scope) {
+ (void)__opencl_atomic_load(Ap, memory_order_relaxed, memory_scope_work_item); // expected-error{{synchronization scope argument to atomic operation is invalid}}
+ (void)__opencl_atomic_load(Ap, memory_order_relaxed, memory_scope_work_group);
+ (void)__opencl_atomic_load(Ap, memory_order_relaxed, memory_scope_device);
+ (void)__opencl_atomic_load(Ap, memory_order_relaxed, memory_scope_all_svm_devices);
+ (void)__opencl_atomic_load(Ap, memory_order_relaxed, memory_scope_sub_group);
+ (void)__opencl_atomic_load(Ap, memory_order_relaxed, scope);
+ (void)__opencl_atomic_load(Ap, memory_order_relaxed, 10); //expected-error{{synchronization scope argument to atomic operation is invalid}}
+
+ // non-integer memory scope is casted to integer type.
+ float fscope;
+ (void)__opencl_atomic_load(Ap, memory_order_relaxed, 1.0f);
+ (void)__opencl_atomic_load(Ap, memory_order_relaxed, fscope);
+ struct S s;
+ (void)__opencl_atomic_load(Ap, memory_order_relaxed, s); //expected-error{{passing 'struct S' to parameter of incompatible type 'int'}}
+}
+
+void nullPointerWarning(atomic_int *Ap, int *p, int val) {
+ // The 'expected' pointer shouldn't be NULL.
+ (void)__opencl_atomic_compare_exchange_strong(Ap, (void *)0, val, memory_order_relaxed, memory_order_relaxed, memory_scope_work_group); // expected-warning {{null passed to a callee that requires a non-null argument}}
+}
diff --git a/test/SemaOpenCL/cl20-device-side-enqueue.cl b/test/SemaOpenCL/cl20-device-side-enqueue.cl
index 3f6527afeadc..207fe7d340ab 100644
--- a/test/SemaOpenCL/cl20-device-side-enqueue.cl
+++ b/test/SemaOpenCL/cl20-device-side-enqueue.cl
@@ -209,3 +209,35 @@ kernel void work_group_size_tests() {
size = get_kernel_preferred_work_group_size_multiple(1); // expected-error{{expected block argument}}
size = get_kernel_preferred_work_group_size_multiple(block_A, 1); // expected-error{{too many arguments to function call, expected 1, have 2}}
}
+
+#pragma OPENCL EXTENSION cl_khr_subgroups : enable
+
+kernel void foo(global int *buf)
+{
+ ndrange_t n;
+ buf[0] = get_kernel_max_sub_group_size_for_ndrange(n, ^(){});
+ buf[0] = get_kernel_max_sub_group_size_for_ndrange(0, ^(){}); // expected-error{{illegal call to 'get_kernel_max_sub_group_size_for_ndrange', expected 'ndrange_t' argument type}}
+ buf[0] = get_kernel_max_sub_group_size_for_ndrange(n, 1); // expected-error{{illegal call to 'get_kernel_max_sub_group_size_for_ndrange', expected block argument type}}
+}
+
+kernel void bar(global int *buf)
+{
+ __private ndrange_t n;
+ buf[0] = get_kernel_sub_group_count_for_ndrange(n, ^(){});
+ buf[0] = get_kernel_sub_group_count_for_ndrange(0, ^(){}); // expected-error{{illegal call to 'get_kernel_sub_group_count_for_ndrange', expected 'ndrange_t' argument type}}
+ buf[0] = get_kernel_sub_group_count_for_ndrange(n, 1); // expected-error{{illegal call to 'get_kernel_sub_group_count_for_ndrange', expected block argument type}}
+}
+
+#pragma OPENCL EXTENSION cl_khr_subgroups : disable
+
+kernel void foo1(global int *buf)
+{
+ ndrange_t n;
+ buf[0] = get_kernel_max_sub_group_size_for_ndrange(n, ^(){}); // expected-error {{use of declaration 'get_kernel_max_sub_group_size_for_ndrange' requires cl_khr_subgroups extension to be enabled}}
+}
+
+kernel void bar1(global int *buf)
+{
+ ndrange_t n;
+ buf[0] = get_kernel_sub_group_count_for_ndrange(n, ^(){}); // expected-error {{use of declaration 'get_kernel_sub_group_count_for_ndrange' requires cl_khr_subgroups extension to be enabled}}
+}
diff --git a/test/SemaOpenCL/clang-builtin-version.cl b/test/SemaOpenCL/clang-builtin-version.cl
index 3e270e64c69d..270345d86a61 100644
--- a/test/SemaOpenCL/clang-builtin-version.cl
+++ b/test/SemaOpenCL/clang-builtin-version.cl
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -fblocks -verify -pedantic -fsyntax-only -ferror-limit 100
+// RUN: %clang_cc1 %s -fblocks -verify -pedantic-errors -fsyntax-only -ferror-limit 100
// Confirm CL2.0 Clang builtins are not available in earlier versions
diff --git a/test/SemaOpenCL/extension-version.cl b/test/SemaOpenCL/extension-version.cl
index 6100346f7072..e56027604651 100644
--- a/test/SemaOpenCL/extension-version.cl
+++ b/test/SemaOpenCL/extension-version.cl
@@ -273,3 +273,21 @@
#endif
#pragma OPENCL EXTENSION cl_amd_media_ops2: enable
+#if (__OPENCL_C_VERSION__ >= 120)
+#ifndef cl_intel_subgroups
+#error "Missing cl_intel_subgroups define"
+#endif
+#else
+// expected-warning@+2{{unsupported OpenCL extension 'cl_intel_subgroups' - ignoring}}
+#endif
+#pragma OPENCL EXTENSION cl_intel_subgroups : enable
+
+#if (__OPENCL_C_VERSION__ >= 120)
+#ifndef cl_intel_subgroups_short
+#error "Missing cl_intel_subgroups_short define"
+#endif
+#else
+// expected-warning@+2{{unsupported OpenCL extension 'cl_intel_subgroups_short' - ignoring}}
+#endif
+#pragma OPENCL EXTENSION cl_intel_subgroups_short : enable
+
diff --git a/test/SemaOpenCL/extern.cl b/test/SemaOpenCL/extern.cl
deleted file mode 100644
index 66efd7005836..000000000000
--- a/test/SemaOpenCL/extern.cl
+++ /dev/null
@@ -1,9 +0,0 @@
-// RUN: %clang_cc1 -x cl -cl-opt-disable -cl-std=CL1.2 -emit-llvm -ffake-address-space-map %s -o - -verify | FileCheck %s
-// expected-no-diagnostics
-
-// CHECK: @foo = external addrspace(2) constant float
-extern constant float foo;
-
-kernel void test(global float* buf) {
- buf[0] += foo;
-}
diff --git a/test/SemaOpenCL/func.cl b/test/SemaOpenCL/func.cl
index dc5b44057b19..83c3b4a6bcf9 100644
--- a/test/SemaOpenCL/func.cl
+++ b/test/SemaOpenCL/func.cl
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only
+// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -triple spir-unknown-unknown
// Variadic functions
void vararg_f(int, ...); // expected-error {{invalid prototype, variadic arguments are not allowed in OpenCL}}
@@ -16,6 +16,9 @@ typedef struct s
//Function pointer
void foo(void*);
+// Expect no diagnostics for an empty parameter list.
+void bar();
+
void bar()
{
// declaring a function pointer is an error
diff --git a/test/SemaOpenCL/invalid-block.cl b/test/SemaOpenCL/invalid-block.cl
index 89bf03264e13..5d6dc380a37a 100644
--- a/test/SemaOpenCL/invalid-block.cl
+++ b/test/SemaOpenCL/invalid-block.cl
@@ -81,3 +81,14 @@ kernel void f7() {
};
return;
}
+
+// Taking address of a capture is not allowed
+int g;
+kernel void f8(int a1) {
+ int a2;
+ void (^bl)(void) = ^(void) {
+ &g; //expected-warning{{expression result unused}}
+ &a1; //expected-error{{taking address of a capture is not allowed}}
+ &a2; //expected-error{{taking address of a capture is not allowed}}
+ };
+}
diff --git a/test/SemaOpenCL/invalid-pipe-builtin-cl2.0.cl b/test/SemaOpenCL/invalid-pipe-builtin-cl2.0.cl
index 386c6b6c7456..619b359c7af9 100644
--- a/test/SemaOpenCL/invalid-pipe-builtin-cl2.0.cl
+++ b/test/SemaOpenCL/invalid-pipe-builtin-cl2.0.cl
@@ -1,4 +1,6 @@
-// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -cl-std=CL2.0
+// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -cl-std=CL2.0 -cl-ext=+cl_khr_subgroups
+
+#pragma OPENCL EXTENSION cl_khr_subgroups : enable
void test1(read_only pipe int p, global int* ptr){
int tmp;
diff --git a/test/SemaOpenCL/invalid-pipes-cl2.0.cl b/test/SemaOpenCL/invalid-pipes-cl2.0.cl
index a50811650d2c..463fd3d0dabc 100644
--- a/test/SemaOpenCL/invalid-pipes-cl2.0.cl
+++ b/test/SemaOpenCL/invalid-pipes-cl2.0.cl
@@ -3,7 +3,7 @@
global pipe int gp; // expected-error {{type '__global read_only pipe int' can only be used as a function parameter in OpenCL}}
global reserve_id_t rid; // expected-error {{the '__global reserve_id_t' type cannot be used to declare a program scope variable}}
-extern pipe write_only int get_pipe(); // expected-error {{type '__global write_only pipe int ()' can only be used as a function parameter in OpenCL}}
+extern pipe write_only int get_pipe(); // expected-error {{type '__global write_only pipe int (void)' can only be used as a function parameter in OpenCL}}
kernel void test_invalid_reserved_id(reserve_id_t ID) { // expected-error {{'reserve_id_t' cannot be used as the type of a kernel parameter}}
}
diff --git a/test/SemaOpenCL/sampler_t.cl b/test/SemaOpenCL/sampler_t.cl
index 4d68dd20a17e..5a1850b02cbd 100644
--- a/test/SemaOpenCL/sampler_t.cl
+++ b/test/SemaOpenCL/sampler_t.cl
@@ -46,36 +46,11 @@ const constant sampler_t glb_smp11 = CLK_ADDRESS_CLAMP_TO_EDGE | CLK_NORMALIZED_
void kernel ker(sampler_t argsmp) {
local sampler_t smp; // expected-error{{sampler type cannot be used with the __local and __global address space qualifiers}}
- const sampler_t const_smp = CLK_ADDRESS_CLAMP_TO_EDGE | CLK_NORMALIZED_COORDS_TRUE | CLK_FILTER_LINEAR;
- const sampler_t const_smp2;
- const sampler_t const_smp3 = const_smp;
- const sampler_t const_smp4 = f();
const sampler_t const_smp5 = 1.0f; // expected-error{{initializing 'const sampler_t' with an expression of incompatible type 'float'}}
const sampler_t const_smp6 = 0x100000000LL; // expected-error{{sampler_t initialization requires 32-bit integer, not 'long long'}}
- foo(glb_smp);
- foo(glb_smp2);
- foo(glb_smp3);
- foo(glb_smp4);
- foo(glb_smp5);
- foo(glb_smp6);
- foo(glb_smp7);
- foo(glb_smp8);
- foo(glb_smp9);
- foo(smp);
- foo(sampler_str.smp);
- foo(const_smp);
- foo(const_smp2);
- foo(const_smp3);
- foo(const_smp4);
- foo(const_smp5);
- foo(const_smp6);
- foo(argsmp);
- foo(5);
foo(5.0f); // expected-error {{passing 'float' to parameter of incompatible type 'sampler_t'}}
- sampler_t sa[] = {argsmp, const_smp}; // expected-error {{array of 'sampler_t' type is invalid in OpenCL}}
- foo(sa[0]);
- foo(bad());
+ sampler_t sa[] = {argsmp, glb_smp}; // expected-error {{array of 'sampler_t' type is invalid in OpenCL}}
}
void bad(sampler_t*); // expected-error{{pointer to type 'sampler_t' is invalid in OpenCL}}
diff --git a/test/SemaOpenCL/storageclass-cl20.cl b/test/SemaOpenCL/storageclass-cl20.cl
index b12676fe7437..581701d2a6a5 100644
--- a/test/SemaOpenCL/storageclass-cl20.cl
+++ b/test/SemaOpenCL/storageclass-cl20.cl
@@ -1,21 +1,41 @@
// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -cl-std=CL2.0
-static constant int G1 = 0;
int G2 = 0;
global int G3 = 0;
local int G4 = 0; // expected-error{{program scope variable must reside in global or constant address space}}
-void kernel foo() {
- static int S1 = 5;
- static global int S2 = 5;
- static private int S3 = 5; // expected-error{{static local variable must reside in global or constant address space}}
+static float g_implicit_static_var = 0;
+static constant float g_constant_static_var = 0;
+static global float g_global_static_var = 0;
+static local float g_local_static_var = 0; // expected-error {{program scope variable must reside in global or constant address space}}
+static private float g_private_static_var = 0; // expected-error {{program scope variable must reside in global or constant address space}}
+static generic float g_generic_static_var = 0; // expected-error {{program scope variable must reside in global or constant address space}}
+
+extern float g_implicit_extern_var;
+extern constant float g_constant_extern_var;
+extern global float g_global_extern_var;
+extern local float g_local_extern_var; // expected-error {{extern variable must reside in global or constant address space}}
+extern private float g_private_extern_var; // expected-error {{extern variable must reside in global or constant address space}}
+extern generic float g_generic_extern_var; // expected-error {{extern variable must reside in global or constant address space}}
+void kernel foo() {
constant int L1 = 0;
local int L2;
global int L3; // expected-error{{function scope variable cannot be declared in global address space}}
generic int L4; // expected-error{{automatic variable qualified with an invalid address space}}
__attribute__((address_space(100))) int L5; // expected-error{{automatic variable qualified with an invalid address space}}
- extern global int G5;
- extern int G6; // expected-error{{extern variable must reside in global or constant address space}}
+ static float l_implicit_static_var = 0;
+ static constant float l_constant_static_var = 0;
+ static global float l_global_static_var = 0;
+ static local float l_local_static_var = 0; // expected-error {{static local variable must reside in global or constant address space}}
+ static private float l_private_static_var = 0; // expected-error {{static local variable must reside in global or constant address space}}
+ static generic float l_generic_static_var = 0; // expected-error {{static local variable must reside in global or constant address space}}
+
+ extern float l_implicit_extern_var;
+ extern constant float l_constant_extern_var;
+ extern global float l_global_extern_var;
+ extern local float l_local_extern_var; // expected-error {{extern variable must reside in global or constant address space}}
+ extern private float l_private_extern_var; // expected-error {{extern variable must reside in global or constant address space}}
+ extern generic float l_generic_extern_var; // expected-error {{extern variable must reside in global or constant address space}}
}
diff --git a/test/SemaOpenCL/storageclass.cl b/test/SemaOpenCL/storageclass.cl
index 9a461068f237..cbcb94509b32 100644
--- a/test/SemaOpenCL/storageclass.cl
+++ b/test/SemaOpenCL/storageclass.cl
@@ -5,6 +5,20 @@ constant int G2 = 0;
int G3 = 0; // expected-error{{program scope variable must reside in constant address space}}
global int G4 = 0; // expected-error{{program scope variable must reside in constant address space}}
+static float g_implicit_static_var = 0; // expected-error {{program scope variable must reside in constant address space}}
+static constant float g_constant_static_var = 0;
+static global float g_global_static_var = 0; // expected-error {{program scope variable must reside in constant address space}}
+static local float g_local_static_var = 0; // expected-error {{program scope variable must reside in constant address space}}
+static private float g_private_static_var = 0; // expected-error {{program scope variable must reside in constant address space}}
+static generic float g_generic_static_var = 0; // expected-error{{OpenCL version 1.2 does not support the 'generic' type qualifier}} // expected-error {{program scope variable must reside in constant address space}}
+
+extern float g_implicit_extern_var; // expected-error {{extern variable must reside in constant address space}}
+extern constant float g_constant_extern_var;
+extern global float g_global_extern_var; // expected-error {{extern variable must reside in constant address space}}
+extern local float g_local_extern_var; // expected-error {{extern variable must reside in constant address space}}
+extern private float g_private_extern_var; // expected-error {{extern variable must reside in constant address space}}
+extern generic float g_generic_extern_var; // expected-error{{OpenCL version 1.2 does not support the 'generic' type qualifier}} // expected-error {{extern variable must reside in constant address space}}
+
void kernel foo(int x) {
// static is not allowed at local scope before CL2.0
static int S1 = 5; // expected-error{{variables in function scope cannot be declared static}}
@@ -45,10 +59,17 @@ void f() {
__attribute__((address_space(100))) int L4; // expected-error{{automatic variable qualified with an invalid address space}}
}
+ static float l_implicit_static_var = 0; // expected-error {{variables in function scope cannot be declared static}}
+ static constant float l_constant_static_var = 0; // expected-error {{variables in function scope cannot be declared static}}
+ static global float l_global_static_var = 0; // expected-error {{variables in function scope cannot be declared static}}
+ static local float l_local_static_var = 0; // expected-error {{variables in function scope cannot be declared static}}
+ static private float l_private_static_var = 0; // expected-error {{variables in function scope cannot be declared static}}
+ static generic float l_generic_static_var = 0; // expected-error{{OpenCL version 1.2 does not support the 'generic' type qualifier}} // expected-error {{variables in function scope cannot be declared static}}
- extern constant float L5;
- extern local float L6; // expected-error{{extern variable must reside in constant address space}}
-
- static int L7 = 0; // expected-error{{variables in function scope cannot be declared static}}
- static int L8; // expected-error{{variables in function scope cannot be declared static}}
+ extern float l_implicit_extern_var; // expected-error {{extern variable must reside in constant address space}}
+ extern constant float l_constant_extern_var;
+ extern global float l_global_extern_var; // expected-error {{extern variable must reside in constant address space}}
+ extern local float l_local_extern_var; // expected-error {{extern variable must reside in constant address space}}
+ extern private float l_private_extern_var; // expected-error {{extern variable must reside in constant address space}}
+ extern generic float l_generic_extern_var; // expected-error{{OpenCL version 1.2 does not support the 'generic' type qualifier}} // expected-error {{extern variable must reside in constant address space}}
}
diff --git a/test/SemaOpenCL/to_addr_builtin.cl b/test/SemaOpenCL/to_addr_builtin.cl
index 56db4abed579..70956f007a5f 100644
--- a/test/SemaOpenCL/to_addr_builtin.cl
+++ b/test/SemaOpenCL/to_addr_builtin.cl
@@ -10,7 +10,7 @@ void test(void) {
glob = to_global(glob, loc);
#if __OPENCL_C_VERSION__ < CL_VERSION_2_0
- // expected-error@-2{{implicit declaration of function 'to_global' is invalid in OpenCL}}
+ // expected-warning@-2{{implicit declaration of function 'to_global' is invalid in OpenCL}}
// expected-warning@-3{{incompatible integer to pointer conversion assigning to '__global int *' from 'int'}}
#else
// expected-error@-5{{invalid number of arguments to function: 'to_global'}}
diff --git a/test/SemaOpenCL/vector_conv_invalid.cl b/test/SemaOpenCL/vector_conv_invalid.cl
index 90cec26a605a..e32d84fd6a7e 100644
--- a/test/SemaOpenCL/vector_conv_invalid.cl
+++ b/test/SemaOpenCL/vector_conv_invalid.cl
@@ -5,10 +5,18 @@ typedef int int4 __attribute((ext_vector_type(4)));
typedef int int3 __attribute((ext_vector_type(3)));
typedef unsigned uint3 __attribute((ext_vector_type(3)));
-void vector_conv_invalid() {
+void vector_conv_invalid(const global int4 *const_global_ptr) {
uint4 u = (uint4)(1);
int4 i = u; // expected-error{{initializing 'int4' (vector of 4 'int' values) with an expression of incompatible type 'uint4' (vector of 4 'unsigned int' values)}}
int4 e = (int4)u; // expected-error{{invalid conversion between ext-vector type 'int4' (vector of 4 'int' values) and 'uint4' (vector of 4 'unsigned int' values)}}
uint3 u4 = (uint3)u; // expected-error{{invalid conversion between ext-vector type 'uint3' (vector of 3 'unsigned int' values) and 'uint4' (vector of 4 'unsigned int' values)}}
+
+ e = (const int4)i;
+ e = (constant int4)i;
+ e = (private int4)i;
+
+ private int4 *private_ptr = (const private int4 *)const_global_ptr; // expected-error{{casting 'const __global int4 *' to type 'const int4 *' changes address space of pointer}}
+ global int4 *global_ptr = const_global_ptr; // expected-warning {{initializing '__global int4 *' with an expression of type 'const __global int4 *' discards qualifiers}}
+ global_ptr = (global int4 *)const_global_ptr;
}
diff --git a/test/SemaOpenCL/vector_swizzle_length.cl b/test/SemaOpenCL/vector_swizzle_length.cl
index 94e3f654d5d9..4dbb5bd76ee0 100644
--- a/test/SemaOpenCL/vector_swizzle_length.cl
+++ b/test/SemaOpenCL/vector_swizzle_length.cl
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only
+// RUN: %clang_cc1 -x cl %s -verify -pedantic -fsyntax-only
typedef float float8 __attribute__((ext_vector_type(8)));
diff --git a/test/SemaTemplate/address_space-dependent.cpp b/test/SemaTemplate/address_space-dependent.cpp
new file mode 100644
index 000000000000..f3d2f3c15d0d
--- /dev/null
+++ b/test/SemaTemplate/address_space-dependent.cpp
@@ -0,0 +1,119 @@
+// RUN: %clang_cc1 -x c++ -std=c++14 -fsyntax-only -verify %s
+
+template <int I, int J, int K>
+void car() {
+ int __attribute__((address_space(I))) __attribute__((address_space(J))) * Y; // expected-error {{multiple address spaces specified for type}}
+ int *__attribute__((address_space(I))) __attribute__((address_space(J))) * Z; // expected-error {{multiple address spaces specified for type}}
+
+ __attribute__((address_space(I))) int local; // expected-error {{automatic variable qualified with an address space}}
+ __attribute__((address_space(J))) int array[5]; // expected-error {{automatic variable qualified with an address space}}
+ __attribute__((address_space(I))) int arrarr[5][5]; // expected-error {{automatic variable qualified with an address space}}
+
+ __attribute__((address_space(J))) * x; // expected-error {{C++ requires a type specifier for all declarations}}
+
+ __attribute__((address_space(I))) float *B;
+
+ typedef __attribute__((address_space(J))) int AS2Int;
+ struct HasASFields {
+ AS2Int typedef_as_field; // expected-error {{field may not be qualified with an address space}}
+ };
+
+ struct _st {
+ int x, y;
+ } s __attribute((address_space(I))) = {1, 1};
+}
+
+template <int I>
+struct HasASTemplateFields {
+ __attribute__((address_space(I))) int as_field; // expected-error {{field may not be qualified with an address space}}
+};
+
+template <int I, int J>
+void foo(__attribute__((address_space(I))) float *a, // expected-note {{candidate template ignored: substitution failure [with I = 1, J = 2]: parameter may not be qualified with an address space}}
+ __attribute__((address_space(J))) float b) {
+ *a = 5.0f + b;
+}
+
+template void foo<1, 2>(float *, float); // expected-error {{explicit instantiation of 'foo' does not refer to a function template, variable template, member function, member class, or static data member}}
+
+template <int I>
+void neg() {
+ __attribute__((address_space(I))) int *bounds; // expected-error {{address space is negative}}
+}
+
+template <long int I>
+void tooBig() {
+ __attribute__((address_space(I))) int *bounds; // expected-error {{address space is larger than the maximum supported (8388598)}}
+}
+
+template <long int I>
+void correct() {
+ __attribute__((address_space(I))) int *bounds;
+}
+
+template <int I, int J>
+char *cmp(__attribute__((address_space(I))) char *x, __attribute__((address_space(J))) char *y) {
+ return x < y ? x : y; // expected-error {{comparison of distinct pointer types ('__attribute__((address_space(1))) char *' and '__attribute__((address_space(2))) char *')}}
+}
+
+typedef void ft(void);
+
+template <int I>
+struct fooFunction {
+ __attribute__((address_space(I))) void **const base = 0;
+
+ void *get_0(void) {
+ return base[0]; // expected-error {{cannot initialize return object of type 'void *' with an lvalue of type '__attribute__((address_space(1))) void *}}
+ }
+
+ __attribute__((address_space(I))) ft qf; // expected-error {{function type may not be qualified with an address space}}
+ __attribute__((address_space(I))) char *test3_val;
+
+ void test3(void) {
+ extern void test3_helper(char *p); // expected-note {{passing argument to parameter 'p' here}}
+ test3_helper(test3_val); // expected-error {{cannot initialize a parameter of type 'char *' with an lvalue of type '__attribute__((address_space(1))) char *'}}
+ }
+};
+
+template <typename T, int N>
+int GetAddressSpaceValue(T __attribute__((address_space(N))) * p) {
+ return N;
+}
+
+template <unsigned A> int __attribute__((address_space(A))) *same_template();
+template <unsigned B> int __attribute__((address_space(B))) *same_template();
+void test_same_template() { (void) same_template<0>(); }
+
+template <unsigned A> int __attribute__((address_space(A))) *different_template(); // expected-note {{candidate function [with A = 0]}}
+template <unsigned B> int __attribute__((address_space(B+1))) *different_template(); // expected-note {{candidate function [with B = 0]}}
+void test_different_template() { (void) different_template<0>(); } // expected-error {{call to 'different_template' is ambiguous}}
+
+template <typename T> struct partial_spec_deduce_as;
+template <typename T, unsigned AS>
+struct partial_spec_deduce_as <__attribute__((address_space(AS))) T *> {
+ static const unsigned value = AS;
+};
+
+int main() {
+ int __attribute__((address_space(1))) * p1;
+ int p = GetAddressSpaceValue(p1);
+
+ car<1, 2, 3>(); // expected-note {{in instantiation of function template specialization 'car<1, 2, 3>' requested here}}
+ HasASTemplateFields<1> HASTF;
+ neg<-1>(); // expected-note {{in instantiation of function template specialization 'neg<-1>' requested here}}
+ correct<0x7FFFF6>();
+ tooBig<8388650>(); // expected-note {{in instantiation of function template specialization 'tooBig<8388650>' requested here}}
+
+ __attribute__((address_space(1))) char *x;
+ __attribute__((address_space(2))) char *y;
+ cmp<1, 2>(x, y); // expected-note {{in instantiation of function template specialization 'cmp<1, 2>' requested here}}
+
+ fooFunction<1> ff;
+ ff.get_0(); // expected-note {{in instantiation of member function 'fooFunction<1>::get_0' requested here}}
+ ff.qf();
+ ff.test3(); // expected-note {{in instantiation of member function 'fooFunction<1>::test3' requested here}}
+
+ static_assert(partial_spec_deduce_as<int __attribute__((address_space(3))) *>::value == 3, "address space value has been incorrectly deduced");
+
+ return 0;
+}
diff --git a/test/SemaTemplate/class-template-decl.cpp b/test/SemaTemplate/class-template-decl.cpp
index 2e36cae14f60..c49154c6527a 100644
--- a/test/SemaTemplate/class-template-decl.cpp
+++ b/test/SemaTemplate/class-template-decl.cpp
@@ -57,8 +57,7 @@ void f() {
template<typename T> class X; // expected-error{{expression}}
}
-template<typename T> class X1 var; // expected-warning{{variable templates are a C++14 extension}} \
- // expected-error {{variable has incomplete type 'class X1'}} \
+template<typename T> class X1 var; // expected-error {{variable has incomplete type 'class X1'}} \
// expected-note {{forward declaration of 'X1'}}
namespace M {
diff --git a/test/SemaTemplate/crash-unparsed-exception.cpp b/test/SemaTemplate/crash-unparsed-exception.cpp
index 1226b35deb70..3137d3fa197c 100644
--- a/test/SemaTemplate/crash-unparsed-exception.cpp
+++ b/test/SemaTemplate/crash-unparsed-exception.cpp
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify -fcxx-exceptions -fexceptions %s
+// expected-no-diagnostics
struct A {
virtual ~A();
@@ -11,7 +12,7 @@ struct C {
~D() throw();
};
struct E : A {
- D<int> d; //expected-error{{exception specification is not available until end of class definition}}
+ D<int> d;
};
- B<int> b; //expected-note{{in instantiation of template class 'B<int>' requested here}}
+ B<int> b;
};
diff --git a/test/SemaTemplate/cxx17-inline-variables.cpp b/test/SemaTemplate/cxx17-inline-variables.cpp
new file mode 100644
index 000000000000..9e6761ee57aa
--- /dev/null
+++ b/test/SemaTemplate/cxx17-inline-variables.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -std=c++17 -verify %s
+// expected-no-diagnostics
+template<bool> struct DominatorTreeBase {
+ static constexpr bool IsPostDominator = true;
+};
+extern template class DominatorTreeBase<false>;
+constexpr bool k = DominatorTreeBase<false>::IsPostDominator;
+
+namespace CompleteType {
+ template<unsigned N> constexpr int f(const bool (&)[N]) { return 0; }
+
+ template<bool ...V> struct X {
+ static constexpr bool arr[] = {V...};
+ static constexpr int value = f(arr);
+ };
+
+ constexpr int n = X<true>::value;
+}
diff --git a/test/SemaTemplate/cxx1z-fold-expressions.cpp b/test/SemaTemplate/cxx1z-fold-expressions.cpp
index aefee92f648a..383f51df21dc 100644
--- a/test/SemaTemplate/cxx1z-fold-expressions.cpp
+++ b/test/SemaTemplate/cxx1z-fold-expressions.cpp
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -std=c++1z -verify %s
+// RUN: %clang_cc1 -std=c++2a -verify %s
template<typename ...T> constexpr auto sum(T ...t) { return (... + t); }
template<typename ...T> constexpr auto product(T ...t) { return (t * ...); }
@@ -76,3 +77,18 @@ template<typename T, typename ...Ts> constexpr decltype(auto) apply(T &t, Ts ...
return (t.*....*ts);
}
static_assert(&apply(a, &A::b, &A::B::c, &A::B::C::d, &A::B::C::D::e) == &a.b.c.d.e);
+
+#if __cplusplus > 201703L
+// The <=> operator is unique among binary operators in not being a
+// fold-operator.
+// FIXME: This diagnostic is not great.
+template<typename ...T> constexpr auto spaceship1(T ...t) { return (t <=> ...); } // expected-error {{expected expression}}
+template<typename ...T> constexpr auto spaceship2(T ...t) { return (... <=> t); } // expected-error {{expected expression}}
+template<typename ...T> constexpr auto spaceship3(T ...t) { return (t <=> ... <=> 0); } // expected-error {{expected expression}}
+#endif
+
+// The GNU binary conditional operator ?: is not recognized as a fold-operator.
+// FIXME: Why not? This seems like it would be useful.
+template<typename ...T> constexpr auto binary_conditional1(T ...t) { return (t ?: ...); } // expected-error {{expected expression}}
+template<typename ...T> constexpr auto binary_conditional2(T ...t) { return (... ?: t); } // expected-error {{expected expression}}
+template<typename ...T> constexpr auto binary_conditional3(T ...t) { return (t ?: ... ?: 0); } // expected-error {{expected expression}}
diff --git a/test/SemaTemplate/deduction-crash.cpp b/test/SemaTemplate/deduction-crash.cpp
index 74a25865aa20..2c58fefa065f 100644
--- a/test/SemaTemplate/deduction-crash.cpp
+++ b/test/SemaTemplate/deduction-crash.cpp
@@ -144,3 +144,20 @@ namespace var_template_partial_spec_incomplete {
template<typename T, typename U = void> int n<T *>; // expected-error +{{}} expected-note {{}}
int k = n<void *>;
}
+
+namespace deduceFunctionSpecializationForInvalidOutOfLineFunction {
+
+template <typename InputT, typename OutputT>
+struct SourceSelectionRequirement {
+ template<typename T>
+ OutputT evaluateSelectionRequirement(InputT &&Value) {
+ }
+};
+
+template <typename InputT, typename OutputT>
+OutputT SourceSelectionRequirement<InputT, OutputT>::
+evaluateSelectionRequirement<void>(InputT &&Value) { // expected-error {{cannot specialize a member of an unspecialized template}}
+ return Value;
+}
+
+}
diff --git a/test/SemaTemplate/default-arguments-cxx0x.cpp b/test/SemaTemplate/default-arguments-cxx0x.cpp
index d9fa2b4a825e..c24ed12a0248 100644
--- a/test/SemaTemplate/default-arguments-cxx0x.cpp
+++ b/test/SemaTemplate/default-arguments-cxx0x.cpp
@@ -87,3 +87,30 @@ namespace PR13986 {
A<1> m_target;
};
}
+
+// rdar://problem/34167492
+// Template B is instantiated during checking if defaulted A copy constructor
+// is constexpr. For this we check if S<int> copy constructor is constexpr. And
+// for this we check S constructor template with default argument that mentions
+// template B. In turn, template instantiation triggers checking defaulted
+// members exception spec. The problem is that it checks defaulted members not
+// for instantiated class only, but all defaulted members so far. In this case
+// we try to check exception spec for A default constructor which requires
+// initializer for the field _a. But initializers are added after constexpr
+// check so we reject the code because cannot find _a initializer.
+namespace rdar34167492 {
+ template <typename T> struct B { using type = bool; };
+
+ template <typename T> struct S {
+ S() noexcept;
+
+ template <typename U, typename B<U>::type = true>
+ S(const S<U>&) noexcept;
+ };
+
+ class A {
+ A() noexcept = default;
+ A(const A&) noexcept = default;
+ S<int> _a{};
+ };
+}
diff --git a/test/SemaTemplate/default-expr-arguments-3.cpp b/test/SemaTemplate/default-expr-arguments-3.cpp
index 173609c04585..4449eb7100aa 100644
--- a/test/SemaTemplate/default-expr-arguments-3.cpp
+++ b/test/SemaTemplate/default-expr-arguments-3.cpp
@@ -21,7 +21,7 @@ namespace PR28795 {
}
// CHECK: ClassTemplateSpecializationDecl {{.*}} struct class2 definition
-// CHECK-NEXT: TemplateArgument type 'int'
+// CHECK: TemplateArgument type 'int'
// CHECK: LambdaExpr {{.*}} 'class (lambda at
// CHECK: ParmVarDecl {{.*}} used f 'enum foo' cinit
// CHECK-NEXT: DeclRefExpr {{.*}} 'enum foo' EnumConstant {{.*}} 'a' 'enum foo'
diff --git a/test/SemaTemplate/explicit-instantiation.cpp b/test/SemaTemplate/explicit-instantiation.cpp
index 42d9f4d332a9..d88c50bc29de 100644
--- a/test/SemaTemplate/explicit-instantiation.cpp
+++ b/test/SemaTemplate/explicit-instantiation.cpp
@@ -124,10 +124,10 @@ namespace PR10086 {
namespace undefined_static_data_member {
template<typename T> struct A {
static int a; // expected-note {{here}}
- template<typename U> static int b; // expected-note {{here}} expected-warning {{extension}}
+ template<typename U> static int b; // expected-note {{here}} expected-warning 0+ {{extension}}
};
struct B {
- template<typename U> static int c; // expected-note {{here}} expected-warning {{extension}}
+ template<typename U> static int c; // expected-note {{here}} expected-warning 0+ {{extension}}
};
template int A<int>::a; // expected-error {{explicit instantiation of undefined static data member 'a' of class template 'undefined_static_data_member::A<int>'}}
@@ -137,14 +137,14 @@ namespace undefined_static_data_member {
template<typename T> struct C {
static int a;
- template<typename U> static int b; // expected-warning {{extension}}
+ template<typename U> static int b; // expected-warning 0+ {{extension}}
};
struct D {
- template<typename U> static int c; // expected-warning {{extension}}
+ template<typename U> static int c; // expected-warning 0+ {{extension}}
};
template<typename T> int C<T>::a;
- template<typename T> template<typename U> int C<T>::b; // expected-warning {{extension}}
- template<typename U> int D::c; // expected-warning {{extension}}
+ template<typename T> template<typename U> int C<T>::b; // expected-warning 0+ {{extension}}
+ template<typename U> int D::c; // expected-warning 0+ {{extension}}
template int C<int>::a;
template int C<int>::b<int>;
diff --git a/test/SemaTemplate/explicit-specialization-member.cpp b/test/SemaTemplate/explicit-specialization-member.cpp
index c0c36808b492..e8165ac9ca7a 100644
--- a/test/SemaTemplate/explicit-specialization-member.cpp
+++ b/test/SemaTemplate/explicit-specialization-member.cpp
@@ -38,24 +38,20 @@ namespace PR18246 {
template<typename T>
template<int N>
- void Baz<T>::bar() { // expected-note {{couldn't infer template argument 'N'}}
+ void Baz<T>::bar() {
}
- // FIXME: We shouldn't try to match this against a prior declaration if
- // template parameter matching failed.
template<typename T>
- void Baz<T>::bar<0>() { // expected-error {{cannot specialize a member of an unspecialized template}} \
- // expected-error {{no function template matches}}
+ void Baz<T>::bar<0>() { // expected-error {{cannot specialize a member of an unspecialized template}}
}
}
namespace PR19340 {
template<typename T> struct Helper {
- template<int N> static void func(const T *m) {} // expected-note {{failed template argument deduction}}
+ template<int N> static void func(const T *m) {}
};
-template<typename T> void Helper<T>::func<2>() {} // expected-error {{cannot specialize a member}} \
- // expected-error {{no function template matches}}
+template<typename T> void Helper<T>::func<2>() {} // expected-error {{cannot specialize a member}}
}
namespace SpecLoc {
diff --git a/test/SemaTemplate/extern-templates.cpp b/test/SemaTemplate/extern-templates.cpp
index 5eb9c9db127c..acbc9d57122e 100644
--- a/test/SemaTemplate/extern-templates.cpp
+++ b/test/SemaTemplate/extern-templates.cpp
@@ -71,3 +71,10 @@ extern template void X1<const void*>::g(const void*);
void g_X1_2(X1<const void *> x1, const void *ptr) {
x1.g(ptr);
}
+
+namespace static_const_member {
+ template <typename T> struct A { static const int n; };
+ template <typename T> const int A<T>::n = 3;
+ extern template struct A<int>;
+ int arr[A<int>::n];
+}
diff --git a/test/SemaTemplate/instantiate-friend-function.cpp b/test/SemaTemplate/instantiate-friend-function.cpp
new file mode 100644
index 000000000000..08602d522df0
--- /dev/null
+++ b/test/SemaTemplate/instantiate-friend-function.cpp
@@ -0,0 +1,49 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+// RUN: %clang_cc1 -S -triple %itanium_abi_triple -std=c++11 -emit-llvm %s -o - | FileCheck %s
+// expected-no-diagnostics
+
+namespace PR10856 {
+ template<typename T> class C;
+
+ template<typename S, typename R = S> C<R> operator - (C<S> m0, C<S> m1);
+ template<typename T> class C {
+ public:
+ template<typename S, typename R> friend C<R> operator - (C<S> m0, C<S> m1);
+ };
+
+ template<typename S, typename R> inline C<R> operator - (C<S> m0, C<S> m1) {
+ C<R> ret;
+ return ret;
+ }
+};
+
+int PR10856_main(int argc, char** argv) {
+ using namespace PR10856;
+ C<int> a;
+ a-a;
+ return 0;
+}
+
+// PR10856::C<int> PR10856::operator-<int, int>(PR10856::C<int>, PR10856::C<int>)
+// CHECK: define {{.*}} @_ZN7PR10856miIiiEENS_1CIT0_EENS1_IT_EES5_
+
+namespace PR10856_Root {
+ template<typename Value, typename Defaulted = void>
+ bool g(Value value);
+
+ template<typename ClassValue> class MyClass {
+ private:
+ template<typename Value, typename Defaulted>
+ friend bool g(Value value);
+ };
+}
+
+namespace PR10856_Root {
+ void f() {
+ MyClass<int> value;
+ g(value);
+ }
+}
+
+// bool PR10856_Root::g<PR10856_Root::MyClass<int>, void>(PR10856_Root::MyClass<int>)
+// CHECK: call {{.*}} @_ZN12PR10856_Root1gINS_7MyClassIiEEvEEbT_
diff --git a/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp b/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp
index c1fcedd58d13..1a84d545c647 100644
--- a/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp
+++ b/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp
@@ -23,6 +23,9 @@ namespace Array {
A<const char*, &(&x)[1]> h; // expected-error {{refers to subobject '&x + 1'}}
A<const char*, 0> i; // expected-error {{not allowed in a converted constant}}
A<const char*, nullptr> j;
+
+ extern char aub[];
+ A<char[], aub> k;
}
namespace Function {
@@ -235,6 +238,10 @@ namespace Auto {
constexpr char s[] = "test";
template<const auto* p> struct S { };
S<s> p;
+
+ template<typename R, typename P, R F(P)> struct A {};
+ template<typename R, typename P, R F(P)> void x(A<R, P, F> a);
+ void g(int) { x(A<void, int, &g>()); }
}
namespace DecltypeAuto {
diff --git a/test/SemaTemplate/temp_arg_template.cpp b/test/SemaTemplate/temp_arg_template.cpp
index 8f59dd724cc2..59deae701801 100644
--- a/test/SemaTemplate/temp_arg_template.cpp
+++ b/test/SemaTemplate/temp_arg_template.cpp
@@ -141,3 +141,10 @@ namespace PR32185 {
template<template<typename T, T> class U> struct A {};
template<template<typename T, T> class U> struct B : A<U> {};
}
+
+namespace PR10147 {
+ template<typename T> struct A {};
+ template<typename T = int> struct A;
+ template<template<typename...> class A> void f(A<int>*) { A<> a; } // expected-warning 0-1{{extension}}
+ void g() { f((A<>*)0); }
+}
diff --git a/test/Tooling/Inputs/clang-diff-basic-src.cpp b/test/Tooling/Inputs/clang-diff-basic-src.cpp
new file mode 100644
index 000000000000..8f15232916d3
--- /dev/null
+++ b/test/Tooling/Inputs/clang-diff-basic-src.cpp
@@ -0,0 +1,33 @@
+namespace src {
+
+void foo() {
+ int x = 321;
+}
+
+void main() { foo(); };
+
+const char *a = "foo";
+
+typedef unsigned int nat;
+
+int p = 1 * 2 * 3 * 4;
+int squared = p * p;
+
+class X {
+ const char *foo(int i) {
+ if (i == 0)
+ return "foo";
+ return 0;
+ }
+
+public:
+ X(){};
+
+ int id(int i) { return i; }
+};
+}
+
+void m() { int x = 0 + 0 + 0; }
+int um = 1 * 2 + 3;
+
+void f1() {{ (void) __func__;;; }}
diff --git a/test/Tooling/Inputs/fixed-header.h b/test/Tooling/Inputs/fixed-header.h
new file mode 100644
index 000000000000..4ce318f3a4e1
--- /dev/null
+++ b/test/Tooling/Inputs/fixed-header.h
@@ -0,0 +1 @@
+#define SECRET_SYMBOL 1
diff --git a/test/Tooling/clang-diff-args.test b/test/Tooling/clang-diff-args.test
new file mode 100644
index 000000000000..a4ce1ea92508
--- /dev/null
+++ b/test/Tooling/clang-diff-args.test
@@ -0,0 +1,12 @@
+RUN: echo a > %t.cpp
+
+CHECK: unknown type name 'X'
+
+check adding compiler cflags
+RUN: clang-diff -ast-dump -extra-arg=-Da=X %t.cpp -- 2>&1 | FileCheck %s
+RUN: clang-diff -ast-dump -extra-arg-before=-Da=X %t.cpp -- 2>&1 | FileCheck %s
+RUN: clang-diff -ast-dump %t.cpp -- 2>&1 -Da=X | FileCheck %s
+
+NOMATCH-CHECK-NOT: {{.}}
+RUN: clang-diff %S/clang-diff-ast.cpp %S/clang-diff-ast.cpp -- 2>&1 -std=c++11 \
+RUN: | FileCheck -check-prefix=NOMATCH-CHECK -allow-empty %s
diff --git a/test/Tooling/clang-diff-ast.cpp b/test/Tooling/clang-diff-ast.cpp
new file mode 100644
index 000000000000..a8efda50a405
--- /dev/null
+++ b/test/Tooling/clang-diff-ast.cpp
@@ -0,0 +1,92 @@
+// RUN: clang-diff -ast-dump %s -- -std=c++11 | FileCheck %s
+
+
+// CHECK: {{^}}TranslationUnitDecl(0)
+// CHECK: {{^}} NamespaceDecl: test;(
+namespace test {
+
+// CHECK: {{^}} FunctionDecl: :f(
+// CHECK: CompoundStmt(
+void f() {
+ // CHECK: VarDecl: i(int)(
+ // CHECK: IntegerLiteral: 1
+ auto i = 1;
+ // CHECK: FloatingLiteral: 1.5(
+ auto r = 1.5;
+ // CHECK: CXXBoolLiteralExpr: true(
+ auto b = true;
+ // CHECK: CallExpr(
+ // CHECK-NOT: ImplicitCastExpr
+ // CHECK: DeclRefExpr: :f(
+ f();
+ // CHECK: UnaryOperator: ++(
+ ++i;
+ // CHECK: BinaryOperator: =(
+ i = i;
+}
+
+} // end namespace test
+
+// CHECK: UsingDirectiveDecl: test(
+using namespace test;
+
+// CHECK: TypedefDecl: nat;unsigned int;(
+typedef unsigned nat;
+// CHECK: TypeAliasDecl: real;double;(
+using real = double;
+
+class Base {
+};
+
+// CHECK: CXXRecordDecl: X;X;(
+class X : Base {
+ int m;
+ // CHECK: CXXMethodDecl: :foo(const char *(int)
+ // CHECK: ParmVarDecl: i(int)(
+ const char *foo(int i) {
+ if (i == 0)
+ // CHECK: StringLiteral: foo(
+ return "foo";
+ // CHECK-NOT: ImplicitCastExpr
+ return 0;
+ }
+
+ // CHECK: AccessSpecDecl: public(
+public:
+ int not_initialized;
+ // CHECK: CXXConstructorDecl: :X(void (char, int){{( __attribute__\(\(thiscall\)\))?}})(
+ // CHECK-NEXT: ParmVarDecl: s(char)
+ // CHECK-NEXT: ParmVarDecl: (int)
+ // CHECK-NEXT: CXXCtorInitializer: Base
+ // CHECK-NEXT: CXXConstructExpr
+ // CHECK-NEXT: CXXCtorInitializer: m
+ // CHECK-NEXT: IntegerLiteral: 0
+ X(char s, int) : Base(), m(0) {
+ // CHECK-NEXT: CompoundStmt
+ // CHECK: MemberExpr: :m(
+ int x = m;
+ }
+ // CHECK: CXXConstructorDecl: :X(void (char){{( __attribute__\(\(thiscall\)\))?}})(
+ // CHECK: CXXCtorInitializer: X
+ X(char s) : X(s, 4) {}
+};
+
+#define M (void)1
+#define MA(a, b) (void)a, b
+// CHECK: FunctionDecl
+// CHECK-NEXT: CompoundStmt
+void macros() {
+ M;
+ MA(1, 2);
+}
+
+#ifndef GUARD
+#define GUARD
+// CHECK-NEXT: NamespaceDecl
+namespace world {
+// nodes from other files are excluded, there should be no output here
+#include "clang-diff-ast.cpp"
+}
+// CHECK-NEXT: FunctionDecl: sentinel
+void sentinel();
+#endif
diff --git a/test/Tooling/clang-diff-basic.cpp b/test/Tooling/clang-diff-basic.cpp
new file mode 100644
index 000000000000..a0c0163530ff
--- /dev/null
+++ b/test/Tooling/clang-diff-basic.cpp
@@ -0,0 +1,57 @@
+// RUN: clang-diff -dump-matches %S/Inputs/clang-diff-basic-src.cpp %s -- | FileCheck %s
+
+// CHECK: Match TranslationUnitDecl{{.*}} to TranslationUnitDecl
+// CHECK: Match NamespaceDecl: src{{.*}} to NamespaceDecl: dst
+namespace dst {
+// CHECK-NOT: Match NamespaceDecl: src{{.*}} to NamespaceDecl: inner
+namespace inner {
+void foo() {
+ // CHECK: Match IntegerLiteral: 321{{.*}} to IntegerLiteral: 322
+ int x = 322;
+}
+}
+
+// CHECK: Match DeclRefExpr: :foo{{.*}} to DeclRefExpr: :inner::foo
+void main() { inner::foo(); }
+
+// CHECK: Match StringLiteral: foo{{.*}} to StringLiteral: foo
+const char *b = "f" "o" "o";
+
+// unsigned is canonicalized to unsigned int
+// CHECK: Match TypedefDecl: :nat;unsigned int;{{.*}} to TypedefDecl: :nat;unsigned int;
+typedef unsigned nat;
+
+// CHECK: Match VarDecl: :p(int){{.*}} to VarDecl: :prod(double)
+// CHECK: Update VarDecl: :p(int){{.*}} to :prod(double)
+// CHECK: Match BinaryOperator: *{{.*}} to BinaryOperator: *
+double prod = 1 * 2 * 10;
+// CHECK: Update DeclRefExpr
+int squared = prod * prod;
+
+class X {
+ const char *foo(int i) {
+ if (i == 0)
+ return "Bar";
+ // CHECK: Insert IfStmt{{.*}} into IfStmt
+ // CHECK: Insert BinaryOperator: =={{.*}} into IfStmt
+ else if (i == -1)
+ return "foo";
+ return 0;
+ }
+ X(){}
+};
+}
+
+// CHECK: Move CompoundStmt{{.*}} into CompoundStmt
+void m() { { int x = 0 + 0 + 0; } }
+// CHECK: Update and Move IntegerLiteral: 7{{.*}} into BinaryOperator: +({{.*}}) at 1
+int um = 1 + 7;
+
+namespace {
+// match with parents of different type
+// CHECK: Match FunctionDecl: f1{{.*}} to FunctionDecl: (anonymous namespace)::f1
+void f1() {{ (void) __func__;;; }}
+}
+
+// CHECK: Delete AccessSpecDecl: public
+// CHECK: Delete CXXMethodDecl
diff --git a/test/Tooling/clang-diff-bottomup.cpp b/test/Tooling/clang-diff-bottomup.cpp
new file mode 100644
index 000000000000..bc5d2cbdf431
--- /dev/null
+++ b/test/Tooling/clang-diff-bottomup.cpp
@@ -0,0 +1,39 @@
+// RUN: %clang_cc1 -E %s > %t.src.cpp
+// RUN: %clang_cc1 -E %s > %t.dst.cpp -DDEST
+// RUN: clang-diff -dump-matches -s=0 %t.src.cpp %t.dst.cpp -- | FileCheck %s
+//
+// Test the bottom-up matching, with maxsize set to 0, so that the optimal matching will never be applied.
+
+#ifndef DEST
+
+void f1() { ; {{;}} }
+void f2() { ;; {{;}} }
+
+#else
+
+// Jaccard similarity threshold is 0.5.
+
+void f1() {
+// CompoundStmt: 3 matched descendants, subtree sizes 4 and 5
+// Jaccard similarity = 3 / (4 + 5 - 3) = 3 / 6 >= 0.5
+// CHECK: Match FunctionDecl: f1(void ())(1) to FunctionDecl: f1(void ())(1)
+// CHECK: Match CompoundStmt(2) to CompoundStmt(2)
+// CHECK: Match CompoundStmt(4) to CompoundStmt(3)
+// CHECK: Match CompoundStmt(5) to CompoundStmt(4)
+// CHECK: Match NullStmt(6) to NullStmt(5)
+ {{;}} ;;
+}
+
+void f2() {
+// CompoundStmt: 3 matched descendants, subtree sizes 4 and 5
+// Jaccard similarity = 3 / (5 + 6 - 3) = 3 / 8 < 0.5
+// CHECK-NOT: Match FunctionDecl(9)
+// CHECK-NOT: Match CompoundStmt(10)
+// CHECK: Match CompoundStmt(11) to CompoundStmt(10)
+// CHECK: Match CompoundStmt(12) to CompoundStmt(11)
+// CHECK: Match NullStmt(13) to NullStmt(12)
+// CHECK-NOT: Match NullStmt(13)
+ {{;}} ;;;
+}
+
+#endif
diff --git a/test/Tooling/clang-diff-html.test b/test/Tooling/clang-diff-html.test
new file mode 100644
index 000000000000..00d9e07d2fcf
--- /dev/null
+++ b/test/Tooling/clang-diff-html.test
@@ -0,0 +1,36 @@
+RUN: clang-diff -html %S/Inputs/clang-diff-basic-src.cpp %S/clang-diff-basic.cpp -- | FileCheck %s
+
+CHECK: <pre><div id='L' class='code'><span id='L0' tid='R0' title='TranslationUnitDecl
+CHECK-NEXT: 0 -> 0'>
+
+match, update
+CHECK: <span id='L[[L:[0-9]+]]' tid='R[[R:[0-9]+]]' title='NamespaceDecl
+CHECK-NEXT: [[L]] -> [[R]]
+CHECK-NEXT: src;' class='u'>namespace src {
+
+match, move
+CHECK: <span id='L[[L:[0-9]+]]' tid='R[[R:[0-9]+]]' title='FunctionDecl
+CHECK-NEXT: [[L]] -> [[R]]
+CHECK-NEXT: :foo(void ())' class='m'>void foo()
+
+match
+CHECK: <span id='L[[L:[0-9]+]]' tid='R[[R:[0-9]+]]' title='FunctionDecl
+CHECK-NEXT: [[L]] -> [[R]]
+CHECK-NEXT: :main(void ())'>void main()
+
+deletion
+CHECK: <span id='L[[L:[0-9]+]]' tid='R-1' title='IntegerLiteral
+CHECK-NEXT: [[L]] -> -1
+CHECK-NEXT: 4' class='d'>4</span>
+
+update + move
+CHECK: 2' class='u m'>2</span>
+
+insertion
+CHECK: <span id='R[[R:[0-9]+]]' tid='L-1' title='StringLiteral
+CHECK-NEXT: -1 -> [[R]]
+CHECK-NEXT: Bar' class='i'>&quot;Bar&quot;</span>
+
+comments
+CHECK: // CHECK: Insert IfStmt{{.*}} into IfStmt
+CHECK: // CHECK: Delete AccessSpecDecl: public
diff --git a/test/Tooling/clang-diff-json.cpp b/test/Tooling/clang-diff-json.cpp
new file mode 100644
index 000000000000..9aac6fa8b15b
--- /dev/null
+++ b/test/Tooling/clang-diff-json.cpp
@@ -0,0 +1,27 @@
+// RUN: clang-diff -ast-dump-json %s -- \
+// RUN: | %python -c 'import json, sys; json.dump(json.loads(sys.stdin.read()), sys.stdout, sort_keys=True, indent=2)' \
+// RUN: | FileCheck %s
+
+// CHECK: "begin": 299,
+// CHECK: "type": "FieldDecl",
+// CHECK: "end": 319,
+// CHECK: "type": "CXXRecordDecl",
+class A {
+ int x;
+};
+
+// CHECK: "children": [
+// CHECK-NEXT: {
+// CHECK-NEXT: "begin":
+// CHECK-NEXT: "children": []
+// CHECK-NEXT: "end":
+// CHECK-NEXT: "id":
+// CHECK-NEXT: "type": "CharacterLiteral"
+// CHECK-NEXT: }
+// CHECK: ]
+// CHECK: "type": "VarDecl",
+char nl = '\n';
+
+// CHECK: "value": "abc \n\t\u0000\u001f"
+char s[] = "abc \n\t\0\x1f";
+
diff --git a/test/Tooling/clang-diff-opt.cpp b/test/Tooling/clang-diff-opt.cpp
new file mode 100644
index 000000000000..771c6abaecb5
--- /dev/null
+++ b/test/Tooling/clang-diff-opt.cpp
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 -E %s > %t.src.cpp
+// RUN: %clang_cc1 -E %s > %t.dst.cpp -DDEST
+// RUN: clang-diff -dump-matches -s=10 %t.src.cpp %t.dst.cpp -- | FileCheck %s
+//
+// Test the behaviour of the matching according to the optimal tree edit
+// distance, implemented with Zhang and Shasha's algorithm.
+// Just for testing we use a tiny value of 10 for maxsize. Subtrees bigger than
+// this size will not be processed by the optimal algorithm.
+
+#ifndef DEST
+
+void f1() { {;} {{;}} }
+
+void f2() { {;} {{;;;;;}} }
+
+void f3() { {;} {{;;;;;;}} }
+
+#else
+
+void f1() {
+// Jaccard similarity = 3 / (5 + 4 - 3) = 3 / 6 >= 0.5
+// The optimal matching algorithm should move the ; into the outer block
+// CHECK: Match CompoundStmt(2) to CompoundStmt(2)
+// CHECK-NOT: Match CompoundStmt(3)
+// CHECK-NEXT: Match NullStmt(4) to NullStmt(3)
+ ; {{;}}
+}
+
+void f2() {
+ // Jaccard similarity = 7 / (10 + 10 - 7) >= 0.5
+ // As none of the subtrees is bigger than 10 nodes, the optimal algorithm
+ // will be run.
+ // CHECK: Match NullStmt(11) to NullStmt(9)
+ ;; {{;;;;;}}
+}
+
+void f3() {
+ // Jaccard similarity = 8 / (11 + 11 - 8) >= 0.5
+ // As the subtrees are bigger than 10 nodes, the optimal algorithm will not
+ // be run.
+ // CHECK: Delete NullStmt(22)
+ ;; {{;;;;;;}}
+}
+
+#endif
diff --git a/test/Tooling/clang-diff-topdown.cpp b/test/Tooling/clang-diff-topdown.cpp
new file mode 100644
index 000000000000..d6c1d770333b
--- /dev/null
+++ b/test/Tooling/clang-diff-topdown.cpp
@@ -0,0 +1,83 @@
+// RUN: %clang_cc1 -E %s > %t.src.cpp
+// RUN: %clang_cc1 -E %s > %t.dst.cpp -DDEST
+// RUN: clang-diff -dump-matches -stop-diff-after=topdown %t.src.cpp %t.dst.cpp -- -std=c++11 | FileCheck %s
+//
+// Test the top-down matching of identical subtrees only.
+
+#ifndef DEST
+
+void f1()
+{
+ // Match some subtree of height greater than 2.
+ // CHECK: Match CompoundStmt(3) to CompoundStmt(3)
+ // CHECK: Match CompoundStmt(4) to CompoundStmt(4)
+ // CHECK: Match NullStmt(5) to NullStmt(5)
+ {{;}}
+
+ // Don't match subtrees that are smaller.
+ // CHECK-NOT: Match CompoundStmt(6)
+ // CHECK-NOT: Match NullStmt(7)
+ {;}
+
+ // Greedy approach - use the first matching subtree when there are multiple
+ // identical subtrees.
+ // CHECK: Match CompoundStmt(8) to CompoundStmt(8)
+ // CHECK: Match CompoundStmt(9) to CompoundStmt(9)
+ // CHECK: Match NullStmt(10) to NullStmt(10)
+ {{;;}}
+}
+
+int x;
+
+namespace src {
+ int x;
+ int x1 = x + 1;
+ int x2 = ::x + 1;
+}
+
+class A { int x = 1 + 1; void f() { int x1 = x; } };
+
+#else
+
+
+void f1() {
+
+ {{;}}
+
+ {;}
+
+ {{;;}}
+ // CHECK-NOT: Match {{.*}} to CompoundStmt(11)
+ // CHECK-NOT: Match {{.*}} to CompoundStmt(12)
+ // CHECK-NOT: Match {{.*}} to NullStmt(13)
+ {{;;}}
+
+ // CHECK-NOT: Match {{.*}} to NullStmt(14)
+ ;
+}
+
+int x;
+
+namespace dst {
+ int x;
+ // CHECK: Match DeclRefExpr: :x(17) to DeclRefExpr: :x(22)
+ int x1 = x + 1;
+ // CHECK: Match DeclRefExpr: x(21) to DeclRefExpr: x(26)
+ int x2 = ::x + 1;
+}
+
+class B {
+ // Only the class name changed; it is not included in the field value,
+ // therefore there is no update.
+ // CHECK: Match FieldDecl: :x(int)(24) to FieldDecl: :x(int)(29)
+ // CHECK-NOT: Update FieldDecl: :x(int)(24)
+ int x = 1+1;
+ void f() {
+ // CHECK: Match MemberExpr: :x(32) to MemberExpr: :x(37)
+ // CHECK-NOT: Update MemberExpr: :x(32)
+ int x1 = B::x;
+ }
+
+};
+
+#endif
diff --git a/test/Tooling/fixed-database.cpp b/test/Tooling/fixed-database.cpp
new file mode 100644
index 000000000000..73d0779258b2
--- /dev/null
+++ b/test/Tooling/fixed-database.cpp
@@ -0,0 +1,19 @@
+// RUN: rm -rf %t
+// RUN: mkdir -p %t/Src
+// RUN: cp "%s" "%t/Src/test.cpp"
+// RUN: mkdir -p %t/Include
+// RUN: cp "%S/Inputs/fixed-header.h" "%t/Include/"
+// -I flag is relative to %t (where compile_flags is), not Src/.
+// RUN: echo '-IInclude/' >> %t/compile_flags.txt
+// RUN: echo "-Dklazz=class" >> %t/compile_flags.txt
+// RUN: echo '-std=c++11' >> %t/compile_flags.txt
+// RUN: clang-check "%t/Src/test.cpp" 2>&1
+// RUN: echo > %t/compile_flags.txt
+// RUN: not clang-check "%t/Src/test.cpp" 2>&1 | FileCheck "%s" -check-prefix=NODB
+
+// NODB: unknown type name 'klazz'
+klazz F{};
+
+// NODB: 'fixed-header.h' file not found
+#include "fixed-header.h"
+static_assert(SECRET_SYMBOL == 1, "");
diff --git a/test/Unit/lit.cfg b/test/Unit/lit.cfg
deleted file mode 100644
index 90eb2ac604a5..000000000000
--- a/test/Unit/lit.cfg
+++ /dev/null
@@ -1,110 +0,0 @@
-# -*- Python -*-
-
-# Configuration file for the 'lit' test runner.
-
-import os
-import platform
-import subprocess
-
-import lit.formats
-import lit.util
-
-# name: The name of this test suite.
-config.name = 'Clang-Unit'
-
-# suffixes: A list of file extensions to treat as test files.
-config.suffixes = []
-
-# test_source_root: The root path where tests are located.
-# test_exec_root: The root path where tests should be run.
-clang_obj_root = getattr(config, 'clang_obj_root', None)
-if clang_obj_root is not None:
- config.test_exec_root = os.path.join(clang_obj_root, 'unittests')
- config.test_source_root = config.test_exec_root
-
-# testFormat: The test format to use to interpret tests.
-llvm_build_mode = getattr(config, 'llvm_build_mode', "Debug")
-config.test_format = lit.formats.GoogleTest(llvm_build_mode, 'Tests')
-
-# Propagate the temp directory. Windows requires this because it uses \Windows\
-# if none of these are present.
-if 'TMP' in os.environ:
- config.environment['TMP'] = os.environ['TMP']
-if 'TEMP' in os.environ:
- config.environment['TEMP'] = os.environ['TEMP']
-
-# Propagate path to symbolizer for ASan/MSan.
-for symbolizer in ['ASAN_SYMBOLIZER_PATH', 'MSAN_SYMBOLIZER_PATH']:
- if symbolizer in os.environ:
- config.environment[symbolizer] = os.environ[symbolizer]
-
-###
-
-# Check that the object root is known.
-if config.test_exec_root is None:
- # Otherwise, we haven't loaded the site specific configuration (the user is
- # probably trying to run on a test file directly, and either the site
- # configuration hasn't been created by the build system, or we are in an
- # out-of-tree build situation).
-
- # Check for 'clang_unit_site_config' user parameter, and use that if available.
- site_cfg = lit_config.params.get('clang_unit_site_config', None)
- if site_cfg and os.path.exists(site_cfg):
- lit_config.load_config(config, site_cfg)
- raise SystemExit
-
- # Try to detect the situation where we are using an out-of-tree build by
- # looking for 'llvm-config'.
- #
- # FIXME: I debated (i.e., wrote and threw away) adding logic to
- # automagically generate the lit.site.cfg if we are in some kind of fresh
- # build situation. This means knowing how to invoke the build system
- # though, and I decided it was too much magic.
-
- llvm_config = lit.util.which('llvm-config', config.environment['PATH'])
- if not llvm_config:
- lit_config.fatal('No site specific configuration available!')
-
- # Get the source and object roots.
- llvm_src_root = subprocess.check_output(['llvm-config', '--src-root']).strip()
- llvm_obj_root = subprocess.check_output(['llvm-config', '--obj-root']).strip()
- clang_src_root = os.path.join(llvm_src_root, "tools", "clang")
- clang_obj_root = os.path.join(llvm_obj_root, "tools", "clang")
-
- # Validate that we got a tree which points to here, using the standard
- # tools/clang layout.
- this_src_root = os.path.join(os.path.dirname(__file__),'..','..')
- if os.path.realpath(clang_src_root) != os.path.realpath(this_src_root):
- lit_config.fatal('No site specific configuration available!')
-
- # Check that the site specific configuration exists.
- site_cfg = os.path.join(clang_obj_root, 'test', 'Unit', 'lit.site.cfg')
- if not os.path.exists(site_cfg):
- lit_config.fatal('No site specific configuration available!')
-
- # Okay, that worked. Notify the user of the automagic, and reconfigure.
- lit_config.note('using out-of-tree build at %r' % clang_obj_root)
- lit_config.load_config(config, site_cfg)
- raise SystemExit
-
-shlibpath_var = ''
-if platform.system() == 'Linux':
- shlibpath_var = 'LD_LIBRARY_PATH'
-elif platform.system() == 'Darwin':
- shlibpath_var = 'DYLD_LIBRARY_PATH'
-elif platform.system() == 'Windows':
- shlibpath_var = 'PATH'
-
-# in stand-alone builds, shlibdir is clang's build tree
-# while llvm_libs_dir is installed LLVM (and possibly older clang)
-llvm_shlib_dir = getattr(config, 'shlibdir', None)
-if not llvm_shlib_dir:
- lit_config.fatal('No shlibdir set!')
-# Point the dynamic loader at dynamic libraries in 'lib'.
-llvm_libs_dir = getattr(config, 'llvm_libs_dir', None)
-if not llvm_libs_dir:
- lit_config.fatal('No LLVM libs dir set!')
-shlibpath = os.path.pathsep.join((llvm_shlib_dir, llvm_libs_dir,
- config.environment.get(shlibpath_var,'')))
-
-config.environment[shlibpath_var] = shlibpath
diff --git a/test/Unit/lit.cfg.py b/test/Unit/lit.cfg.py
new file mode 100644
index 000000000000..342b6928ecea
--- /dev/null
+++ b/test/Unit/lit.cfg.py
@@ -0,0 +1,57 @@
+# -*- Python -*-
+
+# Configuration file for the 'lit' test runner.
+
+import os
+import platform
+import subprocess
+
+import lit.formats
+import lit.util
+
+# name: The name of this test suite.
+config.name = 'Clang-Unit'
+
+# suffixes: A list of file extensions to treat as test files.
+config.suffixes = []
+
+# test_source_root: The root path where tests are located.
+# test_exec_root: The root path where tests should be run.
+config.test_exec_root = os.path.join(config.clang_obj_root, 'unittests')
+config.test_source_root = config.test_exec_root
+
+# testFormat: The test format to use to interpret tests.
+config.test_format = lit.formats.GoogleTest(config.llvm_build_mode, 'Tests')
+
+# Propagate the temp directory. Windows requires this because it uses \Windows\
+# if none of these are present.
+if 'TMP' in os.environ:
+ config.environment['TMP'] = os.environ['TMP']
+if 'TEMP' in os.environ:
+ config.environment['TEMP'] = os.environ['TEMP']
+
+# Propagate path to symbolizer for ASan/MSan.
+for symbolizer in ['ASAN_SYMBOLIZER_PATH', 'MSAN_SYMBOLIZER_PATH']:
+ if symbolizer in os.environ:
+ config.environment[symbolizer] = os.environ[symbolizer]
+
+def find_shlibpath_var():
+ if platform.system() in ['Linux', 'FreeBSD', 'NetBSD', 'SunOS']:
+ yield 'LD_LIBRARY_PATH'
+ elif platform.system() == 'Darwin':
+ yield 'DYLD_LIBRARY_PATH'
+ elif platform.system() == 'Windows':
+ yield 'PATH'
+
+for shlibpath_var in find_shlibpath_var():
+ # in stand-alone builds, shlibdir is clang's build tree
+ # while llvm_libs_dir is installed LLVM (and possibly older clang)
+ shlibpath = os.path.pathsep.join(
+ (config.shlibdir,
+ config.llvm_libs_dir,
+ config.environment.get(shlibpath_var, '')))
+ config.environment[shlibpath_var] = shlibpath
+ break
+else:
+ lit_config.warning("unable to inject shared library path on '{}'"
+ .format(platform.system()))
diff --git a/test/Unit/lit.site.cfg.in b/test/Unit/lit.site.cfg.py.in
index c2f81463f239..715b4d93f58f 100644
--- a/test/Unit/lit.site.cfg.in
+++ b/test/Unit/lit.site.cfg.py.in
@@ -25,4 +25,4 @@ except KeyError:
lit_config.fatal("unable to find %r parameter, use '--param=%s=VALUE'" % (key,key))
# Let the main config do the real work.
-lit_config.load_config(config, "@CLANG_SOURCE_DIR@/test/Unit/lit.cfg")
+lit_config.load_config(config, "@CLANG_SOURCE_DIR@/test/Unit/lit.cfg.py")
diff --git a/test/clang-rename/Field.cpp b/test/clang-rename/Field.cpp
deleted file mode 100644
index c0e9a019e47e..000000000000
--- a/test/clang-rename/Field.cpp
+++ /dev/null
@@ -1,15 +0,0 @@
-class Baz {
- int Foo; /* Test 1 */ // CHECK: int Bar;
-public:
- Baz();
-};
-
-Baz::Baz() : Foo(0) /* Test 2 */ {} // CHECK: Baz::Baz() : Bar(0)
-
-// Test 1.
-// RUN: clang-rename -offset=18 -new-name=Bar %s -- | sed 's,//.*,,' | FileCheck %s
-// Test 2.
-// RUN: clang-rename -offset=89 -new-name=Bar %s -- | sed 's,//.*,,' | FileCheck %s
-
-// To find offsets after modifying the file, use:
-// grep -Ubo 'Foo.*' <file>
diff --git a/test/clang-rename/ForceMulti.cpp b/test/clang-rename/ForceMulti.cpp
new file mode 100644
index 000000000000..41983ce260c8
--- /dev/null
+++ b/test/clang-rename/ForceMulti.cpp
@@ -0,0 +1,8 @@
+class B /* Test 1 */ { // CHECK: class B2 /* Test 1 */ {
+};
+
+class D : public B /* Test 1 */ { // CHECK: class D : public B2 /* Test 1 */ {
+};
+
+// Test 1.
+// RUN: clang-rename -force -qualified-name B -new-name B2 -qualified-name E -new-name E2 %s -- | sed 's,//.*,,' | FileCheck %s
diff --git a/test/clang-rename/TemplatedClassFunction.cpp b/test/clang-rename/TemplatedClassFunction.cpp
index 1f5b0b52ba7a..d7f21e0847c9 100644
--- a/test/clang-rename/TemplatedClassFunction.cpp
+++ b/test/clang-rename/TemplatedClassFunction.cpp
@@ -6,17 +6,22 @@ public:
int main(int argc, char **argv) {
A<int> a;
- a.foo(); /* Test 2 */ // CHECK: a.bar() /* Test 2 */
+ A<double> b;
+ A<float> c;
+ a.foo(); /* Test 2 */ // CHECK: a.bar(); /* Test 2 */
+ b.foo(); /* Test 3 */ // CHECK: b.bar(); /* Test 3 */
+ c.foo(); /* Test 4 */ // CHECK: c.bar(); /* Test 4 */
return 0;
}
// Test 1.
-// RUN: clang-refactor rename -offset=48 -new-name=bar %s -- | sed 's,//.*,,' | FileCheck %s
+// RUN: clang-rename -offset=48 -new-name=bar %s -- | sed 's,//.*,,' | FileCheck %s
// Test 2.
-// RUN: clang-refactor rename -offset=162 -new-name=bar %s -- | sed 's,//.*,,' | FileCheck %s
-//
-// Currently unsupported test.
-// XFAIL: *
+// RUN: clang-rename -offset=191 -new-name=bar %s -- | sed 's,//.*,,' | FileCheck %s
+// Test 3.
+// RUN: clang-rename -offset=255 -new-name=bar %s -- | sed 's,//.*,,' | FileCheck %s
+// Test 4.
+// RUN: clang-rename -offset=319 -new-name=bar %s -- | sed 's,//.*,,' | FileCheck %s
// To find offsets after modifying the file, use:
// grep -Ubo 'foo.*' <file>
diff --git a/test/lit.cfg b/test/lit.cfg
deleted file mode 100644
index 28026578299b..000000000000
--- a/test/lit.cfg
+++ /dev/null
@@ -1,534 +0,0 @@
-# -*- Python -*-
-
-import os
-import platform
-import re
-import subprocess
-import tempfile
-
-import lit.formats
-import lit.util
-
-# Configuration file for the 'lit' test runner.
-
-# name: The name of this test suite.
-config.name = 'Clang'
-
-# Tweak PATH for Win32
-if platform.system() == 'Windows':
- # Seek sane tools in directories and set to $PATH.
- path = getattr(config, 'lit_tools_dir', None)
- path = lit_config.getToolsPath(path,
- config.environment['PATH'],
- ['cmp.exe', 'grep.exe', 'sed.exe'])
- if path is not None:
- path = os.path.pathsep.join((path,
- config.environment['PATH']))
- config.environment['PATH'] = path
-
-# Choose between lit's internal shell pipeline runner and a real shell. If
-# LIT_USE_INTERNAL_SHELL is in the environment, we use that as an override.
-use_lit_shell = os.environ.get("LIT_USE_INTERNAL_SHELL")
-if use_lit_shell:
- # 0 is external, "" is default, and everything else is internal.
- execute_external = (use_lit_shell == "0")
-else:
- # Otherwise we default to internal on Windows and external elsewhere, as
- # bash on Windows is usually very slow.
- execute_external = (not sys.platform in ['win32'])
-
-# testFormat: The test format to use to interpret tests.
-#
-# For now we require '&&' between commands, until they get globally killed and
-# the test runner updated.
-config.test_format = lit.formats.ShTest(execute_external)
-
-# suffixes: A list of file extensions to treat as test files.
-config.suffixes = ['.c', '.cpp', '.cppm', '.m', '.mm', '.cu', '.ll', '.cl', '.s', '.S', '.modulemap', '.test', '.rs']
-
-# excludes: A list of directories to exclude from the testsuite. The 'Inputs'
-# subdirectories contain auxiliary inputs for various tests in their parent
-# directories.
-config.excludes = ['Inputs', 'CMakeLists.txt', 'README.txt', 'LICENSE.txt']
-
-# test_source_root: The root path where tests are located.
-config.test_source_root = os.path.dirname(__file__)
-
-# test_exec_root: The root path where tests should be run.
-clang_obj_root = getattr(config, 'clang_obj_root', None)
-if clang_obj_root is not None:
- config.test_exec_root = os.path.join(clang_obj_root, 'test')
-
-# Set llvm_{src,obj}_root for use by others.
-config.llvm_src_root = getattr(config, 'llvm_src_root', None)
-config.llvm_obj_root = getattr(config, 'llvm_obj_root', None)
-
-# Clear some environment variables that might affect Clang.
-#
-# This first set of vars are read by Clang, but shouldn't affect tests
-# that aren't specifically looking for these features, or are required
-# simply to run the tests at all.
-#
-# FIXME: Should we have a tool that enforces this?
-
-# safe_env_vars = ('TMPDIR', 'TEMP', 'TMP', 'USERPROFILE', 'PWD',
-# 'MACOSX_DEPLOYMENT_TARGET', 'IPHONEOS_DEPLOYMENT_TARGET',
-# 'VCINSTALLDIR', 'VC100COMNTOOLS', 'VC90COMNTOOLS',
-# 'VC80COMNTOOLS')
-possibly_dangerous_env_vars = ['COMPILER_PATH', 'RC_DEBUG_OPTIONS',
- 'CINDEXTEST_PREAMBLE_FILE', 'LIBRARY_PATH',
- 'CPATH', 'C_INCLUDE_PATH', 'CPLUS_INCLUDE_PATH',
- 'OBJC_INCLUDE_PATH', 'OBJCPLUS_INCLUDE_PATH',
- 'LIBCLANG_TIMING', 'LIBCLANG_OBJTRACKING',
- 'LIBCLANG_LOGGING', 'LIBCLANG_BGPRIO_INDEX',
- 'LIBCLANG_BGPRIO_EDIT', 'LIBCLANG_NOTHREADS',
- 'LIBCLANG_RESOURCE_USAGE',
- 'LIBCLANG_CODE_COMPLETION_LOGGING']
-# Clang/Win32 may refer to %INCLUDE%. vsvarsall.bat sets it.
-if platform.system() != 'Windows':
- possibly_dangerous_env_vars.append('INCLUDE')
-for name in possibly_dangerous_env_vars:
- if name in config.environment:
- del config.environment[name]
-
-# Tweak the PATH to include the tools dir and the scripts dir.
-if clang_obj_root is not None:
- clang_tools_dir = getattr(config, 'clang_tools_dir', None)
- if not clang_tools_dir:
- lit_config.fatal('No Clang tools dir set!')
- llvm_tools_dir = getattr(config, 'llvm_tools_dir', None)
- if not llvm_tools_dir:
- lit_config.fatal('No LLVM tools dir set!')
- path = os.path.pathsep.join((
- clang_tools_dir, llvm_tools_dir, config.environment['PATH']))
- config.environment['PATH'] = path
- # in stand-alone builds, llvm_shlib_dir is clang's build tree
- # while llvm_libs_dir is installed LLVM (and possibly older clang)
- llvm_shlib_dir = getattr(config, 'llvm_shlib_dir', None)
- if not llvm_shlib_dir:
- lit_config.fatal('No LLVM shlib dir set!')
- llvm_libs_dir = getattr(config, 'llvm_libs_dir', None)
- if not llvm_libs_dir:
- lit_config.fatal('No LLVM libs dir set!')
- path = os.path.pathsep.join((llvm_shlib_dir, llvm_libs_dir,
- config.environment.get('LD_LIBRARY_PATH','')))
- config.environment['LD_LIBRARY_PATH'] = path
-
-# Propagate path to symbolizer for ASan/MSan.
-for symbolizer in ['ASAN_SYMBOLIZER_PATH', 'MSAN_SYMBOLIZER_PATH']:
- if symbolizer in os.environ:
- config.environment[symbolizer] = os.environ[symbolizer]
-
-###
-
-# Check that the object root is known.
-if config.test_exec_root is None:
- # Otherwise, we haven't loaded the site specific configuration (the user is
- # probably trying to run on a test file directly, and either the site
- # configuration hasn't been created by the build system, or we are in an
- # out-of-tree build situation).
-
- # Check for 'clang_site_config' user parameter, and use that if available.
- site_cfg = lit_config.params.get('clang_site_config', None)
- if site_cfg and os.path.exists(site_cfg):
- lit_config.load_config(config, site_cfg)
- raise SystemExit
-
- # Try to detect the situation where we are using an out-of-tree build by
- # looking for 'llvm-config'.
- #
- # FIXME: I debated (i.e., wrote and threw away) adding logic to
- # automagically generate the lit.site.cfg if we are in some kind of fresh
- # build situation. This means knowing how to invoke the build system though,
- # and I decided it was too much magic. We should solve this by just having
- # the .cfg files generated during the configuration step.
-
- llvm_config = lit.util.which('llvm-config', config.environment['PATH'])
- if not llvm_config:
- lit_config.fatal('No site specific configuration available!')
-
- # Get the source and object roots.
- llvm_src_root = subprocess.check_output(['llvm-config', '--src-root']).strip()
- llvm_obj_root = subprocess.check_output(['llvm-config', '--obj-root']).strip()
- clang_src_root = os.path.join(llvm_src_root, "tools", "clang")
- clang_obj_root = os.path.join(llvm_obj_root, "tools", "clang")
-
- # Validate that we got a tree which points to here, using the standard
- # tools/clang layout.
- this_src_root = os.path.dirname(config.test_source_root)
- if os.path.realpath(clang_src_root) != os.path.realpath(this_src_root):
- lit_config.fatal('No site specific configuration available!')
-
- # Check that the site specific configuration exists.
- site_cfg = os.path.join(clang_obj_root, 'test', 'lit.site.cfg')
- if not os.path.exists(site_cfg):
- lit_config.fatal(
- 'No site specific configuration available! You may need to '
- 'run "make test" in your Clang build directory.')
-
- # Okay, that worked. Notify the user of the automagic, and reconfigure.
- lit_config.note('using out-of-tree build at %r' % clang_obj_root)
- lit_config.load_config(config, site_cfg)
- raise SystemExit
-
-###
-
-# Discover the 'clang' and 'clangcc' to use.
-
-import os
-
-def inferClang(PATH):
- # Determine which clang to use.
- clang = os.getenv('CLANG')
-
- # If the user set clang in the environment, definitely use that and don't
- # try to validate.
- if clang:
- return clang
-
- # Otherwise look in the path.
- clang = lit.util.which('clang', PATH)
-
- if not clang:
- lit_config.fatal("couldn't find 'clang' program, try setting "
- "CLANG in your environment")
-
- return clang
-
-config.clang = inferClang(config.environment['PATH']).replace('\\', '/')
-if not lit_config.quiet:
- lit_config.note('using clang: %r' % config.clang)
-
-# Plugins (loadable modules)
-# TODO: This should be supplied by Makefile or autoconf.
-if sys.platform in ['win32', 'cygwin']:
- has_plugins = config.enable_shared
-else:
- has_plugins = True
-
-if has_plugins and config.llvm_plugin_ext:
- config.available_features.add('plugins')
-
-config.substitutions.append( ('%llvmshlibdir', config.llvm_shlib_dir) )
-config.substitutions.append( ('%pluginext', config.llvm_plugin_ext) )
-config.substitutions.append( ('%PATH%', config.environment['PATH']) )
-
-if config.clang_examples:
- config.available_features.add('examples')
-
-# Note that when substituting %clang_cc1 also fill in the include directory of
-# the builtin headers. Those are part of even a freestanding environment, but
-# Clang relies on the driver to locate them.
-def getClangBuiltinIncludeDir(clang):
- # FIXME: Rather than just getting the version, we should have clang print
- # out its resource dir here in an easy to scrape form.
- cmd = subprocess.Popen([clang, '-print-file-name=include'],
- stdout=subprocess.PIPE,
- env=config.environment)
- if not cmd.stdout:
- lit_config.fatal("Couldn't find the include dir for Clang ('%s')" % clang)
- dir = cmd.stdout.read().strip()
- if sys.platform in ['win32'] and execute_external:
- # Don't pass dosish path separator to msys bash.exe.
- dir = dir.replace('\\', '/')
- # Ensure the result is an ascii string, across Python2.5+ - Python3.
- return str(dir.decode('ascii'))
-
-def makeItaniumABITriple(triple):
- m = re.match(r'(\w+)-(\w+)-(\w+)', triple)
- if not m:
- lit_config.fatal("Could not turn '%s' into Itanium ABI triple" % triple)
- if m.group(3).lower() != 'win32':
- # All non-win32 triples use the Itanium ABI.
- return triple
- return m.group(1) + '-' + m.group(2) + '-mingw32'
-
-def makeMSABITriple(triple):
- m = re.match(r'(\w+)-(\w+)-(\w+)', triple)
- if not m:
- lit_config.fatal("Could not turn '%s' into MS ABI triple" % triple)
- isa = m.group(1).lower()
- vendor = m.group(2).lower()
- os = m.group(3).lower()
- if os == 'win32':
- # If the OS is win32, we're done.
- return triple
- if isa.startswith('x86') or isa == 'amd64' or re.match(r'i\d86', isa):
- # For x86 ISAs, adjust the OS.
- return isa + '-' + vendor + '-win32'
- # -win32 is not supported for non-x86 targets; use a default.
- return 'i686-pc-win32'
-
-config.substitutions.append( ('%clang_analyze_cc1',
- '%clang_cc1 -analyze %analyze') )
-config.substitutions.append( ('%clang_cc1',
- '%s -cc1 -internal-isystem %s -nostdsysteminc'
- % (config.clang,
- getClangBuiltinIncludeDir(config.clang))) )
-config.substitutions.append( ('%clang_cpp', ' ' + config.clang +
- ' --driver-mode=cpp '))
-config.substitutions.append( ('%clang_cl', ' ' + config.clang +
- ' --driver-mode=cl '))
-config.substitutions.append( ('%clangxx', ' ' + config.clang +
- ' --driver-mode=g++ '))
-config.substitutions.append( ('%clang', ' ' + config.clang + ' ') )
-config.substitutions.append( ('%test_debuginfo', ' ' + config.llvm_src_root + '/utils/test_debuginfo.pl ') )
-config.substitutions.append( ('%itanium_abi_triple', makeItaniumABITriple(config.target_triple)) )
-config.substitutions.append( ('%ms_abi_triple', makeMSABITriple(config.target_triple)) )
-config.substitutions.append( ('%resource_dir', getClangBuiltinIncludeDir(config.clang)) )
-
-# The host triple might not be set, at least if we're compiling clang from
-# an already installed llvm.
-if config.host_triple and config.host_triple != '@LLVM_HOST_TRIPLE@':
- config.substitutions.append( ('%target_itanium_abi_host_triple', '--target=%s' % makeItaniumABITriple(config.host_triple)) )
-else:
- config.substitutions.append( ('%target_itanium_abi_host_triple', '') )
-
-config.substitutions.append( ('%src_include_dir', config.clang_src_dir + '/include') )
-
-# FIXME: Find nicer way to prohibit this.
-config.substitutions.append(
- (' clang ', """*** Do not use 'clang' in tests, use '%clang'. ***""") )
-config.substitutions.append(
- (' clang\+\+ ', """*** Do not use 'clang++' in tests, use '%clangxx'. ***"""))
-config.substitutions.append(
- (' clang-cc ',
- """*** Do not use 'clang-cc' in tests, use '%clang_cc1'. ***""") )
-config.substitutions.append(
- (' clang -cc1 -analyze ',
- """*** Do not use 'clang -cc1 -analyze' in tests, use '%clang_analyze_cc1'. ***""") )
-config.substitutions.append(
- (' clang -cc1 ',
- """*** Do not use 'clang -cc1' in tests, use '%clang_cc1'. ***""") )
-config.substitutions.append(
- (' %clang-cc1 ',
- """*** invalid substitution, use '%clang_cc1'. ***""") )
-config.substitutions.append(
- (' %clang-cpp ',
- """*** invalid substitution, use '%clang_cpp'. ***""") )
-config.substitutions.append(
- (' %clang-cl ',
- """*** invalid substitution, use '%clang_cl'. ***""") )
-
-# For each occurrence of a clang tool name as its own word, replace it
-# with the full path to the build directory holding that tool. This
-# ensures that we are testing the tools just built and not some random
-# tools that might happen to be in the user's PATH.
-tool_dirs = os.path.pathsep.join((clang_tools_dir, llvm_tools_dir))
-
-# Regex assertions to reject neighbor hyphens/dots (seen in some tests).
-# For example, don't match 'clang-check-' or '.clang-format'.
-NoPreHyphenDot = r"(?<!(-|\.))"
-NoPostHyphenDot = r"(?!(-|\.))"
-NoPostBar = r"(?!(/|\\))"
-
-tool_patterns = [r"\bFileCheck\b",
- r"\bc-index-test\b",
- NoPreHyphenDot + r"\bclang-check\b" + NoPostHyphenDot,
- NoPreHyphenDot + r"\bclang-format\b" + NoPostHyphenDot,
- # FIXME: Some clang test uses opt?
- NoPreHyphenDot + r"\bopt\b" + NoPostBar + NoPostHyphenDot,
- # Handle these specially as they are strings searched
- # for during testing.
- r"\| \bcount\b",
- r"\| \bnot\b"]
-
-if config.clang_examples:
- tool_patterns.append(NoPreHyphenDot + r"\bclang-interpreter\b" + NoPostHyphenDot)
-
-for pattern in tool_patterns:
- # Extract the tool name from the pattern. This relies on the tool
- # name being surrounded by \b word match operators. If the
- # pattern starts with "| ", include it in the string to be
- # substituted.
- tool_match = re.match(r"^(\\)?((\| )?)\W+b([0-9A-Za-z-_]+)\\b\W*$",
- pattern)
- tool_pipe = tool_match.group(2)
- tool_name = tool_match.group(4)
- tool_path = lit.util.which(tool_name, tool_dirs)
- if not tool_path:
- # Warn, but still provide a substitution.
- lit_config.note('Did not find ' + tool_name + ' in ' + tool_dirs)
- tool_path = clang_tools_dir + '/' + tool_name
- config.substitutions.append((pattern, tool_pipe + tool_path))
-
-###
-
-# Set available features we allow tests to conditionalize on.
-#
-if config.clang_default_cxx_stdlib != '':
- config.available_features.add('default-cxx-stdlib-set')
-
-# Enabled/disabled features
-if config.clang_staticanalyzer:
- config.available_features.add("staticanalyzer")
-
- if config.clang_staticanalyzer_z3 == '1':
- config.available_features.add("z3")
-
-# As of 2011.08, crash-recovery tests still do not pass on FreeBSD.
-if platform.system() not in ['FreeBSD']:
- config.available_features.add('crash-recovery')
-
-# Shell execution
-if execute_external:
- config.available_features.add('shell')
-
-# For tests that require Darwin to run.
-# This is used by debuginfo-tests/*block*.m and debuginfo-tests/foreach.m.
-if platform.system() in ['Darwin']:
- config.available_features.add('system-darwin')
-elif platform.system() in ['Windows']:
- # For tests that require Windows to run.
- config.available_features.add('system-windows')
-
-# ANSI escape sequences in non-dumb terminal
-if platform.system() not in ['Windows']:
- config.available_features.add('ansi-escape-sequences')
-
-# Capability to print utf8 to the terminal.
-# Windows expects codepage, unless Wide API.
-if platform.system() not in ['Windows']:
- config.available_features.add('utf8-capable-terminal')
-
-# Support for libgcc runtime. Used to rule out tests that require
-# clang to run with -rtlib=libgcc.
-if platform.system() not in ['Darwin', 'Fuchsia']:
- config.available_features.add('libgcc')
-
-# Native compilation: Check if triples match.
-# FIXME: Consider cases that target can be executed
-# even if host_triple were different from target_triple.
-if config.host_triple == config.target_triple:
- config.available_features.add("native")
-
-# Case-insensitive file system
-def is_filesystem_case_insensitive():
- handle, path = tempfile.mkstemp(prefix='case-test', dir=config.test_exec_root)
- isInsensitive = os.path.exists(
- os.path.join(
- os.path.dirname(path),
- os.path.basename(path).upper()
- ))
- os.close(handle)
- os.remove(path)
- return isInsensitive
-
-if is_filesystem_case_insensitive():
- config.available_features.add('case-insensitive-filesystem')
-
-# Tests that require the /dev/fd filesystem.
-if os.path.exists("/dev/fd/0") and sys.platform not in ['cygwin']:
- config.available_features.add('dev-fd-fs')
-
-# Not set on native MS environment.
-if not re.match(r'.*-win32$', config.target_triple):
- config.available_features.add('non-ms-sdk')
-
-# Not set on native PS4 environment.
-if not re.match(r'.*-scei-ps4', config.target_triple):
- config.available_features.add('non-ps4-sdk')
-
-# [PR8833] LLP64-incompatible tests
-if not re.match(r'^x86_64.*-(win32|mingw32|windows-gnu)$', config.target_triple):
- config.available_features.add('LP64')
-
-# [PR12920] "clang-driver" -- set if gcc driver is not used.
-if not re.match(r'.*-(cygwin)$', config.target_triple):
- config.available_features.add('clang-driver')
-
-# [PR18856] Depends to remove opened file. On win32, a file could be removed
-# only if all handles were closed.
-if platform.system() not in ['Windows']:
- config.available_features.add('can-remove-opened-file')
-
-# Returns set of available features, registered-target(s), asserts and
-# compile definitions.
-def get_llvm_config_props():
- set_of_features = set()
-
- cmd = subprocess.Popen(
- [
- os.path.join(llvm_tools_dir, 'llvm-config'),
- '--assertion-mode',
- '--targets-built',
- '--cxxflags'
- ],
- stdout=subprocess.PIPE,
- env=config.environment
- )
- # 1st line corresponds to --assertion-mode, "ON" or "OFF".
- line = cmd.stdout.readline().strip().decode('ascii')
- if line == "ON":
- set_of_features.add('asserts')
-
- # 2nd line corresponds to --targets-built, like;
- # AArch64 ARM CppBackend X86
- for arch in cmd.stdout.readline().decode('ascii').split():
- set_of_features.add(arch.lower() + '-registered-target')
-
- # 3rd line contains compile definitions, search it to define if
- # libstdc++ safe mode is set.
- if re.search(r'-D_GLIBCXX_DEBUG\b', cmd.stdout.readline().decode('ascii')):
- set_of_features.add('libstdcxx-safe-mode')
-
- return set_of_features
-
-config.available_features.update(get_llvm_config_props())
-
-if lit.util.which('xmllint'):
- config.available_features.add('xmllint')
-
-# Sanitizers.
-if 'Address' in config.llvm_use_sanitizer:
- config.available_features.add("asan")
-else:
- config.available_features.add("not_asan")
-if 'Memory' in config.llvm_use_sanitizer:
- config.available_features.add("msan")
-if 'Undefined' in config.llvm_use_sanitizer:
- config.available_features.add("ubsan")
-else:
- config.available_features.add("not_ubsan")
-
-if config.enable_backtrace:
- config.available_features.add("backtrace")
-
-if config.have_zlib:
- config.available_features.add("zlib")
-else:
- config.available_features.add("nozlib")
-
-# Check if we should run long running tests.
-if lit_config.params.get("run_long_tests", None) == "true":
- config.available_features.add("long_tests")
-
-# Check if we should use gmalloc.
-use_gmalloc_str = lit_config.params.get('use_gmalloc', None)
-if use_gmalloc_str is not None:
- if use_gmalloc_str.lower() in ('1', 'true'):
- use_gmalloc = True
- elif use_gmalloc_str.lower() in ('', '0', 'false'):
- use_gmalloc = False
- else:
- lit_config.fatal('user parameter use_gmalloc should be 0 or 1')
-else:
- # Default to not using gmalloc
- use_gmalloc = False
-
-# Allow use of an explicit path for gmalloc library.
-# Will default to '/usr/lib/libgmalloc.dylib' if not set.
-gmalloc_path_str = lit_config.params.get('gmalloc_path',
- '/usr/lib/libgmalloc.dylib')
-if use_gmalloc:
- config.environment.update({'DYLD_INSERT_LIBRARIES' : gmalloc_path_str})
-
-# Check if we should allow outputs to console.
-run_console_tests = int(lit_config.params.get('enable_console', '0'))
-if run_console_tests != 0:
- config.available_features.add('console')
-
-lit.util.usePlatformSdkOnDarwin(config, lit_config)
-macOSSDKVersion = lit.util.findPlatformSdkVersionOnMacOS(config, lit_config)
-if macOSSDKVersion is not None:
- config.available_features.add('macos-sdk-' + macOSSDKVersion)
diff --git a/test/lit.cfg.py b/test/lit.cfg.py
new file mode 100644
index 000000000000..5323cfe73550
--- /dev/null
+++ b/test/lit.cfg.py
@@ -0,0 +1,182 @@
+# -*- Python -*-
+
+import os
+import platform
+import re
+import subprocess
+import tempfile
+
+import lit.formats
+import lit.util
+
+from lit.llvm import llvm_config
+from lit.llvm.subst import ToolSubst
+from lit.llvm.subst import FindTool
+
+# Configuration file for the 'lit' test runner.
+
+# name: The name of this test suite.
+config.name = 'Clang'
+
+# testFormat: The test format to use to interpret tests.
+#
+# For now we require '&&' between commands, until they get globally killed and
+# the test runner updated.
+config.test_format = lit.formats.ShTest(not llvm_config.use_lit_shell)
+
+# suffixes: A list of file extensions to treat as test files.
+config.suffixes = ['.c', '.cpp', '.cppm', '.m', '.mm', '.cu',
+ '.ll', '.cl', '.s', '.S', '.modulemap', '.test', '.rs']
+
+# excludes: A list of directories to exclude from the testsuite. The 'Inputs'
+# subdirectories contain auxiliary inputs for various tests in their parent
+# directories.
+config.excludes = ['Inputs', 'CMakeLists.txt', 'README.txt', 'LICENSE.txt', 'debuginfo-tests']
+
+# test_source_root: The root path where tests are located.
+config.test_source_root = os.path.dirname(__file__)
+
+# test_exec_root: The root path where tests should be run.
+config.test_exec_root = os.path.join(config.clang_obj_root, 'test')
+
+llvm_config.use_default_substitutions()
+
+llvm_config.use_clang()
+
+# Propagate path to symbolizer for ASan/MSan.
+llvm_config.with_system_environment(
+ ['ASAN_SYMBOLIZER_PATH', 'MSAN_SYMBOLIZER_PATH'])
+
+config.substitutions.append(('%PATH%', config.environment['PATH']))
+
+
+# For each occurrence of a clang tool name, replace it with the full path to
+# the build directory holding that tool. We explicitly specify the directories
+# to search to ensure that we get the tools just built and not some random
+# tools that might happen to be in the user's PATH.
+tool_dirs = [config.clang_tools_dir, config.llvm_tools_dir]
+
+tools = [
+ 'c-index-test', 'clang-check', 'clang-diff', 'clang-format', 'opt',
+ ToolSubst('%clang_func_map', command=FindTool(
+ 'clang-func-mapping'), unresolved='ignore'),
+]
+
+if config.clang_examples:
+ tools.append('clang-interpreter')
+
+llvm_config.add_tool_substitutions(tools, tool_dirs)
+
+# Plugins (loadable modules)
+# TODO: This should be supplied by Makefile or autoconf.
+if sys.platform in ['win32', 'cygwin']:
+ has_plugins = config.enable_shared
+else:
+ has_plugins = True
+
+if has_plugins and config.llvm_plugin_ext:
+ config.available_features.add('plugins')
+
+# Set available features we allow tests to conditionalize on.
+#
+if config.clang_default_cxx_stdlib != '':
+ config.available_features.add('default-cxx-stdlib-set')
+
+# Enabled/disabled features
+if config.clang_staticanalyzer:
+ config.available_features.add('staticanalyzer')
+
+ if config.clang_staticanalyzer_z3 == '1':
+ config.available_features.add('z3')
+
+# As of 2011.08, crash-recovery tests still do not pass on FreeBSD.
+if platform.system() not in ['FreeBSD']:
+ config.available_features.add('crash-recovery')
+
+# ANSI escape sequences in non-dumb terminal
+if platform.system() not in ['Windows']:
+ config.available_features.add('ansi-escape-sequences')
+
+# Capability to print utf8 to the terminal.
+# Windows expects codepage, unless Wide API.
+if platform.system() not in ['Windows']:
+ config.available_features.add('utf8-capable-terminal')
+
+# Support for libgcc runtime. Used to rule out tests that require
+# clang to run with -rtlib=libgcc.
+if platform.system() not in ['Darwin', 'Fuchsia']:
+ config.available_features.add('libgcc')
+
+# Case-insensitive file system
+
+
+def is_filesystem_case_insensitive():
+ handle, path = tempfile.mkstemp(
+ prefix='case-test', dir=config.test_exec_root)
+ isInsensitive = os.path.exists(
+ os.path.join(
+ os.path.dirname(path),
+ os.path.basename(path).upper()
+ ))
+ os.close(handle)
+ os.remove(path)
+ return isInsensitive
+
+
+if is_filesystem_case_insensitive():
+ config.available_features.add('case-insensitive-filesystem')
+
+# Tests that require the /dev/fd filesystem.
+if os.path.exists('/dev/fd/0') and sys.platform not in ['cygwin']:
+ config.available_features.add('dev-fd-fs')
+
+# Not set on native MS environment.
+if not re.match(r'.*-win32$', config.target_triple):
+ config.available_features.add('non-ms-sdk')
+
+# Not set on native PS4 environment.
+if not re.match(r'.*-scei-ps4', config.target_triple):
+ config.available_features.add('non-ps4-sdk')
+
+# [PR8833] LLP64-incompatible tests
+if not re.match(r'^x86_64.*-(win32|mingw32|windows-gnu)$', config.target_triple):
+ config.available_features.add('LP64')
+
+# [PR12920] "clang-driver" -- set if gcc driver is not used.
+if not re.match(r'.*-(cygwin)$', config.target_triple):
+ config.available_features.add('clang-driver')
+
+# [PR18856] Depends to remove opened file. On win32, a file could be removed
+# only if all handles were closed.
+if platform.system() not in ['Windows']:
+ config.available_features.add('can-remove-opened-file')
+
+
+def calculate_arch_features(arch_string):
+ features = []
+ for arch in arch_string.split():
+ features.append(arch.lower() + '-registered-target')
+ return features
+
+
+llvm_config.feature_config(
+ [('--assertion-mode', {'ON': 'asserts'}),
+ ('--cxxflags', {r'-D_GLIBCXX_DEBUG\b': 'libstdcxx-safe-mode'}),
+ ('--targets-built', calculate_arch_features)
+ ])
+
+if lit.util.which('xmllint'):
+ config.available_features.add('xmllint')
+
+if config.enable_backtrace:
+ config.available_features.add('backtrace')
+
+# Check if we should allow outputs to console.
+run_console_tests = int(lit_config.params.get('enable_console', '0'))
+if run_console_tests != 0:
+ config.available_features.add('console')
+
+lit.util.usePlatformSdkOnDarwin(config, lit_config)
+macOSSDKVersion = lit.util.findPlatformSdkVersionOnMacOS(config, lit_config)
+if macOSSDKVersion is not None:
+ config.available_features.add('macos-sdk-' + macOSSDKVersion)
diff --git a/test/lit.site.cfg.in b/test/lit.site.cfg.py.in
index 63d713987482..9d2b4c591879 100644
--- a/test/lit.site.cfg.in
+++ b/test/lit.site.cfg.py.in
@@ -14,6 +14,7 @@ config.clang_src_dir = "@CLANG_SOURCE_DIR@"
config.clang_tools_dir = "@CLANG_TOOLS_DIR@"
config.host_triple = "@LLVM_HOST_TRIPLE@"
config.target_triple = "@TARGET_TRIPLE@"
+config.host_cxx = "@CMAKE_CXX_COMPILER@"
config.llvm_use_sanitizer = "@LLVM_USE_SANITIZER@"
config.have_zlib = @HAVE_LIBZ@
config.clang_arcmt = @CLANG_ENABLE_ARCMT@
@@ -24,6 +25,8 @@ config.clang_examples = @CLANG_BUILD_EXAMPLES@
config.enable_shared = @ENABLE_SHARED@
config.enable_backtrace = @ENABLE_BACKTRACES@
config.host_arch = "@HOST_ARCH@"
+config.enable_abi_breaking_checks = "@LLVM_ENABLE_ABI_BREAKING_CHECKS@"
+config.python_executable = "@PYTHON_EXECUTABLE@"
# Support substitution of the tools and libs dirs with user parameters. This is
# used when we can't determine the tool dir at configuration time.
@@ -37,5 +40,7 @@ except KeyError:
key, = e.args
lit_config.fatal("unable to find %r parameter, use '--param=%s=VALUE'" % (key,key))
+@LIT_SITE_CFG_IN_FOOTER@
+
# Let the main config do the real work.
-lit_config.load_config(config, "@CLANG_SOURCE_DIR@/test/lit.cfg")
+lit_config.load_config(config, "@CLANG_SOURCE_DIR@/test/lit.cfg.py")